summaryrefslogtreecommitdiffstats
path: root/WebCore/html
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/html')
-rw-r--r--WebCore/html/BaseButtonInputType.cpp38
-rw-r--r--WebCore/html/BaseButtonInputType.h3
-rw-r--r--WebCore/html/BaseCheckableInputType.cpp22
-rw-r--r--WebCore/html/BaseCheckableInputType.h2
-rw-r--r--WebCore/html/BaseDateAndTimeInputType.cpp11
-rw-r--r--WebCore/html/BaseDateAndTimeInputType.h1
-rw-r--r--WebCore/html/CheckboxInputType.cpp16
-rw-r--r--WebCore/html/CheckboxInputType.h2
-rw-r--r--WebCore/html/DateTimeInputType.cpp6
-rw-r--r--WebCore/html/DateTimeInputType.h1
-rw-r--r--WebCore/html/DocTypeStrings.gperf13
-rw-r--r--WebCore/html/FileInputType.cpp6
-rw-r--r--WebCore/html/FileInputType.h1
-rw-r--r--WebCore/html/HTMLAreaElement.cpp8
-rw-r--r--WebCore/html/HTMLFieldSetElement.h1
-rw-r--r--WebCore/html/HTMLImageLoader.cpp7
-rw-r--r--WebCore/html/HTMLInputElement.cpp306
-rw-r--r--WebCore/html/HTMLInputElement.h3
-rw-r--r--WebCore/html/HTMLKeygenElement.h1
-rw-r--r--WebCore/html/HTMLLinkElement.idl2
-rw-r--r--WebCore/html/HTMLMeterElement.cpp10
-rw-r--r--WebCore/html/HTMLMeterElement.h4
-rw-r--r--WebCore/html/HTMLObjectElement.cpp8
-rw-r--r--WebCore/html/HTMLOutputElement.cpp18
-rw-r--r--WebCore/html/HTMLProgressElement.h2
-rw-r--r--WebCore/html/HTMLScriptElement.cpp10
-rw-r--r--WebCore/html/HTMLScriptElement.h6
-rw-r--r--WebCore/html/HTMLStyleElement.idl2
-rw-r--r--WebCore/html/HTMLTagNames.in4
-rw-r--r--WebCore/html/InputType.cpp38
-rw-r--r--WebCore/html/InputType.h8
-rw-r--r--WebCore/html/MonthInputType.cpp17
-rw-r--r--WebCore/html/MonthInputType.h1
-rw-r--r--WebCore/html/RadioInputType.cpp105
-rw-r--r--WebCore/html/RadioInputType.h3
-rw-r--r--WebCore/html/RangeInputType.cpp14
-rw-r--r--WebCore/html/RangeInputType.h1
-rw-r--r--WebCore/html/TextFieldInputType.cpp6
-rw-r--r--WebCore/html/TextFieldInputType.h1
-rw-r--r--WebCore/html/TimeInputType.cpp18
-rw-r--r--WebCore/html/TimeInputType.h1
-rw-r--r--WebCore/html/ValidityState.cpp15
-rw-r--r--WebCore/html/canvas/ArrayBuffer.cpp5
-rw-r--r--WebCore/html/canvas/ArrayBufferView.h3
-rw-r--r--WebCore/html/canvas/ArrayBufferView.idl3
-rw-r--r--WebCore/html/canvas/CanvasRenderingContext2D.cpp9
-rwxr-xr-xWebCore/html/canvas/DataView.cpp228
-rwxr-xr-xWebCore/html/canvas/DataView.h92
-rwxr-xr-xWebCore/html/canvas/DataView.idl83
-rw-r--r--WebCore/html/canvas/Float32Array.cpp7
-rw-r--r--WebCore/html/canvas/Float32Array.h8
-rw-r--r--WebCore/html/canvas/Float32Array.idl3
-rw-r--r--WebCore/html/canvas/Int16Array.cpp7
-rw-r--r--WebCore/html/canvas/Int16Array.h8
-rw-r--r--WebCore/html/canvas/Int16Array.idl3
-rw-r--r--WebCore/html/canvas/Int32Array.cpp7
-rw-r--r--WebCore/html/canvas/Int32Array.h8
-rw-r--r--WebCore/html/canvas/Int32Array.idl3
-rw-r--r--WebCore/html/canvas/Int8Array.cpp7
-rw-r--r--WebCore/html/canvas/Int8Array.h8
-rw-r--r--WebCore/html/canvas/Int8Array.idl3
-rw-r--r--WebCore/html/canvas/TypedArrayBase.h4
-rw-r--r--WebCore/html/canvas/Uint16Array.cpp7
-rw-r--r--WebCore/html/canvas/Uint16Array.h8
-rw-r--r--WebCore/html/canvas/Uint16Array.idl3
-rw-r--r--WebCore/html/canvas/Uint32Array.cpp7
-rw-r--r--WebCore/html/canvas/Uint32Array.h8
-rw-r--r--WebCore/html/canvas/Uint32Array.idl3
-rw-r--r--WebCore/html/canvas/Uint8Array.cpp7
-rw-r--r--WebCore/html/canvas/Uint8Array.h8
-rw-r--r--WebCore/html/canvas/Uint8Array.idl3
-rw-r--r--WebCore/html/canvas/WebGLBuffer.cpp7
-rw-r--r--WebCore/html/canvas/WebGLBuffer.h2
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.cpp1
-rw-r--r--WebCore/html/canvas/WebGLFramebuffer.h6
-rw-r--r--WebCore/html/canvas/WebGLRenderbuffer.cpp1
-rw-r--r--WebCore/html/canvas/WebGLRenderbuffer.h6
-rw-r--r--WebCore/html/canvas/WebGLRenderingContext.cpp24
-rw-r--r--WebCore/html/canvas/WebGLTexture.h2
79 files changed, 1025 insertions, 319 deletions
diff --git a/WebCore/html/BaseButtonInputType.cpp b/WebCore/html/BaseButtonInputType.cpp
index fd6a8ff..0ba1d89 100644
--- a/WebCore/html/BaseButtonInputType.cpp
+++ b/WebCore/html/BaseButtonInputType.cpp
@@ -32,6 +32,7 @@
#include "BaseButtonInputType.h"
#include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
#include "RenderButton.h"
namespace WebCore {
@@ -42,6 +43,43 @@ bool BaseButtonInputType::appendFormData(FormDataList&, bool) const
return false;
}
+bool BaseButtonInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key == "U+0020") {
+ element()->setActive(true, true);
+ // No setDefaultHandled(), because IE dispatches a keypress in this case
+ // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+ }
+ return false;
+}
+
+bool BaseButtonInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+ int charCode = event->charCode();
+ if (charCode == '\r') {
+ element()->dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+ return true;
+ }
+ if (charCode == ' ') {
+ // Prevent scrolling down the page.
+ event->setDefaultHandled();
+ return true;
+ }
+ return false;
+}
+
+bool BaseButtonInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return false;
+ // Simulate mouse click for spacebar for button types.
+ dispatchSimulatedClickIfActive(event);
+ return true;
+}
+
RenderObject* BaseButtonInputType::createRenderer(RenderArena* arena, RenderStyle*) const
{
return new (arena) RenderButton(element());
diff --git a/WebCore/html/BaseButtonInputType.h b/WebCore/html/BaseButtonInputType.h
index e7f683b..59e28bf 100644
--- a/WebCore/html/BaseButtonInputType.h
+++ b/WebCore/html/BaseButtonInputType.h
@@ -42,6 +42,9 @@ protected:
private:
virtual bool appendFormData(FormDataList&, bool) const;
+ virtual bool handleKeydownEvent(KeyboardEvent*);
+ virtual bool handleKeypressEvent(KeyboardEvent*);
+ virtual bool handleKeyupEvent(KeyboardEvent*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
};
diff --git a/WebCore/html/BaseCheckableInputType.cpp b/WebCore/html/BaseCheckableInputType.cpp
index 009e8e4..940acf4 100644
--- a/WebCore/html/BaseCheckableInputType.cpp
+++ b/WebCore/html/BaseCheckableInputType.cpp
@@ -34,6 +34,7 @@
#include "FormDataList.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include "KeyboardEvent.h"
#include "RegularExpression.h"
namespace WebCore {
@@ -57,4 +58,25 @@ bool BaseCheckableInputType::appendFormData(FormDataList& encoding, bool) const
return true;
}
+bool BaseCheckableInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key == "U+0020") {
+ element()->setActive(true, true);
+ // No setDefaultHandled(), because IE dispatches a keypress in this case
+ // and the caller will only dispatch a keypress if we don't call setDefaultHandled().
+ }
+ return false;
+}
+
+bool BaseCheckableInputType::handleKeypressEvent(KeyboardEvent* event)
+{
+ if (event->charCode() == ' ') {
+ // Prevent scrolling down the page.
+ event->setDefaultHandled();
+ return true;
+ }
+ return false;
+}
+
} // namespace WebCore
diff --git a/WebCore/html/BaseCheckableInputType.h b/WebCore/html/BaseCheckableInputType.h
index 02edf29..8cb95cf 100644
--- a/WebCore/html/BaseCheckableInputType.h
+++ b/WebCore/html/BaseCheckableInputType.h
@@ -39,11 +39,13 @@ namespace WebCore {
class BaseCheckableInputType : public InputType {
protected:
BaseCheckableInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual bool handleKeydownEvent(KeyboardEvent*);
private:
virtual bool saveFormControlState(String&) const;
virtual void restoreFormControlState(const String&) const;
virtual bool appendFormData(FormDataList&, bool) const;
+ virtual bool handleKeypressEvent(KeyboardEvent*);
};
} // namespace WebCore
diff --git a/WebCore/html/BaseDateAndTimeInputType.cpp b/WebCore/html/BaseDateAndTimeInputType.cpp
index e780ed6..70243e5 100644
--- a/WebCore/html/BaseDateAndTimeInputType.cpp
+++ b/WebCore/html/BaseDateAndTimeInputType.cpp
@@ -35,6 +35,8 @@
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include <limits>
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
#include <wtf/text/WTFString.h>
@@ -91,6 +93,15 @@ bool BaseDateAndTimeInputType::rangeOverflow(const String& value) const
return isfinite(doubleValue) && doubleValue > maximum();
}
+double BaseDateAndTimeInputType::defaultValueForStepUp() const
+{
+ double ms = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(ms, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ return ms + (offset * msPerMinute);
+}
+
bool BaseDateAndTimeInputType::stepMismatch(const String& value, double step) const
{
const double nan = numeric_limits<double>::quiet_NaN();
diff --git a/WebCore/html/BaseDateAndTimeInputType.h b/WebCore/html/BaseDateAndTimeInputType.h
index 11c60af..ad7302a 100644
--- a/WebCore/html/BaseDateAndTimeInputType.h
+++ b/WebCore/html/BaseDateAndTimeInputType.h
@@ -55,6 +55,7 @@ private:
virtual bool typeMismatch() const;
virtual bool rangeUnderflow(const String&) const;
virtual bool rangeOverflow(const String&) const;
+ virtual double defaultValueForStepUp() const;
virtual bool stepMismatch(const String&, double) const;
virtual double stepBase() const;
virtual bool handleKeydownEvent(KeyboardEvent*);
diff --git a/WebCore/html/CheckboxInputType.cpp b/WebCore/html/CheckboxInputType.cpp
index 572dde0..cd171c1 100644
--- a/WebCore/html/CheckboxInputType.cpp
+++ b/WebCore/html/CheckboxInputType.cpp
@@ -32,6 +32,8 @@
#include "CheckboxInputType.h"
#include "HTMLInputElement.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -51,4 +53,18 @@ bool CheckboxInputType::valueMissing(const String&) const
return !element()->checked();
}
+String CheckboxInputType::valueMissingText() const
+{
+ return validationMessageValueMissingForCheckboxText();
+}
+
+bool CheckboxInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return false;
+ dispatchSimulatedClickIfActive(event);
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/html/CheckboxInputType.h b/WebCore/html/CheckboxInputType.h
index b68e14d..e66ab15 100644
--- a/WebCore/html/CheckboxInputType.h
+++ b/WebCore/html/CheckboxInputType.h
@@ -43,6 +43,8 @@ private:
CheckboxInputType(HTMLInputElement* element) : BaseCheckableInputType(element) { }
virtual const AtomicString& formControlType() const;
virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
+ virtual bool handleKeyupEvent(KeyboardEvent*);
};
} // namespace WebCore
diff --git a/WebCore/html/DateTimeInputType.cpp b/WebCore/html/DateTimeInputType.cpp
index c78a540..78641f8 100644
--- a/WebCore/html/DateTimeInputType.cpp
+++ b/WebCore/html/DateTimeInputType.cpp
@@ -34,6 +34,7 @@
#include "DateComponents.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -53,6 +54,11 @@ const AtomicString& DateTimeInputType::formControlType() const
return InputTypeNames::datetime();
}
+double DateTimeInputType::defaultValueForStepUp() const
+{
+ return currentTimeMS();
+}
+
double DateTimeInputType::minimum() const
{
return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumDateTime());
diff --git a/WebCore/html/DateTimeInputType.h b/WebCore/html/DateTimeInputType.h
index 140975b..9a0efd1 100644
--- a/WebCore/html/DateTimeInputType.h
+++ b/WebCore/html/DateTimeInputType.h
@@ -42,6 +42,7 @@ public:
private:
DateTimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
virtual const AtomicString& formControlType() const;
+ virtual double defaultValueForStepUp() const;
virtual double minimum() const;
virtual double maximum() const;
virtual double defaultStep() const;
diff --git a/WebCore/html/DocTypeStrings.gperf b/WebCore/html/DocTypeStrings.gperf
index 22488eb..2e2a7e8 100644
--- a/WebCore/html/DocTypeStrings.gperf
+++ b/WebCore/html/DocTypeStrings.gperf
@@ -1,3 +1,9 @@
+%{
+#include "HashTools.h"
+#include <string.h>
+
+namespace WebCore {
+%}
%struct-type
struct PubIDInfo;
%omit-struct-type
@@ -88,3 +94,10 @@ struct PubIDInfo;
"-//webtechs//dtd mozilla html//en", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
"-/w3c/dtd html 4.0 transitional/en", PubIDInfo::eQuirks, PubIDInfo::eQuirks
"html", PubIDInfo::eQuirks3, PubIDInfo::eQuirks3
+%%
+const PubIDInfo* findDoctypeEntry(register const char* str, register unsigned int len)
+{
+ return DocTypeStringsHash::findDoctypeEntryImpl(str, len);
+}
+
+} // namespace WebCore
diff --git a/WebCore/html/FileInputType.cpp b/WebCore/html/FileInputType.cpp
index e9d0b5e..b5fc2fb 100644
--- a/WebCore/html/FileInputType.cpp
+++ b/WebCore/html/FileInputType.cpp
@@ -27,6 +27,7 @@
#include "FileList.h"
#include "FormDataList.h"
#include "HTMLInputElement.h"
+#include "LocalizedStrings.h"
#include "RenderFileUploadControl.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/text/WTFString.h>
@@ -77,6 +78,11 @@ bool FileInputType::valueMissing(const String& value) const
return value.isEmpty();
}
+String FileInputType::valueMissingText() const
+{
+ return element()->multiple() ? validationMessageValueMissingForMultipleFileText() : validationMessageValueMissingForFileText();
+}
+
bool FileInputType::handleDOMActivateEvent(Event* event)
{
if (element()->disabled() || !element()->renderer())
diff --git a/WebCore/html/FileInputType.h b/WebCore/html/FileInputType.h
index 142afaf..df95ffc 100644
--- a/WebCore/html/FileInputType.h
+++ b/WebCore/html/FileInputType.h
@@ -44,6 +44,7 @@ private:
virtual const AtomicString& formControlType() const;
virtual bool appendFormData(FormDataList&, bool) const;
virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
virtual bool handleDOMActivateEvent(Event*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
};
diff --git a/WebCore/html/HTMLAreaElement.cpp b/WebCore/html/HTMLAreaElement.cpp
index cebfda2..dc87ef6 100644
--- a/WebCore/html/HTMLAreaElement.cpp
+++ b/WebCore/html/HTMLAreaElement.cpp
@@ -23,6 +23,7 @@
#include "HTMLAreaElement.h"
#include "Attribute.h"
+#include "Frame.h"
#include "HTMLImageElement.h"
#include "HTMLMapElement.h"
#include "HTMLNames.h"
@@ -98,6 +99,13 @@ Path HTMLAreaElement::getPath(RenderObject* obj) const
size = obj->absoluteOutlineBounds().size();
Path p = getRegion(size);
+ float zoomFactor = document()->frame()->pageZoomFactor();
+ if (zoomFactor != 1.0f) {
+ AffineTransform zoomTransform;
+ zoomTransform.scale(zoomFactor);
+ p.transform(zoomTransform);
+ }
+
p.translate(absPos - FloatPoint());
return p;
}
diff --git a/WebCore/html/HTMLFieldSetElement.h b/WebCore/html/HTMLFieldSetElement.h
index db99a89..dcc8d0c 100644
--- a/WebCore/html/HTMLFieldSetElement.h
+++ b/WebCore/html/HTMLFieldSetElement.h
@@ -35,6 +35,7 @@ public:
private:
HTMLFieldSetElement(const QualifiedName&, Document*, HTMLFormElement*);
+ virtual bool isEnumeratable() const { return true; }
virtual bool supportsFocus() const;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual const AtomicString& formControlType() const;
diff --git a/WebCore/html/HTMLImageLoader.cpp b/WebCore/html/HTMLImageLoader.cpp
index f620542..a1a3b26 100644
--- a/WebCore/html/HTMLImageLoader.cpp
+++ b/WebCore/html/HTMLImageLoader.cpp
@@ -48,7 +48,7 @@ HTMLImageLoader::~HTMLImageLoader()
void HTMLImageLoader::dispatchLoadEvent()
{
bool errorOccurred = image()->errorOccurred();
- if (!errorOccurred && image()->httpStatusCodeErrorOccurred())
+ if (!errorOccurred && image()->response().httpStatusCode() >= 400)
errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror.
element()->dispatchEvent(Event::create(errorOccurred ? eventNames().errorEvent : eventNames().loadEvent, false, false));
}
@@ -65,8 +65,9 @@ void HTMLImageLoader::notifyFinished(CachedResource*)
Element* elem = element();
ImageLoader::notifyFinished(cachedImage);
+ bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
#if USE(JSC)
- if (!cachedImage->errorOccurred() && !cachedImage->httpStatusCodeErrorOccurred()) {
+ if (!loadError) {
if (!elem->inDocument()) {
JSC::JSGlobalData* globalData = JSDOMWindowBase::commonJSGlobalData();
globalData->heap.reportExtraMemoryCost(cachedImage->encodedSize());
@@ -74,7 +75,7 @@ void HTMLImageLoader::notifyFinished(CachedResource*)
}
#endif
- if ((cachedImage->errorOccurred() || cachedImage->httpStatusCodeErrorOccurred()) && elem->hasTagName(HTMLNames::objectTag))
+ if (loadError && elem->hasTagName(HTMLNames::objectTag))
static_cast<HTMLObjectElement*>(elem)->renderFallbackContent();
}
diff --git a/WebCore/html/HTMLInputElement.cpp b/WebCore/html/HTMLInputElement.cpp
index b704fc1..765e4fc 100644
--- a/WebCore/html/HTMLInputElement.cpp
+++ b/WebCore/html/HTMLInputElement.cpp
@@ -283,6 +283,11 @@ String HTMLInputElement::typeMismatchText() const
return m_inputType->typeMismatchText();
}
+String HTMLInputElement::valueMissingText() const
+{
+ return m_inputType->valueMissingText();
+}
+
bool HTMLInputElement::getAllowedValueStep(double* step) const
{
return getAllowedValueStepWithDecimalPlaces(step, 0);
@@ -332,13 +337,13 @@ bool HTMLInputElement::getAllowedValueStepWithDecimalPlaces(double* step, unsign
void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
{
double step;
- unsigned stepDecimalPlaces;
+ unsigned stepDecimalPlaces, currentDecimalPlaces;
if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces)) {
ec = INVALID_STATE_ERR;
return;
}
const double nan = numeric_limits<double>::quiet_NaN();
- double current = m_inputType->parseToDouble(value(), nan);
+ double current = m_inputType->parseToDoubleWithDecimalPlaces(value(), nan, &currentDecimalPlaces);
if (!isfinite(current)) {
ec = INVALID_STATE_ERR;
return;
@@ -359,8 +364,13 @@ void HTMLInputElement::applyStep(double count, ExceptionCode& ec)
double base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
baseDecimalPlaces = min(baseDecimalPlaces, 16u);
if (newValue < pow(10.0, 21.0)) {
- double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
- newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
+ if (stepMismatch(value())) {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, currentDecimalPlaces)));
+ newValue = round(newValue * scale) / scale;
+ } else {
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+ newValue = round((base + round((newValue - base) / step) * step) * scale) / scale;
+ }
}
if (newValue - m_inputType->maximum() > acceptableError) {
ec = INVALID_STATE_ERR;
@@ -774,7 +784,7 @@ void HTMLInputElement::parseMappedAttribute(Attribute* attr)
#if ENABLE(INPUT_SPEECH)
else if (attr->name() == webkitspeechAttr) {
if (renderer())
- renderer()->updateFromElement();
+ toRenderTextControlSingleLine(renderer())->speechAttributeChanged();
setNeedsStyleRecalc();
} else if (attr->name() == onwebkitspeechchangeAttr)
setAttributeEventListener(eventNames().webkitspeechchangeEvent, createAttributeEventListener(this, attr));
@@ -1293,11 +1303,6 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// FIXME: It would be better to refactor this for the different types of input element.
// Having them all in one giant function makes this hard to read, and almost all the handling is type-specific.
- bool implicitSubmission = false;
-
- if (isTextField() && evt->type() == eventNames().textInputEvent && evt->isTextEvent() && static_cast<TextEvent*>(evt)->data() == "\n")
- implicitSubmission = true;
-
if (evt->isMouseEvent() && evt->type() == eventNames().clickEvent && m_inputType->handleClickEvent(static_cast<MouseEvent*>(evt)))
return;
@@ -1306,8 +1311,7 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// Call the base event handler before any of our own event handling for almost all events in text fields.
// Makes editing keyboard handling take precedence over the keydown and keypress handling in this function.
- bool callBaseClassEarly = isTextField() && !implicitSubmission
- && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
+ bool callBaseClassEarly = isTextField() && (evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
if (callBaseClassEarly) {
HTMLFormControlElementWithState::defaultEventHandler(evt);
if (evt->defaultHandled())
@@ -1323,180 +1327,13 @@ void HTMLInputElement::defaultEventHandler(Event* evt)
// Use key press event here since sending simulated mouse events
// on key down blocks the proper sending of the key press event.
- if (evt->type() == eventNames().keypressEvent && evt->isKeyboardEvent()) {
- bool clickElement = false;
-
- int charCode = static_cast<KeyboardEvent*>(evt)->charCode();
-
- if (charCode == '\r') {
- switch (deprecatedInputType()) {
- case CHECKBOX:
- case COLOR:
- case DATE:
- case DATETIME:
- case DATETIMELOCAL:
- case EMAIL:
- case HIDDEN:
- case ISINDEX:
- case MONTH:
- case NUMBER:
- case PASSWORD:
- case RADIO:
- case RANGE:
- case SEARCH:
- case TELEPHONE:
- case TEXT:
- case TIME:
- case URL:
- case WEEK:
- // Simulate mouse click on the default form button for enter for these types of elements.
- implicitSubmission = true;
- break;
- case BUTTON:
- case FILE:
- case IMAGE:
- case RESET:
- case SUBMIT:
- // Simulate mouse click for enter for these types of elements.
- clickElement = true;
- break;
- }
- } else if (charCode == ' ') {
- switch (deprecatedInputType()) {
- case BUTTON:
- case CHECKBOX:
- case FILE:
- case IMAGE:
- case RESET:
- case SUBMIT:
- case RADIO:
- // Prevent scrolling down the page.
- evt->setDefaultHandled();
- return;
- default:
- break;
- }
- }
-
- if (clickElement) {
- dispatchSimulatedClick(evt);
- evt->setDefaultHandled();
- return;
- }
- }
-
- if (evt->type() == eventNames().keydownEvent && evt->isKeyboardEvent()) {
- const String& key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
-
- if (key == "U+0020") {
- switch (deprecatedInputType()) {
- case BUTTON:
- case CHECKBOX:
- case FILE:
- case IMAGE:
- case RESET:
- case SUBMIT:
- case RADIO:
- setActive(true, true);
- // No setDefaultHandled(), because IE dispatches a keypress in this case
- // and the caller will only dispatch a keypress if we don't call setDefaultHandled.
- return;
- default:
- break;
- }
- }
-
- if (deprecatedInputType() == RADIO && (key == "Up" || key == "Down" || key == "Left" || key == "Right")) {
- // Left and up mean "previous radio button".
- // Right and down mean "next radio button".
- // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves
- // to the right). Seems strange, but we'll match it.
- // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
- if (!document()->frame() || !document()->frame()->settings() || !document()->frame()->settings()->isSpatialNavigationEnabled()) {
- bool forward = (key == "Down" || key == "Right");
-
- // We can only stay within the form's children if the form hasn't been demoted to a leaf because
- // of malformed HTML.
- Node* n = this;
- while ((n = (forward ? n->traverseNextNode() : n->traversePreviousNode()))) {
- // Once we encounter a form element, we know we're through.
- if (n->hasTagName(formTag))
- break;
-
- // Look for more radio buttons.
- if (n->hasTagName(inputTag)) {
- HTMLInputElement* elt = static_cast<HTMLInputElement*>(n);
- if (elt->form() != form())
- break;
- if (n->hasTagName(inputTag)) {
- HTMLInputElement* inputElt = static_cast<HTMLInputElement*>(n);
- if (inputElt->deprecatedInputType() == RADIO && inputElt->name() == name() && inputElt->isFocusable()) {
- inputElt->setChecked(true);
- document()->setFocusedNode(inputElt);
- inputElt->dispatchSimulatedClick(evt, false, false);
- evt->setDefaultHandled();
- break;
- }
- }
- }
- }
- }
- }
- }
-
- if (evt->type() == eventNames().keyupEvent && evt->isKeyboardEvent()) {
- bool clickElement = false;
-
- const String& key = static_cast<KeyboardEvent*>(evt)->keyIdentifier();
-
- if (key == "U+0020") {
- switch (deprecatedInputType()) {
- case BUTTON:
- case CHECKBOX:
- case FILE:
- case IMAGE:
- case RESET:
- case SUBMIT:
- // Simulate mouse click for spacebar for these types of elements.
- // The AppKit already does this for some, but not all, of them.
- clickElement = true;
- break;
- case RADIO:
- // If an unselected radio is tabbed into (because the entire group has nothing
- // checked, or because of some explicit .focus() call), then allow space to check it.
- if (!checked())
- clickElement = true;
- break;
- case COLOR:
- case DATE:
- case DATETIME:
- case DATETIMELOCAL:
- case EMAIL:
- case HIDDEN:
- case ISINDEX:
- case MONTH:
- case NUMBER:
- case PASSWORD:
- case RANGE:
- case SEARCH:
- case TELEPHONE:
- case TEXT:
- case TIME:
- case URL:
- case WEEK:
- break;
- }
- }
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keypressEvent && m_inputType->handleKeypressEvent(static_cast<KeyboardEvent*>(evt)))
+ return;
- if (clickElement) {
- if (active())
- dispatchSimulatedClick(evt);
- evt->setDefaultHandled();
- return;
- }
- }
+ if (evt->isKeyboardEvent() && evt->type() == eventNames().keyupEvent && m_inputType->handleKeyupEvent(static_cast<KeyboardEvent*>(evt)))
+ return;
- if (implicitSubmission) {
+ if (m_inputType->shouldSubmitImplicitly(evt)) {
if (isSearchField()) {
addSearchResult();
onSearch();
@@ -1860,37 +1697,113 @@ HTMLOptionElement* HTMLInputElement::selectedOption() const
void HTMLInputElement::stepUpFromRenderer(int n)
{
// The differences from stepUp()/stepDown():
- // If the current value is not a number, the value will be
- // - The value should be the minimum value if n > 0
- // - The value should be the maximum value if n < 0
+ //
+ // Difference 1: the current value
+ // If the current value is not a number, including empty, the current value is assumed as 0.
+ // * If 0 is in-range, and matches to step value
+ // - The value should be the +step if n > 0
+ // - The value should be the -step if n < 0
+ // If -step or +step is out of range, new value should be 0.
+ // * If 0 is smaller than the minimum value
+ // - The value should be the minimum value for any n
+ // * If 0 is larger than the maximum value
+ // - The value should be the maximum value for any n
+ // * If 0 is in-range, but not matched to step value
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number min=-100 step=3> -> 2
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number min=-100 step=3> -> -1
+ // As for date/datetime-local/month/time/week types, the current value is assumed as "the current local date/time".
+ // As for datetime type, the current value is assumed as "the current date/time in UTC".
// If the current value is smaller than the minimum value:
// - The value should be the minimum value if n > 0
// - Nothing should happen if n < 0
// If the current value is larger than the maximum value:
// - The value should be the maximum value if n < 0
// - Nothing should happen if n > 0
-
- ASSERT(hasSpinButton());
- if (!hasSpinButton())
+ //
+ // Difference 2: clamping steps
+ // If the current value is not matched to step value:
+ // - The value should be the larger matched value nearest to 0 if n > 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 5
+ // - The value should be the smaler matched value nearest to 0 if n < 0
+ // e.g. <input type=number value=3 min=-100 step=3> -> 2
+ //
+ // n is assumed as -n if step < 0.
+
+ ASSERT(hasSpinButton() || m_inputType->isRangeControl());
+ if (!hasSpinButton() && !m_inputType->isRangeControl())
return;
ASSERT(n);
if (!n)
return;
+ unsigned stepDecimalPlaces, baseDecimalPlaces;
+ double step, base;
+ // The value will be the default value after stepping for <input value=(empty/invalid) step="any" />
+ // FIXME: Not any changes after stepping, even if it is an invalid value, may be better.
+ // (e.g. Stepping-up for <input type="number" value="foo" step="any" /> => "foo")
+ if (equalIgnoringCase(getAttribute(stepAttr), "any"))
+ step = 0;
+ else if (!getAllowedValueStepWithDecimalPlaces(&step, &stepDecimalPlaces))
+ return;
+ base = m_inputType->stepBaseWithDecimalPlaces(&baseDecimalPlaces);
+ baseDecimalPlaces = min(baseDecimalPlaces, 16u);
+
+ int sign;
+ if (step > 0)
+ sign = n;
+ else if (step < 0)
+ sign = -n;
+ else
+ sign = 0;
+
const double nan = numeric_limits<double>::quiet_NaN();
String currentStringValue = value();
double current = m_inputType->parseToDouble(currentStringValue, nan);
- if (!isfinite(current) || (n > 0 && current < m_inputType->minimum()) || (n < 0 && current > m_inputType->maximum()))
- setValue(m_inputType->serialize(n > 0 ? m_inputType->minimum() : m_inputType->maximum()));
+ if (!isfinite(current)) {
+ ExceptionCode ec;
+ current = m_inputType->defaultValueForStepUp();
+ setValueAsNumber(current, ec);
+ }
+ if ((sign > 0 && current < m_inputType->minimum()) || (sign < 0 && current > m_inputType->maximum()))
+ setValue(m_inputType->serialize(sign > 0 ? m_inputType->minimum() : m_inputType->maximum()));
else {
ExceptionCode ec;
- stepUp(n, ec);
+ if (stepMismatch(currentStringValue)) {
+ ASSERT(step);
+ double newValue;
+ double scale = pow(10.0, static_cast<double>(max(stepDecimalPlaces, baseDecimalPlaces)));
+
+ if (sign < 0)
+ newValue = round((base + floor((current - base) / step) * step) * scale) / scale;
+ else if (sign > 0)
+ newValue = round((base + ceil((current - base) / step) * step) * scale) / scale;
+ else
+ newValue = current;
+
+ if (newValue < m_inputType->minimum())
+ newValue = m_inputType->minimum();
+ if (newValue > m_inputType->maximum())
+ newValue = m_inputType->maximum();
+
+ setValueAsNumber(newValue, ec);
+ current = newValue;
+ if (n > 1)
+ applyStep(n - 1, ec);
+ else if (n < -1)
+ applyStep(n + 1, ec);
+ } else
+ applyStep(n, ec);
}
if (currentStringValue != value()) {
if (renderer() && renderer()->isTextField())
toRenderTextControl(renderer())->setChangedSinceLastChangeEvent(true);
- dispatchEvent(Event::create(eventNames().inputEvent, true, false));
+ if (m_inputType->isRangeControl())
+ dispatchFormControlChangeEvent();
+ else
+ dispatchEvent(Event::create(eventNames().inputEvent, true, false));
}
}
@@ -1938,11 +1851,6 @@ bool HTMLInputElement::isSpeechEnabled() const
return false;
}
-void HTMLInputElement::dispatchWebkitSpeechChangeEvent()
-{
- ASSERT(isSpeechEnabled());
- dispatchEvent(Event::create(eventNames().webkitspeechchangeEvent, true, false));
-}
#endif
} // namespace
diff --git a/WebCore/html/HTMLInputElement.h b/WebCore/html/HTMLInputElement.h
index 9884117..0f0e97e 100644
--- a/WebCore/html/HTMLInputElement.h
+++ b/WebCore/html/HTMLInputElement.h
@@ -27,6 +27,7 @@
#include "HTMLFormControlElement.h"
#include "HTMLFormElement.h"
#include "InputElement.h"
+#include "InputType.h"
#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -73,6 +74,7 @@ public:
String stepBaseString() const;
String stepString() const;
String typeMismatchText() const;
+ String valueMissingText() const;
// Implementations of HTMLInputElement::stepUp() and stepDown().
void stepUp(int, ExceptionCode&);
@@ -107,7 +109,6 @@ public:
#if ENABLE(INPUT_SPEECH)
virtual bool isSpeechEnabled() const;
- void dispatchWebkitSpeechChangeEvent();
#endif
bool checked() const { return m_checked; }
diff --git a/WebCore/html/HTMLKeygenElement.h b/WebCore/html/HTMLKeygenElement.h
index 4c08014..f722e5b 100644
--- a/WebCore/html/HTMLKeygenElement.h
+++ b/WebCore/html/HTMLKeygenElement.h
@@ -36,7 +36,6 @@ private:
HTMLKeygenElement(const QualifiedName&, Document*, HTMLFormElement*);
virtual const AtomicString& formControlType() const;
- virtual bool isEnumeratable() const { return false; }
virtual void parseMappedAttribute(Attribute*);
virtual bool appendFormData(FormDataList&, bool);
diff --git a/WebCore/html/HTMLLinkElement.idl b/WebCore/html/HTMLLinkElement.idl
index 734e8cc..9419e15 100644
--- a/WebCore/html/HTMLLinkElement.idl
+++ b/WebCore/html/HTMLLinkElement.idl
@@ -20,7 +20,7 @@
module html {
- interface HTMLLinkElement : HTMLElement {
+ interface [CustomMarkFunction] HTMLLinkElement : HTMLElement {
attribute [Reflect] boolean disabled;
attribute [Reflect] DOMString charset;
attribute [Reflect, URL] DOMString href;
diff --git a/WebCore/html/HTMLMeterElement.cpp b/WebCore/html/HTMLMeterElement.cpp
index 3de69df..09c5210 100644
--- a/WebCore/html/HTMLMeterElement.cpp
+++ b/WebCore/html/HTMLMeterElement.cpp
@@ -36,17 +36,15 @@ namespace WebCore {
using namespace HTMLNames;
-// FIXME: This constructor should take an explicit form element pointer passed from the
-// parser like the constructors for all the other classes derived from HTMLFormControlElement.
-HTMLMeterElement::HTMLMeterElement(const QualifiedName& tagName, Document* document)
- : HTMLFormControlElement(tagName, document, 0)
+HTMLMeterElement::HTMLMeterElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
+ : HTMLFormControlElement(tagName, document, form)
{
ASSERT(hasTagName(meterTag));
}
-PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document)
+PassRefPtr<HTMLMeterElement> HTMLMeterElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
{
- return adoptRef(new HTMLMeterElement(tagName, document));
+ return adoptRef(new HTMLMeterElement(tagName, document, form));
}
RenderObject* HTMLMeterElement::createRenderer(RenderArena* arena, RenderStyle*)
diff --git a/WebCore/html/HTMLMeterElement.h b/WebCore/html/HTMLMeterElement.h
index cefad97..dedad6a 100644
--- a/WebCore/html/HTMLMeterElement.h
+++ b/WebCore/html/HTMLMeterElement.h
@@ -28,7 +28,7 @@ namespace WebCore {
class HTMLMeterElement : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLMeterElement> create(const QualifiedName&, Document*);
+ static PassRefPtr<HTMLMeterElement> create(const QualifiedName&, Document*, HTMLFormElement*);
enum GaugeRegion {
GaugeRegionOptimum,
@@ -56,7 +56,7 @@ public:
GaugeRegion gaugeRegion() const;
private:
- HTMLMeterElement(const QualifiedName&, Document*);
+ HTMLMeterElement(const QualifiedName&, Document*, HTMLFormElement*);
virtual bool recalcWillValidate() const { return false; }
diff --git a/WebCore/html/HTMLObjectElement.cpp b/WebCore/html/HTMLObjectElement.cpp
index c07d050..69974a8 100644
--- a/WebCore/html/HTMLObjectElement.cpp
+++ b/WebCore/html/HTMLObjectElement.cpp
@@ -287,12 +287,8 @@ bool HTMLObjectElement::rendererIsNeeded(RenderStyle* style)
Frame* frame = document()->frame();
if (!frame)
return false;
-
- // Temporary Workaround for Gears plugin - see bug 24215 for details and bug 24346 to track removal.
- // Gears expects the plugin to be instantiated even if display:none is set
- // for the object element.
- bool isGearsPlugin = equalIgnoringCase(getAttribute(typeAttr), "application/x-googlegears");
- return isGearsPlugin || HTMLPlugInImageElement::rendererIsNeeded(style);
+
+ return HTMLPlugInImageElement::rendererIsNeeded(style);
}
void HTMLObjectElement::insertedIntoDocument()
diff --git a/WebCore/html/HTMLOutputElement.cpp b/WebCore/html/HTMLOutputElement.cpp
index b83263e..2f1d490 100644
--- a/WebCore/html/HTMLOutputElement.cpp
+++ b/WebCore/html/HTMLOutputElement.cpp
@@ -40,7 +40,7 @@ inline HTMLOutputElement::HTMLOutputElement(const QualifiedName& tagName, Docume
: HTMLFormControlElement(tagName, document, form)
, m_isDefaultValueMode(true)
, m_isSetTextContentInProgress(false)
- , m_defaultValue()
+ , m_defaultValue("")
, m_tokens(DOMSettableTokenList::create())
{
}
@@ -91,6 +91,8 @@ void HTMLOutputElement::reset()
// value mode flag to "default" and then to set the element's textContent
// attribute to the default value.
m_isDefaultValueMode = true;
+ if (m_defaultValue == value())
+ return;
setTextContentInternal(m_defaultValue);
}
@@ -103,6 +105,8 @@ void HTMLOutputElement::setValue(const String& value)
{
// The value mode flag set to "value" when the value attribute is set.
m_isDefaultValueMode = false;
+ if (value == this->value())
+ return;
setTextContentInternal(value);
}
@@ -113,11 +117,13 @@ String HTMLOutputElement::defaultValue() const
void HTMLOutputElement::setDefaultValue(const String& value)
{
- m_defaultValue = value;
- // The spec requires the value attribute set to the default value
- // when the element's value mode flag to "default".
- if (m_isDefaultValueMode)
- setTextContentInternal(value);
+ if (m_defaultValue == value)
+ return;
+ m_defaultValue = value;
+ // The spec requires the value attribute set to the default value
+ // when the element's value mode flag to "default".
+ if (m_isDefaultValueMode)
+ setTextContentInternal(value);
}
void HTMLOutputElement::setTextContentInternal(const String& value)
diff --git a/WebCore/html/HTMLProgressElement.h b/WebCore/html/HTMLProgressElement.h
index 7900063..429e9c0 100644
--- a/WebCore/html/HTMLProgressElement.h
+++ b/WebCore/html/HTMLProgressElement.h
@@ -28,7 +28,7 @@ namespace WebCore {
class HTMLProgressElement : public HTMLFormControlElement {
public:
- static PassRefPtr<HTMLProgressElement> create(const QualifiedName&, Document*, HTMLFormElement* = 0);
+ static PassRefPtr<HTMLProgressElement> create(const QualifiedName&, Document*, HTMLFormElement*);
double value() const;
void setValue(double, ExceptionCode&);
diff --git a/WebCore/html/HTMLScriptElement.cpp b/WebCore/html/HTMLScriptElement.cpp
index 0ee93df..e229bb8 100644
--- a/WebCore/html/HTMLScriptElement.cpp
+++ b/WebCore/html/HTMLScriptElement.cpp
@@ -35,16 +35,16 @@ namespace WebCore {
using namespace HTMLNames;
-inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document* document, bool createdByParser, bool isEvaluated)
+inline HTMLScriptElement::HTMLScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool wasAlreadyStarted)
: HTMLElement(tagName, document)
- , ScriptElement(this, createdByParser, isEvaluated)
+ , ScriptElement(this, wasInsertedByParser, wasAlreadyStarted)
{
ASSERT(hasTagName(scriptTag));
}
-PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document* document, bool createdByParser)
+PassRefPtr<HTMLScriptElement> HTMLScriptElement::create(const QualifiedName& tagName, Document* document, bool wasInsertedByParser)
{
- return adoptRef(new HTMLScriptElement(tagName, document, createdByParser, false));
+ return adoptRef(new HTMLScriptElement(tagName, document, wasInsertedByParser, false));
}
bool HTMLScriptElement::isURLAttribute(Attribute* attr) const
@@ -175,7 +175,7 @@ void HTMLScriptElement::dispatchErrorEvent()
PassRefPtr<Element> HTMLScriptElement::cloneElementWithoutAttributesAndChildren() const
{
- return adoptRef(new HTMLScriptElement(tagQName(), document(), false, isEvaluated()));
+ return adoptRef(new HTMLScriptElement(tagQName(), document(), false, wasAlreadyStarted()));
}
}
diff --git a/WebCore/html/HTMLScriptElement.h b/WebCore/html/HTMLScriptElement.h
index 5b91ecc..09773c5 100644
--- a/WebCore/html/HTMLScriptElement.h
+++ b/WebCore/html/HTMLScriptElement.h
@@ -31,17 +31,15 @@ namespace WebCore {
class HTMLScriptElement : public HTMLElement, public ScriptElement {
public:
- static PassRefPtr<HTMLScriptElement> create(const QualifiedName&, Document*, bool createdByParser);
+ static PassRefPtr<HTMLScriptElement> create(const QualifiedName&, Document*, bool wasInsertedByParser);
String text() const { return scriptContent(); }
void setText(const String&);
KURL src() const;
- bool haveFiredLoadEvent() const { return ScriptElement::haveFiredLoadEvent(); }
-
private:
- HTMLScriptElement(const QualifiedName&, Document*, bool createdByParser, bool isEvaluated);
+ HTMLScriptElement(const QualifiedName&, Document*, bool wasInsertedByParser, bool wasAlreadyStarted);
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
diff --git a/WebCore/html/HTMLStyleElement.idl b/WebCore/html/HTMLStyleElement.idl
index 29a8924..d78e9d3 100644
--- a/WebCore/html/HTMLStyleElement.idl
+++ b/WebCore/html/HTMLStyleElement.idl
@@ -20,7 +20,7 @@
module html {
- interface HTMLStyleElement : HTMLElement {
+ interface [CustomMarkFunction] HTMLStyleElement : HTMLElement {
attribute [Reflect] boolean disabled;
attribute [Reflect] DOMString media;
attribute [Reflect] DOMString type;
diff --git a/WebCore/html/HTMLTagNames.in b/WebCore/html/HTMLTagNames.in
index be2cf90..cd4ebcc 100644
--- a/WebCore/html/HTMLTagNames.in
+++ b/WebCore/html/HTMLTagNames.in
@@ -83,7 +83,7 @@ mark interfaceName=HTMLElement
marquee
menu
meta
-meter interfaceName=HTMLMeterElement, conditional=METER_TAG
+meter interfaceName=HTMLMeterElement, constructorNeedsFormElement, conditional=METER_TAG
nav interfaceName=HTMLElement
nobr interfaceName=HTMLElement
noembed interfaceName=HTMLElement
@@ -98,7 +98,7 @@ p interfaceName=HTMLParagraphElement
param
plaintext interfaceName=HTMLElement
pre
-progress interfaceName=HTMLProgressElement, conditional=PROGRESS_TAG
+progress interfaceName=HTMLProgressElement, constructorNeedsFormElement, conditional=PROGRESS_TAG
q interfaceName=HTMLQuoteElement
rp interfaceName=HTMLElement
rt interfaceName=HTMLElement
diff --git a/WebCore/html/InputType.cpp b/WebCore/html/InputType.cpp
index 6dd002c..8a7a979 100644
--- a/WebCore/html/InputType.cpp
+++ b/WebCore/html/InputType.cpp
@@ -41,6 +41,7 @@
#include "HiddenInputType.h"
#include "ImageInputType.h"
#include "IsIndexInputType.h"
+#include "KeyboardEvent.h"
#include "LocalizedStrings.h"
#include "MonthInputType.h"
#include "NumberInputType.h"
@@ -125,6 +126,11 @@ bool InputType::isTextType() const
return false;
}
+bool InputType::isRangeControl() const
+{
+ return false;
+}
+
bool InputType::saveFormControlState(String& result) const
{
String currentValue = element()->value();
@@ -213,6 +219,11 @@ bool InputType::rangeOverflow(const String&) const
return false;
}
+double InputType::defaultValueForStepUp() const
+{
+ return 0;
+}
+
double InputType::minimum() const
{
ASSERT_NOT_REACHED();
@@ -275,6 +286,11 @@ String InputType::typeMismatchText() const
return validationMessageTypeMismatchText();
}
+String InputType::valueMissingText() const
+{
+ return validationMessageValueMissingText();
+}
+
bool InputType::handleClickEvent(MouseEvent*)
{
return false;
@@ -290,6 +306,21 @@ bool InputType::handleKeydownEvent(KeyboardEvent*)
return false;
}
+bool InputType::handleKeypressEvent(KeyboardEvent*)
+{
+ return false;
+}
+
+bool InputType::handleKeyupEvent(KeyboardEvent*)
+{
+ return false;
+}
+
+bool InputType::shouldSubmitImplicitly(Event* event)
+{
+ return event->isKeyboardEvent() && event->type() == eventNames().keypressEvent && static_cast<KeyboardEvent*>(event)->charCode() == '\r';
+}
+
RenderObject* InputType::createRenderer(RenderArena*, RenderStyle* style) const
{
return RenderObject::createObject(element(), style);
@@ -319,6 +350,12 @@ String InputType::serialize(double) const
return String();
}
+void InputType::dispatchSimulatedClickIfActive(KeyboardEvent* event) const
+{
+ if (element()->active())
+ element()->dispatchSimulatedClick(event);
+ event->setDefaultHandled();
+}
namespace InputTypeNames {
@@ -472,4 +509,3 @@ const AtomicString& week()
} // namespace WebCore::InpuTypeNames
} // namespace WebCore
-
diff --git a/WebCore/html/InputType.h b/WebCore/html/InputType.h
index f1a5b6d..f275ae8 100644
--- a/WebCore/html/InputType.h
+++ b/WebCore/html/InputType.h
@@ -60,6 +60,7 @@ public:
virtual bool isTextField() const;
virtual bool isTextType() const;
+ virtual bool isRangeControl() const;
virtual const AtomicString& formControlType() const = 0;
// Form value functions
@@ -89,6 +90,7 @@ public:
virtual bool patternMismatch(const String&) const;
virtual bool rangeUnderflow(const String&) const;
virtual bool rangeOverflow(const String&) const;
+ virtual double defaultValueForStepUp() const;
virtual double minimum() const;
virtual double maximum() const;
virtual bool stepMismatch(const String&, double) const;
@@ -100,6 +102,7 @@ public:
virtual bool scaledStepValeuShouldBeInteger() const;
virtual double acceptableError(double) const;
virtual String typeMismatchText() const;
+ virtual String valueMissingText() const;
// Event handlers
// If the return value is true, do no further default event handling in the
@@ -109,6 +112,10 @@ public:
virtual bool handleClickEvent(MouseEvent*);
virtual bool handleDOMActivateEvent(Event*);
virtual bool handleKeydownEvent(KeyboardEvent*);
+ virtual bool handleKeypressEvent(KeyboardEvent*);
+ virtual bool handleKeyupEvent(KeyboardEvent*);
+ // A helper for event handlers.
+ virtual bool shouldSubmitImplicitly(Event*);
// Miscellaneous functions
@@ -136,6 +143,7 @@ public:
protected:
InputType(HTMLInputElement* element) : m_element(element) { }
HTMLInputElement* element() const { return m_element; }
+ void dispatchSimulatedClickIfActive(KeyboardEvent*) const;
// We can't make this a static const data member because VC++ doesn't like it.
static double defaultStepBase() { return 0.0; }
diff --git a/WebCore/html/MonthInputType.cpp b/WebCore/html/MonthInputType.cpp
index cbde5cb..38f9d00 100644
--- a/WebCore/html/MonthInputType.cpp
+++ b/WebCore/html/MonthInputType.cpp
@@ -34,6 +34,8 @@
#include "DateComponents.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
@@ -74,6 +76,21 @@ void MonthInputType::setValueAsDate(double value, ExceptionCode&) const
element()->setValue(date.toString());
}
+double MonthInputType::defaultValueForStepUp() const
+{
+ double current = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(current, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ current += offset * msPerMinute;
+
+ DateComponents date;
+ date.setMillisecondsSinceEpochForMonth(current);
+ double months = date.monthsSinceEpoch();
+ ASSERT(isfinite(months));
+ return months;
+}
+
double MonthInputType::minimum() const
{
return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumMonth());
diff --git a/WebCore/html/MonthInputType.h b/WebCore/html/MonthInputType.h
index 50cf7d5..23536e2 100644
--- a/WebCore/html/MonthInputType.h
+++ b/WebCore/html/MonthInputType.h
@@ -45,6 +45,7 @@ private:
virtual double valueAsDate() const;
virtual void setValueAsDate(double, ExceptionCode&) const;
virtual double parseToDouble(const String&, double) const;
+ virtual double defaultValueForStepUp() const;
virtual double minimum() const;
virtual double maximum() const;
virtual double defaultStep() const;
diff --git a/WebCore/html/RadioInputType.cpp b/WebCore/html/RadioInputType.cpp
index a6c4707..4c459be 100644
--- a/WebCore/html/RadioInputType.cpp
+++ b/WebCore/html/RadioInputType.cpp
@@ -1,42 +1,41 @@
/*
+ * Copyright (C) 2005 Apple Inc. All rights reserved.
* Copyright (C) 2010 Google Inc. All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
*
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- * * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
*
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#include "RadioInputType.h"
+#include "Frame.h"
#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "KeyboardEvent.h"
+#include "LocalizedStrings.h"
#include "MouseEvent.h"
+#include "Settings.h"
+#include "SpatialNavigation.h"
#include <wtf/PassOwnPtr.h>
namespace WebCore {
+using namespace HTMLNames;
+
PassOwnPtr<InputType> RadioInputType::create(HTMLInputElement* element)
{
return adoptPtr(new RadioInputType(element));
@@ -52,10 +51,70 @@ bool RadioInputType::valueMissing(const String&) const
return !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
}
+String RadioInputType::valueMissingText() const
+{
+ return validationMessageValueMissingForRadioText();
+}
+
bool RadioInputType::handleClickEvent(MouseEvent* event)
{
event->setDefaultHandled();
return true;
}
+bool RadioInputType::handleKeydownEvent(KeyboardEvent* event)
+{
+ if (BaseCheckableInputType::handleKeydownEvent(event))
+ return true;
+ const String& key = event->keyIdentifier();
+ if (key != "Up" && key != "Down" && key != "Left" && key != "Right")
+ return false;
+
+ // Left and up mean "previous radio button".
+ // Right and down mean "next radio button".
+ // Tested in WinIE, and even for RTL, left still means previous radio button (and so moves
+ // to the right). Seems strange, but we'll match it.
+ // However, when using Spatial Navigation, we need to be able to navigate without changing the selection.
+ Document* document = element()->document();
+ if (isSpatialNavigationEnabled(document->frame()))
+ return false;
+ bool forward = (key == "Down" || key == "Right");
+
+ // We can only stay within the form's children if the form hasn't been demoted to a leaf because
+ // of malformed HTML.
+ Node* node = element();
+ while ((node = (forward ? node->traverseNextNode() : node->traversePreviousNode()))) {
+ // Once we encounter a form element, we know we're through.
+ if (node->hasTagName(formTag))
+ break;
+ // Look for more radio buttons.
+ if (!node->hasTagName(inputTag))
+ continue;
+ HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node);
+ if (inputElement->form() != element()->form())
+ break;
+ if (inputElement->isRadioButton() && inputElement->name() == element()->name() && inputElement->isFocusable()) {
+ inputElement->setChecked(true);
+ document->setFocusedNode(inputElement);
+ inputElement->dispatchSimulatedClick(event, false, false);
+ event->setDefaultHandled();
+ return true;
+ }
+ }
+ return false;
+}
+
+bool RadioInputType::handleKeyupEvent(KeyboardEvent* event)
+{
+ const String& key = event->keyIdentifier();
+ if (key != "U+0020")
+ return false;
+ // If an unselected radio is tabbed into (because the entire group has nothing
+ // checked, or because of some explicit .focus() call), then allow space to check it.
+ if (element()->checked())
+ return false;
+ dispatchSimulatedClickIfActive(event);
+ return true;
+}
+
} // namespace WebCore
diff --git a/WebCore/html/RadioInputType.h b/WebCore/html/RadioInputType.h
index 2798010..62becf6 100644
--- a/WebCore/html/RadioInputType.h
+++ b/WebCore/html/RadioInputType.h
@@ -43,7 +43,10 @@ private:
RadioInputType(HTMLInputElement* element) : BaseCheckableInputType(element) { }
virtual const AtomicString& formControlType() const;
virtual bool valueMissing(const String&) const;
+ virtual String valueMissingText() const;
virtual bool handleClickEvent(MouseEvent*);
+ virtual bool handleKeydownEvent(KeyboardEvent*);
+ virtual bool handleKeyupEvent(KeyboardEvent*);
};
} // namespace WebCore
diff --git a/WebCore/html/RangeInputType.cpp b/WebCore/html/RangeInputType.cpp
index ad47f14..50520cd 100644
--- a/WebCore/html/RangeInputType.cpp
+++ b/WebCore/html/RangeInputType.cpp
@@ -55,6 +55,11 @@ PassOwnPtr<InputType> RangeInputType::create(HTMLInputElement* element)
return adoptPtr(new RangeInputType(element));
}
+bool RangeInputType::isRangeControl() const
+{
+ return true;
+}
+
const AtomicString& RangeInputType::formControlType() const
{
return InputTypeNames::range();
@@ -143,6 +148,9 @@ bool RangeInputType::handleKeydownEvent(KeyboardEvent* event)
double step = (max - min) / 100;
double current = parseToDouble(element()->value(), numeric_limits<double>::quiet_NaN());
ASSERT(isfinite(current));
+ // Stepping-up and -down for step="any" are special cases for type="range" from renderer for convenient.
+ // No stepping normally for step="any". They cannot be handled by stepUp()/stepDown()/stepUpFromRenderer().
+ // So calculating values stepped-up or -down here.
double newValue;
if (key == "Up" || key == "Right") {
newValue = current + step;
@@ -159,10 +167,8 @@ bool RangeInputType::handleKeydownEvent(KeyboardEvent* event)
}
} else {
int stepMagnification = (key == "Up" || key == "Right") ? 1 : -1;
- String lastStringValue = element()->value();
- element()->stepUp(stepMagnification, ec);
- if (lastStringValue != element()->value())
- element()->dispatchFormControlChangeEvent();
+ // Reasonable stepping-up/-down by stepUpFromRenderer() unless step="any"
+ element()->stepUpFromRenderer(stepMagnification);
}
event->setDefaultHandled();
return true;
diff --git a/WebCore/html/RangeInputType.h b/WebCore/html/RangeInputType.h
index c2bbb0f..14280e8 100644
--- a/WebCore/html/RangeInputType.h
+++ b/WebCore/html/RangeInputType.h
@@ -41,6 +41,7 @@ public:
private:
RangeInputType(HTMLInputElement* element) : InputType(element) { }
+ virtual bool isRangeControl() const;
virtual const AtomicString& formControlType() const;
virtual double valueAsNumber() const;
virtual void setValueAsNumber(double, ExceptionCode&) const;
diff --git a/WebCore/html/TextFieldInputType.cpp b/WebCore/html/TextFieldInputType.cpp
index d93f972..8b74359 100644
--- a/WebCore/html/TextFieldInputType.cpp
+++ b/WebCore/html/TextFieldInputType.cpp
@@ -35,6 +35,7 @@
#include "HTMLInputElement.h"
#include "KeyboardEvent.h"
#include "RenderTextControlSingleLine.h"
+#include "TextEvent.h"
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -75,6 +76,11 @@ bool TextFieldInputType::handleKeydownEventForSpinButton(KeyboardEvent* event)
return true;
}
+bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
+{
+ return (event->type() == eventNames().textInputEvent && event->isTextEvent() && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
+}
+
RenderObject* TextFieldInputType::createRenderer(RenderArena* arena, RenderStyle*) const
{
return new (arena) RenderTextControlSingleLine(element(), element()->placeholderShouldBeVisible());
diff --git a/WebCore/html/TextFieldInputType.h b/WebCore/html/TextFieldInputType.h
index 50418aa..07f06e9 100644
--- a/WebCore/html/TextFieldInputType.h
+++ b/WebCore/html/TextFieldInputType.h
@@ -44,6 +44,7 @@ protected:
virtual bool valueMissing(const String&) const;
virtual bool handleKeydownEvent(KeyboardEvent*);
bool handleKeydownEventForSpinButton(KeyboardEvent*);
+ virtual bool shouldSubmitImplicitly(Event*);
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const;
};
diff --git a/WebCore/html/TimeInputType.cpp b/WebCore/html/TimeInputType.cpp
index 27dce90..6b381be 100644
--- a/WebCore/html/TimeInputType.cpp
+++ b/WebCore/html/TimeInputType.cpp
@@ -34,6 +34,9 @@
#include "DateComponents.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
+#include <wtf/CurrentTime.h>
+#include <wtf/DateMath.h>
+#include <wtf/MathExtras.h>
#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -53,6 +56,21 @@ const AtomicString& TimeInputType::formControlType() const
return InputTypeNames::time();
}
+double TimeInputType::defaultValueForStepUp() const
+{
+ double current = currentTimeMS();
+ double utcOffset = calculateUTCOffset();
+ double dstOffset = calculateDSTOffset(current, utcOffset);
+ int offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute);
+ current += offset * msPerMinute;
+
+ DateComponents date;
+ date.setMillisecondsSinceMidnight(current);
+ double milliseconds = date.millisecondsSinceEpoch();
+ ASSERT(isfinite(milliseconds));
+ return milliseconds;
+}
+
double TimeInputType::minimum() const
{
return parseToDouble(element()->fastGetAttribute(minAttr), DateComponents::minimumTime());
diff --git a/WebCore/html/TimeInputType.h b/WebCore/html/TimeInputType.h
index 6070fa0..b50d987 100644
--- a/WebCore/html/TimeInputType.h
+++ b/WebCore/html/TimeInputType.h
@@ -42,6 +42,7 @@ public:
private:
TimeInputType(HTMLInputElement* element) : BaseDateAndTimeInputType(element) { }
virtual const AtomicString& formControlType() const;
+ virtual double defaultValueForStepUp() const;
virtual double minimum() const;
virtual double maximum() const;
virtual double defaultStep() const;
diff --git a/WebCore/html/ValidityState.cpp b/WebCore/html/ValidityState.cpp
index 84fc664..ef3de66 100644
--- a/WebCore/html/ValidityState.cpp
+++ b/WebCore/html/ValidityState.cpp
@@ -42,17 +42,24 @@ String ValidityState::validationMessage() const
if (customError())
return m_customErrorMessage;
- if (valueMissing())
- return validationMessageValueMissingText();
- if (patternMismatch())
- return validationMessagePatternMismatchText();
bool isInputElement = m_control->hasTagName(inputTag);
bool isTextAreaElement = m_control->hasTagName(textareaTag);
+ // The order of the following checks is meaningful. e.g. We'd like to show the
+ // valueMissing message even if the control has other validation errors.
+ if (valueMissing()) {
+ if (m_control->hasTagName(selectTag))
+ return validationMessageValueMissingForSelectText();
+ if (isInputElement)
+ return static_cast<HTMLInputElement*>(m_control)->valueMissingText();
+ return validationMessageValueMissingText();
+ }
if (typeMismatch()) {
if (isInputElement)
return static_cast<HTMLInputElement*>(m_control)->typeMismatchText();
return validationMessageTypeMismatchText();
}
+ if (patternMismatch())
+ return validationMessagePatternMismatchText();
if (tooLong()) {
if (!isInputElement && !isTextAreaElement) {
ASSERT_NOT_REACHED();
diff --git a/WebCore/html/canvas/ArrayBuffer.cpp b/WebCore/html/canvas/ArrayBuffer.cpp
index ee8f149..2136f64 100644
--- a/WebCore/html/canvas/ArrayBuffer.cpp
+++ b/WebCore/html/canvas/ArrayBuffer.cpp
@@ -85,7 +85,10 @@ ArrayBuffer::~ArrayBuffer()
void* ArrayBuffer::tryAllocate(unsigned numElements, unsigned elementByteSize)
{
void* result;
- // Do not allow 32-bit overflow of the total size
+ // Do not allow 32-bit overflow of the total size.
+ // FIXME: Why not? The tryFastCalloc function already checks its arguments,
+ // and will fail if there is any overflow, so why should we include a
+ // redudant unnecessarily restrictive check here?
if (numElements) {
unsigned totalSize = numElements * elementByteSize;
if (totalSize / numElements != elementByteSize)
diff --git a/WebCore/html/canvas/ArrayBufferView.h b/WebCore/html/canvas/ArrayBufferView.h
index ee685b1..701abbc 100644
--- a/WebCore/html/canvas/ArrayBufferView.h
+++ b/WebCore/html/canvas/ArrayBufferView.h
@@ -46,6 +46,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
virtual bool isIntArray() const { return false; }
virtual bool isUnsignedIntArray() const { return false; }
virtual bool isFloatArray() const { return false; }
+ virtual bool isDataView() const { return false; }
PassRefPtr<ArrayBuffer> buffer() const
{
@@ -62,9 +63,7 @@ class ArrayBufferView : public RefCounted<ArrayBufferView> {
return m_byteOffset;
}
- virtual unsigned length() const = 0;
virtual unsigned byteLength() const = 0;
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const = 0;
virtual ~ArrayBufferView();
diff --git a/WebCore/html/canvas/ArrayBufferView.idl b/WebCore/html/canvas/ArrayBufferView.idl
index 74a3fe3..be217c1 100644
--- a/WebCore/html/canvas/ArrayBufferView.idl
+++ b/WebCore/html/canvas/ArrayBufferView.idl
@@ -28,8 +28,5 @@ module html {
readonly attribute ArrayBuffer buffer;
readonly attribute unsigned long byteOffset;
readonly attribute unsigned long byteLength;
- readonly attribute unsigned long length;
-
- [Custom] ArrayBufferView slice(in long start, in long end);
};
}
diff --git a/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index b9f86ce..eb552c6 100644
--- a/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -813,9 +813,7 @@ void CanvasRenderingContext2D::fill()
return;
if (!m_path.isEmpty()) {
- c->beginPath();
- c->addPath(m_path);
- c->fillPath();
+ c->fillPath(m_path);
didDraw(m_path.boundingRect());
}
@@ -833,9 +831,6 @@ void CanvasRenderingContext2D::stroke()
return;
if (!m_path.isEmpty()) {
- c->beginPath();
- c->addPath(m_path);
-
#if PLATFORM(QT)
// Fast approximation of the stroke's bounding rect.
// This yields a slightly oversized rect but is very fast
@@ -846,7 +841,7 @@ void CanvasRenderingContext2D::stroke()
CanvasStrokeStyleApplier strokeApplier(this);
FloatRect boundingRect = m_path.strokeBoundingRect(&strokeApplier);
#endif
- c->strokePath();
+ c->strokePath(m_path);
didDraw(boundingRect);
}
diff --git a/WebCore/html/canvas/DataView.cpp b/WebCore/html/canvas/DataView.cpp
new file mode 100755
index 0000000..d030211
--- /dev/null
+++ b/WebCore/html/canvas/DataView.cpp
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(3D_CANVAS) || ENABLE(BLOB)
+
+#include "DataView.h"
+
+namespace {
+
+template<typename T>
+union Value {
+ T data;
+ char bytes[sizeof(T)];
+};
+
+}
+
+namespace WebCore {
+
+PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+{
+ if (byteOffset + byteLength > buffer->byteLength())
+ return 0;
+ return adoptRef(new DataView(buffer, byteOffset, byteLength));
+}
+
+DataView::DataView(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
+ : ArrayBufferView(buffer, byteOffset)
+ , m_byteLength(byteLength)
+{
+}
+
+static bool needToFlipBytes(bool littleEndian)
+{
+#if CPU(BIG_ENDIAN)
+ return littleEndian;
+#else
+ return !littleEndian;
+#endif
+}
+
+inline void swapBytes(char* p, char* q)
+{
+ char temp = *p;
+ *p = *q;
+ *q = temp;
+}
+
+static void flipBytesFor16Bits(char* p)
+{
+ swapBytes(p, p + 1);
+}
+
+static void flipBytesFor32Bits(char* p)
+{
+ swapBytes(p, p + 3);
+ swapBytes(p + 1, p + 2);
+}
+
+static void flipBytesFor64Bits(char* p)
+{
+ swapBytes(p, p + 7);
+ swapBytes(p + 1, p + 6);
+ swapBytes(p + 2, p + 5);
+ swapBytes(p + 3, p + 4);
+}
+
+static void flipBytesIfNeeded(char* value, size_t size, bool littleEndian)
+{
+ if (!needToFlipBytes(littleEndian))
+ return;
+
+ switch (size) {
+ case 1:
+ // Nothing to do.
+ break;
+ case 2:
+ flipBytesFor16Bits(value);
+ break;
+ case 4:
+ flipBytesFor32Bits(value);
+ break;
+ case 8:
+ flipBytesFor64Bits(value);
+ break;
+ default:
+ ASSERT_NOT_REACHED();
+ break;
+ }
+}
+
+template<typename T>
+T DataView::getData(unsigned byteOffset, bool littleEndian, ExceptionCode& ec) const
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return 0;
+ }
+
+ // We do not want to load the data directly since it would cause a bus error on architectures that don't support unaligned loads.
+ Value<T> value;
+ memcpy(value.bytes, static_cast<const char*>(m_baseAddress) + byteOffset, sizeof(T));
+ flipBytesIfNeeded(value.bytes, sizeof(T), littleEndian);
+ return value.data;
+}
+
+template<typename T>
+void DataView::setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode& ec)
+{
+ if (beyondRange<T>(byteOffset)) {
+ ec = INDEX_SIZE_ERR;
+ return;
+ }
+
+ // We do not want to store the data directly since it would cause a bus error on architectures that don't support unaligned stores.
+ Value<T> tempValue;
+ tempValue.data = value;
+ flipBytesIfNeeded(tempValue.bytes, sizeof(T), littleEndian);
+ memcpy(static_cast<char*>(m_baseAddress) + byteOffset, tempValue.bytes, sizeof(T));
+}
+
+char DataView::getInt8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<char>(byteOffset, false, ec);
+}
+
+unsigned char DataView::getUint8(unsigned byteOffset, ExceptionCode& ec)
+{
+ return getData<unsigned char>(byteOffset, false, ec);
+}
+
+short DataView::getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<short>(byteOffset, littleEndian, ec);
+}
+
+unsigned short DataView::getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<unsigned short>(byteOffset, littleEndian, ec);
+}
+
+int DataView::getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<int>(byteOffset, littleEndian, ec);
+}
+
+unsigned DataView::getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<unsigned>(byteOffset, littleEndian, ec);
+}
+
+float DataView::getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<float>(byteOffset, littleEndian, ec);
+}
+
+double DataView::getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode& ec)
+{
+ return getData<double>(byteOffset, littleEndian, ec);
+}
+
+void DataView::setInt8(unsigned byteOffset, char value, ExceptionCode& ec)
+{
+ setData<char>(byteOffset, value, false, ec);
+}
+
+void DataView::setUint8(unsigned byteOffset, unsigned char value, ExceptionCode& ec)
+{
+ setData<unsigned char>(byteOffset, value, false, ec);
+}
+
+void DataView::setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<short>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint16(unsigned byteOffset, unsigned short value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<unsigned short>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setInt32(unsigned byteOffset, int value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<int>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setUint32(unsigned byteOffset, unsigned value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<unsigned>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<float>(byteOffset, value, littleEndian, ec);
+}
+
+void DataView::setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode& ec)
+{
+ setData<double>(byteOffset, value, littleEndian, ec);
+}
+
+}
+
+#endif // ENABLE(3D_CANVAS) || ENABLE(BLOB)
diff --git a/WebCore/html/canvas/DataView.h b/WebCore/html/canvas/DataView.h
new file mode 100755
index 0000000..0681341
--- /dev/null
+++ b/WebCore/html/canvas/DataView.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DataView_h
+#define DataView_h
+
+#include "ArrayBufferView.h"
+#include "ExceptionCode.h"
+#include <wtf/PassRefPtr.h>
+
+namespace WebCore {
+
+class DataView : public ArrayBufferView {
+public:
+ static PassRefPtr<DataView> create(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ virtual bool isDataView() const { return true; }
+ virtual unsigned length() const { return m_byteLength; }
+ virtual unsigned byteLength() const { return m_byteLength; }
+ virtual PassRefPtr<ArrayBufferView> slice(int, int) const { return 0; }
+
+ char getInt8(unsigned byteOffset, ExceptionCode&);
+ unsigned char getUint8(unsigned byteOffset, ExceptionCode&);
+ short getInt16(unsigned byteOffset, ExceptionCode& ec) { return getInt16(byteOffset, false, ec); }
+ short getInt16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ unsigned short getUint16(unsigned byteOffset, ExceptionCode& ec) { return getUint16(byteOffset, false, ec); }
+ unsigned short getUint16(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ int getInt32(unsigned byteOffset, ExceptionCode& ec) { return getInt32(byteOffset, false, ec); }
+ int getInt32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ unsigned getUint32(unsigned byteOffset, ExceptionCode& ec) { return getUint32(byteOffset, false, ec); }
+ unsigned getUint32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ float getFloat32(unsigned byteOffset, ExceptionCode& ec) { return getFloat32(byteOffset, false, ec); }
+ float getFloat32(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+ double getFloat64(unsigned byteOffset, ExceptionCode& ec) { return getFloat64(byteOffset, false, ec); }
+ double getFloat64(unsigned byteOffset, bool littleEndian, ExceptionCode&);
+
+ void setInt8(unsigned byteOffset, char value, ExceptionCode&);
+ void setUint8(unsigned byteOffset, unsigned char value, ExceptionCode&);
+ void setInt16(unsigned byteOffset, short value, ExceptionCode& ec) { setInt16(byteOffset, value, false, ec); }
+ void setInt16(unsigned byteOffset, short value, bool littleEndian, ExceptionCode&);
+ void setUint16(unsigned byteOffset, unsigned short value, ExceptionCode& ec) { setUint16(byteOffset, value, false, ec); }
+ void setUint16(unsigned byteOffset, unsigned short value, bool littleEndian, ExceptionCode&);
+ void setInt32(unsigned byteOffset, int value, ExceptionCode& ec) { setInt32(byteOffset, value, false, ec); }
+ void setInt32(unsigned byteOffset, int value, bool littleEndian, ExceptionCode&);
+ void setUint32(unsigned byteOffset, unsigned value, ExceptionCode& ec) { setUint32(byteOffset, value, false, ec); }
+ void setUint32(unsigned byteOffset, unsigned value, bool littleEndian, ExceptionCode&);
+ void setFloat32(unsigned byteOffset, float value, ExceptionCode& ec) { setFloat32(byteOffset, value, false, ec); }
+ void setFloat32(unsigned byteOffset, float value, bool littleEndian, ExceptionCode&);
+ void setFloat64(unsigned byteOffset, double value, ExceptionCode& ec) { setFloat64(byteOffset, value, false, ec); }
+ void setFloat64(unsigned byteOffset, double value, bool littleEndian, ExceptionCode&);
+
+private:
+ DataView(PassRefPtr<ArrayBuffer>, unsigned byteOffset, unsigned byteLength);
+
+ template<typename T>
+ inline bool beyondRange(unsigned byteOffset) const { return byteOffset + sizeof(T) > m_byteLength; }
+
+ template<typename T>
+ T getData(unsigned byteOffset, bool littleEndian, ExceptionCode&) const;
+
+ template<typename T>
+ void setData(unsigned byteOffset, T value, bool littleEndian, ExceptionCode&);
+
+ unsigned m_byteLength;
+};
+
+
+} // namespace WebCore
+
+#endif // DataView_h
diff --git a/WebCore/html/canvas/DataView.idl b/WebCore/html/canvas/DataView.idl
new file mode 100755
index 0000000..bef8805
--- /dev/null
+++ b/WebCore/html/canvas/DataView.idl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+module html {
+
+ interface [
+ Conditional=3D_CANVAS|BLOB,
+ CanBeConstructed,
+ CustomConstructFunction,
+ CustomToJS,
+ NoStaticTables,
+ V8CustomConstructor
+ ] DataView : ArrayBufferView {
+ // All these methods raise an exception if they would read or write beyond the end of the view.
+
+ // We have to use custom code because our code generator does not support char type.
+ // char getInt8(in unsigned long byteOffset);
+ // unsigned char getUint8(in unsigned long byteOffset);
+ [Custom] DOMObject getInt8()
+ raises (DOMException);
+ [Custom] DOMObject getUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] short getInt16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] unsigned short getUint16(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] long getInt32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] unsigned long getUint32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // Use custom code to handle NaN case for JSC.
+ [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] float getFloat32(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [JSCCustom, StrictTypeChecking, RequiresAllArguments=Raise] double getFloat64(in unsigned long byteOffset, in [Optional] boolean littleEndian)
+ raises (DOMException);
+
+ // We have to use custom code because our code generator does not support char type.
+ // void setInt8(in unsigned long byteOffset, in byte value);
+ // void setUint8(in unsigned long byteOffset, in unsigned byte value);
+ [Custom] void setInt8()
+ raises (DOMException);
+ [Custom] void setUint8()
+ raises (DOMException);
+
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setInt16(in unsigned long byteOffset, in short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setUint16(in unsigned long byteOffset, in unsigned short value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setInt32(in unsigned long byteOffset, in long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setUint32(in unsigned long byteOffset, in unsigned long value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat32(in unsigned long byteOffset, in float value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ [StrictTypeChecking, RequiresAllArguments=Raise] void setFloat64(in unsigned long byteOffset, in double value, in [Optional] boolean littleEndian)
+ raises (DOMException);
+ };
+
+}
diff --git a/WebCore/html/canvas/Float32Array.cpp b/WebCore/html/canvas/Float32Array.cpp
index e918d8f..1b26aef 100644
--- a/WebCore/html/canvas/Float32Array.cpp
+++ b/WebCore/html/canvas/Float32Array.cpp
@@ -52,7 +52,12 @@ Float32Array::Float32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset,
{
}
-PassRefPtr<ArrayBufferView> Float32Array::slice(int start, int end) const
+PassRefPtr<Float32Array> Float32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Float32Array> Float32Array::slice(int start, int end) const
{
return sliceImpl<Float32Array>(start, end);
}
diff --git a/WebCore/html/canvas/Float32Array.h b/WebCore/html/canvas/Float32Array.h
index ab57087..c03fcc3 100644
--- a/WebCore/html/canvas/Float32Array.h
+++ b/WebCore/html/canvas/Float32Array.h
@@ -33,7 +33,7 @@
namespace WebCore {
class Float32Array : public TypedArrayBase<float> {
- public:
+public:
static PassRefPtr<Float32Array> create(unsigned length);
static PassRefPtr<Float32Array> create(const float* array, unsigned length);
static PassRefPtr<Float32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -62,7 +62,10 @@ class Float32Array : public TypedArrayBase<float> {
return result;
}
- private:
+ PassRefPtr<Float32Array> slice(int start) const;
+ PassRefPtr<Float32Array> slice(int start, int end) const;
+
+private:
Float32Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -71,7 +74,6 @@ class Float32Array : public TypedArrayBase<float> {
// Overridden from ArrayBufferView.
virtual bool isFloatArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Float32Array.idl b/WebCore/html/canvas/Float32Array.idl
index c3c0a2d..b979d29 100644
--- a/WebCore/html/canvas/Float32Array.idl
+++ b/WebCore/html/canvas/Float32Array.idl
@@ -39,6 +39,9 @@ module html {
] Float32Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 4;
+ readonly attribute unsigned long length;
+ Float32Array slice(in long start, in [Optional] long end);
+
// void set(in Float32Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/Int16Array.cpp b/WebCore/html/canvas/Int16Array.cpp
index 635ea5e..a3d04bc 100644
--- a/WebCore/html/canvas/Int16Array.cpp
+++ b/WebCore/html/canvas/Int16Array.cpp
@@ -51,7 +51,12 @@ Int16Array::Int16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi
{
}
-PassRefPtr<ArrayBufferView> Int16Array::slice(int start, int end) const
+PassRefPtr<Int16Array> Int16Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int16Array> Int16Array::slice(int start, int end) const
{
return sliceImpl<Int16Array>(start, end);
}
diff --git a/WebCore/html/canvas/Int16Array.h b/WebCore/html/canvas/Int16Array.h
index 00877ef..a6286c6 100644
--- a/WebCore/html/canvas/Int16Array.h
+++ b/WebCore/html/canvas/Int16Array.h
@@ -33,7 +33,7 @@ namespace WebCore {
class ArrayBuffer;
class Int16Array : public IntegralTypedArrayBase<short> {
- public:
+public:
static PassRefPtr<Int16Array> create(unsigned length);
static PassRefPtr<Int16Array> create(short* array, unsigned length);
static PassRefPtr<Int16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -41,7 +41,10 @@ class Int16Array : public IntegralTypedArrayBase<short> {
using TypedArrayBase<short>::set;
using IntegralTypedArrayBase<short>::set;
- private:
+ PassRefPtr<Int16Array> slice(int start) const;
+ PassRefPtr<Int16Array> slice(int start, int end) const;
+
+private:
Int16Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -50,7 +53,6 @@ class Int16Array : public IntegralTypedArrayBase<short> {
// Overridden from ArrayBufferView.
virtual bool isShortArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Int16Array.idl b/WebCore/html/canvas/Int16Array.idl
index 7980a69..f1f5c8b 100644
--- a/WebCore/html/canvas/Int16Array.idl
+++ b/WebCore/html/canvas/Int16Array.idl
@@ -38,6 +38,9 @@ module html {
] Int16Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 2;
+ readonly attribute unsigned long length;
+ Int16Array slice(in long start, in [Optional] long end);
+
// void set(in Int16Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/Int32Array.cpp b/WebCore/html/canvas/Int32Array.cpp
index cc926a3..266c941 100644
--- a/WebCore/html/canvas/Int32Array.cpp
+++ b/WebCore/html/canvas/Int32Array.cpp
@@ -52,7 +52,12 @@ Int32Array::Int32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi
{
}
-PassRefPtr<ArrayBufferView> Int32Array::slice(int start, int end) const
+PassRefPtr<Int32Array> Int32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int32Array> Int32Array::slice(int start, int end) const
{
return sliceImpl<Int32Array>(start, end);
}
diff --git a/WebCore/html/canvas/Int32Array.h b/WebCore/html/canvas/Int32Array.h
index bd05450..068a677 100644
--- a/WebCore/html/canvas/Int32Array.h
+++ b/WebCore/html/canvas/Int32Array.h
@@ -32,7 +32,7 @@
namespace WebCore {
class Int32Array : public IntegralTypedArrayBase<int> {
- public:
+public:
static PassRefPtr<Int32Array> create(unsigned length);
static PassRefPtr<Int32Array> create(int* array, unsigned length);
static PassRefPtr<Int32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -42,7 +42,10 @@ class Int32Array : public IntegralTypedArrayBase<int> {
using IntegralTypedArrayBase<int>::set;
#endif
- private:
+ PassRefPtr<Int32Array> slice(int start) const;
+ PassRefPtr<Int32Array> slice(int start, int end) const;
+
+private:
Int32Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -51,7 +54,6 @@ class Int32Array : public IntegralTypedArrayBase<int> {
// Overridden from ArrayBufferView.
virtual bool isIntArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Int32Array.idl b/WebCore/html/canvas/Int32Array.idl
index bd1554d..f96b53c 100644
--- a/WebCore/html/canvas/Int32Array.idl
+++ b/WebCore/html/canvas/Int32Array.idl
@@ -39,6 +39,9 @@ module html {
] Int32Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 4;
+ readonly attribute unsigned long length;
+ Int32Array slice(in long start, in [Optional] long end);
+
// void set(in Int32Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/Int8Array.cpp b/WebCore/html/canvas/Int8Array.cpp
index c2dd2fa..89ed316 100644
--- a/WebCore/html/canvas/Int8Array.cpp
+++ b/WebCore/html/canvas/Int8Array.cpp
@@ -52,7 +52,12 @@ Int8Array::Int8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsign
{
}
-PassRefPtr<ArrayBufferView> Int8Array::slice(int start, int end) const
+PassRefPtr<Int8Array> Int8Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Int8Array> Int8Array::slice(int start, int end) const
{
return sliceImpl<Int8Array>(start, end);
}
diff --git a/WebCore/html/canvas/Int8Array.h b/WebCore/html/canvas/Int8Array.h
index d267f7f..a5df302 100644
--- a/WebCore/html/canvas/Int8Array.h
+++ b/WebCore/html/canvas/Int8Array.h
@@ -34,7 +34,7 @@ namespace WebCore {
class ArrayBuffer;
class Int8Array : public IntegralTypedArrayBase<signed char> {
- public:
+public:
static PassRefPtr<Int8Array> create(unsigned length);
static PassRefPtr<Int8Array> create(signed char* array, unsigned length);
static PassRefPtr<Int8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -42,7 +42,10 @@ class Int8Array : public IntegralTypedArrayBase<signed char> {
using TypedArrayBase<signed char>::set;
using IntegralTypedArrayBase<signed char>::set;
- private:
+ PassRefPtr<Int8Array> slice(int start) const;
+ PassRefPtr<Int8Array> slice(int start, int end) const;
+
+private:
Int8Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -51,7 +54,6 @@ class Int8Array : public IntegralTypedArrayBase<signed char> {
// Overridden from ArrayBufferView.
virtual bool isByteArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Int8Array.idl b/WebCore/html/canvas/Int8Array.idl
index ec0bdb7..08a608b 100644
--- a/WebCore/html/canvas/Int8Array.idl
+++ b/WebCore/html/canvas/Int8Array.idl
@@ -39,6 +39,9 @@ module html {
] Int8Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 1;
+ readonly attribute unsigned long length;
+ Int8Array slice(in long start, in [Optional] long end);
+
// void set(in Int8Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/TypedArrayBase.h b/WebCore/html/canvas/TypedArrayBase.h
index 77283df..2bef6f0 100644
--- a/WebCore/html/canvas/TypedArrayBase.h
+++ b/WebCore/html/canvas/TypedArrayBase.h
@@ -55,12 +55,12 @@ class TypedArrayBase : public ArrayBufferView {
// Overridden from ArrayBufferView. This must be public because of
// rules about inheritance of members in template classes, and
// because it is accessed via pointers to subclasses.
- virtual unsigned length() const
+ unsigned length() const
{
return m_length;
}
- protected:
+ protected:
TypedArrayBase(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length)
: ArrayBufferView(buffer, byteOffset)
, m_length(length)
diff --git a/WebCore/html/canvas/Uint16Array.cpp b/WebCore/html/canvas/Uint16Array.cpp
index a0f891c..5312888 100644
--- a/WebCore/html/canvas/Uint16Array.cpp
+++ b/WebCore/html/canvas/Uint16Array.cpp
@@ -52,7 +52,12 @@ Uint16Array::Uint16Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un
{
}
-PassRefPtr<ArrayBufferView> Uint16Array::slice(int start, int end) const
+PassRefPtr<Uint16Array> Uint16Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint16Array> Uint16Array::slice(int start, int end) const
{
return sliceImpl<Uint16Array>(start, end);
}
diff --git a/WebCore/html/canvas/Uint16Array.h b/WebCore/html/canvas/Uint16Array.h
index fee31f6..f63b67d 100644
--- a/WebCore/html/canvas/Uint16Array.h
+++ b/WebCore/html/canvas/Uint16Array.h
@@ -34,7 +34,7 @@ namespace WebCore {
class ArrayBuffer;
class Uint16Array : public IntegralTypedArrayBase<unsigned short> {
- public:
+public:
static PassRefPtr<Uint16Array> create(unsigned length);
static PassRefPtr<Uint16Array> create(unsigned short* array, unsigned length);
static PassRefPtr<Uint16Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -42,7 +42,10 @@ class Uint16Array : public IntegralTypedArrayBase<unsigned short> {
using TypedArrayBase<unsigned short>::set;
using IntegralTypedArrayBase<unsigned short>::set;
- private:
+ PassRefPtr<Uint16Array> slice(int start) const;
+ PassRefPtr<Uint16Array> slice(int start, int end) const;
+
+private:
Uint16Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -51,7 +54,6 @@ class Uint16Array : public IntegralTypedArrayBase<unsigned short> {
// Overridden from ArrayBufferView.
virtual bool isUnsignedShortArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Uint16Array.idl b/WebCore/html/canvas/Uint16Array.idl
index 75a7499..8e778b4 100644
--- a/WebCore/html/canvas/Uint16Array.idl
+++ b/WebCore/html/canvas/Uint16Array.idl
@@ -39,6 +39,9 @@ module html {
] Uint16Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 2;
+ readonly attribute unsigned long length;
+ Uint16Array slice(in long start, in [Optional] long end);
+
// void set(in Uint16Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/Uint32Array.cpp b/WebCore/html/canvas/Uint32Array.cpp
index f49a83a..f5bd959 100644
--- a/WebCore/html/canvas/Uint32Array.cpp
+++ b/WebCore/html/canvas/Uint32Array.cpp
@@ -52,7 +52,12 @@ Uint32Array::Uint32Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, un
{
}
-PassRefPtr<ArrayBufferView> Uint32Array::slice(int start, int end) const
+PassRefPtr<Uint32Array> Uint32Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint32Array> Uint32Array::slice(int start, int end) const
{
return sliceImpl<Uint32Array>(start, end);
}
diff --git a/WebCore/html/canvas/Uint32Array.h b/WebCore/html/canvas/Uint32Array.h
index db23088..9c0f137 100644
--- a/WebCore/html/canvas/Uint32Array.h
+++ b/WebCore/html/canvas/Uint32Array.h
@@ -34,7 +34,7 @@ namespace WebCore {
class ArrayBuffer;
class Uint32Array : public IntegralTypedArrayBase<unsigned int> {
- public:
+public:
static PassRefPtr<Uint32Array> create(unsigned length);
static PassRefPtr<Uint32Array> create(unsigned int* array, unsigned length);
static PassRefPtr<Uint32Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -42,7 +42,10 @@ class Uint32Array : public IntegralTypedArrayBase<unsigned int> {
using TypedArrayBase<unsigned int>::set;
using IntegralTypedArrayBase<unsigned int>::set;
- private:
+ PassRefPtr<Uint32Array> slice(int start) const;
+ PassRefPtr<Uint32Array> slice(int start, int end) const;
+
+private:
Uint32Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -51,7 +54,6 @@ class Uint32Array : public IntegralTypedArrayBase<unsigned int> {
// Overridden from ArrayBufferView.
virtual bool isUnsignedIntArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Uint32Array.idl b/WebCore/html/canvas/Uint32Array.idl
index 06e17c6..9fbf30c 100644
--- a/WebCore/html/canvas/Uint32Array.idl
+++ b/WebCore/html/canvas/Uint32Array.idl
@@ -39,6 +39,9 @@ module html {
] Uint32Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 4;
+ readonly attribute unsigned long length;
+ Uint32Array slice(in long start, in [Optional] long end);
+
// void set(in Uint32Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/Uint8Array.cpp b/WebCore/html/canvas/Uint8Array.cpp
index 6c785f9..99b8a09 100644
--- a/WebCore/html/canvas/Uint8Array.cpp
+++ b/WebCore/html/canvas/Uint8Array.cpp
@@ -52,7 +52,12 @@ Uint8Array::Uint8Array(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsi
{
}
-PassRefPtr<ArrayBufferView> Uint8Array::slice(int start, int end) const
+PassRefPtr<Uint8Array> Uint8Array::slice(int start) const
+{
+ return slice(start, length());
+}
+
+PassRefPtr<Uint8Array> Uint8Array::slice(int start, int end) const
{
return sliceImpl<Uint8Array>(start, end);
}
diff --git a/WebCore/html/canvas/Uint8Array.h b/WebCore/html/canvas/Uint8Array.h
index fce63da..66154b5 100644
--- a/WebCore/html/canvas/Uint8Array.h
+++ b/WebCore/html/canvas/Uint8Array.h
@@ -34,7 +34,7 @@ namespace WebCore {
class ArrayBuffer;
class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
- public:
+public:
static PassRefPtr<Uint8Array> create(unsigned length);
static PassRefPtr<Uint8Array> create(unsigned char* array, unsigned length);
static PassRefPtr<Uint8Array> create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned length);
@@ -44,7 +44,10 @@ class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
using IntegralTypedArrayBase<unsigned char>::set;
#endif
- private:
+ PassRefPtr<Uint8Array> slice(int start) const;
+ PassRefPtr<Uint8Array> slice(int start, int end) const;
+
+private:
Uint8Array(PassRefPtr<ArrayBuffer> buffer,
unsigned byteOffset,
unsigned length);
@@ -53,7 +56,6 @@ class Uint8Array : public IntegralTypedArrayBase<unsigned char> {
// Overridden from ArrayBufferView.
virtual bool isUnsignedByteArray() const { return true; }
- virtual PassRefPtr<ArrayBufferView> slice(int start, int end) const;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/Uint8Array.idl b/WebCore/html/canvas/Uint8Array.idl
index bd28023..7fe7e21 100644
--- a/WebCore/html/canvas/Uint8Array.idl
+++ b/WebCore/html/canvas/Uint8Array.idl
@@ -39,6 +39,9 @@ module html {
] Uint8Array : ArrayBufferView {
const unsigned int BYTES_PER_ELEMENT = 1;
+ readonly attribute unsigned long length;
+ Uint8Array slice(in long start, in [Optional] long end);
+
// void set(in Uint8Array array, [Optional] in unsigned long offset);
// void set(in sequence<long> array, [Optional] in unsigned long offset);
[Custom] void set();
diff --git a/WebCore/html/canvas/WebGLBuffer.cpp b/WebCore/html/canvas/WebGLBuffer.cpp
index 99d9cad..36ef048 100644
--- a/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/WebCore/html/canvas/WebGLBuffer.cpp
@@ -170,8 +170,7 @@ unsigned WebGLBuffer::byteLength() const
long WebGLBuffer::getCachedMaxIndex(unsigned long type)
{
- size_t numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry);
- for (size_t i = 0; i < numEntries; i++)
+ for (size_t i = 0; i < WTF_ARRAY_LENGTH(m_maxIndexCache); ++i)
if (m_maxIndexCache[i].type == type)
return m_maxIndexCache[i].maxIndex;
return -1;
@@ -179,8 +178,8 @@ long WebGLBuffer::getCachedMaxIndex(unsigned long type)
void WebGLBuffer::setCachedMaxIndex(unsigned long type, long value)
{
- int numEntries = sizeof(m_maxIndexCache) / sizeof(MaxIndexCacheEntry);
- for (int i = 0; i < numEntries; i++)
+ size_t numEntries = WTF_ARRAY_LENGTH(m_maxIndexCache);
+ for (size_t i = 0; i < numEntries; ++i)
if (m_maxIndexCache[i].type == type) {
m_maxIndexCache[i].maxIndex = value;
return;
diff --git a/WebCore/html/canvas/WebGLBuffer.h b/WebCore/html/canvas/WebGLBuffer.h
index f18a9bf..af819a3 100644
--- a/WebCore/html/canvas/WebGLBuffer.h
+++ b/WebCore/html/canvas/WebGLBuffer.h
@@ -59,6 +59,8 @@ public:
unsigned long getTarget() const { return m_target; }
void setTarget(unsigned long);
+ bool hasEverBeenBound() const { return object() && m_target; }
+
protected:
WebGLBuffer(WebGLRenderingContext*);
diff --git a/WebCore/html/canvas/WebGLFramebuffer.cpp b/WebCore/html/canvas/WebGLFramebuffer.cpp
index 5bf3779..9e2db56 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -75,6 +75,7 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx
WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
: WebGLObject(ctx)
+ , m_hasEverBeenBound(false)
{
setObject(context()->graphicsContext3D()->createFramebuffer());
}
diff --git a/WebCore/html/canvas/WebGLFramebuffer.h b/WebCore/html/canvas/WebGLFramebuffer.h
index 394b770..b86417d 100644
--- a/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/WebCore/html/canvas/WebGLFramebuffer.h
@@ -56,6 +56,10 @@ public:
// Return false does not mean COMPLETE, might still be INCOMPLETE.
bool isIncomplete(bool checkInternalFormat) const;
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
protected:
WebGLFramebuffer(WebGLRenderingContext*);
@@ -76,6 +80,8 @@ private:
RefPtr<WebGLObject> m_depthAttachment;
RefPtr<WebGLObject> m_stencilAttachment;
RefPtr<WebGLObject> m_depthStencilAttachment;
+
+ bool m_hasEverBeenBound;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.cpp b/WebCore/html/canvas/WebGLRenderbuffer.cpp
index b9efd47..0c3ac84 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -45,6 +45,7 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
, m_width(0)
, m_height(0)
, m_isValid(true)
+ , m_hasEverBeenBound(false)
{
setObject(context()->graphicsContext3D()->createRenderbuffer());
}
diff --git a/WebCore/html/canvas/WebGLRenderbuffer.h b/WebCore/html/canvas/WebGLRenderbuffer.h
index 9a23ca5..a432f9d 100644
--- a/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -60,6 +60,10 @@ public:
bool isInitialized() const { return m_initialized; }
void setInitialized() { m_initialized = true; }
+ bool hasEverBeenBound() const { return object() && m_hasEverBeenBound; }
+
+ void setHasEverBeenBound() { m_hasEverBeenBound = true; }
+
protected:
WebGLRenderbuffer(WebGLRenderingContext*);
@@ -72,6 +76,8 @@ private:
bool m_initialized;
unsigned long m_width, m_height;
bool m_isValid; // This is only false if internalFormat is DEPTH_STENCIL and packed_depth_stencil is not supported.
+
+ bool m_hasEverBeenBound;
};
} // namespace WebCore
diff --git a/WebCore/html/canvas/WebGLRenderingContext.cpp b/WebCore/html/canvas/WebGLRenderingContext.cpp
index 0cbbc8e..b201692 100644
--- a/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -310,6 +310,8 @@ void WebGLRenderingContext::bindFramebuffer(unsigned long target, WebGLFramebuff
}
m_framebufferBinding = buffer;
m_context->bindFramebuffer(target, objectOrZero(buffer));
+ if (buffer)
+ buffer->setHasEverBeenBound();
cleanupAfterGraphicsCall(false);
}
@@ -328,6 +330,8 @@ void WebGLRenderingContext::bindRenderbuffer(unsigned long target, WebGLRenderbu
}
m_renderbufferBinding = renderBuffer;
m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
+ if (renderBuffer)
+ renderBuffer->setHasEverBeenBound();
cleanupAfterGraphicsCall(false);
}
@@ -2080,6 +2084,9 @@ bool WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
if (!buffer || isContextLost())
return false;
+ if (!buffer->hasEverBeenBound())
+ return false;
+
return m_context->isBuffer(buffer->object());
}
@@ -2100,6 +2107,9 @@ bool WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
if (!framebuffer || isContextLost())
return false;
+ if (!framebuffer->hasEverBeenBound())
+ return false;
+
return m_context->isFramebuffer(framebuffer->object());
}
@@ -2116,6 +2126,9 @@ bool WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
if (!renderbuffer || isContextLost())
return false;
+ if (!renderbuffer->hasEverBeenBound())
+ return false;
+
return m_context->isRenderbuffer(renderbuffer->object());
}
@@ -2132,6 +2145,9 @@ bool WebGLRenderingContext::isTexture(WebGLTexture* texture)
if (!texture || isContextLost())
return false;
+ if (!texture->hasEverBeenBound())
+ return false;
+
return m_context->isTexture(texture->object());
}
@@ -2233,10 +2249,14 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
return;
}
- if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ if (format != GraphicsContext3D::RGBA && type != GraphicsContext3D::UNSIGNED_BYTE) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
+ if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ return;
+ }
// Validate array type against pixel type.
if ((type == GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedByteArray())
|| (type != GraphicsContext3D::UNSIGNED_BYTE && !pixels->isUnsignedShortArray())) {
@@ -2258,7 +2278,7 @@ void WebGLRenderingContext::readPixels(long x, long y, long width, long height,
// The last row needs no padding.
unsigned long totalBytes = bytesPerRow * height - padding;
unsigned long num = totalBytes / bytesPerComponent;
- if (pixels->length() < num) {
+ if (pixels->byteLength() / bytesPerComponent < num) {
m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
diff --git a/WebCore/html/canvas/WebGLTexture.h b/WebCore/html/canvas/WebGLTexture.h
index 6ee3dcc..493ef7e 100644
--- a/WebCore/html/canvas/WebGLTexture.h
+++ b/WebCore/html/canvas/WebGLTexture.h
@@ -61,6 +61,8 @@ public:
// Determine if texture sampling should always return [0, 0, 0, 1] (OpenGL ES 2.0 Sec 3.8.2).
bool needToUseBlackTexture() const;
+ bool hasEverBeenBound() const { return object() && m_target; }
+
static int computeLevelCount(int width, int height);
protected: