summaryrefslogtreecommitdiff
path: root/Source/WebCore/html
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
committerSimon Hausmann <simon.hausmann@nokia.com>2012-02-03 09:55:33 +0100
commitcd44dc59cdfc39534aef4d417e9f3c412e3be139 (patch)
tree8d89889ba95ed6ec9322e733846cc9cce9d7dff1 /Source/WebCore/html
parentd11f84f5b5cdc0d92a08af01b13472fdd5f9acb9 (diff)
downloadqtwebkit-cd44dc59cdfc39534aef4d417e9f3c412e3be139.tar.gz
Imported WebKit commit fce473cb4d55aa9fe9d0b0322a2fffecb731b961 (http://svn.webkit.org/repository/webkit/trunk@106560)
Diffstat (limited to 'Source/WebCore/html')
-rw-r--r--Source/WebCore/html/CheckboxInputType.cpp2
-rw-r--r--Source/WebCore/html/ClassList.cpp2
-rw-r--r--Source/WebCore/html/DOMSettableTokenList.idl1
-rw-r--r--Source/WebCore/html/DOMTokenList.idl1
-rw-r--r--Source/WebCore/html/FileInputType.cpp4
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.cpp50
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.h10
-rw-r--r--Source/WebCore/html/HTMLAnchorElement.idl16
-rw-r--r--Source/WebCore/html/HTMLAreaElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLAttributeNames.in2
-rw-r--r--Source/WebCore/html/HTMLButtonElement.idl4
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.cpp19
-rw-r--r--Source/WebCore/html/HTMLCanvasElement.h2
-rw-r--r--Source/WebCore/html/HTMLCollection.idl2
-rw-r--r--Source/WebCore/html/HTMLDetailsElement.cpp35
-rw-r--r--Source/WebCore/html/HTMLDocument.idl14
-rw-r--r--Source/WebCore/html/HTMLElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLElement.idl10
-rw-r--r--Source/WebCore/html/HTMLElementsAllInOne.cpp2
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.cpp43
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.h1
-rw-r--r--Source/WebCore/html/HTMLEmbedElement.idl2
-rw-r--r--Source/WebCore/html/HTMLFormCollection.cpp1
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.cpp16
-rw-r--r--Source/WebCore/html/HTMLFormControlElement.h1
-rw-r--r--Source/WebCore/html/HTMLFormElement.cpp2
-rw-r--r--Source/WebCore/html/HTMLFormElement.idl6
-rw-r--r--Source/WebCore/html/HTMLFrameElement.idl6
-rw-r--r--Source/WebCore/html/HTMLFrameElementBase.cpp18
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLIFrameElement.idl4
-rw-r--r--Source/WebCore/html/HTMLImageElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLInputElement.cpp64
-rw-r--r--Source/WebCore/html/HTMLInputElement.h4
-rw-r--r--Source/WebCore/html/HTMLInputElement.idl12
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.cpp68
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.h46
-rw-r--r--Source/WebCore/html/HTMLIsIndexElement.idl27
-rw-r--r--Source/WebCore/html/HTMLLinkElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLMediaElement.cpp343
-rw-r--r--Source/WebCore/html/HTMLMediaElement.h46
-rw-r--r--Source/WebCore/html/HTMLMediaElement.idl4
-rw-r--r--Source/WebCore/html/HTMLMetaElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLObjectElement.cpp21
-rw-r--r--Source/WebCore/html/HTMLObjectElement.idl4
-rw-r--r--Source/WebCore/html/HTMLOutputElement.idl4
-rw-r--r--Source/WebCore/html/HTMLParamElement.cpp8
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.cpp11
-rw-r--r--Source/WebCore/html/HTMLPlugInElement.h4
-rw-r--r--Source/WebCore/html/HTMLPlugInImageElement.cpp20
-rw-r--r--Source/WebCore/html/HTMLPropertiesCollection.cpp4
-rw-r--r--Source/WebCore/html/HTMLPropertiesCollection.h4
-rw-r--r--Source/WebCore/html/HTMLScriptElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLScriptElement.h1
-rw-r--r--Source/WebCore/html/HTMLScriptElement.idl2
-rw-r--r--Source/WebCore/html/HTMLSelectElement.cpp132
-rw-r--r--Source/WebCore/html/HTMLSelectElement.idl4
-rw-r--r--Source/WebCore/html/HTMLSourceElement.cpp4
-rw-r--r--Source/WebCore/html/HTMLStyleElement.cpp78
-rw-r--r--Source/WebCore/html/HTMLStyleElement.h8
-rw-r--r--Source/WebCore/html/HTMLSummaryElement.cpp6
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLTableCellElement.h6
-rw-r--r--Source/WebCore/html/HTMLTableColElement.cpp9
-rw-r--r--Source/WebCore/html/HTMLTableColElement.h5
-rw-r--r--Source/WebCore/html/HTMLTableElement.cpp208
-rw-r--r--Source/WebCore/html/HTMLTableElement.h17
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.cpp7
-rw-r--r--Source/WebCore/html/HTMLTableSectionElement.h3
-rw-r--r--Source/WebCore/html/HTMLTagNames.in3
-rw-r--r--Source/WebCore/html/HTMLTextAreaElement.idl6
-rw-r--r--Source/WebCore/html/HTMLTitleElement.idl2
-rw-r--r--Source/WebCore/html/HTMLTrackElement.cpp14
-rw-r--r--Source/WebCore/html/HTMLTrackElement.h4
-rw-r--r--Source/WebCore/html/HiddenInputType.cpp14
-rw-r--r--Source/WebCore/html/HiddenInputType.h2
-rw-r--r--Source/WebCore/html/ImageDocument.cpp14
-rw-r--r--Source/WebCore/html/InputType.cpp4
-rw-r--r--Source/WebCore/html/InputType.h1
-rw-r--r--Source/WebCore/html/NumberInputType.cpp10
-rw-r--r--Source/WebCore/html/PasswordInputType.cpp15
-rw-r--r--Source/WebCore/html/PasswordInputType.h2
-rw-r--r--Source/WebCore/html/RadioInputType.cpp8
-rw-r--r--Source/WebCore/html/RadioInputType.h1
-rw-r--r--Source/WebCore/html/StepRange.cpp6
-rw-r--r--Source/WebCore/html/TextFieldInputType.cpp9
-rw-r--r--Source/WebCore/html/TextFieldInputType.h1
-rw-r--r--Source/WebCore/html/ValidationMessage.cpp2
-rw-r--r--Source/WebCore/html/canvas/CanvasGradient.idl5
-rw-r--r--Source/WebCore/html/canvas/CanvasPattern.idl6
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.cpp2
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext.idl4
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp29
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.h1
-rw-r--r--Source/WebCore/html/canvas/CanvasRenderingContext2D.idl17
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.cpp2
-rw-r--r--Source/WebCore/html/canvas/CanvasStyle.h4
-rw-r--r--Source/WebCore/html/canvas/OESVertexArrayObject.cpp6
-rw-r--r--Source/WebCore/html/canvas/Uint8ClampedArray.idl47
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLBuffer.h8
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextures.cpp44
-rw-r--r--Source/WebCore/html/canvas/WebGLCompressedTextures.h3
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.cpp106
-rw-r--r--Source/WebCore/html/canvas/WebGLContextGroup.h71
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.cpp65
-rw-r--r--Source/WebCore/html/canvas/WebGLContextObject.h69
-rw-r--r--Source/WebCore/html/canvas/WebGLDebugShaders.cpp2
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.cpp59
-rw-r--r--Source/WebCore/html/canvas/WebGLFramebuffer.h25
-rw-r--r--Source/WebCore/html/canvas/WebGLGetInfo.cpp60
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.cpp43
-rw-r--r--Source/WebCore/html/canvas/WebGLObject.h35
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.cpp21
-rw-r--r--Source/WebCore/html/canvas/WebGLProgram.h10
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderbuffer.h8
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.cpp812
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.h83
-rw-r--r--Source/WebCore/html/canvas/WebGLRenderingContext.idl10
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLShader.h8
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.cpp66
-rw-r--r--Source/WebCore/html/canvas/WebGLSharedObject.h75
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.cpp14
-rw-r--r--Source/WebCore/html/canvas/WebGLTexture.h8
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp11
-rw-r--r--Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h8
-rw-r--r--Source/WebCore/html/parser/CSSPreloadScanner.cpp1
-rw-r--r--Source/WebCore/html/parser/HTMLConstructionSite.cpp11
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.cpp30
-rw-r--r--Source/WebCore/html/parser/HTMLPreloadScanner.h4
-rw-r--r--Source/WebCore/html/shadow/ContentInclusionSelector.cpp155
-rw-r--r--Source/WebCore/html/shadow/ContentInclusionSelector.h150
-rw-r--r--Source/WebCore/html/shadow/ContentSelectorQuery.cpp161
-rw-r--r--Source/WebCore/html/shadow/ContentSelectorQuery.h67
-rw-r--r--Source/WebCore/html/shadow/HTMLContentElement.cpp130
-rw-r--r--Source/WebCore/html/shadow/HTMLContentElement.h89
-rw-r--r--Source/WebCore/html/shadow/HTMLContentElement.idl34
-rw-r--r--Source/WebCore/html/shadow/MediaControlElements.cpp14
-rw-r--r--Source/WebCore/html/shadow/SliderThumbElement.cpp2
-rw-r--r--Source/WebCore/html/shadow/TextControlInnerElements.cpp10
-rw-r--r--Source/WebCore/html/track/WebVTTParser.cpp2
143 files changed, 2968 insertions, 1394 deletions
diff --git a/Source/WebCore/html/CheckboxInputType.cpp b/Source/WebCore/html/CheckboxInputType.cpp
index dda172aec..ed83517b9 100644
--- a/Source/WebCore/html/CheckboxInputType.cpp
+++ b/Source/WebCore/html/CheckboxInputType.cpp
@@ -51,7 +51,7 @@ const AtomicString& CheckboxInputType::formControlType() const
bool CheckboxInputType::valueMissing(const String&) const
{
- return !element()->checked();
+ return element()->required() && !element()->checked();
}
String CheckboxInputType::valueMissingText() const
diff --git a/Source/WebCore/html/ClassList.cpp b/Source/WebCore/html/ClassList.cpp
index 349d64dce..2ea838202 100644
--- a/Source/WebCore/html/ClassList.cpp
+++ b/Source/WebCore/html/ClassList.cpp
@@ -140,7 +140,7 @@ const SpaceSplitString& ClassList::classNames() const
ASSERT(m_element->hasClass());
if (!m_classNamesForQuirksMode.isNull())
return m_classNamesForQuirksMode;
- return m_element->attributeMap()->classNames();
+ return m_element->attributeData()->classNames();
}
} // namespace WebCore
diff --git a/Source/WebCore/html/DOMSettableTokenList.idl b/Source/WebCore/html/DOMSettableTokenList.idl
index 6260623ee..02c6500b0 100644
--- a/Source/WebCore/html/DOMSettableTokenList.idl
+++ b/Source/WebCore/html/DOMSettableTokenList.idl
@@ -25,7 +25,6 @@
module core {
interface [
- GenerateConstructor,
HasIndexGetter,
GenerateToJS
] DOMSettableTokenList : DOMTokenList {
diff --git a/Source/WebCore/html/DOMTokenList.idl b/Source/WebCore/html/DOMTokenList.idl
index f94491cbe..0bcc4889f 100644
--- a/Source/WebCore/html/DOMTokenList.idl
+++ b/Source/WebCore/html/DOMTokenList.idl
@@ -26,7 +26,6 @@ module core {
interface [
GenerateIsReachable=ImplElementRoot,
- GenerateConstructor,
HasIndexGetter
] DOMTokenList {
readonly attribute unsigned long length;
diff --git a/Source/WebCore/html/FileInputType.cpp b/Source/WebCore/html/FileInputType.cpp
index 655e81ead..ea9a2ee68 100644
--- a/Source/WebCore/html/FileInputType.cpp
+++ b/Source/WebCore/html/FileInputType.cpp
@@ -129,7 +129,7 @@ bool FileInputType::appendFormData(FormDataList& encoding, bool multipart) const
bool FileInputType::valueMissing(const String& value) const
{
- return value.isEmpty();
+ return element()->required() && value.isEmpty();
}
String FileInputType::valueMissingText() const
@@ -139,7 +139,7 @@ String FileInputType::valueMissingText() const
void FileInputType::handleDOMActivateEvent(Event* event)
{
- if (element()->disabled() || !element()->renderer())
+ if (element()->disabled())
return;
if (!ScriptController::processingUserGesture())
diff --git a/Source/WebCore/html/HTMLAnchorElement.cpp b/Source/WebCore/html/HTMLAnchorElement.cpp
index d60185282..6cfce16df 100644
--- a/Source/WebCore/html/HTMLAnchorElement.cpp
+++ b/Source/WebCore/html/HTMLAnchorElement.cpp
@@ -48,6 +48,7 @@ using namespace HTMLNames;
HTMLAnchorElement::HTMLAnchorElement(const QualifiedName& tagName, Document* document)
: HTMLElement(tagName, document)
+ , m_hasRootEditableElementForSelectionOnMouseDown(false)
, m_wasShiftKeyDownOnMouseDown(false)
, m_linkRelations(0)
, m_cachedVisitedLinkHash(0)
@@ -64,6 +65,11 @@ PassRefPtr<HTMLAnchorElement> HTMLAnchorElement::create(const QualifiedName& tag
return adoptRef(new HTMLAnchorElement(tagName, document));
}
+HTMLAnchorElement::~HTMLAnchorElement()
+{
+ clearRootEditableElementForSelectionOnMouseDown();
+}
+
// This function does not allow leading spaces before the port number.
static unsigned parsePortFromStringPosition(const String& value, unsigned portStart, unsigned& portEnd)
{
@@ -158,12 +164,12 @@ void HTMLAnchorElement::defaultEventHandler(Event* event)
// This keeps track of the editable block that the selection was in (if it was in one) just before the link was clicked
// for the LiveWhenNotFocused editable link behavior
if (event->type() == eventNames().mousedownEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() != RightButton && document()->frame() && document()->frame()->selection()) {
- m_rootEditableElementForSelectionOnMouseDown = document()->frame()->selection()->rootEditableElement();
+ setRootEditableElementForSelectionOnMouseDown(document()->frame()->selection()->rootEditableElement());
m_wasShiftKeyDownOnMouseDown = static_cast<MouseEvent*>(event)->shiftKey();
} else if (event->type() == eventNames().mouseoverEvent) {
// These are cleared on mouseover and not mouseout because their values are needed for drag events,
// but drag events happen after mouse out events.
- m_rootEditableElementForSelectionOnMouseDown = 0;
+ clearRootEditableElementForSelectionOnMouseDown();
m_wasShiftKeyDownOnMouseDown = false;
}
}
@@ -546,7 +552,7 @@ bool HTMLAnchorElement::treatLinkAsLiveForEventType(EventType eventType) const
// If the selection prior to clicking on this link resided in the same editable block as this link,
// and the shift key isn't pressed, we don't want to follow the link.
case EditableLinkLiveWhenNotFocused:
- return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && m_rootEditableElementForSelectionOnMouseDown != rootEditableElement());
+ return eventType == MouseEventWithShiftKey || (eventType == MouseEventWithoutShiftKey && rootEditableElementForSelectionOnMouseDown() != rootEditableElement());
case EditableLinkOnlyLiveWithShiftKey:
return eventType == MouseEventWithShiftKey;
@@ -587,10 +593,44 @@ String HTMLAnchorElement::itemValueText() const
return getURLAttribute(hrefAttr);
}
-void HTMLAnchorElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLAnchorElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(hrefAttr, value, ec);
+ setAttribute(hrefAttr, value);
}
#endif
+typedef HashMap<const HTMLAnchorElement*, RefPtr<Element> > RootEditableElementMap;
+
+static RootEditableElementMap& rootEditableElementMap()
+{
+ DEFINE_STATIC_LOCAL(RootEditableElementMap, map, ());
+ return map;
+}
+
+Element* HTMLAnchorElement::rootEditableElementForSelectionOnMouseDown() const
+{
+ if (!m_hasRootEditableElementForSelectionOnMouseDown)
+ return 0;
+ return rootEditableElementMap().get(this).get();
+}
+
+void HTMLAnchorElement::clearRootEditableElementForSelectionOnMouseDown()
+{
+ if (!m_hasRootEditableElementForSelectionOnMouseDown)
+ return;
+ rootEditableElementMap().remove(this);
+ m_hasRootEditableElementForSelectionOnMouseDown = false;
+}
+
+void HTMLAnchorElement::setRootEditableElementForSelectionOnMouseDown(Element* element)
+{
+ if (!element) {
+ clearRootEditableElementForSelectionOnMouseDown();
+ return;
+ }
+
+ rootEditableElementMap().set(this, element);
+ m_hasRootEditableElementForSelectionOnMouseDown = true;
+}
+
}
diff --git a/Source/WebCore/html/HTMLAnchorElement.h b/Source/WebCore/html/HTMLAnchorElement.h
index cbda84145..99a6332ce 100644
--- a/Source/WebCore/html/HTMLAnchorElement.h
+++ b/Source/WebCore/html/HTMLAnchorElement.h
@@ -58,6 +58,8 @@ public:
static PassRefPtr<HTMLAnchorElement> create(Document*);
static PassRefPtr<HTMLAnchorElement> create(const QualifiedName&, Document*);
+ virtual ~HTMLAnchorElement();
+
KURL href() const;
void setHref(const AtomicString&);
@@ -133,9 +135,13 @@ private:
virtual void setItemValueText(const String&, ExceptionCode&) OVERRIDE;
#endif
- RefPtr<Element> m_rootEditableElementForSelectionOnMouseDown;
+ Element* rootEditableElementForSelectionOnMouseDown() const;
+ void setRootEditableElementForSelectionOnMouseDown(Element*);
+ void clearRootEditableElementForSelectionOnMouseDown();
+
+ bool m_hasRootEditableElementForSelectionOnMouseDown : 1;
bool m_wasShiftKeyDownOnMouseDown : 1;
- uint32_t m_linkRelations : 31;
+ uint32_t m_linkRelations : 30;
mutable LinkHash m_cachedVisitedLinkHash;
};
diff --git a/Source/WebCore/html/HTMLAnchorElement.idl b/Source/WebCore/html/HTMLAnchorElement.idl
index 5669a281c..898f9eab7 100644
--- a/Source/WebCore/html/HTMLAnchorElement.idl
+++ b/Source/WebCore/html/HTMLAnchorElement.idl
@@ -43,15 +43,15 @@ module html {
readonly attribute DOMString protocol;
readonly attribute DOMString search;
#else
- attribute [ConvertNullToNullString] DOMString hash;
- attribute [ConvertNullToNullString] DOMString host;
- attribute [ConvertNullToNullString] DOMString hostname;
- attribute [ConvertNullToNullString] DOMString pathname;
- attribute [ConvertNullToNullString] DOMString port;
- attribute [ConvertNullToNullString] DOMString protocol;
- attribute [ConvertNullToNullString] DOMString search;
+ attribute [TreatNullAs=EmptyString] DOMString hash;
+ attribute [TreatNullAs=EmptyString] DOMString host;
+ attribute [TreatNullAs=EmptyString] DOMString hostname;
+ attribute [TreatNullAs=EmptyString] DOMString pathname;
+ attribute [TreatNullAs=EmptyString] DOMString port;
+ attribute [TreatNullAs=EmptyString] DOMString protocol;
+ attribute [TreatNullAs=EmptyString] DOMString search;
- readonly attribute [ConvertNullToNullString] DOMString origin;
+ readonly attribute [TreatNullAs=EmptyString] DOMString origin;
#endif
readonly attribute DOMString text;
diff --git a/Source/WebCore/html/HTMLAreaElement.cpp b/Source/WebCore/html/HTMLAreaElement.cpp
index d763d789a..b00471678 100644
--- a/Source/WebCore/html/HTMLAreaElement.cpp
+++ b/Source/WebCore/html/HTMLAreaElement.cpp
@@ -252,9 +252,9 @@ String HTMLAreaElement::itemValueText() const
return getURLAttribute(hrefAttr);
}
-void HTMLAreaElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLAreaElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(hrefAttr, value, ec);
+ setAttribute(hrefAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLAttributeNames.in b/Source/WebCore/html/HTMLAttributeNames.in
index 776c5e9d9..60d96d53d 100644
--- a/Source/WebCore/html/HTMLAttributeNames.in
+++ b/Source/WebCore/html/HTMLAttributeNames.in
@@ -246,6 +246,7 @@ onwebkitanimationend
onwebkitbeginfullscreen
onwebkitendfullscreen
onwebkitfullscreenchange
+onwebkitfullscreenerror
onwebkittransitionend
open
optimum
@@ -278,6 +279,7 @@ scoped
scrollamount
scrolldelay
scrolling
+select
selected
shape
size
diff --git a/Source/WebCore/html/HTMLButtonElement.idl b/Source/WebCore/html/HTMLButtonElement.idl
index ff7dab7ba..c91947bb3 100644
--- a/Source/WebCore/html/HTMLButtonElement.idl
+++ b/Source/WebCore/html/HTMLButtonElement.idl
@@ -24,8 +24,8 @@ module html {
readonly attribute HTMLFormElement form;
attribute [Reflect, URL] DOMString formAction;
- attribute [ConvertNullToNullString] DOMString formEnctype;
- attribute [ConvertNullToNullString] DOMString formMethod;
+ attribute [TreatNullAs=EmptyString] DOMString formEnctype;
+ attribute [TreatNullAs=EmptyString] DOMString formMethod;
attribute [Reflect] boolean formNoValidate;
attribute [Reflect] DOMString formTarget;
readonly attribute ValidityState validity;
diff --git a/Source/WebCore/html/HTMLCanvasElement.cpp b/Source/WebCore/html/HTMLCanvasElement.cpp
index 681fb93ca..143d33475 100644
--- a/Source/WebCore/html/HTMLCanvasElement.cpp
+++ b/Source/WebCore/html/HTMLCanvasElement.cpp
@@ -443,6 +443,22 @@ bool HTMLCanvasElement::shouldAccelerate(const IntSize& size) const
#endif
}
+bool HTMLCanvasElement::shouldDefer() const
+{
+#if USE(SKIA)
+ if (m_context && !m_context->is2d())
+ return false;
+
+ Settings* settings = document()->settings();
+ if (!settings || !settings->deferred2dCanvasEnabled())
+ return false;
+
+ return true;
+#else
+ return false;
+#endif
+}
+
void HTMLCanvasElement::createImageBuffer() const
{
ASSERT(!m_imageBuffer);
@@ -471,7 +487,8 @@ void HTMLCanvasElement::createImageBuffer() const
#else
Unaccelerated;
#endif
- m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode);
+ DeferralMode deferralMode = shouldDefer() ? Deferred : NonDeferred;
+ m_imageBuffer = ImageBuffer::create(bufferSize, ColorSpaceDeviceRGB, renderingMode, deferralMode);
if (!m_imageBuffer)
return;
m_imageBuffer->context()->scale(FloatSize(bufferSize.width() / logicalSize.width(), bufferSize.height() / logicalSize.height()));
diff --git a/Source/WebCore/html/HTMLCanvasElement.h b/Source/WebCore/html/HTMLCanvasElement.h
index 1bfe52cfe..0493902b2 100644
--- a/Source/WebCore/html/HTMLCanvasElement.h
+++ b/Source/WebCore/html/HTMLCanvasElement.h
@@ -146,6 +146,8 @@ private:
void setSurfaceSize(const IntSize&);
+ bool shouldDefer() const;
+
HashSet<CanvasObserver*> m_observers;
IntSize m_size;
diff --git a/Source/WebCore/html/HTMLCollection.idl b/Source/WebCore/html/HTMLCollection.idl
index a25f8b0d8..8fa2309cc 100644
--- a/Source/WebCore/html/HTMLCollection.idl
+++ b/Source/WebCore/html/HTMLCollection.idl
@@ -28,7 +28,7 @@ module html {
Polymorphic
] HTMLCollection {
readonly attribute unsigned long length;
- [Custom] Node item(in [Optional=CallWithDefaultValue] unsigned long index);
+ Node item(in [Optional=CallWithDefaultValue] unsigned long index);
[Custom] Node namedItem(in [Optional=CallWithDefaultValue] DOMString name);
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
diff --git a/Source/WebCore/html/HTMLDetailsElement.cpp b/Source/WebCore/html/HTMLDetailsElement.cpp
index fad9af804..ddec73876 100644
--- a/Source/WebCore/html/HTMLDetailsElement.cpp
+++ b/Source/WebCore/html/HTMLDetailsElement.cpp
@@ -23,12 +23,12 @@
#if ENABLE(DETAILS)
+#include "HTMLContentElement.h"
#include "HTMLNames.h"
#include "HTMLSummaryElement.h"
#include "LocalizedStrings.h"
#include "MouseEvent.h"
#include "RenderDetails.h"
-#include "ShadowContentElement.h"
#include "ShadowRoot.h"
#include "Text.h"
@@ -36,17 +36,21 @@ namespace WebCore {
using namespace HTMLNames;
-class DetailsContentElement : public ShadowContentElement {
+static const AtomicString& summaryQuerySelector()
+{
+ DEFINE_STATIC_LOCAL(AtomicString, selector, ("summary:first-of-type"));
+ return selector;
+};
+
+class DetailsContentElement : public HTMLContentElement {
public:
static PassRefPtr<DetailsContentElement> create(Document*);
private:
DetailsContentElement(Document* document)
- : ShadowContentElement(HTMLNames::divTag, document)
+ : HTMLContentElement(HTMLNames::divTag, document)
{
}
-
- virtual bool shouldInclude(Node*);
};
PassRefPtr<DetailsContentElement> DetailsContentElement::create(Document* document)
@@ -54,24 +58,16 @@ PassRefPtr<DetailsContentElement> DetailsContentElement::create(Document* docume
return adoptRef(new DetailsContentElement(document));
}
-bool DetailsContentElement::shouldInclude(Node* node)
-{
- HTMLDetailsElement* details = static_cast<HTMLDetailsElement*>(shadowAncestorNode());
- return details->mainSummary() != node;
-}
-
-
-class DetailsSummaryElement : public ShadowContentElement {
+class DetailsSummaryElement : public HTMLContentElement {
public:
static PassRefPtr<DetailsSummaryElement> create(Document*);
private:
DetailsSummaryElement(Document* document)
- : ShadowContentElement(HTMLNames::divTag, document)
+ : HTMLContentElement(HTMLNames::divTag, document)
{
+ setSelect(summaryQuerySelector());
}
-
- virtual bool shouldInclude(Node*);
};
PassRefPtr<DetailsSummaryElement> DetailsSummaryElement::create(Document* document)
@@ -79,13 +75,6 @@ PassRefPtr<DetailsSummaryElement> DetailsSummaryElement::create(Document* docume
return adoptRef(new DetailsSummaryElement(document));
}
-bool DetailsSummaryElement::shouldInclude(Node* node)
-{
- HTMLDetailsElement* details = static_cast<HTMLDetailsElement*>(shadowAncestorNode());
- return details->mainSummary() == node;
-}
-
-
PassRefPtr<HTMLDetailsElement> HTMLDetailsElement::create(const QualifiedName& tagName, Document* document)
{
RefPtr<HTMLDetailsElement> result = adoptRef(new HTMLDetailsElement(tagName, document));
diff --git a/Source/WebCore/html/HTMLDocument.idl b/Source/WebCore/html/HTMLDocument.idl
index d2400a884..a7a6bcda6 100644
--- a/Source/WebCore/html/HTMLDocument.idl
+++ b/Source/WebCore/html/HTMLDocument.idl
@@ -48,19 +48,19 @@ module html {
readonly attribute long width;
readonly attribute long height;
#endif
- attribute [ConvertNullToNullString] DOMString dir;
- attribute [ConvertNullToNullString] DOMString designMode;
+ attribute [TreatNullAs=EmptyString] DOMString dir;
+ attribute [TreatNullAs=EmptyString] DOMString designMode;
readonly attribute DOMString compatMode;
readonly attribute Element activeElement;
boolean hasFocus();
// Deprecated attributes
- attribute [ConvertNullToNullString] DOMString bgColor;
- attribute [ConvertNullToNullString] DOMString fgColor;
- attribute [ConvertNullToNullString] DOMString alinkColor;
- attribute [ConvertNullToNullString] DOMString linkColor;
- attribute [ConvertNullToNullString] DOMString vlinkColor;
+ attribute [TreatNullAs=EmptyString] DOMString bgColor;
+ attribute [TreatNullAs=EmptyString] DOMString fgColor;
+ attribute [TreatNullAs=EmptyString] DOMString alinkColor;
+ attribute [TreatNullAs=EmptyString] DOMString linkColor;
+ attribute [TreatNullAs=EmptyString] DOMString vlinkColor;
};
}
diff --git a/Source/WebCore/html/HTMLElement.cpp b/Source/WebCore/html/HTMLElement.cpp
index a78f4d057..680c23b5d 100644
--- a/Source/WebCore/html/HTMLElement.cpp
+++ b/Source/WebCore/html/HTMLElement.cpp
@@ -330,6 +330,8 @@ void HTMLElement::parseMappedAttribute(Attribute* attr)
#if ENABLE(FULLSCREEN_API)
} else if (attr->name() == onwebkitfullscreenchangeAttr) {
setAttributeEventListener(eventNames().webkitfullscreenchangeEvent, createAttributeEventListener(this, attr));
+ } else if (attr->name() == onwebkitfullscreenerrorAttr) {
+ setAttributeEventListener(eventNames().webkitfullscreenerrorEvent, createAttributeEventListener(this, attr));
#endif
}
}
diff --git a/Source/WebCore/html/HTMLElement.idl b/Source/WebCore/html/HTMLElement.idl
index 7257755ae..068cb8d74 100644
--- a/Source/WebCore/html/HTMLElement.idl
+++ b/Source/WebCore/html/HTMLElement.idl
@@ -40,13 +40,13 @@ module html {
attribute [Reflect] DOMString accessKey;
// Extensions
- attribute [ConvertNullToNullString] DOMString innerHTML
+ attribute [TreatNullAs=EmptyString] DOMString innerHTML
setter raises(DOMException);
- attribute [ConvertNullToNullString] DOMString innerText
+ attribute [TreatNullAs=EmptyString] DOMString innerText
setter raises(DOMException);
- attribute [ConvertNullToNullString] DOMString outerHTML
+ attribute [TreatNullAs=EmptyString] DOMString outerHTML
setter raises(DOMException);
- attribute [ConvertNullToNullString] DOMString outerText
+ attribute [TreatNullAs=EmptyString] DOMString outerText
setter raises(DOMException);
Element insertAdjacentElement(in [Optional=CallWithDefaultValue] DOMString where,
@@ -61,7 +61,7 @@ module html {
readonly attribute HTMLCollection children;
- attribute [ConvertNullToNullString] DOMString contentEditable
+ attribute [TreatNullAs=EmptyString] DOMString contentEditable
setter raises(DOMException);
readonly attribute boolean isContentEditable;
diff --git a/Source/WebCore/html/HTMLElementsAllInOne.cpp b/Source/WebCore/html/HTMLElementsAllInOne.cpp
index b624e627b..ba4b99aba 100644
--- a/Source/WebCore/html/HTMLElementsAllInOne.cpp
+++ b/Source/WebCore/html/HTMLElementsAllInOne.cpp
@@ -41,6 +41,7 @@
#include "HTMLBodyElement.cpp"
#include "HTMLButtonElement.cpp"
#include "HTMLCanvasElement.cpp"
+#include "HTMLContentElement.cpp"
#include "HTMLDataListElement.cpp"
#include "HTMLDetailsElement.cpp"
#include "HTMLDListElement.cpp"
@@ -64,7 +65,6 @@
#include "HTMLIFrameElement.cpp"
#include "HTMLImageElement.cpp"
#include "HTMLInputElement.cpp"
-#include "HTMLIsIndexElement.cpp"
#include "HTMLKeygenElement.cpp"
#include "HTMLLIElement.cpp"
#include "HTMLLabelElement.cpp"
diff --git a/Source/WebCore/html/HTMLEmbedElement.cpp b/Source/WebCore/html/HTMLEmbedElement.cpp
index d0bd344f2..309aafe05 100644
--- a/Source/WebCore/html/HTMLEmbedElement.cpp
+++ b/Source/WebCore/html/HTMLEmbedElement.cpp
@@ -117,7 +117,7 @@ void HTMLEmbedElement::parseMappedAttribute(Attribute* attr)
void HTMLEmbedElement::parametersForPlugin(Vector<String>& paramNames, Vector<String>& paramValues)
{
- NamedNodeMap* attributes = this->attributes(true);
+ NamedNodeMap* attributes = updatedAttributes();
if (!attributes)
return;
@@ -154,11 +154,8 @@ void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption)
Vector<String> paramValues;
parametersForPlugin(paramNames, paramValues);
- ASSERT(!m_inBeforeLoadEventHandler);
- m_inBeforeLoadEventHandler = true;
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(m_url);
- m_inBeforeLoadEventHandler = false;
-
+ RefPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
+ bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(m_url);
if (!beforeLoadAllowedLoad) {
if (document()->isPluginDocument()) {
// Plugins inside plugin documents load differently than other plugins. By the time
@@ -168,8 +165,9 @@ void HTMLEmbedElement::updateWidget(PluginCreationOption pluginCreationOption)
}
return;
}
+ if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
+ return;
- RefPtr<HTMLEmbedElement> protect(this); // Loading the plugin might remove us from the document.
SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
// FIXME: beforeLoad could have detached the renderer! Just like in the <object> case above.
loader->requestObject(this, m_url, getAttribute(nameAttr), m_serviceType, paramNames, paramValues);
@@ -211,33 +209,6 @@ void HTMLEmbedElement::insertedIntoDocument()
HTMLPlugInImageElement::insertedIntoDocument();
if (!inDocument())
return;
-
- String width = getAttribute(widthAttr);
- String height = getAttribute(heightAttr);
- if (!width.isEmpty() || !height.isEmpty()) {
- Node* n = parentNode();
- while (n && !n->hasTagName(objectTag))
- n = n->parentNode();
- if (n) {
- if (!width.isEmpty())
- static_cast<HTMLObjectElement*>(n)->setAttribute(widthAttr, width);
- if (!height.isEmpty())
- static_cast<HTMLObjectElement*>(n)->setAttribute(heightAttr, height);
- }
- }
-}
-
-void HTMLEmbedElement::attributeChanged(Attribute* attr, bool preserveDecls)
-{
- HTMLPlugInImageElement::attributeChanged(attr, preserveDecls);
-
- if ((attr->name() == widthAttr || attr->name() == heightAttr) && !attr->isEmpty()) {
- ContainerNode* n = parentNode();
- while (n && !n->hasTagName(objectTag))
- n = n->parentNode();
- if (n)
- static_cast<HTMLObjectElement*>(n)->setAttribute(attr->name(), attr->value());
- }
}
bool HTMLEmbedElement::isURLAttribute(Attribute* attr) const
@@ -263,9 +234,9 @@ String HTMLEmbedElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLEmbedElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLEmbedElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLEmbedElement.h b/Source/WebCore/html/HTMLEmbedElement.h
index bd6764df9..12ce2714b 100644
--- a/Source/WebCore/html/HTMLEmbedElement.h
+++ b/Source/WebCore/html/HTMLEmbedElement.h
@@ -39,7 +39,6 @@ private:
virtual bool rendererIsNeeded(const NodeRenderingContext&);
virtual void insertedIntoDocument();
- virtual void attributeChanged(Attribute*, bool preserveDecls = false);
virtual bool isURLAttribute(Attribute*) const;
virtual const QualifiedName& imageSourceAttributeName() const;
diff --git a/Source/WebCore/html/HTMLEmbedElement.idl b/Source/WebCore/html/HTMLEmbedElement.idl
index e395fc65e..0ef638450 100644
--- a/Source/WebCore/html/HTMLEmbedElement.idl
+++ b/Source/WebCore/html/HTMLEmbedElement.idl
@@ -42,7 +42,7 @@ module html {
#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
- [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException);
+ [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException);
#endif
#endif
};
diff --git a/Source/WebCore/html/HTMLFormCollection.cpp b/Source/WebCore/html/HTMLFormCollection.cpp
index d25653fe8..919e09c01 100644
--- a/Source/WebCore/html/HTMLFormCollection.cpp
+++ b/Source/WebCore/html/HTMLFormCollection.cpp
@@ -37,6 +37,7 @@ using namespace HTMLNames;
HTMLFormCollection::HTMLFormCollection(HTMLFormElement* form)
: HTMLCollection(form, OtherCollection)
+ , currentPos(0)
{
}
diff --git a/Source/WebCore/html/HTMLFormControlElement.cpp b/Source/WebCore/html/HTMLFormControlElement.cpp
index b13b25676..2b06f3d04 100644
--- a/Source/WebCore/html/HTMLFormControlElement.cpp
+++ b/Source/WebCore/html/HTMLFormControlElement.cpp
@@ -122,15 +122,21 @@ void HTMLFormControlElement::parseMappedAttribute(Attribute* attr)
} else if (attr->name() == requiredAttr) {
bool oldRequired = m_required;
m_required = !attr->isNull();
- if (oldRequired != m_required) {
- setNeedsValidityCheck();
- setNeedsStyleRecalc(); // Updates for :required :optional classes.
- }
+ if (oldRequired != m_required)
+ requiredAttributeChanged();
} else
HTMLElement::parseMappedAttribute(attr);
setNeedsWillValidateCheck();
}
+void HTMLFormControlElement::requiredAttributeChanged()
+{
+ setNeedsValidityCheck();
+ // Style recalculation is needed because style selectors may include
+ // :required and :optional pseudo-classes.
+ setNeedsStyleRecalc();
+}
+
static bool shouldAutofocus(HTMLFormControlElement* element)
{
if (!element->autofocus())
@@ -139,6 +145,8 @@ static bool shouldAutofocus(HTMLFormControlElement* element)
return false;
if (element->document()->ignoreAutofocus())
return false;
+ if (element->document()->isSandboxed(SandboxAutomaticFeatures))
+ return false;
if (element->hasAutofocused())
return false;
diff --git a/Source/WebCore/html/HTMLFormControlElement.h b/Source/WebCore/html/HTMLFormControlElement.h
index f500b6df9..edc406f51 100644
--- a/Source/WebCore/html/HTMLFormControlElement.h
+++ b/Source/WebCore/html/HTMLFormControlElement.h
@@ -115,6 +115,7 @@ protected:
HTMLFormControlElement(const QualifiedName& tagName, Document*, HTMLFormElement*);
virtual void parseMappedAttribute(Attribute*);
+ virtual void requiredAttributeChanged();
virtual void attach();
virtual void insertedIntoTree(bool deep);
virtual void removedFromTree(bool deep);
diff --git a/Source/WebCore/html/HTMLFormElement.cpp b/Source/WebCore/html/HTMLFormElement.cpp
index 92b684a4e..695a39b10 100644
--- a/Source/WebCore/html/HTMLFormElement.cpp
+++ b/Source/WebCore/html/HTMLFormElement.cpp
@@ -248,7 +248,7 @@ bool HTMLFormElement::validateInteractively(Event* event)
continue;
String message("An invalid form control with name='%name' is not focusable.");
message.replace("%name", unhandledAssociatedElement->name());
- frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, 0, document()->url().string());
+ frame->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, ErrorMessageLevel, message, document()->url().string());
}
}
return false;
diff --git a/Source/WebCore/html/HTMLFormElement.idl b/Source/WebCore/html/HTMLFormElement.idl
index c6967eacf..d1884efe8 100644
--- a/Source/WebCore/html/HTMLFormElement.idl
+++ b/Source/WebCore/html/HTMLFormElement.idl
@@ -31,9 +31,9 @@ module html {
attribute [Reflect] boolean noValidate;
attribute [Reflect=accept_charset] DOMString acceptCharset;
attribute [Reflect, URL] DOMString action;
- attribute [ConvertNullToNullString] DOMString encoding;
- attribute [ConvertNullToNullString] DOMString enctype;
- attribute [ConvertNullToNullString] DOMString method;
+ attribute [TreatNullAs=EmptyString] DOMString encoding;
+ attribute [TreatNullAs=EmptyString] DOMString enctype;
+ attribute [TreatNullAs=EmptyString] DOMString method;
attribute [Reflect] DOMString target;
attribute [Reflect] DOMString autocomplete;
diff --git a/Source/WebCore/html/HTMLFrameElement.idl b/Source/WebCore/html/HTMLFrameElement.idl
index dfe4ef89c..1c6851b8a 100644
--- a/Source/WebCore/html/HTMLFrameElement.idl
+++ b/Source/WebCore/html/HTMLFrameElement.idl
@@ -32,19 +32,19 @@ module html {
attribute [Reflect, URL] DOMString src;
// Introduced in DOM Level 2:
- readonly attribute [CheckFrameSecurity] Document contentDocument;
+ readonly attribute [CheckAccessToNode] Document contentDocument;
// Extensions
readonly attribute DOMWindow contentWindow;
#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
- [SVGCheckSecurityDocument] SVGDocument getSVGDocument()
+ [CheckAccessToNode] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
- attribute [ConvertNullToNullString, CustomSetter] DOMString location;
+ attribute [TreatNullAs=EmptyString, CustomSetter] DOMString location;
readonly attribute long width;
readonly attribute long height;
diff --git a/Source/WebCore/html/HTMLFrameElementBase.cpp b/Source/WebCore/html/HTMLFrameElementBase.cpp
index f5d22a418..fddec7f92 100644
--- a/Source/WebCore/html/HTMLFrameElementBase.cpp
+++ b/Source/WebCore/html/HTMLFrameElementBase.cpp
@@ -201,16 +201,14 @@ void HTMLFrameElementBase::insertedIntoDocument()
if (!document()->frame())
return;
- // Loads may cause synchronous javascript execution (e.g. beforeload or
- // src=javascript), which could try to access the renderer before the normal
- // parser machinery would call lazyAttach() and set us as needing style
- // resolve. Any code which expects this to be attached will resolve style
- // before using renderer(), so this will make sure we attach in time.
- // FIXME: Normally lazyAttach marks the renderer as attached(), but we don't
- // want to do that here, as as callers expect to call attach() right after
- // this and attach() will ASSERT(!attached())
- ASSERT(!renderer()); // This recalc is unecessary if we already have a renderer.
- lazyAttach(DoNotSetAttached);
+ // JavaScript in src=javascript: and beforeonload can access the renderer
+ // during attribute parsing *before* the normal parser machinery would
+ // attach the element. To support this, we lazyAttach here, but only
+ // if we don't already have a renderer (if we're inserted
+ // as part of a DocumentFragment, insertedIntoDocument from an earlier element
+ // could have forced a style resolve and already attached us).
+ if (!renderer())
+ lazyAttach(DoNotSetAttached);
setNameAndOpenURL();
}
diff --git a/Source/WebCore/html/HTMLIFrameElement.cpp b/Source/WebCore/html/HTMLIFrameElement.cpp
index ae60a1e74..817b5d749 100644
--- a/Source/WebCore/html/HTMLIFrameElement.cpp
+++ b/Source/WebCore/html/HTMLIFrameElement.cpp
@@ -128,9 +128,9 @@ String HTMLIFrameElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLIFrameElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLIFrameElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLIFrameElement.idl b/Source/WebCore/html/HTMLIFrameElement.idl
index 7f9e25a97..1e88269e0 100644
--- a/Source/WebCore/html/HTMLIFrameElement.idl
+++ b/Source/WebCore/html/HTMLIFrameElement.idl
@@ -34,14 +34,14 @@ module html {
attribute [Reflect] DOMString width;
// Introduced in DOM Level 2:
- readonly attribute [CheckFrameSecurity] Document contentDocument;
+ readonly attribute [CheckAccessToNode] Document contentDocument;
// Extensions
readonly attribute DOMWindow contentWindow;
#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
- [SVGCheckSecurityDocument] SVGDocument getSVGDocument()
+ [CheckAccessToNode] SVGDocument getSVGDocument()
raises(DOMException);
#endif
#endif
diff --git a/Source/WebCore/html/HTMLImageElement.cpp b/Source/WebCore/html/HTMLImageElement.cpp
index adc9eb904..b5c513de7 100644
--- a/Source/WebCore/html/HTMLImageElement.cpp
+++ b/Source/WebCore/html/HTMLImageElement.cpp
@@ -375,9 +375,9 @@ String HTMLImageElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLImageElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLImageElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLInputElement.cpp b/Source/WebCore/html/HTMLInputElement.cpp
index 3bb9af093..413c1277c 100644
--- a/Source/WebCore/html/HTMLInputElement.cpp
+++ b/Source/WebCore/html/HTMLInputElement.cpp
@@ -119,6 +119,9 @@ HTMLInputElement::~HTMLInputElement()
// Need to remove form association while this is still an HTMLInputElement
// so that virtual functions are called correctly.
setForm(0);
+ // setForm(0) may register this to a document-level radio button group.
+ // We should unregister it to avoid accessing a deleted object.
+ document()->checkedRadioButtons().removeButton(this);
}
const AtomicString& HTMLInputElement::formControlName() const
@@ -175,38 +178,6 @@ bool HTMLInputElement::shouldAutocomplete() const
return HTMLTextFormControlElement::shouldAutocomplete();
}
-void HTMLInputElement::updateCheckedRadioButtons()
-{
- checkedRadioButtons().addButton(this);
-
- if (form()) {
- const Vector<FormAssociatedElement*>& controls = form()->associatedElements();
- for (unsigned i = 0; i < controls.size(); ++i) {
- if (!controls[i]->isFormControlElement())
- continue;
- HTMLFormControlElement* control = static_cast<HTMLFormControlElement*>(controls[i]);
- if (control->name() != name())
- continue;
- if (control->type() != type())
- continue;
- control->setNeedsValidityCheck();
- }
- } else {
- typedef Document::FormElementListHashSet::const_iterator Iterator;
- Iterator end = document()->formElements()->end();
- for (Iterator it = document()->formElements()->begin(); it != end; ++it) {
- HTMLFormControlElementWithState* control = *it;
- if (control->formControlName() != name())
- continue;
- if (control->formControlType() != type())
- continue;
- if (control->form())
- continue;
- control->setNeedsValidityCheck();
- }
- }
-}
-
bool HTMLInputElement::isValidValue(const String& value) const
{
if (!m_inputType->canSetStringValue()) {
@@ -229,8 +200,6 @@ bool HTMLInputElement::typeMismatch() const
bool HTMLInputElement::valueMissing(const String& value) const
{
- if (!isRequiredFormControl() || readOnly() || disabled())
- return false;
return m_inputType->valueMissing(value);
}
@@ -503,23 +472,12 @@ bool HTMLInputElement::shouldUseInputMethod()
void HTMLInputElement::handleFocusEvent()
{
- if (!isTextField())
- return;
- if (isPasswordField() && document()->frame())
- document()->setUseSecureKeyboardEntryWhenActive(true);
+ m_inputType->handleFocusEvent();
}
void HTMLInputElement::handleBlurEvent()
{
m_inputType->handleBlurEvent();
- if (!isTextField())
- return;
- Frame* frame = document()->frame();
- if (!frame)
- return;
- if (isPasswordField())
- document()->setUseSecureKeyboardEntryWhenActive(false);
- frame->editor()->textFieldDidEndEditing(this);
}
void HTMLInputElement::setType(const String& type)
@@ -960,13 +918,11 @@ void HTMLInputElement::setChecked(bool nowChecked, bool sendChangeEvent)
if (checked() == nowChecked)
return;
- checkedRadioButtons().removeButton(this);
-
m_reflectsCheckedAttribute = false;
m_isChecked = nowChecked;
setNeedsStyleRecalc();
if (isRadioButton())
- updateCheckedRadioButtons();
+ checkedRadioButtons().updateCheckedState(this);
if (renderer() && renderer()->style()->hasAppearance())
renderer()->theme()->stateChanged(renderer(), CheckedState);
setNeedsValidityCheck();
@@ -1300,8 +1256,10 @@ void HTMLInputElement::setDefaultValue(const String &value)
setAttribute(valueAttr, value);
}
-void HTMLInputElement::setDefaultName(const AtomicString& name)
+void HTMLInputElement::setInitialName(const AtomicString& name)
{
+ ASSERT(hasTagName(isindexTag));
+ ASSERT(m_name.isNull());
m_name = name;
}
@@ -1554,6 +1512,12 @@ bool HTMLInputElement::recalcWillValidate() const
return m_inputType->supportsValidation() && HTMLTextFormControlElement::recalcWillValidate();
}
+void HTMLInputElement::requiredAttributeChanged()
+{
+ HTMLTextFormControlElement::requiredAttributeChanged();
+ checkedRadioButtons().requiredAttributeChanged(this);
+}
+
#if ENABLE(INPUT_COLOR)
void HTMLInputElement::selectColorInColorChooser(const Color& color)
{
diff --git a/Source/WebCore/html/HTMLInputElement.h b/Source/WebCore/html/HTMLInputElement.h
index d21244d39..47ac4d326 100644
--- a/Source/WebCore/html/HTMLInputElement.h
+++ b/Source/WebCore/html/HTMLInputElement.h
@@ -188,8 +188,6 @@ public:
String defaultValue() const;
void setDefaultValue(const String&);
- void setDefaultName(const AtomicString&);
-
Vector<String> acceptMIMETypes();
String accept() const;
String alt() const;
@@ -243,6 +241,7 @@ public:
protected:
HTMLInputElement(const QualifiedName&, Document*, HTMLFormElement*, bool createdByParser);
void createShadowSubtree();
+ void setInitialName(const AtomicString&);
virtual void defaultEventHandler(Event*);
private:
@@ -322,6 +321,7 @@ private:
virtual bool isOptionalFormControl() const { return !isRequiredFormControl(); }
virtual bool isRequiredFormControl() const;
virtual bool recalcWillValidate() const;
+ virtual void requiredAttributeChanged() OVERRIDE;
void updateType();
diff --git a/Source/WebCore/html/HTMLInputElement.idl b/Source/WebCore/html/HTMLInputElement.idl
index 7463334bb..bedeb9ae4 100644
--- a/Source/WebCore/html/HTMLInputElement.idl
+++ b/Source/WebCore/html/HTMLInputElement.idl
@@ -21,13 +21,13 @@
module html {
interface HTMLInputElement : HTMLElement {
- attribute [ConvertNullToNullString] DOMString defaultValue;
+ attribute [TreatNullAs=EmptyString] DOMString defaultValue;
attribute [Reflect=checked] boolean defaultChecked;
attribute [Reflect] DOMString dirName;
readonly attribute HTMLFormElement form;
attribute [Reflect, URL] DOMString formAction;
- attribute [ConvertNullToNullString] DOMString formEnctype;
- attribute [ConvertNullToNullString] DOMString formMethod;
+ attribute [TreatNullAs=EmptyString] DOMString formEnctype;
+ attribute [TreatNullAs=EmptyString] DOMString formMethod;
attribute [Reflect] boolean formNoValidate;
attribute [Reflect] DOMString formTarget;
readonly attribute ValidityState validity;
@@ -57,9 +57,9 @@ module html {
#endif
attribute [Reflect, URL] DOMString src;
attribute [Reflect] DOMString step;
- attribute [ConvertNullToNullString] DOMString type; // readonly dropped as part of DOM level 2
+ attribute [TreatNullAs=EmptyString] DOMString type; // readonly dropped as part of DOM level 2
attribute [Reflect] DOMString useMap;
- attribute [ConvertNullToNullString] DOMString value;
+ attribute [TreatNullAs=EmptyString] DOMString value;
#if !defined(LANGUAGE_CPP) || !LANGUAGE_CPP
attribute Date valueAsDate setter raises(DOMException);
#endif
@@ -78,7 +78,7 @@ module html {
void click();
#if !defined(LANGUAGE_JAVASCRIPT) || !LANGUAGE_JAVASCRIPT
- void setValueForUser(in [ConvertNullToNullString] DOMString value);
+ void setValueForUser(in [TreatNullAs=EmptyString] DOMString value);
#endif
// WinIE extension:
diff --git a/Source/WebCore/html/HTMLIsIndexElement.cpp b/Source/WebCore/html/HTMLIsIndexElement.cpp
deleted file mode 100644
index f7cf5ecd1..000000000
--- a/Source/WebCore/html/HTMLIsIndexElement.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
- * (C) 2006 Alexey Proskuryakov (ap@nypop.com)
- *
- * 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.
- *
- * 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.
- *
- */
-
-#include "config.h"
-#include "HTMLIsIndexElement.h"
-
-#include "Attribute.h"
-#include "HTMLNames.h"
-
-namespace WebCore {
-
-using namespace HTMLNames;
-
-HTMLIsIndexElement::HTMLIsIndexElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
- : HTMLInputElement(tagName, document, form, false)
-{
- ASSERT(hasTagName(isindexTag));
- setDefaultName(isindexTag.localName());
-}
-
-PassRefPtr<HTMLIsIndexElement> HTMLIsIndexElement::create(Document* document, HTMLFormElement* form)
-{
- RefPtr<HTMLIsIndexElement> element = adoptRef(new HTMLIsIndexElement(isindexTag, document, form));
- element->createShadowSubtree();
- return element.release();
-}
-
-PassRefPtr<HTMLIsIndexElement> HTMLIsIndexElement::create(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
-{
- RefPtr<HTMLIsIndexElement> element = adoptRef(new HTMLIsIndexElement(tagName, document, form));
- element->createShadowSubtree();
- return element.release();
-}
-
-void HTMLIsIndexElement::parseMappedAttribute(Attribute* attr)
-{
- if (attr->name() == promptAttr)
- setValue(attr->value());
- else if (attr->name() == placeholderAttr)
- updatePlaceholderVisibility(true);
- else
- // don't call HTMLInputElement::parseMappedAttribute here, as it would
- // accept attributes this element does not support
- HTMLFormControlElement::parseMappedAttribute(attr);
-}
-
-} // namespace
diff --git a/Source/WebCore/html/HTMLIsIndexElement.h b/Source/WebCore/html/HTMLIsIndexElement.h
deleted file mode 100644
index 857ef7578..000000000
--- a/Source/WebCore/html/HTMLIsIndexElement.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * (C) 1999 Antti Koivisto (koivisto@kde.org)
- * (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2010 Apple Inc. All rights reserved.
- *
- * 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.
- *
- * 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.
- *
- */
-
-#ifndef HTMLIsIndexElement_h
-#define HTMLIsIndexElement_h
-
-#include "HTMLInputElement.h"
-
-namespace WebCore {
-
-class HTMLIsIndexElement : public HTMLInputElement {
-public:
- static PassRefPtr<HTMLIsIndexElement> create(Document*, HTMLFormElement*);
- static PassRefPtr<HTMLIsIndexElement> create(const QualifiedName&, Document*, HTMLFormElement*);
-
-private:
- HTMLIsIndexElement(const QualifiedName&, Document*, HTMLFormElement*);
-
- virtual bool canTriggerImplicitSubmission() const { return true; }
-
- virtual void parseMappedAttribute(Attribute*);
-};
-
-} // namespace
-
-#endif
diff --git a/Source/WebCore/html/HTMLIsIndexElement.idl b/Source/WebCore/html/HTMLIsIndexElement.idl
deleted file mode 100644
index 028a1800a..000000000
--- a/Source/WebCore/html/HTMLIsIndexElement.idl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2006, 2010 Apple Inc. All rights reserved.
- *
- * 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.
- *
- * 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.
- */
-
-module html {
-
- interface HTMLIsIndexElement : HTMLInputElement {
- readonly attribute HTMLFormElement form;
- attribute [Reflect] DOMString prompt;
- };
-
-}
diff --git a/Source/WebCore/html/HTMLLinkElement.cpp b/Source/WebCore/html/HTMLLinkElement.cpp
index 124163d93..fa54279ca 100644
--- a/Source/WebCore/html/HTMLLinkElement.cpp
+++ b/Source/WebCore/html/HTMLLinkElement.cpp
@@ -454,9 +454,9 @@ String HTMLLinkElement::itemValueText() const
return getURLAttribute(hrefAttr);
}
-void HTMLLinkElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLLinkElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(hrefAttr, value, ec);
+ setAttribute(hrefAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLMediaElement.cpp b/Source/WebCore/html/HTMLMediaElement.cpp
index 4f06af6ea..e8bb788d6 100644
--- a/Source/WebCore/html/HTMLMediaElement.cpp
+++ b/Source/WebCore/html/HTMLMediaElement.cpp
@@ -51,6 +51,7 @@
#include "HTMLNames.h"
#include "HTMLSourceElement.h"
#include "HTMLVideoElement.h"
+#include "Language.h"
#include "Logging.h"
#include "MediaController.h"
#include "MediaControls.h"
@@ -174,7 +175,6 @@ HTMLMediaElement::HTMLMediaElement(const QualifiedName& tagName, Document* docum
: HTMLElement(tagName, document)
, ActiveDOMObject(document, this)
, m_loadTimer(this, &HTMLMediaElement::loadTimerFired)
- , m_asyncEventTimer(this, &HTMLMediaElement::asyncEventTimerFired)
, m_progressEventTimer(this, &HTMLMediaElement::progressEventTimerFired)
, m_playbackProgressTimer(this, &HTMLMediaElement::playbackProgressTimerFired)
, m_playedTimeRanges()
@@ -541,29 +541,10 @@ void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
#if LOG_MEDIA_EVENTS
LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.string().ascii().data());
#endif
- m_pendingEvents.append(Event::create(eventName, false, true));
- if (!m_asyncEventTimer.isActive())
- m_asyncEventTimer.startOneShot(0);
-}
-
-void HTMLMediaElement::asyncEventTimerFired(Timer<HTMLMediaElement>*)
-{
- Vector<RefPtr<Event> > pendingEvents;
- ExceptionCode ec = 0;
+ RefPtr<Event> event = Event::create(eventName, false, true);
+ event->setTarget(this);
- m_pendingEvents.swap(pendingEvents);
- unsigned count = pendingEvents.size();
- for (unsigned ndx = 0; ndx < count; ++ndx) {
-#if LOG_MEDIA_EVENTS
- LOG(Media, "HTMLMediaElement::asyncEventTimerFired - dispatching '%s'", pendingEvents[ndx]->type().string().ascii().data());
-#endif
- if (pendingEvents[ndx]->type() == eventNames().canplayEvent) {
- m_dispatchingCanPlayEvent = true;
- dispatchEvent(pendingEvents[ndx].release(), ec);
- m_dispatchingCanPlayEvent = false;
- } else
- dispatchEvent(pendingEvents[ndx].release(), ec);
- }
+ m_asyncEventQueue.enqueueEvent(event.release());
}
void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
@@ -577,7 +558,7 @@ void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
#if ENABLE(VIDEO_TRACK)
if (m_pendingLoadFlags & TextTrackResource)
- configureTextTracks();
+ configureNewTextTracks();
#endif
m_pendingLoadFlags = 0;
@@ -985,6 +966,8 @@ void HTMLMediaElement::updateActiveTextTrackCues(float movieTime)
bool HTMLMediaElement::textTracksAreReady() const
{
+ // 4.8.10.12.1 Text track model
+ // ...
// The text tracks of a media element are ready if all the text tracks whose mode was not
// in the disabled state when the element's resource selection algorithm last started now
// have a text track readiness state of loaded or failed to load.
@@ -1020,7 +1003,7 @@ void HTMLMediaElement::textTrackModeChanged(TextTrack* track)
if (trackElement->track() != track)
continue;
- // Mark this track as "configured" so configureTextTrack won't change the mode again.
+ // Mark this track as "configured" so configureNewTextTracks won't change the mode again.
trackElement->setHasBeenConfigured(true);
if (track->mode() != TextTrack::DISABLED && trackElement->readyState() == HTMLTrackElement::NONE)
trackElement->scheduleLoad();
@@ -1192,8 +1175,7 @@ void HTMLMediaElement::mediaEngineError(PassRefPtr<MediaError> err)
void HTMLMediaElement::cancelPendingEventsAndCallbacks()
{
LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
-
- m_pendingEvents.clear();
+ m_asyncEventQueue.cancelAllEvents();
for (Node* node = firstChild(); node; node = node->nextSibling()) {
if (node->hasTagName(sourceTag))
@@ -1273,14 +1255,12 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
if (state == MediaPlayer::Idle) {
if (m_networkState > NETWORK_IDLE) {
- m_progressEventTimer.stop();
- if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress)
- mediaControls()->bufferingProgressed();
-
+ changeNetworkStateFromLoadingToIdle();
scheduleEvent(eventNames().suspendEvent);
setShouldDelayLoadEvent(false);
+ } else {
+ m_networkState = NETWORK_IDLE;
}
- m_networkState = NETWORK_IDLE;
}
if (state == MediaPlayer::Loading) {
@@ -1290,16 +1270,8 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
}
if (state == MediaPlayer::Loaded) {
- if (m_networkState != NETWORK_IDLE) {
- m_progressEventTimer.stop();
- if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress)
- mediaControls()->bufferingProgressed();
-
- // Schedule one last progress event so we guarantee that at least one is fired
- // for files that load very quickly.
- scheduleEvent(eventNames().progressEvent);
- }
- m_networkState = NETWORK_IDLE;
+ if (m_networkState != NETWORK_IDLE)
+ changeNetworkStateFromLoadingToIdle();
m_completelyLoaded = true;
}
@@ -1307,6 +1279,18 @@ void HTMLMediaElement::setNetworkState(MediaPlayer::NetworkState state)
mediaControls()->updateStatusDisplay();
}
+void HTMLMediaElement::changeNetworkStateFromLoadingToIdle()
+{
+ m_progressEventTimer.stop();
+ if (hasMediaControls() && m_player->bytesLoaded() != m_previousProgress)
+ mediaControls()->bufferingProgressed();
+
+ // Schedule one last progress event so we guarantee that at least one is fired
+ // for files that load very quickly.
+ scheduleEvent(eventNames().progressEvent);
+ m_networkState = NETWORK_IDLE;
+}
+
void HTMLMediaElement::mediaPlayerReadyStateChanged(MediaPlayer*)
{
beginProcessingMediaPlayerCallback();
@@ -1398,7 +1382,7 @@ void HTMLMediaElement::setReadyState(MediaPlayer::ReadyState state)
if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
scheduleEvent(eventNames().playingEvent);
- if (m_autoplaying && m_paused && autoplay()) {
+ if (m_autoplaying && m_paused && autoplay() && !document()->isSandboxed(SandboxAutomaticFeatures)) {
m_paused = false;
invalidateCachedTime();
scheduleEvent(eventNames().playEvent);
@@ -2217,7 +2201,7 @@ float HTMLMediaElement::percentLoaded() const
}
#if ENABLE(VIDEO_TRACK)
-PassRefPtr<TextTrack> HTMLMediaElement::addTrack(const String& kind, const String& label, const String& language, ExceptionCode& ec)
+PassRefPtr<TextTrack> HTMLMediaElement::addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode& ec)
{
if (!RuntimeEnabledFeatures::webkitVideoTrackEnabled())
return 0;
@@ -2259,15 +2243,13 @@ TextTrackList* HTMLMediaElement::textTracks()
HTMLTrackElement* HTMLMediaElement::showingTrackWithSameKind(HTMLTrackElement* trackElement) const
{
- HTMLTrackElement* showingTrack = 0;
-
for (Node* node = firstChild(); node; node = node->nextSibling()) {
if (trackElement == node)
continue;
if (!node->hasTagName(trackTag))
continue;
- showingTrack = static_cast<HTMLTrackElement*>(node);
+ HTMLTrackElement* showingTrack = static_cast<HTMLTrackElement*>(node);
if (showingTrack->kind() == trackElement->kind() && showingTrack->track()->mode() == TextTrack::SHOWING)
return showingTrack;
}
@@ -2298,7 +2280,7 @@ void HTMLMediaElement::trackWasAdded(HTMLTrackElement* trackElement)
scheduleLoad(TextTrackResource);
}
-void HTMLMediaElement::trackWillBeRemoved(HTMLTrackElement* trackElement)
+void HTMLMediaElement::trackWasRemoved(HTMLTrackElement* trackElement)
{
ASSERT(trackElement->hasTagName(trackTag));
@@ -2308,7 +2290,7 @@ void HTMLMediaElement::trackWillBeRemoved(HTMLTrackElement* trackElement)
#if !LOG_DISABLED
if (trackElement->hasTagName(trackTag)) {
KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::trackWillBeRemoved - 'src' is %s", urlForLogging(url).utf8().data());
+ LOG(Media, "HTMLMediaElement::trackWasRemoved - 'src' is %s", urlForLogging(url).utf8().data());
}
#endif
@@ -2334,131 +2316,176 @@ bool HTMLMediaElement::userIsInterestedInThisLanguage(const String&) const
return true;
}
-bool HTMLMediaElement::userIsInterestedInThisTrack(HTMLTrackElement* trackElement) const
+bool HTMLMediaElement::userIsInterestedInThisTrackKind(String kind) const
{
- RefPtr<TextTrack> textTrack = trackElement->track();
- if (!textTrack)
- return false;
-
- String kind = textTrack->kind();
- if (!TextTrack::isValidKindKeyword(kind))
- return false;
-
// If ... the user has indicated an interest in having a track with this text track kind, text track language, ...
Settings* settings = document()->settings();
if (!settings)
return false;
- if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) {
- if (kind == TextTrack::subtitlesKeyword() && !settings->shouldDisplaySubtitles())
- return false;
- if (kind == TextTrack::captionsKeyword() && !settings->shouldDisplayCaptions())
- return false;
- return userIsInterestedInThisLanguage(trackElement->srclang());
- }
+ if (kind == TextTrack::subtitlesKeyword())
+ return settings->shouldDisplaySubtitles();
+ if (kind == TextTrack::captionsKeyword())
+ return settings->shouldDisplayCaptions();
+ if (kind == TextTrack::descriptionsKeyword())
+ return settings->shouldDisplayTextDescriptions();
- if (kind == TextTrack::descriptionsKeyword()) {
- if (!settings->shouldDisplayTextDescriptions())
- return false;
- return userIsInterestedInThisLanguage(trackElement->srclang());
- }
-
return false;
}
-void HTMLMediaElement::configureTextTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::configureTextTrackGroup(const TrackGroup& group) const
{
-#if !LOG_DISABLED
- if (trackElement->hasTagName(trackTag)) {
- KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
- LOG(Media, "HTMLMediaElement::configureTextTrack - 'src' is %s", urlForLogging(url).utf8().data());
+ ASSERT(group.tracks.size());
+
+ String bestMatchingLanguage;
+ if (group.hasSrcLang) {
+ Vector<String> languages;
+ languages.reserveInitialCapacity(group.tracks.size());
+ for (size_t i = 0; i < group.tracks.size(); ++i) {
+ String srcLanguage = group.tracks[i]->track()->language();
+ if (srcLanguage.length())
+ languages.append(srcLanguage);
+ }
+ bestMatchingLanguage = preferredLanguageFromList(languages);
}
-#endif
- // 4.8.10.12.3 Sourcing out-of-band text tracks
-
- // When a text track corresponding to a track element is added to a media element's list of text tracks,
- // the user agent must set the text track mode appropriately, as determined by the following conditions:
- RefPtr<TextTrack> textTrack = trackElement->track();
- if (!textTrack)
- return;
-
- TextTrack::Mode mode = TextTrack::HIDDEN;
- HTMLTrackElement* trackElementCurrentlyShowing = showingTrackWithSameKind(trackElement);
- String kind = textTrack->kind();
- bool hideDefaultTrack = false;
-
- if (userIsInterestedInThisTrack(trackElement)) {
- if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword()) {
- // * If the text track kind is subtitles or captions and the user has indicated an interest in having a
+ // First, find the track in the group that should be enabled (if any).
+ HTMLTrackElement* trackElementToEnable = 0;
+ HTMLTrackElement* defaultTrack = 0;
+ HTMLTrackElement* fallbackTrack = 0;
+ for (size_t i = 0; !trackElementToEnable && i < group.tracks.size(); ++i) {
+ HTMLTrackElement* trackElement = group.tracks[i];
+ RefPtr<TextTrack> textTrack = trackElement->track();
+
+ if (userIsInterestedInThisTrackKind(textTrack->kind())) {
+ // * If the text track kind is { [subtitles or captions] [descriptions] } and the user has indicated an interest in having a
// track with this text track kind, text track language, and text track label enabled, and there is no
// other text track in the media element's list of text tracks with a text track kind of either subtitles
// or captions whose text track mode is showing
- hideDefaultTrack = trackElementCurrentlyShowing && trackElementCurrentlyShowing->track()->showingByDefault();
- if (!trackElementCurrentlyShowing || hideDefaultTrack) {
- // Let the text track mode be showing.
- // If there is a text track in the media element's list of text tracks whose text track mode is showing
- // by default, the user agent must furthermore change that text track's text track mode to hidden.
- mode = TextTrack::SHOWING;
- }
- } else if (kind == TextTrack::descriptionsKeyword()) {
- // * If the text track kind is descriptions and the user has indicated an interest in having text
- // descriptions with this text track language and text track label enabled, and there is no other text
- // track in the media element's list of text tracks with a text track kind of descriptions whose text
- // track mode is showing
- hideDefaultTrack = trackElementCurrentlyShowing && trackElementCurrentlyShowing->track()->showingByDefault();
- if (!trackElementCurrentlyShowing || hideDefaultTrack) {
- // Let the text track mode be showing.
- // If there is a text track in the media element's list of text tracks whose text track mode is showing
- // by default, the user agent must furthermore change that text track's text track mode to hidden.
- mode = TextTrack::SHOWING;
- }
- } else if (kind == TextTrack::chaptersKeyword()) {
+ // ...
// * If the text track kind is chapters and the text track language is one that the user agent has reason
// to believe is appropriate for the user, and there is no other text track in the media element's list of
// text tracks with a text track kind of chapters whose text track mode is showing
// Let the text track mode be showing.
- if (!trackElementCurrentlyShowing)
- mode = TextTrack::SHOWING;
+ if (bestMatchingLanguage.length()) {
+ if (textTrack->language() == bestMatchingLanguage)
+ trackElementToEnable = trackElement;
+ } else if (trackElement->isDefault()) {
+ // The user is interested in this type of track, but their language preference doesn't match any track so we will
+ // enable the 'default' track.
+ defaultTrack = trackElement;
+ }
+
+ // Remember the first track that doesn't match language or have 'default' to potentially use as fallback.
+ if (!fallbackTrack)
+ fallbackTrack = trackElement;
+ } else if (!group.visibleTrack && !defaultTrack && trackElement->isDefault()) {
+ // * If the track element has a default attribute specified, and there is no other text track in the media
+ // element's list of text tracks whose text track mode is showing or showing by default
+ // Let the text track mode be showing by default.
+ defaultTrack = trackElement;
}
- } else if (!trackElementCurrentlyShowing && trackElement->isDefault()) {
- // * If the track element has a default attribute specified, and there is no other text track in the media
- // element's list of text tracks whose text track mode is showing or showing by default
- // Let the text track mode be showing by default.
- mode = TextTrack::SHOWING;
- textTrack->setShowingByDefault(false);
- } else {
- // Otherwise
- // Let the text track mode be disabled.
- mode = TextTrack::DISABLED;
}
- ExceptionCode unusedException;
- if (hideDefaultTrack) {
- trackElementCurrentlyShowing->track()->setMode(TextTrack::HIDDEN, unusedException);
- trackElementCurrentlyShowing->track()->setShowingByDefault(false);
+ if (!trackElementToEnable && defaultTrack)
+ trackElementToEnable = defaultTrack;
+
+ // If no track matches the user's preferred language and non was marked 'default', enable the first track
+ // because the user has explicitly stated a preference for this kind of track.
+ if (!trackElementToEnable && fallbackTrack)
+ trackElementToEnable = fallbackTrack;
+
+ for (size_t i = 0; i < group.tracks.size(); ++i) {
+ HTMLTrackElement* trackElement = group.tracks[i];
+ RefPtr<TextTrack> textTrack = trackElement->track();
+ ExceptionCode unusedException;
+
+ if (trackElementToEnable == trackElement) {
+ textTrack->setMode(TextTrack::SHOWING, unusedException);
+ if (defaultTrack == trackElement)
+ textTrack->setShowingByDefault(true);
+ } else {
+ if (textTrack->showingByDefault()) {
+ // If there is a text track in the media element's list of text tracks whose text track
+ // mode is showing by default, the user agent must furthermore change that text track's
+ // text track mode to hidden.
+ textTrack->setShowingByDefault(false);
+ textTrack->setMode(TextTrack::HIDDEN, unusedException);
+ } else
+ textTrack->setMode(TextTrack::DISABLED, unusedException);
+ }
}
- textTrack->setMode(mode, unusedException);
+ if (trackElementToEnable && group.defaultTrack && group.defaultTrack != trackElementToEnable) {
+ RefPtr<TextTrack> textTrack = group.defaultTrack->track();
+ if (textTrack && textTrack->showingByDefault()) {
+ ExceptionCode unusedException;
+ textTrack->setShowingByDefault(false);
+ textTrack->setMode(TextTrack::HIDDEN, unusedException);
+ }
+ }
}
-
-void HTMLMediaElement::configureTextTracks()
+
+void HTMLMediaElement::configureNewTextTracks()
{
+ TrackGroup captionAndSubtitleTracks(TrackGroup::CaptionsAndSubtitles);
+ TrackGroup descriptionTracks(TrackGroup::Description);
+ TrackGroup chapterTracks(TrackGroup::Chapter);
+ TrackGroup metadataTracks(TrackGroup::Metadata);
+ TrackGroup otherTracks(TrackGroup::Other);
+
for (Node* node = firstChild(); node; node = node->nextSibling()) {
if (!node->hasTagName(trackTag))
continue;
+
HTMLTrackElement* trackElement = static_cast<HTMLTrackElement*>(node);
+ RefPtr<TextTrack> textTrack = trackElement->track();
+ if (!textTrack)
+ continue;
+
+ String kind = textTrack->kind();
+ TrackGroup* currentGroup;
+ if (kind == TextTrack::subtitlesKeyword() || kind == TextTrack::captionsKeyword())
+ currentGroup = &captionAndSubtitleTracks;
+ else if (kind == TextTrack::descriptionsKeyword())
+ currentGroup = &descriptionTracks;
+ else if (kind == TextTrack::chaptersKeyword())
+ currentGroup = &chapterTracks;
+ else if (kind == TextTrack::metadataKeyword())
+ currentGroup = &metadataTracks;
+ else
+ currentGroup = &otherTracks;
+
+ if (!currentGroup->visibleTrack && textTrack->mode() == TextTrack::SHOWING)
+ currentGroup->visibleTrack = trackElement;
+ if (!currentGroup->defaultTrack && trackElement->isDefault())
+ currentGroup->defaultTrack = trackElement;
+
+ // Do not add this track to the group if it has already been automatically configured
+ // as we only want to call configureTextTrack once per track so that adding another
+ // track after the initial configuration doesn't reconfigure every track - only those
+ // that should be changed by the new addition. For example all metadata tracks are
+ // disabled by default, and we don't want a track that has been enabled by script
+ // to be disabled automatically when a new metadata track is added later.
+ if (trackElement->hasBeenConfigured())
+ continue;
- // Only call configureTextTrack once per track so that adding another track after
- // the initial configuration doesn't reconfigure every track, only those that should
- // be changed by the new addition. For example all metadata tracks are disabled by
- // default, and we don't want a track that has been enabled by script to be disabled
- // automatically when a new track element is added later.
- if (!trackElement->hasBeenConfigured())
- configureTextTrack(trackElement);
+ if (textTrack->language().length())
+ currentGroup->hasSrcLang = true;
+ currentGroup->tracks.append(trackElement);
}
+
+ if (captionAndSubtitleTracks.tracks.size())
+ configureTextTrackGroup(captionAndSubtitleTracks);
+ if (descriptionTracks.tracks.size())
+ configureTextTrackGroup(descriptionTracks);
+ if (chapterTracks.tracks.size())
+ configureTextTrackGroup(chapterTracks);
+ if (metadataTracks.tracks.size())
+ configureTextTrackGroup(metadataTracks);
+ if (otherTracks.tracks.size())
+ configureTextTrackGroup(otherTracks);
}
-
#endif
bool HTMLMediaElement::havePotentialSourceChild()
@@ -2785,6 +2812,14 @@ void HTMLMediaElement::mediaPlayerSawUnsupportedTracks(MediaPlayer*)
}
}
+void HTMLMediaElement::mediaPlayerResourceNotSupported(MediaPlayer*)
+{
+ LOG(Media, "HTMLMediaElement::mediaPlayerResourceNotSupported");
+
+ // The MediaPlayer came across content which no installed engine supports.
+ mediaLoadingFailed(MediaPlayer::FormatError);
+}
+
// MediaPlayerPresentation methods
void HTMLMediaElement::mediaPlayerRepaint(MediaPlayer*)
{
@@ -3167,11 +3202,7 @@ void HTMLMediaElement::resume()
bool HTMLMediaElement::hasPendingActivity() const
{
- // Return true when we have pending events so we can't fire events after the JS
- // object gets collected.
- bool pending = m_pendingEvents.size();
- LOG(Media, "HTMLMediaElement::hasPendingActivity -> %s", boolString(pending));
- return pending;
+ return m_asyncEventQueue.hasPendingEvents();
}
void HTMLMediaElement::mediaVolumeDidChange()
@@ -3610,9 +3641,9 @@ String HTMLMediaElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLMediaElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLMediaElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
@@ -3682,6 +3713,24 @@ void HTMLMediaElement::updateMediaController()
m_mediaController->reportControllerState();
}
+bool HTMLMediaElement::dispatchEvent(PassRefPtr<Event> event)
+{
+ bool dispatchResult;
+ bool isCanPlayEvent;
+
+ isCanPlayEvent = (event->type() == eventNames().canplayEvent);
+
+ if (isCanPlayEvent)
+ m_dispatchingCanPlayEvent = true;
+
+ dispatchResult = HTMLElement::dispatchEvent(event);
+
+ if (isCanPlayEvent)
+ m_dispatchingCanPlayEvent = false;
+
+ return dispatchResult;
+}
+
bool HTMLMediaElement::isBlocked() const
{
// A media element is a blocked media element if its readyState attribute is in the
diff --git a/Source/WebCore/html/HTMLMediaElement.h b/Source/WebCore/html/HTMLMediaElement.h
index 198b9b210..98fdf5a0f 100644
--- a/Source/WebCore/html/HTMLMediaElement.h
+++ b/Source/WebCore/html/HTMLMediaElement.h
@@ -30,6 +30,7 @@
#include "HTMLElement.h"
#include "ActiveDOMObject.h"
+#include "GenericEventQueue.h"
#include "MediaCanStartListener.h"
#include "MediaControllerInterface.h"
#include "MediaPlayer.h"
@@ -196,18 +197,39 @@ public:
float percentLoaded() const;
#if ENABLE(VIDEO_TRACK)
- PassRefPtr<TextTrack> addTrack(const String& kind, const String& label, const String& language, ExceptionCode&);
- PassRefPtr<TextTrack> addTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTrack(kind, label, emptyString(), ec); }
- PassRefPtr<TextTrack> addTrack(const String& kind, ExceptionCode& ec) { return addTrack(kind, emptyString(), emptyString(), ec); }
+ PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, const String& language, ExceptionCode&);
+ PassRefPtr<TextTrack> addTextTrack(const String& kind, const String& label, ExceptionCode& ec) { return addTextTrack(kind, label, emptyString(), ec); }
+ PassRefPtr<TextTrack> addTextTrack(const String& kind, ExceptionCode& ec) { return addTextTrack(kind, emptyString(), emptyString(), ec); }
TextTrackList* textTracks();
CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
virtual void trackWasAdded(HTMLTrackElement*);
- virtual void trackWillBeRemoved(HTMLTrackElement*);
-
- void configureTextTrack(HTMLTrackElement*);
- void configureTextTracks();
+ virtual void trackWasRemoved(HTMLTrackElement*);
+
+ struct TrackGroup {
+ enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
+
+ TrackGroup(GroupKind kind)
+ : visibleTrack(0)
+ , defaultTrack(0)
+ , kind(kind)
+ , hasSrcLang(false)
+ {
+ }
+
+ Vector<HTMLTrackElement*> tracks;
+ HTMLTrackElement* visibleTrack;
+ HTMLTrackElement* defaultTrack;
+ GroupKind kind;
+ bool hasSrcLang;
+ };
+
+ void configureTextTrackGroupForLanguage(const TrackGroup&) const;
+ void configureNewTextTracks();
+ void configureTextTrackGroup(const TrackGroup&) const;
+
+ bool userIsInterestedInThisTrackKind(String) const;
bool textTracksAreReady() const;
void configureTextTrackDisplay();
@@ -273,6 +295,8 @@ public:
MediaController* controller() const;
void setController(PassRefPtr<MediaController>);
+ virtual bool dispatchEvent(PassRefPtr<Event>);
+
protected:
HTMLMediaElement(const QualifiedName&, Document*, bool);
virtual ~HTMLMediaElement();
@@ -347,6 +371,7 @@ private:
virtual void mediaPlayerRateChanged(MediaPlayer*);
virtual void mediaPlayerPlaybackStateChanged(MediaPlayer*);
virtual void mediaPlayerSawUnsupportedTracks(MediaPlayer*);
+ virtual void mediaPlayerResourceNotSupported(MediaPlayer*);
virtual void mediaPlayerRepaint(MediaPlayer*);
virtual void mediaPlayerSizeChanged(MediaPlayer*);
#if USE(ACCELERATED_COMPOSITING)
@@ -364,7 +389,6 @@ private:
#endif
void loadTimerFired(Timer<HTMLMediaElement>*);
- void asyncEventTimerFired(Timer<HTMLMediaElement>*);
void progressEventTimerFired(Timer<HTMLMediaElement>*);
void playbackProgressTimerFired(Timer<HTMLMediaElement>*);
void startPlaybackProgressTimer();
@@ -398,7 +422,6 @@ private:
#if ENABLE(VIDEO_TRACK)
void updateActiveTextTrackCues(float);
bool userIsInterestedInThisLanguage(const String&) const;
- bool userIsInterestedInThisTrack(HTMLTrackElement*) const;
HTMLTrackElement* showingTrackWithSameKind(HTMLTrackElement*) const;
bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; }
@@ -449,6 +472,8 @@ private:
virtual void* preDispatchEventHandler(Event*);
+ void changeNetworkStateFromLoadingToIdle();
+
#if ENABLE(MICRODATA)
virtual String itemValueText() const;
virtual void setItemValueText(const String&, ExceptionCode&);
@@ -467,11 +492,10 @@ private:
#endif
Timer<HTMLMediaElement> m_loadTimer;
- Timer<HTMLMediaElement> m_asyncEventTimer;
Timer<HTMLMediaElement> m_progressEventTimer;
Timer<HTMLMediaElement> m_playbackProgressTimer;
- Vector<RefPtr<Event> > m_pendingEvents;
RefPtr<TimeRanges> m_playedTimeRanges;
+ GenericEventQueue m_asyncEventQueue;
float m_playbackRate;
float m_defaultPlaybackRate;
diff --git a/Source/WebCore/html/HTMLMediaElement.idl b/Source/WebCore/html/HTMLMediaElement.idl
index 2dd55d562..484d574e8 100644
--- a/Source/WebCore/html/HTMLMediaElement.idl
+++ b/Source/WebCore/html/HTMLMediaElement.idl
@@ -112,12 +112,12 @@ module html {
#endif
#if defined(ENABLE_VIDEO_TRACK) && ENABLE_VIDEO_TRACK
- [EnabledAtRuntime=webkitVideoTrack] TextTrack addTrack(in DOMString kind, in [Optional] DOMString label, in [Optional] DOMString language)
+ [EnabledAtRuntime=webkitVideoTrack] TextTrack addTextTrack(in DOMString kind, in [Optional] DOMString label, in [Optional] DOMString language)
raises (DOMException);
readonly attribute [EnabledAtRuntime=webkitVideoTrack] TextTrackList textTracks;
#endif
- attribute [Reflect, ConvertNullToNullString, ConvertNullStringToNull] DOMString mediaGroup;
+ attribute [Reflect, TreatNullAs=EmptyString, ConvertNullStringToNull] DOMString mediaGroup;
attribute [CustomSetter] MediaController controller;
};
}
diff --git a/Source/WebCore/html/HTMLMetaElement.cpp b/Source/WebCore/html/HTMLMetaElement.cpp
index c27b9ba23..213ae15b1 100644
--- a/Source/WebCore/html/HTMLMetaElement.cpp
+++ b/Source/WebCore/html/HTMLMetaElement.cpp
@@ -103,9 +103,9 @@ String HTMLMetaElement::itemValueText() const
return getAttribute(contentAttr);
}
-void HTMLMetaElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLMetaElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(contentAttr, value, ec);
+ setAttribute(contentAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLObjectElement.cpp b/Source/WebCore/html/HTMLObjectElement.cpp
index 3f9f77fb2..590d69b98 100644
--- a/Source/WebCore/html/HTMLObjectElement.cpp
+++ b/Source/WebCore/html/HTMLObjectElement.cpp
@@ -177,7 +177,7 @@ void HTMLObjectElement::parametersForPlugin(Vector<String>& paramNames, Vector<S
}
// Turn the attributes of the <object> element into arrays, but don't override <param> values.
- NamedNodeMap* attributes = this->attributes(true);
+ NamedNodeMap* attributes = updatedAttributes();
if (attributes) {
for (unsigned i = 0; i < attributes->length(); ++i) {
Attribute* it = attributes->attributeItem(i);
@@ -289,22 +289,13 @@ void HTMLObjectElement::updateWidget(PluginCreationOption pluginCreationOption)
if (pluginCreationOption == CreateOnlyNonNetscapePlugins && wouldLoadAsNetscapePlugin(url, serviceType))
return;
- ASSERT(!m_inBeforeLoadEventHandler);
- m_inBeforeLoadEventHandler = true;
- bool beforeLoadAllowedLoad = dispatchBeforeLoadEvent(url);
- m_inBeforeLoadEventHandler = false;
-
- // beforeload events can modify the DOM, potentially causing
- // RenderWidget::destroy() to be called. Ensure we haven't been
- // destroyed before continuing.
- // FIXME: Should this render fallback content?
- if (!renderer())
+ RefPtr<HTMLObjectElement> protect(this); // beforeload and plugin loading can make arbitrary DOM mutations.
+ bool beforeLoadAllowedLoad = guardedDispatchBeforeLoadEvent(url);
+ if (!renderer()) // Do not load the plugin if beforeload removed this element or its renderer.
return;
- RefPtr<HTMLObjectElement> protect(this); // Loading the plugin might remove us from the document.
SubframeLoader* loader = document()->frame()->loader()->subframeLoader();
bool success = beforeLoadAllowedLoad && hasValidClassId() && loader->requestObject(this, url, getAttribute(nameAttr), serviceType, paramNames, paramValues);
-
if (!success && fallbackContent)
renderFallbackContent();
}
@@ -520,9 +511,9 @@ String HTMLObjectElement::itemValueText() const
return getURLAttribute(dataAttr);
}
-void HTMLObjectElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLObjectElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(dataAttr, value, ec);
+ setAttribute(dataAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLObjectElement.idl b/Source/WebCore/html/HTMLObjectElement.idl
index c1fa8c003..27e998a1b 100644
--- a/Source/WebCore/html/HTMLObjectElement.idl
+++ b/Source/WebCore/html/HTMLObjectElement.idl
@@ -49,11 +49,11 @@ module html {
void setCustomValidity(in [ConvertUndefinedOrNullToNullString] DOMString error);
// Introduced in DOM Level 2:
- readonly attribute [CheckFrameSecurity] Document contentDocument;
+ readonly attribute [CheckAccessToNode] Document contentDocument;
#if defined(ENABLE_SVG) && ENABLE_SVG
#if !defined(LANGUAGE_OBJECTIVE_C) || !LANGUAGE_OBJECTIVE_C || defined(ENABLE_SVG_DOM_OBJC_BINDINGS) && ENABLE_SVG_DOM_OBJC_BINDINGS
- [SVGCheckSecurityDocument] SVGDocument getSVGDocument() raises(DOMException);
+ [CheckAccessToNode] SVGDocument getSVGDocument() raises(DOMException);
#endif
#endif
diff --git a/Source/WebCore/html/HTMLOutputElement.idl b/Source/WebCore/html/HTMLOutputElement.idl
index 4e6cbfbd7..378ae53de 100644
--- a/Source/WebCore/html/HTMLOutputElement.idl
+++ b/Source/WebCore/html/HTMLOutputElement.idl
@@ -29,8 +29,8 @@ module html {
attribute [Reflect] DOMString name;
readonly attribute DOMString type;
- attribute [ConvertNullToNullString] DOMString defaultValue;
- attribute [ConvertNullToNullString] DOMString value;
+ attribute [TreatNullAs=EmptyString] DOMString defaultValue;
+ attribute [TreatNullAs=EmptyString] DOMString value;
readonly attribute boolean willValidate;
readonly attribute ValidityState validity;
diff --git a/Source/WebCore/html/HTMLParamElement.cpp b/Source/WebCore/html/HTMLParamElement.cpp
index d1f53a14d..aa228bc31 100644
--- a/Source/WebCore/html/HTMLParamElement.cpp
+++ b/Source/WebCore/html/HTMLParamElement.cpp
@@ -65,10 +65,10 @@ void HTMLParamElement::parseMappedAttribute(Attribute* attr)
bool HTMLParamElement::isURLAttribute(Attribute* attr) const
{
- if (attr->name() == valueAttr) {
- Attribute* attr = attributes()->getAttributeItem(nameAttr);
- if (attr) {
- const AtomicString& value = attr->value();
+ if (attr->name() == valueAttr && hasAttributes()) {
+ Attribute* nameAttribute = attributeMap()->getAttributeItem(nameAttr);
+ if (nameAttribute) {
+ const AtomicString& value = nameAttribute->value();
if (isURLParameter(value))
return true;
}
diff --git a/Source/WebCore/html/HTMLPlugInElement.cpp b/Source/WebCore/html/HTMLPlugInElement.cpp
index cc6f3dea6..6229d2e03 100644
--- a/Source/WebCore/html/HTMLPlugInElement.cpp
+++ b/Source/WebCore/html/HTMLPlugInElement.cpp
@@ -110,6 +110,17 @@ PassScriptInstance HTMLPlugInElement::getInstance()
return m_instance;
}
+bool HTMLPlugInElement::guardedDispatchBeforeLoadEvent(const String& sourceURL)
+{
+ ASSERT(!m_inBeforeLoadEventHandler);
+ m_inBeforeLoadEventHandler = true;
+ // static_cast is used to avoid a compile error since dispatchBeforeLoadEvent
+ // is intentionally undefined on this class.
+ bool beforeLoadAllowedLoad = static_cast<HTMLFrameOwnerElement*>(this)->dispatchBeforeLoadEvent(sourceURL);
+ m_inBeforeLoadEventHandler = false;
+ return beforeLoadAllowedLoad;
+}
+
Widget* HTMLPlugInElement::pluginWidget()
{
if (m_inBeforeLoadEventHandler) {
diff --git a/Source/WebCore/html/HTMLPlugInElement.h b/Source/WebCore/html/HTMLPlugInElement.h
index 7dadfda9f..a10af6141 100644
--- a/Source/WebCore/html/HTMLPlugInElement.h
+++ b/Source/WebCore/html/HTMLPlugInElement.h
@@ -62,8 +62,12 @@ protected:
virtual void parseMappedAttribute(Attribute*);
bool m_inBeforeLoadEventHandler;
+ // Subclasses should use guardedDispatchBeforeLoadEvent instead of calling dispatchBeforeLoadEvent directly.
+ bool guardedDispatchBeforeLoadEvent(const String& sourceURL);
private:
+ bool dispatchBeforeLoadEvent(const String& sourceURL); // Not implemented, generates a compile error if subclasses call this by mistake.
+
virtual void defaultEventHandler(Event*);
virtual RenderWidget* renderWidgetForJSBindings() = 0;
diff --git a/Source/WebCore/html/HTMLPlugInImageElement.cpp b/Source/WebCore/html/HTMLPlugInImageElement.cpp
index ce9bb7431..515022aad 100644
--- a/Source/WebCore/html/HTMLPlugInImageElement.cpp
+++ b/Source/WebCore/html/HTMLPlugInImageElement.cpp
@@ -217,25 +217,23 @@ void HTMLPlugInImageElement::didMoveToNewDocument(Document* oldDocument)
void HTMLPlugInImageElement::documentWillSuspendForPageCache()
{
- if (RenderStyle* rs = renderStyle()) {
- m_customStyleForPageCache = RenderStyle::clone(rs);
+ if (RenderStyle* renderStyle = this->renderStyle()) {
+ m_customStyleForPageCache = RenderStyle::clone(renderStyle);
m_customStyleForPageCache->setDisplay(NONE);
- }
-
- setHasCustomStyleForRenderer();
+ setHasCustomStyleForRenderer();
- if (m_customStyleForPageCache)
recalcStyle(Force);
-
+ }
+
HTMLPlugInElement::documentWillSuspendForPageCache();
}
void HTMLPlugInImageElement::documentDidResumeFromPageCache()
{
- clearHasCustomStyleForRenderer();
-
if (m_customStyleForPageCache) {
m_customStyleForPageCache = 0;
+ clearHasCustomStyleForRenderer();
+
recalcStyle(Force);
}
@@ -244,9 +242,7 @@ void HTMLPlugInImageElement::documentDidResumeFromPageCache()
PassRefPtr<RenderStyle> HTMLPlugInImageElement::customStyleForRenderer()
{
- if (!m_customStyleForPageCache)
- return renderStyle();
-
+ ASSERT(m_customStyleForPageCache);
return m_customStyleForPageCache;
}
diff --git a/Source/WebCore/html/HTMLPropertiesCollection.cpp b/Source/WebCore/html/HTMLPropertiesCollection.cpp
index 86fcecfae..6aac467ad 100644
--- a/Source/WebCore/html/HTMLPropertiesCollection.cpp
+++ b/Source/WebCore/html/HTMLPropertiesCollection.cpp
@@ -49,12 +49,12 @@ static inline bool compareTreeOrder(Node* node1, Node* node2)
return (node2->compareDocumentPosition(node1) & (Node::DOCUMENT_POSITION_PRECEDING | Node::DOCUMENT_POSITION_DISCONNECTED)) == Node::DOCUMENT_POSITION_PRECEDING;
}
-PassOwnPtr<HTMLPropertiesCollection> HTMLPropertiesCollection::create(PassRefPtr<Node> itemNode)
+PassOwnPtr<HTMLPropertiesCollection> HTMLPropertiesCollection::create(Node* itemNode)
{
return adoptPtr(new HTMLPropertiesCollection(itemNode));
}
-HTMLPropertiesCollection::HTMLPropertiesCollection(PassRefPtr<Node> itemNode)
+HTMLPropertiesCollection::HTMLPropertiesCollection(Node* itemNode)
: HTMLCollection(itemNode, ItemProperties)
, m_propertyNames(DOMStringList::create())
{
diff --git a/Source/WebCore/html/HTMLPropertiesCollection.h b/Source/WebCore/html/HTMLPropertiesCollection.h
index e7524f983..2572eebc4 100644
--- a/Source/WebCore/html/HTMLPropertiesCollection.h
+++ b/Source/WebCore/html/HTMLPropertiesCollection.h
@@ -41,7 +41,7 @@ class DOMStringList;
class HTMLPropertiesCollection : public HTMLCollection {
public:
- static PassOwnPtr<HTMLPropertiesCollection> create(PassRefPtr<Node>);
+ static PassOwnPtr<HTMLPropertiesCollection> create(Node*);
virtual ~HTMLPropertiesCollection();
unsigned length() const OVERRIDE;
@@ -51,7 +51,7 @@ public:
PassRefPtr<DOMStringList> names() const;
private:
- HTMLPropertiesCollection(PassRefPtr<Node>);
+ HTMLPropertiesCollection(Node*);
void findPropetiesOfAnItem(Node* current) const;
diff --git a/Source/WebCore/html/HTMLScriptElement.cpp b/Source/WebCore/html/HTMLScriptElement.cpp
index 9b18ec5d3..a4c5586dc 100644
--- a/Source/WebCore/html/HTMLScriptElement.cpp
+++ b/Source/WebCore/html/HTMLScriptElement.cpp
@@ -85,12 +85,6 @@ void HTMLScriptElement::insertedIntoDocument()
ScriptElement::insertedIntoDocument();
}
-void HTMLScriptElement::removedFromDocument()
-{
- HTMLElement::removedFromDocument();
- ScriptElement::removedFromDocument();
-}
-
void HTMLScriptElement::setText(const String &value)
{
ExceptionCode ec = 0;
diff --git a/Source/WebCore/html/HTMLScriptElement.h b/Source/WebCore/html/HTMLScriptElement.h
index ee6f7b560..a5fe048a1 100644
--- a/Source/WebCore/html/HTMLScriptElement.h
+++ b/Source/WebCore/html/HTMLScriptElement.h
@@ -46,7 +46,6 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
- virtual void removedFromDocument();
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void attributeChanged(Attribute*, bool preserveDecls = false);
diff --git a/Source/WebCore/html/HTMLScriptElement.idl b/Source/WebCore/html/HTMLScriptElement.idl
index fa799cb2c..03b5ac816 100644
--- a/Source/WebCore/html/HTMLScriptElement.idl
+++ b/Source/WebCore/html/HTMLScriptElement.idl
@@ -20,7 +20,7 @@
module html {
interface HTMLScriptElement : HTMLElement {
- attribute [ConvertNullToNullString] DOMString text;
+ attribute [TreatNullAs=EmptyString] DOMString text;
attribute [Reflect=for] DOMString htmlFor;
attribute [Reflect] DOMString event;
attribute [Reflect] DOMString charset;
diff --git a/Source/WebCore/html/HTMLSelectElement.cpp b/Source/WebCore/html/HTMLSelectElement.cpp
index bfebf8e64..4bd10b800 100644
--- a/Source/WebCore/html/HTMLSelectElement.cpp
+++ b/Source/WebCore/html/HTMLSelectElement.cpp
@@ -61,19 +61,6 @@ using namespace HTMLNames;
// Upper limit agreed upon with representatives of Opera and Mozilla.
static const unsigned maxSelectItems = 10000;
-// Configure platform-specific behavior when focused pop-up receives arrow/space/return keystroke.
-// (PLATFORM(MAC) and PLATFORM(GTK) are always false in Chromium, hence the extra tests.)
-#if PLATFORM(MAC) || (PLATFORM(CHROMIUM) && OS(DARWIN))
-#define ARROW_KEYS_POP_MENU 1
-#define SPACE_OR_RETURN_POP_MENU 0
-#elif PLATFORM(GTK) || (PLATFORM(CHROMIUM) && OS(UNIX))
-#define ARROW_KEYS_POP_MENU 0
-#define SPACE_OR_RETURN_POP_MENU 1
-#else
-#define ARROW_KEYS_POP_MENU 0
-#define SPACE_OR_RETURN_POP_MENU 0
-#endif
-
static const DOMTimeStamp typeAheadTimeout = 1000;
HTMLSelectElement::HTMLSelectElement(const QualifiedName& tagName, Document* document, HTMLFormElement* form)
@@ -247,10 +234,13 @@ String HTMLSelectElement::value() const
void HTMLSelectElement::setValue(const String &value)
{
- if (value.isNull())
+ // We clear the previously selected option(s) when needed, to guarantee calling setSelectedIndex() only once.
+ if (value.isNull()) {
+ setSelectedIndex(-1);
return;
- // find the option with value() matching the given parameter
- // and make it the current selection.
+ }
+
+ // Find the option with value() matching the given parameter and make it the current selection.
const Vector<HTMLElement*>& items = listItems();
unsigned optionIndex = 0;
for (unsigned i = 0; i < items.size(); i++) {
@@ -262,6 +252,8 @@ void HTMLSelectElement::setValue(const String &value)
optionIndex++;
}
}
+
+ setSelectedIndex(-1);
}
void HTMLSelectElement::parseMappedAttribute(Attribute* attr)
@@ -775,8 +767,10 @@ void HTMLSelectElement::optionSelectionStateChanged(HTMLOptionElement* option, b
ASSERT(option->ownerSelectElement() == this);
if (optionIsSelected)
selectOption(option->index());
+ else if (!usesMenuList())
+ selectOption(-1);
else
- selectOption(m_multiple ? -1 : nextSelectableListIndex(-1));
+ selectOption(nextSelectableListIndex(-1));
}
void HTMLSelectElement::selectOption(int optionIndex, SelectOptionFlags flags)
@@ -986,7 +980,12 @@ void HTMLSelectElement::reset()
#if !PLATFORM(WIN) || OS(WINCE)
bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
{
-#if ARROW_KEYS_POP_MENU
+ const Page* page = document()->page();
+ RefPtr<RenderTheme> renderTheme = page ? page->theme() : RenderTheme::defaultTheme();
+
+ if (!renderTheme->popsMenuByArrowKeys())
+ return false;
+
if (!isSpatialNavigationEnabled(document()->frame())) {
if (event->keyIdentifier() == "Down" || event->keyIdentifier() == "Up") {
focus();
@@ -1007,15 +1006,16 @@ bool HTMLSelectElement::platformHandleKeydownEvent(KeyboardEvent* event)
}
return true;
}
-#else
- UNUSED_PARAM(event);
-#endif
+
return false;
}
#endif
void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
{
+ const Page* page = document()->page();
+ RefPtr<RenderTheme> renderTheme = page ? page->theme() : RenderTheme::defaultTheme();
+
if (event->type() == eventNames().keydownEvent) {
if (!renderer() || !event->isKeyboardEvent())
return;
@@ -1074,48 +1074,49 @@ void HTMLSelectElement::menuListDefaultEventHandler(Event* event)
return;
}
-#if SPACE_OR_RETURN_POP_MENU
- if (keyCode == ' ' || keyCode == '\r') {
- focus();
-
- // Calling focus() may cause us to lose our renderer, in which case
- // do not want to handle the event.
- if (!renderer())
- return;
-
- // Save the selection so it can be compared to the new selection
- // when dispatching change events during selectOption, which
- // gets called from RenderMenuList::valueChanged, which gets called
- // after the user makes a selection from the menu.
- saveLastSelection();
- if (RenderMenuList* menuList = toRenderMenuList(renderer()))
- menuList->showPopup();
- handled = true;
+ if (renderTheme->popsMenuBySpaceOrReturn()) {
+ if (keyCode == ' ' || keyCode == '\r') {
+ focus();
+
+ // Calling focus() may cause us to lose our renderer, in which case
+ // do not want to handle the event.
+ if (!renderer())
+ return;
+
+ // Save the selection so it can be compared to the new selection
+ // when dispatching change events during selectOption, which
+ // gets called from RenderMenuList::valueChanged, which gets called
+ // after the user makes a selection from the menu.
+ saveLastSelection();
+ if (RenderMenuList* menuList = toRenderMenuList(renderer()))
+ menuList->showPopup();
+ handled = true;
+ }
+ } else if (renderTheme->popsMenuByArrowKeys()) {
+ if (keyCode == ' ') {
+ focus();
+
+ // Calling focus() may cause us to lose our renderer, in which case
+ // do not want to handle the event.
+ if (!renderer())
+ return;
+
+ // Save the selection so it can be compared to the new selection
+ // when dispatching change events during selectOption, which
+ // gets called from RenderMenuList::valueChanged, which gets called
+ // after the user makes a selection from the menu.
+ saveLastSelection();
+ if (RenderMenuList* menuList = toRenderMenuList(renderer()))
+ menuList->showPopup();
+ handled = true;
+ } else if (keyCode == '\r') {
+ if (form())
+ form()->submitImplicitly(event, false);
+ dispatchChangeEventForMenuList();
+ handled = true;
+ }
}
-#elif ARROW_KEYS_POP_MENU
- if (keyCode == ' ') {
- focus();
-
- // Calling focus() may cause us to lose our renderer, in which case
- // do not want to handle the event.
- if (!renderer())
- return;
- // Save the selection so it can be compared to the new selection
- // when dispatching change events during selectOption, which
- // gets called from RenderMenuList::valueChanged, which gets called
- // after the user makes a selection from the menu.
- saveLastSelection();
- if (RenderMenuList* menuList = toRenderMenuList(renderer()))
- menuList->showPopup();
- handled = true;
- } else if (keyCode == '\r') {
- if (form())
- form()->submitImplicitly(event, false);
- dispatchChangeEventForMenuList();
- handled = true;
- }
-#endif
if (handled)
event->setDefaultHandled();
}
@@ -1158,7 +1159,7 @@ void HTMLSelectElement::updateSelectedState(int listIndex, bool multi, bool shif
if (clickedElement->hasTagName(optionTag)) {
// Keep track of whether an active selection (like during drag
// selection), should select or deselect.
- if (toHTMLOptionElement(clickedElement)->selected() && multi)
+ if (toHTMLOptionElement(clickedElement)->selected() && multiSelect)
m_activeSelectionState = false;
if (!m_activeSelectionState)
toHTMLOptionElement(clickedElement)->setSelectedState(false);
@@ -1226,8 +1227,11 @@ void HTMLSelectElement::listBoxDefaultEventHandler(Event* event)
if (m_multiple) {
setActiveSelectionEndIndex(listIndex);
updateListBoxSelection(false);
- } else
- updateSelectedState(listIndex, false, false);
+ } else {
+ setActiveSelectionAnchorIndex(listIndex);
+ setActiveSelectionEndIndex(listIndex);
+ updateListBoxSelection(true);
+ }
event->setDefaultHandled();
}
} else if (event->type() == eventNames().mouseupEvent && event->isMouseEvent() && static_cast<MouseEvent*>(event)->button() == LeftButton && document()->frame()->eventHandler()->autoscrollRenderer() != renderer()) {
diff --git a/Source/WebCore/html/HTMLSelectElement.idl b/Source/WebCore/html/HTMLSelectElement.idl
index 45a345601..9749780c1 100644
--- a/Source/WebCore/html/HTMLSelectElement.idl
+++ b/Source/WebCore/html/HTMLSelectElement.idl
@@ -26,7 +26,7 @@ module html {
] HTMLSelectElement : HTMLElement {
readonly attribute DOMString type;
attribute long selectedIndex;
- attribute [ConvertNullToNullString] DOMString value;
+ attribute [TreatNullAs=EmptyString] DOMString value;
// Modified in DOM Level 2:
#if defined(LANGUAGE_OBJECTIVE_C) && LANGUAGE_OBJECTIVE_C
@@ -48,7 +48,7 @@ module html {
attribute [Reflect] boolean disabled;
attribute [Reflect] boolean autofocus;
attribute boolean multiple;
- attribute [ConvertNullToNullString] DOMString name;
+ attribute [TreatNullAs=EmptyString] DOMString name;
attribute [Reflect] boolean required;
attribute long size;
diff --git a/Source/WebCore/html/HTMLSourceElement.cpp b/Source/WebCore/html/HTMLSourceElement.cpp
index 99f211ad2..df2605756 100644
--- a/Source/WebCore/html/HTMLSourceElement.cpp
+++ b/Source/WebCore/html/HTMLSourceElement.cpp
@@ -127,9 +127,9 @@ String HTMLSourceElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLSourceElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLSourceElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLStyleElement.cpp b/Source/WebCore/html/HTMLStyleElement.cpp
index 9efe80aa0..cc1fa2300 100644
--- a/Source/WebCore/html/HTMLStyleElement.cpp
+++ b/Source/WebCore/html/HTMLStyleElement.cpp
@@ -38,12 +38,17 @@ using namespace HTMLNames;
inline HTMLStyleElement::HTMLStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser)
: HTMLElement(tagName, document)
, StyleElement(document, createdByParser)
+#if ENABLE(STYLE_SCOPED)
+ , m_isRegisteredWithScopingNode(false)
+#endif
{
ASSERT(hasTagName(styleTag));
}
HTMLStyleElement::~HTMLStyleElement()
{
+ // During tear-down, willRemove isn't called, so m_isRegisteredWithScopingNode may still be set here.
+ // Therefore we can't ASSERT(!m_isRegisteredWithScopingNode).
StyleElement::clearDocumentData(document(), this);
}
@@ -56,6 +61,15 @@ void HTMLStyleElement::parseMappedAttribute(Attribute* attr)
{
if (attr->name() == titleAttr && m_sheet)
m_sheet->setTitle(attr->value());
+#if ENABLE(STYLE_SCOPED)
+ else if (attr->name() == scopedAttr) {
+ if (!attr->isNull() && !m_isRegisteredWithScopingNode && inDocument())
+ registerWithScopingNode();
+ else if (attr->isNull() && m_isRegisteredWithScopingNode)
+ unregisterWithScopingNode();
+
+ }
+#endif
else
HTMLElement::parseMappedAttribute(attr);
}
@@ -66,18 +80,82 @@ void HTMLStyleElement::finishParsingChildren()
HTMLElement::finishParsingChildren();
}
+#if ENABLE(STYLE_SCOPED)
+void HTMLStyleElement::registerWithScopingNode()
+{
+ // Note: We cannot rely on the 'scoped' element already being present when this method is invoked.
+ // Therefore we cannot rely on scoped()!
+ ASSERT(!m_isRegisteredWithScopingNode);
+ ASSERT(inDocument());
+ if (!m_isRegisteredWithScopingNode) {
+ Element* scope = parentElement();
+ if (!scope)
+ return;
+
+ scope->registerScopedHTMLStyleChild();
+ scope->setNeedsStyleRecalc();
+ if (inDocument() && !document()->parsing() && document()->renderer())
+ document()->styleSelectorChanged(DeferRecalcStyle);
+
+ m_isRegisteredWithScopingNode = true;
+ }
+}
+
+void HTMLStyleElement::unregisterWithScopingNode()
+{
+ // Note: We cannot rely on the 'scoped' element still being present when this method is invoked.
+ // Therefore we cannot rely on scoped()!
+ ASSERT(m_isRegisteredWithScopingNode);
+ if (m_isRegisteredWithScopingNode) {
+ Element* scope = parentElement();
+ ASSERT(scope);
+ if (scope) {
+ ASSERT(scope->hasScopedHTMLStyleChild());
+ scope->unregisterScopedHTMLStyleChild();
+ scope->setNeedsStyleRecalc();
+ }
+ if (inDocument() && !document()->parsing() && document()->renderer())
+ document()->styleSelectorChanged(DeferRecalcStyle);
+
+ m_isRegisteredWithScopingNode = false;
+ }
+}
+#endif
+
void HTMLStyleElement::insertedIntoDocument()
{
HTMLElement::insertedIntoDocument();
StyleElement::insertedIntoDocument(document(), this);
+#if ENABLE(STYLE_SCOPED)
+ if (scoped() && !m_isRegisteredWithScopingNode)
+ registerWithScopingNode();
+#endif
}
void HTMLStyleElement::removedFromDocument()
{
+#if ENABLE(STYLE_SCOPED)
+ ASSERT(!m_isRegisteredWithScopingNode);
+#endif
HTMLElement::removedFromDocument();
StyleElement::removedFromDocument(document(), this);
}
+
+#if ENABLE(STYLE_SCOPED)
+void HTMLStyleElement::willRemove()
+{
+ // In the current implementation, <style scoped> is only registered if the node is in the document.
+ // That is, because willRemove() is also called if an ancestor is removed from the document.
+ // Now, if we want to register <style scoped> even if it's not inDocument,
+ // we'd need to find a way to discern whether that is the case, or whether <style scoped> itself is about to be removed.
+ ASSERT(!scoped() || !inDocument() || m_isRegisteredWithScopingNode);
+ if (m_isRegisteredWithScopingNode)
+ unregisterWithScopingNode();
+ HTMLElement::willRemove();
+}
+#endif
+
void HTMLStyleElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
{
StyleElement::childrenChanged(this);
diff --git a/Source/WebCore/html/HTMLStyleElement.h b/Source/WebCore/html/HTMLStyleElement.h
index 6baaee3b7..d56d46d6d 100644
--- a/Source/WebCore/html/HTMLStyleElement.h
+++ b/Source/WebCore/html/HTMLStyleElement.h
@@ -55,6 +55,9 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual void insertedIntoDocument();
virtual void removedFromDocument();
+#if ENABLE(STYLE_SCOPED)
+ virtual void willRemove();
+#endif
virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
virtual void finishParsingChildren();
@@ -67,6 +70,11 @@ private:
virtual const AtomicString& media() const;
virtual const AtomicString& type() const;
+
+ void registerWithScopingNode();
+ void unregisterWithScopingNode();
+
+ bool m_isRegisteredWithScopingNode;
};
} //namespace
diff --git a/Source/WebCore/html/HTMLSummaryElement.cpp b/Source/WebCore/html/HTMLSummaryElement.cpp
index ecf1085ce..9925627fe 100644
--- a/Source/WebCore/html/HTMLSummaryElement.cpp
+++ b/Source/WebCore/html/HTMLSummaryElement.cpp
@@ -24,12 +24,12 @@
#if ENABLE(DETAILS)
#include "DetailsMarkerControl.h"
+#include "HTMLContentElement.h"
#include "HTMLDetailsElement.h"
#include "HTMLNames.h"
#include "MouseEvent.h"
#include "PlatformMouseEvent.h"
#include "RenderSummary.h"
-#include "ShadowContentElement.h"
#include "ShadowRoot.h"
@@ -37,13 +37,13 @@ namespace WebCore {
using namespace HTMLNames;
-class SummaryContentElement : public ShadowContentElement {
+class SummaryContentElement : public HTMLContentElement {
public:
static PassRefPtr<SummaryContentElement> create(Document*);
private:
SummaryContentElement(Document* document)
- : ShadowContentElement(HTMLNames::divTag, document)
+ : HTMLContentElement(HTMLNames::divTag, document)
{
}
};
diff --git a/Source/WebCore/html/HTMLTableCellElement.cpp b/Source/WebCore/html/HTMLTableCellElement.cpp
index 7e205d9e2..9a96a3607 100644
--- a/Source/WebCore/html/HTMLTableCellElement.cpp
+++ b/Source/WebCore/html/HTMLTableCellElement.cpp
@@ -118,15 +118,14 @@ void HTMLTableCellElement::parseMappedAttribute(Attribute* attr)
HTMLTablePartElement::parseMappedAttribute(attr);
}
-// used by table cells to share style decls created by the enclosing table.
-void HTMLTableCellElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableCellElement::additionalAttributeStyle()
{
ContainerNode* p = parentNode();
while (p && !p->hasTagName(tableTag))
p = p->parentNode();
if (!p)
- return;
- static_cast<HTMLTableElement*>(p)->addSharedCellDecls(results);
+ return 0;
+ return static_cast<HTMLTableElement*>(p)->additionalCellStyle();
}
bool HTMLTableCellElement::isURLAttribute(Attribute *attr) const
diff --git a/Source/WebCore/html/HTMLTableCellElement.h b/Source/WebCore/html/HTMLTableCellElement.h
index 5a472727b..d7ddc8692 100644
--- a/Source/WebCore/html/HTMLTableCellElement.h
+++ b/Source/WebCore/html/HTMLTableCellElement.h
@@ -56,10 +56,8 @@ private:
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
- // used by table cells to share style decls created by the enclosing table.
- virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
- virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
-
+ virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
+
virtual bool isURLAttribute(Attribute*) const;
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
diff --git a/Source/WebCore/html/HTMLTableColElement.cpp b/Source/WebCore/html/HTMLTableColElement.cpp
index 96af70827..10657e682 100644
--- a/Source/WebCore/html/HTMLTableColElement.cpp
+++ b/Source/WebCore/html/HTMLTableColElement.cpp
@@ -77,17 +77,16 @@ void HTMLTableColElement::parseMappedAttribute(Attribute* attr)
HTMLTablePartElement::parseMappedAttribute(attr);
}
-// used by table columns and column groups to share style decls created by the enclosing table.
-void HTMLTableColElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableColElement::additionalAttributeStyle()
{
if (!hasLocalName(colgroupTag))
- return;
+ return 0;
ContainerNode* p = parentNode();
while (p && !p->hasTagName(tableTag))
p = p->parentNode();
if (!p)
- return;
- static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(false, results);
+ return 0;
+ return static_cast<HTMLTableElement*>(p)->additionalGroupStyle(false);
}
void HTMLTableColElement::setSpan(int n)
diff --git a/Source/WebCore/html/HTMLTableColElement.h b/Source/WebCore/html/HTMLTableColElement.h
index c7517d10a..36180c773 100644
--- a/Source/WebCore/html/HTMLTableColElement.h
+++ b/Source/WebCore/html/HTMLTableColElement.h
@@ -44,9 +44,8 @@ private:
virtual bool mapToEntry(const QualifiedName&, MappedAttributeEntry&) const;
virtual void parseMappedAttribute(Attribute*);
- virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
- virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
-
+ virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
+
int m_span;
};
diff --git a/Source/WebCore/html/HTMLTableElement.cpp b/Source/WebCore/html/HTMLTableElement.cpp
index 342cff2b3..cac8b4d61 100644
--- a/Source/WebCore/html/HTMLTableElement.cpp
+++ b/Source/WebCore/html/HTMLTableElement.cpp
@@ -436,8 +436,7 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr)
HTMLElement::parseMappedAttribute(attr);
if (bordersBefore != cellBorders() || oldPadding != m_padding) {
- if (oldPadding != m_padding)
- m_paddingDecl = 0;
+ m_sharedCellStyle = 0;
bool cellChanged = false;
for (Node* child = firstChild(); child; child = child->nextSibling())
cellChanged |= setTableCellsChanged(child);
@@ -446,28 +445,27 @@ void HTMLTableElement::parseMappedAttribute(Attribute* attr)
}
}
-void HTMLTableElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+static CSSMutableStyleDeclaration* leakBorderStyle(int value)
{
- if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
- return;
-
- AtomicString borderValue = m_borderColorAttr ? "solid" : "outset";
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, tableborderAttr, borderValue);
- if (!decl) {
- decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
- ASSERT(!decl->useStrictParsing());
+ RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+ style->setProperty(CSSPropertyBorderTopStyle, value);
+ style->setProperty(CSSPropertyBorderBottomStyle, value);
+ style->setProperty(CSSPropertyBorderLeftStyle, value);
+ style->setProperty(CSSPropertyBorderRightStyle, value);
+ return style.release().leakRef();
+}
- int value = m_borderColorAttr ? CSSValueSolid : CSSValueOutset;
- decl->setMappedProperty(this, CSSPropertyBorderTopStyle, value);
- decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, value);
- decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, value);
- decl->setMappedProperty(this, CSSPropertyBorderRightStyle, value);
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalAttributeStyle()
+{
+ if ((!m_borderAttr && !m_borderColorAttr) || m_frameAttr)
+ return 0;
- setMappedAttributeDecl(ePersistent, tableborderAttr, borderValue, decl);
- decl->setMappedState(ePersistent, tableborderAttr, borderValue);
+ if (m_borderColorAttr) {
+ static CSSMutableStyleDeclaration* solidBorderStyle = leakBorderStyle(CSSValueSolid);
+ return solidBorderStyle;
}
-
- results.append(decl);
+ static CSSMutableStyleDeclaration* outsetBorderStyle = leakBorderStyle(CSSValueOutset);
+ return outsetBorderStyle;
}
HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
@@ -493,118 +491,92 @@ HTMLTableElement::CellBorders HTMLTableElement::cellBorders() const
return NoBorders;
}
-void HTMLTableElement::addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>& results)
-{
- addSharedCellBordersDecl(results);
- addSharedCellPaddingDecl(results);
-}
-
-void HTMLTableElement::addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>& results)
-{
- CellBorders borders = cellBorders();
-
- static const AtomicString* cellBorderNames[] = { new AtomicString("none"), new AtomicString("solid"), new AtomicString("inset"), new AtomicString("solid-cols"), new AtomicString("solid-rows") };
- const AtomicString& cellborderValue = *cellBorderNames[borders];
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, cellborderAttr, cellborderValue);
- if (!decl) {
- decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
- ASSERT(!decl->useStrictParsing());
-
- switch (borders) {
- case SolidBordersColsOnly:
- decl->setMappedProperty(this, CSSPropertyBorderLeftWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderRightWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
- break;
- case SolidBordersRowsOnly:
- decl->setMappedProperty(this, CSSPropertyBorderTopWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderBottomWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
- break;
- case SolidBorders:
- decl->setMappedProperty(this, CSSPropertyBorderWidth, "1px");
- decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
- break;
- case InsetBorders:
- decl->setMappedProperty(this, CSSPropertyBorderWidth, "1px");
- decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueInset);
- decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueInset);
- decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueInset);
- decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueInset);
- decl->setMappedProperty(this, CSSPropertyBorderColor, "inherit");
- break;
- case NoBorders:
- decl->setMappedProperty(this, CSSPropertyBorderWidth, "0");
- break;
- }
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::createSharedCellStyle()
+{
+ RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+
+ switch (cellBorders()) {
+ case SolidBordersColsOnly:
+ style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderColor, "inherit");
+ break;
+ case SolidBordersRowsOnly:
+ style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderColor, "inherit");
+ break;
+ case SolidBorders:
+ style->setProperty(CSSPropertyBorderWidth, "1px");
+ style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderColor, "inherit");
+ break;
+ case InsetBorders:
+ style->setProperty(CSSPropertyBorderWidth, "1px");
+ style->setProperty(CSSPropertyBorderTopStyle, CSSValueInset);
+ style->setProperty(CSSPropertyBorderBottomStyle, CSSValueInset);
+ style->setProperty(CSSPropertyBorderLeftStyle, CSSValueInset);
+ style->setProperty(CSSPropertyBorderRightStyle, CSSValueInset);
+ style->setProperty(CSSPropertyBorderColor, "inherit");
+ break;
+ case NoBorders:
+ style->setProperty(CSSPropertyBorderWidth, "0");
+ break;
+ }
- setMappedAttributeDecl(ePersistent, cellborderAttr, *cellBorderNames[borders], decl);
- decl->setMappedState(ePersistent, cellborderAttr, cellborderValue);
+ if (m_padding) {
+ String value = String::number(m_padding) + "px";
+ style->setProperty(CSSPropertyPaddingTop, value);
+ style->setProperty(CSSPropertyPaddingBottom, value);
+ style->setProperty(CSSPropertyPaddingLeft, value);
+ style->setProperty(CSSPropertyPaddingRight, value);
}
- results.append(decl);
+ return style.release();
}
-void HTMLTableElement::addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalCellStyle()
{
- if (m_padding == 0)
- return;
+ if (!m_sharedCellStyle)
+ m_sharedCellStyle = createSharedCellStyle();
+ return m_sharedCellStyle;
+}
- if (!m_paddingDecl) {
- String paddingValue = String::number(m_padding);
- m_paddingDecl = getMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue);
- if (!m_paddingDecl) {
- m_paddingDecl = CSSMappedAttributeDeclaration::create();
- ASSERT(!m_paddingDecl->useStrictParsing());
-
- m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingTop, paddingValue);
- m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingRight, paddingValue);
- m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingBottom, paddingValue);
- m_paddingDecl->setMappedProperty(this, CSSPropertyPaddingLeft, paddingValue);
- }
- setMappedAttributeDecl(eUniversal, cellpaddingAttr, paddingValue, m_paddingDecl.get());
- m_paddingDecl->setMappedState(eUniversal, cellpaddingAttr, paddingValue);
+static CSSMutableStyleDeclaration* leakGroupBorderStyle(int rows)
+{
+ RefPtr<CSSMutableStyleDeclaration> style = CSSMutableStyleDeclaration::create();
+ if (rows) {
+ style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
+ } else {
+ style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
+ style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
+ style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
}
-
- results.append(m_paddingDecl.get());
+ return style.release().leakRef();
}
-void HTMLTableElement::addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableElement::additionalGroupStyle(bool rows)
{
if (m_rulesAttr != GroupsRules)
- return;
-
- AtomicString rulesValue = rows ? "rowgroups" : "colgroups";
- CSSMappedAttributeDeclaration* decl = getMappedAttributeDecl(ePersistent, rulesAttr, rulesValue);
- if (!decl) {
- decl = CSSMappedAttributeDeclaration::create().leakRef(); // This single ref pins us in the table until the document dies.
- ASSERT(!decl->useStrictParsing());
-
- if (rows) {
- decl->setMappedProperty(this, CSSPropertyBorderTopWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderBottomWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderTopStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderBottomStyle, CSSValueSolid);
- } else {
- decl->setMappedProperty(this, CSSPropertyBorderLeftWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderRightWidth, CSSValueThin);
- decl->setMappedProperty(this, CSSPropertyBorderLeftStyle, CSSValueSolid);
- decl->setMappedProperty(this, CSSPropertyBorderRightStyle, CSSValueSolid);
- }
+ return 0;
- setMappedAttributeDecl(ePersistent, rulesAttr, rulesValue, decl);
- decl->setMappedState(ePersistent, rulesAttr, rulesValue);
+ if (rows) {
+ static CSSMutableStyleDeclaration* rowBorderStyle = leakGroupBorderStyle(true);
+ return rowBorderStyle;
}
-
- results.append(decl);
+ static CSSMutableStyleDeclaration* columnBorderStyle = leakGroupBorderStyle(false);
+ return columnBorderStyle;
}
void HTMLTableElement::attach()
diff --git a/Source/WebCore/html/HTMLTableElement.h b/Source/WebCore/html/HTMLTableElement.h
index deed9518d..cfde1df95 100644
--- a/Source/WebCore/html/HTMLTableElement.h
+++ b/Source/WebCore/html/HTMLTableElement.h
@@ -66,8 +66,8 @@ public:
virtual void attach();
- void addSharedCellDecls(Vector<CSSMutableStyleDeclaration*>&);
- void addSharedGroupDecls(bool rows, Vector<CSSMutableStyleDeclaration*>&);
+ PassRefPtr<CSSMutableStyleDeclaration> additionalCellStyle();
+ PassRefPtr<CSSMutableStyleDeclaration> additionalGroupStyle(bool rows);
private:
HTMLTableElement(const QualifiedName&, Document*);
@@ -76,21 +76,18 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual bool isURLAttribute(Attribute*) const;
- // Used to obtain either a solid or outset border decl and to deal with the frame
- // and rules attributes.
- virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
- virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+ // Used to obtain either a solid or outset border decl and to deal with the frame and rules attributes.
+ virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
- void addSharedCellBordersDecl(Vector<CSSMutableStyleDeclaration*>&);
- void addSharedCellPaddingDecl(Vector<CSSMutableStyleDeclaration*>&);
-
enum TableRules { UnsetRules, NoneRules, GroupsRules, RowsRules, ColsRules, AllRules };
enum CellBorders { NoBorders, SolidBorders, InsetBorders, SolidBordersColsOnly, SolidBordersRowsOnly };
CellBorders cellBorders() const;
+ PassRefPtr<CSSMutableStyleDeclaration> createSharedCellStyle();
+
HTMLTableSectionElement* lastBody() const;
bool m_borderAttr; // Sets a precise border width and creates an outset border for the table and for its cells.
@@ -100,8 +97,8 @@ private:
// are present, to none otherwise).
unsigned short m_padding;
- RefPtr<CSSMappedAttributeDeclaration> m_paddingDecl;
OwnPtr<HTMLTableRowsCollection> m_rowsCollection;
+ RefPtr<CSSMutableStyleDeclaration> m_sharedCellStyle;
};
} //namespace
diff --git a/Source/WebCore/html/HTMLTableSectionElement.cpp b/Source/WebCore/html/HTMLTableSectionElement.cpp
index 3297ad624..ef6e9f23e 100644
--- a/Source/WebCore/html/HTMLTableSectionElement.cpp
+++ b/Source/WebCore/html/HTMLTableSectionElement.cpp
@@ -47,15 +47,14 @@ PassRefPtr<HTMLTableSectionElement> HTMLTableSectionElement::create(const Qualif
return adoptRef(new HTMLTableSectionElement(tagName, document));
}
-// used by table row groups to share style decls created by the enclosing table.
-void HTMLTableSectionElement::additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>& results)
+PassRefPtr<CSSMutableStyleDeclaration> HTMLTableSectionElement::additionalAttributeStyle()
{
ContainerNode* p = parentNode();
while (p && !p->hasTagName(tableTag))
p = p->parentNode();
if (!p)
- return;
- static_cast<HTMLTableElement*>(p)->addSharedGroupDecls(true, results);
+ return 0;
+ return static_cast<HTMLTableElement*>(p)->additionalGroupStyle(true);
}
// these functions are rather slow, since we need to get the row at
diff --git a/Source/WebCore/html/HTMLTableSectionElement.h b/Source/WebCore/html/HTMLTableSectionElement.h
index 295904c4a..b1680c42e 100644
--- a/Source/WebCore/html/HTMLTableSectionElement.h
+++ b/Source/WebCore/html/HTMLTableSectionElement.h
@@ -56,8 +56,7 @@ public:
private:
HTMLTableSectionElement(const QualifiedName& tagName, Document*);
- virtual bool canHaveAdditionalAttributeStyleDecls() const { return true; }
- virtual void additionalAttributeStyleDecls(Vector<CSSMutableStyleDeclaration*>&);
+ virtual PassRefPtr<CSSMutableStyleDeclaration> additionalAttributeStyle() OVERRIDE;
};
} //namespace
diff --git a/Source/WebCore/html/HTMLTagNames.in b/Source/WebCore/html/HTMLTagNames.in
index f1c30a01f..4c302edd4 100644
--- a/Source/WebCore/html/HTMLTagNames.in
+++ b/Source/WebCore/html/HTMLTagNames.in
@@ -31,6 +31,7 @@ code interfaceName=HTMLElement
col interfaceName=HTMLTableColElement
colgroup interfaceName=HTMLTableColElement
command interfaceName=HTMLElement
+content interfaceName=HTMLContentElement, conditional=SHADOW_DOM
datalist interfaceName=HTMLDataListElement, conditional=DATALIST
dd interfaceName=HTMLElement
del interfaceName=HTMLModElement
@@ -67,7 +68,7 @@ image mapToTagName=img
img interfaceName=HTMLImageElement, constructorNeedsFormElement
input constructorNeedsFormElement, constructorNeedsCreatedByParser
ins interfaceName=HTMLModElement
-isindex interfaceName=HTMLIsIndexElement, constructorNeedsFormElement
+isindex interfaceName=HTMLUnknownElement
kbd interfaceName=HTMLElement
keygen constructorNeedsFormElement
label
diff --git a/Source/WebCore/html/HTMLTextAreaElement.idl b/Source/WebCore/html/HTMLTextAreaElement.idl
index 62f3e6b1d..b34142350 100644
--- a/Source/WebCore/html/HTMLTextAreaElement.idl
+++ b/Source/WebCore/html/HTMLTextAreaElement.idl
@@ -22,7 +22,7 @@
module html {
interface HTMLTextAreaElement : HTMLElement {
- attribute [ConvertNullToNullString] DOMString defaultValue;
+ attribute [TreatNullAs=EmptyString] DOMString defaultValue;
readonly attribute HTMLFormElement form;
readonly attribute ValidityState validity;
attribute long cols;
@@ -30,14 +30,14 @@ module html {
attribute [Reflect] boolean disabled;
attribute [Reflect] boolean autofocus;
attribute long maxLength setter raises(DOMException);
- attribute [ConvertNullToNullString] DOMString name;
+ attribute [TreatNullAs=EmptyString] DOMString name;
attribute [Reflect] DOMString placeholder;
attribute [Reflect] boolean readOnly;
attribute [Reflect] boolean required;
attribute long rows;
attribute [Reflect] DOMString wrap;
readonly attribute DOMString type;
- attribute [ConvertNullToNullString] DOMString value;
+ attribute [TreatNullAs=EmptyString] DOMString value;
readonly attribute unsigned long textLength;
void select();
diff --git a/Source/WebCore/html/HTMLTitleElement.idl b/Source/WebCore/html/HTMLTitleElement.idl
index de857e8ee..3692c39de 100644
--- a/Source/WebCore/html/HTMLTitleElement.idl
+++ b/Source/WebCore/html/HTMLTitleElement.idl
@@ -20,7 +20,7 @@
module html {
interface HTMLTitleElement : HTMLElement {
- attribute [ConvertNullToNullString] DOMString text;
+ attribute [TreatNullAs=EmptyString] DOMString text;
};
}
diff --git a/Source/WebCore/html/HTMLTrackElement.cpp b/Source/WebCore/html/HTMLTrackElement.cpp
index 13a77a810..e723c5d08 100644
--- a/Source/WebCore/html/HTMLTrackElement.cpp
+++ b/Source/WebCore/html/HTMLTrackElement.cpp
@@ -72,20 +72,20 @@ PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(const QualifiedName& tagNa
return adoptRef(new HTMLTrackElement(tagName, document));
}
-void HTMLTrackElement::insertedIntoTree(bool deep)
+void HTMLTrackElement::insertedIntoDocument()
{
- HTMLElement::insertedIntoTree(deep);
+ HTMLElement::insertedIntoDocument();
if (HTMLMediaElement* parent = mediaElement())
parent->trackWasAdded(this);
}
-void HTMLTrackElement::willRemove()
+void HTMLTrackElement::removedFromDocument()
{
if (HTMLMediaElement* parent = mediaElement())
- parent->trackWillBeRemoved(this);
+ parent->trackWasRemoved(this);
- HTMLElement::willRemove();
+ HTMLElement::removedFromDocument();
}
void HTMLTrackElement::parseMappedAttribute(Attribute* attribute)
@@ -353,9 +353,9 @@ String HTMLTrackElement::itemValueText() const
return getURLAttribute(srcAttr);
}
-void HTMLTrackElement::setItemValueText(const String& value, ExceptionCode& ec)
+void HTMLTrackElement::setItemValueText(const String& value, ExceptionCode&)
{
- setAttribute(srcAttr, value, ec);
+ setAttribute(srcAttr, value);
}
#endif
diff --git a/Source/WebCore/html/HTMLTrackElement.h b/Source/WebCore/html/HTMLTrackElement.h
index 86d2aecd2..965e39631 100644
--- a/Source/WebCore/html/HTMLTrackElement.h
+++ b/Source/WebCore/html/HTMLTrackElement.h
@@ -78,8 +78,8 @@ private:
virtual void parseMappedAttribute(Attribute*);
virtual void attributeChanged(Attribute*, bool preserveDecls);
- virtual void insertedIntoTree(bool);
- virtual void willRemove();
+ virtual void insertedIntoDocument() OVERRIDE;
+ virtual void removedFromDocument() OVERRIDE;
virtual bool isURLAttribute(Attribute*) const;
#if ENABLE(MICRODATA)
diff --git a/Source/WebCore/html/HiddenInputType.cpp b/Source/WebCore/html/HiddenInputType.cpp
index cc3ab5a02..fc103975b 100644
--- a/Source/WebCore/html/HiddenInputType.cpp
+++ b/Source/WebCore/html/HiddenInputType.cpp
@@ -46,10 +46,22 @@ PassOwnPtr<InputType> HiddenInputType::create(HTMLInputElement* element)
return adoptPtr(new HiddenInputType(element));
}
-const AtomicString& HiddenInputType::formControlType() const {
+const AtomicString& HiddenInputType::formControlType() const
+{
return InputTypeNames::hidden();
}
+bool HiddenInputType::saveFormControlState(String& result) const
+{
+ result = element()->value();
+ return true;
+}
+
+void HiddenInputType::restoreFormControlState(const String& string) const
+{
+ element()->setAttribute(valueAttr, string);
+}
+
bool HiddenInputType::supportsValidation() const
{
return false;
diff --git a/Source/WebCore/html/HiddenInputType.h b/Source/WebCore/html/HiddenInputType.h
index 07a3fecdf..fd86fbc1f 100644
--- a/Source/WebCore/html/HiddenInputType.h
+++ b/Source/WebCore/html/HiddenInputType.h
@@ -42,6 +42,8 @@ public:
private:
HiddenInputType(HTMLInputElement* element) : InputType(element) { }
virtual const AtomicString& formControlType() const OVERRIDE;
+ virtual bool saveFormControlState(String&) const OVERRIDE;
+ virtual void restoreFormControlState(const String&) const OVERRIDE;
virtual bool supportsValidation() const OVERRIDE;
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) const OVERRIDE;
virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
diff --git a/Source/WebCore/html/ImageDocument.cpp b/Source/WebCore/html/ImageDocument.cpp
index d4a73d381..dc95a0d71 100644
--- a/Source/WebCore/html/ImageDocument.cpp
+++ b/Source/WebCore/html/ImageDocument.cpp
@@ -253,8 +253,7 @@ void ImageDocument::resizeImageToFit()
m_imageElement->setWidth(static_cast<int>(imageSize.width() * scale));
m_imageElement->setHeight(static_cast<int>(imageSize.height() * scale));
- ExceptionCode ec;
- m_imageElement->style()->setProperty(CSSPropertyCursor, "-webkit-zoom-in", false, ec);
+ m_imageElement->ensureInlineStyleDecl()->setProperty(CSSPropertyCursor, "-webkit-zoom-in", false);
}
void ImageDocument::imageClicked(int x, int y)
@@ -307,11 +306,10 @@ void ImageDocument::restoreImageSize()
m_imageElement->setWidth(imageSize.width());
m_imageElement->setHeight(imageSize.height());
- ExceptionCode ec;
if (imageFitsInWindow())
- m_imageElement->style()->removeProperty(CSSPropertyCursor, ec);
+ m_imageElement->ensureInlineStyleDecl()->removeProperty(CSSPropertyCursor);
else
- m_imageElement->style()->setProperty(CSSPropertyCursor, "-webkit-zoom-out", false, ec);
+ m_imageElement->ensureInlineStyleDecl()->setProperty(CSSPropertyCursor, "-webkit-zoom-out", false);
m_didShrinkImage = false;
}
@@ -341,12 +339,10 @@ void ImageDocument::windowSizeChanged()
// If the image has been explicitly zoomed in, restore the cursor if the image fits
// and set it to a zoom out cursor if the image doesn't fit
if (!m_shouldShrinkImage) {
- ExceptionCode ec;
-
if (fitsInWindow)
- m_imageElement->style()->removeProperty(CSSPropertyCursor, ec);
+ m_imageElement->ensureInlineStyleDecl()->removeProperty(CSSPropertyCursor);
else
- m_imageElement->style()->setProperty(CSSPropertyCursor, "-webkit-zoom-out", false, ec);
+ m_imageElement->ensureInlineStyleDecl()->setProperty(CSSPropertyCursor, "-webkit-zoom-out", false);
return;
}
diff --git a/Source/WebCore/html/InputType.cpp b/Source/WebCore/html/InputType.cpp
index 510239278..551f095ca 100644
--- a/Source/WebCore/html/InputType.cpp
+++ b/Source/WebCore/html/InputType.cpp
@@ -436,6 +436,10 @@ bool InputType::shouldUseInputMethod() const
return false;
}
+void InputType::handleFocusEvent()
+{
+}
+
void InputType::handleBlurEvent()
{
}
diff --git a/Source/WebCore/html/InputType.h b/Source/WebCore/html/InputType.h
index c13fa0833..93e600e8f 100644
--- a/Source/WebCore/html/InputType.h
+++ b/Source/WebCore/html/InputType.h
@@ -183,6 +183,7 @@ public:
virtual PassRefPtr<HTMLFormElement> formForSubmission() const;
virtual bool isKeyboardFocusable() const;
virtual bool shouldUseInputMethod() const;
+ virtual void handleFocusEvent();
virtual void handleBlurEvent();
virtual void accessKeyAction(bool sendMouseEvents);
virtual bool canBeSuccessfulSubmitButton();
diff --git a/Source/WebCore/html/NumberInputType.cpp b/Source/WebCore/html/NumberInputType.cpp
index 6d0e972b3..44fb35a73 100644
--- a/Source/WebCore/html/NumberInputType.cpp
+++ b/Source/WebCore/html/NumberInputType.cpp
@@ -288,24 +288,24 @@ String NumberInputType::visibleValue() const
String currentValue = element()->value();
if (currentValue.isEmpty())
return currentValue;
+ // FIXME: The following three lines should be removed when we
+ // remove the second argument of convertToLocalizedNumber().
double doubleValue = numeric_limits<double>::quiet_NaN();
unsigned decimalPlace;
parseToDoubleForNumberTypeWithDecimalPlaces(currentValue, &doubleValue, &decimalPlace);
- String localized = formatLocalizedNumber(doubleValue, decimalPlace);
- return localized.isEmpty() ? currentValue : localized;
+ return convertToLocalizedNumber(currentValue, decimalPlace);
}
String NumberInputType::convertFromVisibleValue(const String& visibleValue) const
{
if (visibleValue.isEmpty())
return visibleValue;
- double parsedNumber = parseLocalizedNumber(visibleValue);
- return isfinite(parsedNumber) ? serializeForNumberType(parsedNumber) : visibleValue;
+ return convertFromLocalizedNumber(visibleValue);
}
bool NumberInputType::isAcceptableValue(const String& proposedValue)
{
- return proposedValue.isEmpty() || isfinite(parseLocalizedNumber(proposedValue)) || parseToDoubleForNumberType(proposedValue, 0);
+ return proposedValue.isEmpty() || parseToDoubleForNumberType(convertFromLocalizedNumber(proposedValue), 0) || parseToDoubleForNumberType(proposedValue, 0);
}
String NumberInputType::sanitizeValue(const String& proposedValue) const
diff --git a/Source/WebCore/html/PasswordInputType.cpp b/Source/WebCore/html/PasswordInputType.cpp
index 2a9ad0200..c11d3c63d 100644
--- a/Source/WebCore/html/PasswordInputType.cpp
+++ b/Source/WebCore/html/PasswordInputType.cpp
@@ -32,6 +32,7 @@
#include "config.h"
#include "PasswordInputType.h"
+#include "HTMLInputElement.h"
#include <wtf/Assertions.h>
#include <wtf/PassOwnPtr.h>
@@ -86,4 +87,18 @@ bool PasswordInputType::isPasswordField() const
return true;
}
+void PasswordInputType::handleFocusEvent()
+{
+ BaseTextInputType::handleFocusEvent();
+ if (element()->document()->frame())
+ element()->document()->setUseSecureKeyboardEntryWhenActive(true);
+}
+
+void PasswordInputType::handleBlurEvent()
+{
+ if (element()->document()->frame())
+ element()->document()->setUseSecureKeyboardEntryWhenActive(false);
+ BaseTextInputType::handleBlurEvent();
+}
+
} // namespace WebCore
diff --git a/Source/WebCore/html/PasswordInputType.h b/Source/WebCore/html/PasswordInputType.h
index e9ca18e44..10680acb2 100644
--- a/Source/WebCore/html/PasswordInputType.h
+++ b/Source/WebCore/html/PasswordInputType.h
@@ -49,6 +49,8 @@ private:
virtual bool shouldRespectListAttribute() OVERRIDE;
virtual bool shouldRespectSpeechAttribute() OVERRIDE;
virtual bool isPasswordField() const OVERRIDE;
+ virtual void handleFocusEvent() OVERRIDE;
+ virtual void handleBlurEvent() OVERRIDE;
};
} // namespace WebCore
diff --git a/Source/WebCore/html/RadioInputType.cpp b/Source/WebCore/html/RadioInputType.cpp
index 7e69517a3..baec9e861 100644
--- a/Source/WebCore/html/RadioInputType.cpp
+++ b/Source/WebCore/html/RadioInputType.cpp
@@ -48,7 +48,7 @@ const AtomicString& RadioInputType::formControlType() const
bool RadioInputType::valueMissing(const String&) const
{
- return !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
+ return element()->checkedRadioButtons().isInRequiredGroup(element()) && !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
}
String RadioInputType::valueMissingText() const
@@ -133,12 +133,6 @@ bool RadioInputType::isKeyboardFocusable() const
return element()->checked() || !element()->checkedRadioButtons().checkedButtonForGroup(element()->name());
}
-void RadioInputType::attach()
-{
- InputType::attach();
- element()->updateCheckedRadioButtons();
-}
-
bool RadioInputType::shouldSendChangeEventAfterCheckedChanged()
{
// Don't send a change event for a radio button that's getting unchecked.
diff --git a/Source/WebCore/html/RadioInputType.h b/Source/WebCore/html/RadioInputType.h
index 525ed691c..9cefe516b 100644
--- a/Source/WebCore/html/RadioInputType.h
+++ b/Source/WebCore/html/RadioInputType.h
@@ -48,7 +48,6 @@ private:
virtual void handleKeydownEvent(KeyboardEvent*) OVERRIDE;
virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
virtual bool isKeyboardFocusable() const OVERRIDE;
- virtual void attach() OVERRIDE;
virtual bool shouldSendChangeEventAfterCheckedChanged() OVERRIDE;
virtual PassOwnPtr<ClickHandlingState> willDispatchClick() OVERRIDE;
virtual void didDispatchClick(Event*, const ClickHandlingState&) OVERRIDE;
diff --git a/Source/WebCore/html/StepRange.cpp b/Source/WebCore/html/StepRange.cpp
index 68b0ebd37..7948020d0 100644
--- a/Source/WebCore/html/StepRange.cpp
+++ b/Source/WebCore/html/StepRange.cpp
@@ -35,10 +35,10 @@ using namespace HTMLNames;
StepRange::StepRange(const HTMLInputElement* element)
{
- if (element->hasAttribute(precisionAttr)) {
- step = 1.0;
+ step = 1;
+ if (element->hasAttribute(precisionAttr))
hasStep = !equalIgnoringCase(element->getAttribute(precisionAttr), "float");
- } else
+ else
hasStep = element->getAllowedValueStep(&step);
maximum = element->maximum();
diff --git a/Source/WebCore/html/TextFieldInputType.cpp b/Source/WebCore/html/TextFieldInputType.cpp
index c9c908335..3ec15bcde 100644
--- a/Source/WebCore/html/TextFieldInputType.cpp
+++ b/Source/WebCore/html/TextFieldInputType.cpp
@@ -69,7 +69,7 @@ bool TextFieldInputType::isTextField() const
bool TextFieldInputType::valueMissing(const String& value) const
{
- return value.isEmpty();
+ return element()->required() && value.isEmpty();
}
bool TextFieldInputType::canSetSuggestedValue()
@@ -161,6 +161,13 @@ void TextFieldInputType::forwardEvent(Event* event)
}
}
+void TextFieldInputType::handleBlurEvent()
+{
+ InputType::handleBlurEvent();
+ if (Frame* frame = element()->document()->frame())
+ frame->editor()->textFieldDidEndEditing(element());
+}
+
bool TextFieldInputType::shouldSubmitImplicitly(Event* event)
{
return (event->type() == eventNames().textInputEvent && event->hasInterface(eventNames().interfaceForTextEvent) && static_cast<TextEvent*>(event)->data() == "\n") || InputType::shouldSubmitImplicitly(event);
diff --git a/Source/WebCore/html/TextFieldInputType.h b/Source/WebCore/html/TextFieldInputType.h
index 161884d67..f94018bb0 100644
--- a/Source/WebCore/html/TextFieldInputType.h
+++ b/Source/WebCore/html/TextFieldInputType.h
@@ -63,6 +63,7 @@ protected:
virtual void destroyShadowSubtree() OVERRIDE;
virtual void disabledAttributeChanged() OVERRIDE;
virtual void readonlyAttributeChanged() OVERRIDE;
+ virtual void handleBlurEvent() OVERRIDE;
private:
virtual bool isTextField() const OVERRIDE;
diff --git a/Source/WebCore/html/ValidationMessage.cpp b/Source/WebCore/html/ValidationMessage.cpp
index b69b2b494..604e54a13 100644
--- a/Source/WebCore/html/ValidationMessage.cpp
+++ b/Source/WebCore/html/ValidationMessage.cpp
@@ -119,7 +119,7 @@ static void adjustBubblePosition(const LayoutRect& hostRect, HTMLElement* bubble
hostY -= containerLocation.y() + container->borderTop();
}
- CSSInlineStyleDeclaration* style = bubble->ensureInlineStyleDecl();
+ CSSMutableStyleDeclaration* style = bubble->ensureInlineStyleDecl();
style->setProperty(CSSPropertyTop, hostY + hostRect.height(), CSSPrimitiveValue::CSS_PX);
// The 'left' value of ::-webkit-validation-bubble-arrow.
const int bubbleArrowTopOffset = 32;
diff --git a/Source/WebCore/html/canvas/CanvasGradient.idl b/Source/WebCore/html/canvas/CanvasGradient.idl
index 48f75bbda..75b19279b 100644
--- a/Source/WebCore/html/canvas/CanvasGradient.idl
+++ b/Source/WebCore/html/canvas/CanvasGradient.idl
@@ -25,10 +25,7 @@
module html {
- interface [
- InterfaceUUID=bb1108ea-6b8c-4a08-894a-218628630cdb,
- ImplementationUUID=a2942ae6-2731-4286-98cc-9d5e79e20de1
- ] CanvasGradient {
+ interface CanvasGradient {
void addColorStop(in [Optional=CallWithDefaultValue] float offset,
in [Optional=CallWithDefaultValue] DOMString color)
diff --git a/Source/WebCore/html/canvas/CanvasPattern.idl b/Source/WebCore/html/canvas/CanvasPattern.idl
index 1cac8f880..e5aa0360b 100644
--- a/Source/WebCore/html/canvas/CanvasPattern.idl
+++ b/Source/WebCore/html/canvas/CanvasPattern.idl
@@ -25,11 +25,7 @@
module html {
- interface [
- InterfaceUUID=c2131348-6d8c-47b5-86cc-d41aff34ce15,
- ImplementationUUID=82f5d713-3d17-44dd-aa4a-7766fe345940
- ] CanvasPattern {
-
+ interface CanvasPattern {
};
}
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
index b3f387eb7..c73fc99e4 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.cpp
@@ -82,6 +82,8 @@ bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
if (!video->hasSingleSecurityOrigin())
return true;
+#else
+ UNUSED_PARAM(video);
#endif
return false;
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext.idl b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
index b53bdce5a..d8657cc8f 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext.idl
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext.idl
@@ -28,9 +28,7 @@ module html {
interface [
CustomMarkFunction,
GenerateIsReachable,
- CustomToJS,
- InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
- ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
+ CustomToJS
] CanvasRenderingContext {
readonly attribute HTMLCanvasElement canvas;
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
index 948c21942..a24cd692a 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
@@ -219,6 +219,7 @@ CanvasRenderingContext2D::State::State(const State& other)
, m_globalComposite(other.m_globalComposite)
, m_transform(other.m_transform)
, m_invertibleCTM(other.m_invertibleCTM)
+ , m_lineDashOffset(other.m_lineDashOffset)
, m_textAlign(other.m_textAlign)
, m_textBaseline(other.m_textBaseline)
, m_unparsedFont(other.m_unparsedFont)
@@ -314,7 +315,7 @@ void CanvasRenderingContext2D::setAllAttributesToDefault()
if (!context)
return;
- context->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+ applyShadow();
context->setAlpha(1);
context->setCompositeOperation(CompositeSourceOver);
}
@@ -1149,7 +1150,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
if (!c)
return;
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ applyShadow();
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, const String& color, float alpha)
@@ -1167,7 +1168,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
if (!c)
return;
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ applyShadow();
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float grayLevel, float alpha)
@@ -1180,7 +1181,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
if (!c)
return;
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ applyShadow();
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float r, float g, float b, float a)
@@ -1193,7 +1194,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
if (!c)
return;
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ applyShadow();
}
void CanvasRenderingContext2D::setShadow(float width, float height, float blur, float c, float m, float y, float k, float a)
@@ -1213,7 +1214,7 @@ void CanvasRenderingContext2D::setShadow(float width, float height, float blur,
CGContextSetShadowWithColor(dc->platformContext(), adjustedShadowSize(width, -height), blur, shadowColor);
CGColorRelease(shadowColor);
#else
- dc->setLegacyShadow(FloatSize(width, -height), blur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ applyShadow();
#endif
}
@@ -1231,9 +1232,17 @@ void CanvasRenderingContext2D::applyShadow()
if (!c)
return;
- float width = state().m_shadowOffset.width();
- float height = state().m_shadowOffset.height();
- c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ if (shouldDrawShadows()) {
+ float width = state().m_shadowOffset.width();
+ float height = state().m_shadowOffset.height();
+ c->setLegacyShadow(FloatSize(width, -height), state().m_shadowBlur, state().m_shadowColor, ColorSpaceDeviceRGB);
+ } else
+ c->setLegacyShadow(FloatSize(), 0, Color::transparent, ColorSpaceDeviceRGB);
+}
+
+bool CanvasRenderingContext2D::shouldDrawShadows() const
+{
+ return alphaChannel(state().m_shadowColor) && (state().m_shadowBlur || !state().m_shadowOffset.isZero());
}
static LayoutSize size(HTMLImageElement* image)
@@ -1986,7 +1995,7 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
String declarationText("font: ");
declarationText += newFont;
parser.parseDeclaration(tempDecl.get(), declarationText);
- if (!tempDecl->length())
+ if (tempDecl->isEmpty())
return;
// The parse succeeded.
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
index 4b3df1592..1f481b755 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.h
@@ -278,6 +278,7 @@ private:
const State& state() const { return m_stateStack.last(); }
void applyShadow();
+ bool shouldDrawShadows() const;
void didDraw(const FloatRect&, unsigned options = CanvasDidDrawApplyAll);
void didDrawEntireCanvas();
diff --git a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
index 0168e4c66..d7efe1328 100644
--- a/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
+++ b/Source/WebCore/html/canvas/CanvasRenderingContext2D.idl
@@ -25,10 +25,7 @@
module html {
- interface [
- InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
- ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54
- ] CanvasRenderingContext2D : CanvasRenderingContext {
+ interface CanvasRenderingContext2D : CanvasRenderingContext {
void save();
void restore();
@@ -52,7 +49,7 @@ module html {
in [Optional=CallWithDefaultValue] float dy);
attribute float globalAlpha;
- attribute [ConvertNullToNullString] DOMString globalCompositeOperation;
+ attribute [TreatNullAs=EmptyString] DOMString globalCompositeOperation;
CanvasGradient createLinearGradient(in [Optional=CallWithDefaultValue] float x0,
in [Optional=CallWithDefaultValue] float y0,
@@ -68,14 +65,14 @@ module html {
raises (DOMException);
attribute float lineWidth;
- attribute [ConvertNullToNullString] DOMString lineCap;
- attribute [ConvertNullToNullString] DOMString lineJoin;
+ attribute [TreatNullAs=EmptyString] DOMString lineCap;
+ attribute [TreatNullAs=EmptyString] DOMString lineJoin;
attribute float miterLimit;
attribute float shadowOffsetX;
attribute float shadowOffsetY;
attribute float shadowBlur;
- attribute [ConvertNullToNullString] DOMString shadowColor;
+ attribute [TreatNullAs=EmptyString] DOMString shadowColor;
// FIXME: These attributes should also be implemented for V8.
#if !(defined(V8_BINDING) && V8_BINDING)
@@ -207,9 +204,9 @@ module html {
void putImageData(in ImageData imagedata, in float dx, in float dy, in float dirtyX, in float dirtyY, in float dirtyWidth, in float dirtyHeight)
raises(DOMException);
- CanvasPattern createPattern(in HTMLCanvasElement canvas, in [ConvertNullToNullString] DOMString repetitionType)
+ CanvasPattern createPattern(in HTMLCanvasElement canvas, in [TreatNullAs=EmptyString] DOMString repetitionType)
raises (DOMException);
- CanvasPattern createPattern(in HTMLImageElement image, in [ConvertNullToNullString] DOMString repetitionType)
+ CanvasPattern createPattern(in HTMLImageElement image, in [TreatNullAs=EmptyString] DOMString repetitionType)
raises (DOMException);
ImageData createImageData(in ImageData imagedata)
raises (DOMException);
diff --git a/Source/WebCore/html/canvas/CanvasStyle.cpp b/Source/WebCore/html/canvas/CanvasStyle.cpp
index 3aee6e8f1..3ed1fee58 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.cpp
+++ b/Source/WebCore/html/canvas/CanvasStyle.cpp
@@ -69,7 +69,7 @@ RGBA32 currentColor(HTMLCanvasElement* canvas)
if (!canvas || !canvas->inDocument())
return Color::black;
RGBA32 rgba = Color::black;
- CSSParser::parseColor(rgba, canvas->style()->getPropertyValue(CSSPropertyColor));
+ CSSParser::parseColor(rgba, canvas->ensureInlineStyleDecl()->getPropertyValue(CSSPropertyColor));
return rgba;
}
diff --git a/Source/WebCore/html/canvas/CanvasStyle.h b/Source/WebCore/html/canvas/CanvasStyle.h
index 8f4bfd402..431fb2824 100644
--- a/Source/WebCore/html/canvas/CanvasStyle.h
+++ b/Source/WebCore/html/canvas/CanvasStyle.h
@@ -88,8 +88,8 @@ namespace WebCore {
RefPtr<CanvasPattern> m_pattern;
struct CMYKAValues {
- CMYKAValues() {}
- CMYKAValues(float cyan, float magenta, float yellow, float black, float alpha) : c(cyan), m(magenta), y(yellow), k(black), a(alpha) {}
+ CMYKAValues() : c(0), m(0), y(0), k(0), a(0) { }
+ CMYKAValues(float cyan, float magenta, float yellow, float black, float alpha) : c(cyan), m(magenta), y(yellow), k(black), a(alpha) { }
float c;
float m;
float y;
diff --git a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
index a26d7069f..cea525c39 100644
--- a/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
+++ b/Source/WebCore/html/canvas/OESVertexArrayObject.cpp
@@ -60,7 +60,7 @@ PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES
return 0;
RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
- m_context->addObject(o.get());
+ m_context->addContextObject(o.get());
return o.release();
}
@@ -69,7 +69,7 @@ void OESVertexArrayObject::deleteVertexArrayOES(WebGLVertexArrayObjectOES* array
if (!arrayObject || m_context->isContextLost())
return;
- arrayObject->deleteObject();
+ arrayObject->deleteObject(m_context->graphicsContext3D());
}
GC3Dboolean OESVertexArrayObject::isVertexArrayOES(WebGLVertexArrayObjectOES* arrayObject)
@@ -90,7 +90,7 @@ void OESVertexArrayObject::bindVertexArrayOES(WebGLVertexArrayObjectOES* arrayOb
if (m_context->isContextLost())
return;
- if (arrayObject && arrayObject->context() != m_context) {
+ if (arrayObject && !arrayObject->validate(0, context())) {
m_context->graphicsContext3D()->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
return;
}
diff --git a/Source/WebCore/html/canvas/Uint8ClampedArray.idl b/Source/WebCore/html/canvas/Uint8ClampedArray.idl
new file mode 100644
index 000000000..31b8247de
--- /dev/null
+++ b/Source/WebCore/html/canvas/Uint8ClampedArray.idl
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 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 COMPUTER, INC. ``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 COMPUTER, INC. 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.
+ */
+
+module html {
+ interface [
+ CustomConstructor,
+ HasNumericIndexGetter,
+ HasCustomIndexSetter,
+ GenerateNativeConverter,
+ NoStaticTables,
+ CustomToJS,
+ DontCheckEnums
+ ] Uint8ClampedArray : Uint8Array {
+ const unsigned int BYTES_PER_ELEMENT = 1;
+
+ readonly attribute unsigned long length;
+ Uint8ClampedArray subarray(in [Optional=CallWithDefaultValue] long start, in [Optional] long end);
+
+ // FIXME: Missing other setters!
+ // void set(in Uint8ClampedArray array, [Optional] in unsigned long offset);
+ // void set(in sequence<long> array, [Optional] in unsigned long offset);
+ [Custom] void set();
+ };
+}
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.cpp b/Source/WebCore/html/canvas/WebGLBuffer.cpp
index 997dba500..fc6d40860 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLBuffer.cpp
@@ -30,6 +30,7 @@
#include "WebGLBuffer.h"
#include "CheckedInt.h"
+#include "WebGLContextGroup.h"
#include "WebGLRenderingContext.h"
#include <wtf/ArrayBufferView.h>
@@ -41,18 +42,23 @@ PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
}
WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
- : WebGLObject(ctx)
+ : WebGLSharedObject(ctx)
, m_target(0)
, m_byteLength(0)
, m_nextAvailableCacheEntry(0)
{
- setObject(context()->graphicsContext3D()->createBuffer());
+ setObject(ctx->graphicsContext3D()->createBuffer());
clearCachedMaxIndices();
}
-void WebGLBuffer::deleteObjectImpl(Platform3DObject object)
+WebGLBuffer::~WebGLBuffer()
{
- context()->graphicsContext3D()->deleteBuffer(object);
+ deleteObject(0);
+}
+
+void WebGLBuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ context3d->deleteBuffer(object);
}
bool WebGLBuffer::associateBufferDataImpl(ArrayBuffer* array, GC3Dintptr byteOffset, GC3Dsizeiptr byteLength)
diff --git a/Source/WebCore/html/canvas/WebGLBuffer.h b/Source/WebCore/html/canvas/WebGLBuffer.h
index 0157ece65..849c3582b 100644
--- a/Source/WebCore/html/canvas/WebGLBuffer.h
+++ b/Source/WebCore/html/canvas/WebGLBuffer.h
@@ -26,7 +26,7 @@
#ifndef WebGLBuffer_h
#define WebGLBuffer_h
-#include "WebGLObject.h"
+#include "WebGLSharedObject.h"
#include <wtf/ArrayBuffer.h>
#include <wtf/Forward.h>
@@ -35,9 +35,9 @@
namespace WebCore {
-class WebGLBuffer : public WebGLObject {
+class WebGLBuffer : public WebGLSharedObject {
public:
- virtual ~WebGLBuffer() { deleteObject(); }
+ virtual ~WebGLBuffer();
static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
@@ -64,7 +64,7 @@ public:
protected:
WebGLBuffer(WebGLRenderingContext*);
- virtual void deleteObjectImpl(Platform3DObject o);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
private:
virtual bool isBuffer() const { return true; }
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp b/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp
index 1eab78723..151980caa 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextures.cpp
@@ -125,16 +125,16 @@ bool WebGLCompressedTextures::validateCompressedTexFormat(GC3Denum format)
return false;
}
-bool WebGLCompressedTextures::validateCompressedTexFuncData(GC3Dsizei width, GC3Dsizei height,
- GC3Denum format, ArrayBufferView* pixels)
+bool WebGLCompressedTextures::validateCompressedTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
+ GC3Denum format, ArrayBufferView* pixels)
{
- GraphicsContext3D* context = m_context->graphicsContext3D();
if (!pixels) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no pixels");
return false;
}
if (width < 0 || height < 0) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
return false;
}
@@ -172,12 +172,12 @@ bool WebGLCompressedTextures::validateCompressedTexFuncData(GC3Dsizei width, GC3
}
break;
default:
- context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid format");
return false;
}
if (pixels->byteLength() != bytesRequired) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
return false;
}
@@ -229,30 +229,29 @@ bool WebGLCompressedTextures::validateCompressedTexSubDimensions(GC3Denum target
void WebGLCompressedTextures::compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
GC3Dsizei height, GC3Dint border, ArrayBufferView* data)
{
- GraphicsContext3D* context = m_context->graphicsContext3D();
if (m_context->isContextLost())
return;
if (!validateCompressedTexFormat(internalformat)) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
return;
}
if (border) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "border not 0");
return;
}
- if (!validateCompressedTexFuncData(width, height, internalformat, data))
+ if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
return;
- WebGLTexture* tex = m_context->validateTextureBinding(target, true);
+ WebGLTexture* tex = m_context->validateTextureBinding("compressedTexImage2D", target, true);
if (!tex)
return;
if (!m_context->isGLES2NPOTStrict()) {
if (level && WebGLTexture::isNPOT(width, height)) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
return;
}
}
- context->compressedTexImage2D(target, level, internalformat, width, height,
- border, data->byteLength(), data->baseAddress());
+ m_context->graphicsContext3D()->compressedTexImage2D(target, level, internalformat, width, height,
+ border, data->byteLength(), data->baseAddress());
tex->setLevelInfo(target, level, internalformat, width, height, GraphicsContext3D::UNSIGNED_BYTE);
m_context->cleanupAfterGraphicsCall(false);
}
@@ -260,32 +259,31 @@ void WebGLCompressedTextures::compressedTexImage2D(GC3Denum target, GC3Dint leve
void WebGLCompressedTextures::compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data)
{
- GraphicsContext3D* context = m_context->graphicsContext3D();
if (m_context->isContextLost())
return;
if (!validateCompressedTexFormat(format)) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
return;
}
- if (!validateCompressedTexFuncData(width, height, format, data))
+ if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
return;
- WebGLTexture* tex = m_context->validateTextureBinding(target, true);
+ WebGLTexture* tex = m_context->validateTextureBinding("compressedTexSubImage2D", target, true);
if (!tex)
return;
if (format != tex->getInternalFormat(target, level)) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "compressedTexSubImage2D", "format does not match texture format");
return;
}
if (!validateCompressedTexSubDimensions(target, level, xoffset, yoffset, width, height, format, tex)) {
- context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "compressedTexSubImage2D", "dimensions invalid for format");
return;
}
- context->compressedTexSubImage2D(target, level, xoffset, yoffset,
- width, height, format, data->byteLength(), data->baseAddress());
+ m_context->graphicsContext3D()->compressedTexSubImage2D(target, level, xoffset, yoffset,
+ width, height, format, data->byteLength(), data->baseAddress());
m_context->cleanupAfterGraphicsCall(false);
}
diff --git a/Source/WebCore/html/canvas/WebGLCompressedTextures.h b/Source/WebCore/html/canvas/WebGLCompressedTextures.h
index 699370668..52b71c213 100644
--- a/Source/WebCore/html/canvas/WebGLCompressedTextures.h
+++ b/Source/WebCore/html/canvas/WebGLCompressedTextures.h
@@ -54,7 +54,8 @@ public:
private:
WebGLCompressedTextures(WebGLRenderingContext*);
- bool validateCompressedTexFuncData(GC3Dsizei width, GC3Dsizei height,
+ bool validateCompressedTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
GC3Denum format, ArrayBufferView* pixels);
bool validateCompressedTexFormat(GC3Denum format);
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.cpp b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
new file mode 100644
index 000000000..d3af2bbbe
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.cpp
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLContextGroup.h"
+
+#include "GraphicsContext3D.h"
+#include "WebGLRenderingContext.h"
+#include "WebGLSharedObject.h"
+
+#if PLATFORM(QT)
+#undef emit
+#endif
+
+namespace WebCore {
+
+PassRefPtr<WebGLContextGroup> WebGLContextGroup::create()
+{
+ RefPtr<WebGLContextGroup> contextGroup = adoptRef(new WebGLContextGroup());
+ return contextGroup.release();
+}
+
+WebGLContextGroup::WebGLContextGroup()
+{
+}
+
+WebGLContextGroup::~WebGLContextGroup()
+{
+ detachAndRemoveAllObjects();
+}
+
+GraphicsContext3D* WebGLContextGroup::getAGraphicsContext3D()
+{
+ ASSERT(!m_contexts.isEmpty());
+ HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
+ return (*it)->graphicsContext3D();
+}
+
+void WebGLContextGroup::addContext(WebGLRenderingContext* context)
+{
+ m_contexts.add(context);
+}
+
+void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
+{
+ // We must call detachAndRemoveAllObjects before removing the last context.
+ if (m_contexts.size() == 1 && m_contexts.contains(context))
+ detachAndRemoveAllObjects();
+
+ m_contexts.remove(context);
+}
+
+void WebGLContextGroup::removeObject(WebGLSharedObject* object)
+{
+ m_groupObjects.remove(object);
+}
+
+void WebGLContextGroup::addObject(WebGLSharedObject* object)
+{
+ m_groupObjects.add(object);
+}
+
+void WebGLContextGroup::detachAndRemoveAllObjects()
+{
+ while (!m_groupObjects.isEmpty()) {
+ HashSet<WebGLSharedObject*>::iterator it = m_groupObjects.begin();
+ (*it)->detachContextGroup();
+ }
+}
+
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
+{
+ for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
+ (*it)->loseContextImpl(mode);
+
+ detachAndRemoveAllObjects();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLContextGroup.h b/Source/WebCore/html/canvas/WebGLContextGroup.h
new file mode 100644
index 000000000..aa7036ae6
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextGroup.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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.
+ */
+
+#ifndef WebGLContextGroup_h
+#define WebGLContextGroup_h
+
+#include <WebGLRenderingContext.h>
+#include <wtf/HashSet.h>
+#include <wtf/PassRefPtr.h>
+#include <wtf/RefCounted.h>
+
+namespace WebCore {
+
+class GraphicsContext3D;
+class WebGLExtension;
+class WebGLSharedObject;
+class WebGLRenderingContext;
+
+typedef int ExceptionCode;
+
+class WebGLContextGroup : public RefCounted<WebGLContextGroup> {
+public:
+ static PassRefPtr<WebGLContextGroup> create();
+ virtual ~WebGLContextGroup();
+
+ void addContext(WebGLRenderingContext*);
+ void removeContext(WebGLRenderingContext*);
+
+ void addObject(WebGLSharedObject*);
+ void removeObject(WebGLSharedObject*);
+
+ GraphicsContext3D* getAGraphicsContext3D();
+
+ void loseContextGroup(WebGLRenderingContext::LostContextMode);
+
+ private:
+ friend class WebGLObject;
+
+ WebGLContextGroup();
+
+ void detachAndRemoveAllObjects();
+
+ HashSet<WebGLRenderingContext*> m_contexts;
+ HashSet<WebGLSharedObject*> m_groupObjects;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextGroup_h
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.cpp b/Source/WebCore/html/canvas/WebGLContextObject.cpp
new file mode 100644
index 000000000..9b3ab0b9c
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextObject.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLContextObject.h"
+
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
+ : WebGLObject(context)
+ , m_context(context)
+{
+}
+
+WebGLContextObject::~WebGLContextObject()
+{
+ if (m_context)
+ m_context->removeContextObject(this);
+}
+
+void WebGLContextObject::detachContext()
+{
+ detach();
+ if (m_context) {
+ deleteObject(m_context->graphicsContext3D());
+ m_context->removeContextObject(this);
+ m_context = 0;
+ }
+}
+
+GraphicsContext3D* WebGLContextObject::getAGraphicsContext3D() const
+{
+ return m_context ? m_context->graphicsContext3D() : 0;
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLContextObject.h b/Source/WebCore/html/canvas/WebGLContextObject.h
new file mode 100644
index 000000000..e67f50705
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLContextObject.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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.
+ */
+
+#ifndef WebGLContextObject_h
+#define WebGLContextObject_h
+
+#include "GraphicsContext3D.h"
+#include "WebGLObject.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+class WebGLRenderingContext;
+
+// WebGLContextObject the base class for objects that are owned by a specific
+// WebGLRenderingContext.
+class WebGLContextObject : public WebGLObject {
+public:
+ virtual ~WebGLContextObject();
+
+ WebGLRenderingContext* context() const { return m_context; }
+
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const
+ {
+ return context == m_context;
+ }
+
+ void detachContext();
+
+protected:
+ WebGLContextObject(WebGLRenderingContext*);
+
+ virtual bool hasGroupOrContext() const
+ {
+ return m_context;
+ }
+
+ virtual GraphicsContext3D* getAGraphicsContext3D() const;
+
+private:
+ Platform3DObject m_object;
+ WebGLRenderingContext* m_context;
+};
+
+} // namespace WebCore
+
+#endif // WebGLContextObject_h
diff --git a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
index 5d2c3176d..5499aed9f 100644
--- a/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
+++ b/Source/WebCore/html/canvas/WebGLDebugShaders.cpp
@@ -61,7 +61,7 @@ String WebGLDebugShaders::getTranslatedShaderSource(WebGLShader* shader, Excepti
UNUSED_PARAM(ec);
if (m_context->isContextLost())
return String();
- if (!m_context->validateWebGLObject(shader))
+ if (!m_context->validateWebGLObject("getTranslatedShaderSource", shader))
return "";
return m_context->graphicsContext3D()->getExtensions()->getTranslatedShaderSourceANGLE(shader->object());
}
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
index d1af518c0..3683f139b 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.cpp
@@ -29,13 +29,14 @@
#include "WebGLFramebuffer.h"
+#include "WebGLContextGroup.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
namespace {
- bool isAttachmentComplete(WebGLObject* attachedObject, GC3Denum attachment)
+ bool isAttachmentComplete(WebGLSharedObject* attachedObject, GC3Denum attachment)
{
ASSERT(attachedObject && attachedObject->object());
ASSERT(attachedObject->isRenderbuffer());
@@ -62,7 +63,7 @@ namespace {
return true;
}
- GC3Dsizei getImageWidth(WebGLObject* attachedObject)
+ GC3Dsizei getImageWidth(WebGLSharedObject* attachedObject)
{
ASSERT(attachedObject && attachedObject->object());
ASSERT(attachedObject->isRenderbuffer());
@@ -70,7 +71,7 @@ namespace {
return buffer->getWidth();
}
- GC3Dsizei getImageHeight(WebGLObject* attachedObject)
+ GC3Dsizei getImageHeight(WebGLSharedObject* attachedObject)
{
ASSERT(attachedObject && attachedObject->object());
ASSERT(attachedObject->isRenderbuffer());
@@ -78,7 +79,7 @@ namespace {
return buffer->getHeight();
}
- bool isUninitialized(WebGLObject* attachedObject)
+ bool isUninitialized(WebGLSharedObject* attachedObject)
{
if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()
&& !(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isInitialized())
@@ -86,13 +87,13 @@ namespace {
return false;
}
- void setInitialized(WebGLObject* attachedObject)
+ void setInitialized(WebGLSharedObject* attachedObject)
{
if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer())
(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->setInitialized();
}
- bool isValid(WebGLObject* attachedObject)
+ bool isValidRenderbuffer(WebGLSharedObject* attachedObject)
{
if (attachedObject && attachedObject->object() && attachedObject->isRenderbuffer()) {
if (!(reinterpret_cast<WebGLRenderbuffer*>(attachedObject))->isValid())
@@ -109,12 +110,17 @@ PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx
}
WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
- : WebGLObject(ctx)
+ : WebGLContextObject(ctx)
, m_hasEverBeenBound(false)
, m_texTarget(0)
, m_texLevel(-1)
{
- setObject(context()->graphicsContext3D()->createFramebuffer());
+ setObject(ctx->graphicsContext3D()->createFramebuffer());
+}
+
+WebGLFramebuffer::~WebGLFramebuffer()
+{
+ deleteObject(0);
}
void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture* texture, GC3Dint level)
@@ -179,7 +185,7 @@ void WebGLFramebuffer::setAttachmentForBoundFramebuffer(GC3Denum attachment, Web
renderbuffer->onAttached();
}
-WebGLObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
+WebGLSharedObject* WebGLFramebuffer::getAttachment(GC3Denum attachment) const
{
if (!object())
return 0;
@@ -203,10 +209,12 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
ASSERT(isBound());
if (!object())
return;
+
+ GraphicsContext3D* context3d = context()->graphicsContext3D();
switch (attachment) {
case GraphicsContext3D::COLOR_ATTACHMENT0:
if (m_colorAttachment) {
- m_colorAttachment->onDetached();
+ m_colorAttachment->onDetached(context3d);
m_colorAttachment = 0;
m_texTarget = 0;
m_texLevel = -1;
@@ -214,19 +222,19 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
break;
case GraphicsContext3D::DEPTH_ATTACHMENT:
if (m_depthAttachment) {
- m_depthAttachment->onDetached();
+ m_depthAttachment->onDetached(context3d);
m_depthAttachment = 0;
}
break;
case GraphicsContext3D::STENCIL_ATTACHMENT:
if (m_stencilAttachment) {
- m_stencilAttachment->onDetached();
+ m_stencilAttachment->onDetached(context3d);
m_stencilAttachment = 0;
}
break;
case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
if (m_depthStencilAttachment) {
- m_depthStencilAttachment->onDetached();
+ m_depthStencilAttachment->onDetached(context3d);
m_depthStencilAttachment = 0;
}
break;
@@ -236,14 +244,16 @@ void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(GC3Denum attachment)
}
}
-void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLObject* attachment)
+void WebGLFramebuffer::removeAttachmentFromBoundFramebuffer(WebGLSharedObject* attachment)
{
ASSERT(isBound());
if (!object())
return;
if (!attachment)
return;
+
GraphicsContext3D* gc3d = context()->graphicsContext3D();
+
if (attachment == m_colorAttachment.get()) {
if (attachment->isRenderbuffer())
gc3d->framebufferRenderbuffer(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::RENDERBUFFER, 0);
@@ -337,7 +347,7 @@ GC3Denum WebGLFramebuffer::checkStatus() const
if (isDepthStencilAttached()) {
if (!isAttachmentComplete(m_depthStencilAttachment.get(), GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT))
return GraphicsContext3D::FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
- if (!isValid(m_depthStencilAttachment.get()))
+ if (!isValidRenderbuffer(m_depthStencilAttachment.get()))
return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
if (!count) {
width = getImageWidth(m_depthStencilAttachment.get());
@@ -369,29 +379,29 @@ GC3Denum WebGLFramebuffer::checkStatus() const
return GraphicsContext3D::FRAMEBUFFER_COMPLETE;
}
-bool WebGLFramebuffer::onAccess(bool needToInitializeRenderbuffers)
+bool WebGLFramebuffer::onAccess(GraphicsContext3D* context3d, bool needToInitializeRenderbuffers)
{
if (checkStatus() != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
return false;
if (needToInitializeRenderbuffers)
- return initializeRenderbuffers();
+ return initializeRenderbuffers(context3d);
return true;
}
-void WebGLFramebuffer::deleteObjectImpl(Platform3DObject object)
+void WebGLFramebuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
if (m_colorAttachment)
- m_colorAttachment->onDetached();
+ m_colorAttachment->onDetached(context3d);
if (m_depthAttachment)
- m_depthAttachment->onDetached();
+ m_depthAttachment->onDetached(context3d);
if (m_stencilAttachment)
- m_stencilAttachment->onDetached();
+ m_stencilAttachment->onDetached(context3d);
if (m_depthStencilAttachment)
- m_depthStencilAttachment->onDetached();
- context()->graphicsContext3D()->deleteFramebuffer(object);
+ m_depthStencilAttachment->onDetached(context3d);
+ context3d->deleteFramebuffer(object);
}
-bool WebGLFramebuffer::initializeRenderbuffers()
+bool WebGLFramebuffer::initializeRenderbuffers(GraphicsContext3D* g3d)
{
ASSERT(object());
bool initColor = false, initDepth = false, initStencil = false;
@@ -418,7 +428,6 @@ bool WebGLFramebuffer::initializeRenderbuffers()
// We only clear un-initialized renderbuffers when they are ready to be
// read, i.e., when the framebuffer is complete.
- GraphicsContext3D* g3d = context()->graphicsContext3D();
if (g3d->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE)
return false;
diff --git a/Source/WebCore/html/canvas/WebGLFramebuffer.h b/Source/WebCore/html/canvas/WebGLFramebuffer.h
index 110f51395..66a1ffa49 100644
--- a/Source/WebCore/html/canvas/WebGLFramebuffer.h
+++ b/Source/WebCore/html/canvas/WebGLFramebuffer.h
@@ -26,7 +26,8 @@
#ifndef WebGLFramebuffer_h
#define WebGLFramebuffer_h
-#include "WebGLObject.h"
+#include "WebGLContextObject.h"
+#include "WebGLSharedObject.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -36,19 +37,19 @@ namespace WebCore {
class WebGLRenderbuffer;
class WebGLTexture;
-class WebGLFramebuffer : public WebGLObject {
+class WebGLFramebuffer : public WebGLContextObject {
public:
- virtual ~WebGLFramebuffer() { deleteObject(); }
+ virtual ~WebGLFramebuffer();
static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, GC3Denum texTarget, WebGLTexture*, GC3Dint level);
void setAttachmentForBoundFramebuffer(GC3Denum attachment, WebGLRenderbuffer*);
// If an object is attached to the currently bound framebuffer, remove it.
- void removeAttachmentFromBoundFramebuffer(WebGLObject*);
+ void removeAttachmentFromBoundFramebuffer(WebGLSharedObject*);
// If a given attachment point for the currently bound framebuffer is not null, remove the attached object.
void removeAttachmentFromBoundFramebuffer(GC3Denum);
- WebGLObject* getAttachment(GC3Denum) const;
+ WebGLSharedObject* getAttachment(GC3Denum) const;
GC3Denum getColorBufferFormat() const;
GC3Dsizei getColorBufferWidth() const;
@@ -60,7 +61,7 @@ public:
// Return false if the framebuffer is incomplete; otherwise initialize
// the buffers if they haven't been initialized and
// needToInitializeRenderbuffers is true.
- bool onAccess(bool needToInitializeRenderbuffers);
+ bool onAccess(GraphicsContext3D*, bool needToInitializeRenderbuffers);
// Software version of glCheckFramebufferStatus(), except that when
// FRAMEBUFFER_COMPLETE is returned, it is still possible for
@@ -75,13 +76,13 @@ public:
protected:
WebGLFramebuffer(WebGLRenderingContext*);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
private:
virtual bool isFramebuffer() const { return true; }
// Return false if framebuffer is incomplete.
- bool initializeRenderbuffers();
+ bool initializeRenderbuffers(GraphicsContext3D*);
// Check if the framebuffer is currently bound.
bool isBound() const;
@@ -91,10 +92,10 @@ private:
bool isStencilAttached() const { return (m_stencilAttachment && m_stencilAttachment->object()); }
bool isDepthStencilAttached() const { return (m_depthStencilAttachment && m_depthStencilAttachment->object()); }
- RefPtr<WebGLObject> m_colorAttachment;
- RefPtr<WebGLObject> m_depthAttachment;
- RefPtr<WebGLObject> m_stencilAttachment;
- RefPtr<WebGLObject> m_depthStencilAttachment;
+ RefPtr<WebGLSharedObject> m_colorAttachment;
+ RefPtr<WebGLSharedObject> m_depthAttachment;
+ RefPtr<WebGLSharedObject> m_stencilAttachment;
+ RefPtr<WebGLSharedObject> m_depthStencilAttachment;
bool m_hasEverBeenBound;
diff --git a/Source/WebCore/html/canvas/WebGLGetInfo.cpp b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
index bce383676..87bec7919 100644
--- a/Source/WebCore/html/canvas/WebGLGetInfo.cpp
+++ b/Source/WebCore/html/canvas/WebGLGetInfo.cpp
@@ -45,11 +45,18 @@ namespace WebCore {
WebGLGetInfo::WebGLGetInfo(bool value)
: m_type(kTypeBool)
, m_bool(value)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
{
}
WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
: m_type(kTypeBoolArray)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
{
if (!value || size <=0)
return;
@@ -60,83 +67,136 @@ WebGLGetInfo::WebGLGetInfo(const bool* value, int size)
WebGLGetInfo::WebGLGetInfo(float value)
: m_type(kTypeFloat)
+ , m_bool(false)
, m_float(value)
+ , m_int(0)
+ , m_unsignedInt(0)
{
}
WebGLGetInfo::WebGLGetInfo(int value)
: m_type(kTypeInt)
+ , m_bool(false)
+ , m_float(0)
, m_int(value)
+ , m_unsignedInt(0)
{
}
WebGLGetInfo::WebGLGetInfo()
: m_type(kTypeNull)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
{
}
WebGLGetInfo::WebGLGetInfo(const String& value)
: m_type(kTypeString)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
, m_string(value)
+ , m_unsignedInt(0)
{
}
WebGLGetInfo::WebGLGetInfo(unsigned int value)
: m_type(kTypeUnsignedInt)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
, m_unsignedInt(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLBuffer> value)
: m_type(kTypeWebGLBuffer)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglBuffer(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<Float32Array> value)
: m_type(kTypeWebGLFloatArray)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglFloatArray(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLFramebuffer> value)
: m_type(kTypeWebGLFramebuffer)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglFramebuffer(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<Int32Array> value)
: m_type(kTypeWebGLIntArray)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglIntArray(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLProgram> value)
: m_type(kTypeWebGLProgram)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglProgram(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLRenderbuffer> value)
: m_type(kTypeWebGLRenderbuffer)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglRenderbuffer(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLTexture> value)
: m_type(kTypeWebGLTexture)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglTexture(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<Uint8Array> value)
: m_type(kTypeWebGLUnsignedByteArray)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglUnsignedByteArray(value)
{
}
WebGLGetInfo::WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES> value)
: m_type(kTypeWebGLVertexArrayObjectOES)
+ , m_bool(false)
+ , m_float(0)
+ , m_int(0)
+ , m_unsignedInt(0)
, m_webglVertexArrayObject(value)
{
}
diff --git a/Source/WebCore/html/canvas/WebGLObject.cpp b/Source/WebCore/html/canvas/WebGLObject.cpp
index 7b629a69c..192852c75 100644
--- a/Source/WebCore/html/canvas/WebGLObject.cpp
+++ b/Source/WebCore/html/canvas/WebGLObject.cpp
@@ -29,13 +29,20 @@
#include "WebGLObject.h"
+#include "OESStandardDerivatives.h"
+#include "OESTextureFloat.h"
+#include "OESVertexArrayObject.h"
+#include "WebGLCompressedTextures.h"
+#include "WebGLContextGroup.h"
+#include "WebGLDebugRendererInfo.h"
+#include "WebGLDebugShaders.h"
+#include "WebGLLoseContext.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
-WebGLObject::WebGLObject(WebGLRenderingContext* context)
+WebGLObject::WebGLObject(WebGLRenderingContext*)
: m_object(0)
- , m_context(context)
, m_attachmentCount(0)
, m_deleted(false)
{
@@ -43,8 +50,6 @@ WebGLObject::WebGLObject(WebGLRenderingContext* context)
WebGLObject::~WebGLObject()
{
- if (m_context)
- m_context->removeObject(this);
}
void WebGLObject::setObject(Platform3DObject object)
@@ -54,26 +59,38 @@ void WebGLObject::setObject(Platform3DObject object)
m_object = object;
}
-void WebGLObject::deleteObject()
+void WebGLObject::deleteObject(GraphicsContext3D* context3d)
{
m_deleted = true;
- if (!m_context || !m_object)
+ if (!m_object)
return;
+
+ if (!hasGroupOrContext())
+ return;
+
if (!m_attachmentCount) {
- m_context->graphicsContext3D()->makeContextCurrent();
- deleteObjectImpl(m_object);
+ if (!context3d)
+ context3d = getAGraphicsContext3D();
+
+ if (context3d)
+ deleteObjectImpl(context3d, m_object);
+
m_object = 0;
}
}
-void WebGLObject::detachContext()
+void WebGLObject::detach()
{
m_attachmentCount = 0; // Make sure OpenGL resource is deleted.
- if (m_context) {
- deleteObject();
- m_context->removeObject(this);
- m_context = 0;
}
+
+
+void WebGLObject::onDetached(GraphicsContext3D* context3d)
+{
+ if (m_attachmentCount)
+ --m_attachmentCount;
+ if (m_deleted)
+ deleteObject(context3d);
}
}
diff --git a/Source/WebCore/html/canvas/WebGLObject.h b/Source/WebCore/html/canvas/WebGLObject.h
index 44cc36f6b..841d0f9fc 100644
--- a/Source/WebCore/html/canvas/WebGLObject.h
+++ b/Source/WebCore/html/canvas/WebGLObject.h
@@ -33,6 +33,8 @@
namespace WebCore {
+class GraphicsContext3D;
+class WebGLContextGroup;
class WebGLRenderingContext;
class WebGLObject : public RefCounted<WebGLObject> {
@@ -44,33 +46,19 @@ public:
// deleteObject may not always delete the OpenGL resource. For programs and
// shaders, deletion is delayed until they are no longer attached.
// FIXME: revisit this when resource sharing between contexts are implemented.
- void deleteObject();
-
- void detachContext();
-
- WebGLRenderingContext* context() const { return m_context; }
-
- virtual bool isBuffer() const { return false; }
- virtual bool isFramebuffer() const { return false; }
- virtual bool isProgram() const { return false; }
- virtual bool isRenderbuffer() const { return false; }
- virtual bool isShader() const { return false; }
- virtual bool isTexture() const { return false; }
+ void deleteObject(GraphicsContext3D*);
void onAttached() { ++m_attachmentCount; }
- void onDetached()
- {
- if (m_attachmentCount)
- --m_attachmentCount;
- if (m_deleted)
- deleteObject();
- }
+ void onDetached(GraphicsContext3D*);
// This indicates whether the client side issue a delete call already, not
// whether the OpenGL resource is deleted.
// object()==0 indicates the OpenGL resource is deleted.
bool isDeleted() { return m_deleted; }
+ // True if this object belongs to the group or context.
+ virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
+
protected:
WebGLObject(WebGLRenderingContext*);
@@ -78,11 +66,16 @@ protected:
void setObject(Platform3DObject);
// deleteObjectImpl should be only called once to delete the OpenGL resource.
- virtual void deleteObjectImpl(Platform3DObject) = 0;
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject) = 0;
+
+ virtual bool hasGroupOrContext() const = 0;
+
+ virtual void detach();
+
+ virtual GraphicsContext3D* getAGraphicsContext3D() const = 0;
private:
Platform3DObject m_object;
- WebGLRenderingContext* m_context;
unsigned m_attachmentCount;
bool m_deleted;
};
diff --git a/Source/WebCore/html/canvas/WebGLProgram.cpp b/Source/WebCore/html/canvas/WebGLProgram.cpp
index d3efda47d..f68543ce4 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.cpp
+++ b/Source/WebCore/html/canvas/WebGLProgram.cpp
@@ -29,6 +29,7 @@
#include "WebGLProgram.h"
+#include "WebGLContextGroup.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -39,32 +40,36 @@ PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
}
WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
- : WebGLObject(ctx)
+ : WebGLSharedObject(ctx)
, m_linkStatus(false)
, m_linkCount(0)
{
- setObject(context()->graphicsContext3D()->createProgram());
+ setObject(ctx->graphicsContext3D()->createProgram());
}
-void WebGLProgram::deleteObjectImpl(Platform3DObject obj)
+WebGLProgram::~WebGLProgram()
{
- context()->graphicsContext3D()->deleteProgram(obj);
+ deleteObject(0);
+}
+
+void WebGLProgram::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject obj)
+{
+ context3d->deleteProgram(obj);
if (m_vertexShader) {
- m_vertexShader->onDetached();
+ m_vertexShader->onDetached(context3d);
m_vertexShader = 0;
}
if (m_fragmentShader) {
- m_fragmentShader->onDetached();
+ m_fragmentShader->onDetached(context3d);
m_fragmentShader = 0;
}
}
-bool WebGLProgram::cacheActiveAttribLocations()
+bool WebGLProgram::cacheActiveAttribLocations(GraphicsContext3D* context3d)
{
m_activeAttribLocations.clear();
if (!object())
return false;
- GraphicsContext3D* context3d = context()->graphicsContext3D();
// Assume link status has already been cached.
if (!m_linkStatus)
diff --git a/Source/WebCore/html/canvas/WebGLProgram.h b/Source/WebCore/html/canvas/WebGLProgram.h
index 0dd3ba0fa..150501100 100644
--- a/Source/WebCore/html/canvas/WebGLProgram.h
+++ b/Source/WebCore/html/canvas/WebGLProgram.h
@@ -26,7 +26,7 @@
#ifndef WebGLProgram_h
#define WebGLProgram_h
-#include "WebGLObject.h"
+#include "WebGLSharedObject.h"
#include "WebGLShader.h"
@@ -36,15 +36,15 @@
namespace WebCore {
-class WebGLProgram : public WebGLObject {
+class WebGLProgram : public WebGLSharedObject {
public:
- virtual ~WebGLProgram() { deleteObject(); }
+ virtual ~WebGLProgram();
static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
// cacheActiveAttribLocation() is only called once after linkProgram()
// succeeds.
- bool cacheActiveAttribLocations();
+ bool cacheActiveAttribLocations(GraphicsContext3D*);
unsigned numActiveAttribLocations() const;
GC3Dint getActiveAttribLocation(GC3Duint index) const;
@@ -67,7 +67,7 @@ public:
protected:
WebGLProgram(WebGLRenderingContext*);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
private:
virtual bool isProgram() const { return true; }
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
index 93b9165c9..daaf9d4ee 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.cpp
@@ -29,6 +29,7 @@
#include "WebGLRenderbuffer.h"
+#include "WebGLContextGroup.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -38,8 +39,13 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* c
return adoptRef(new WebGLRenderbuffer(ctx));
}
+WebGLRenderbuffer::~WebGLRenderbuffer()
+{
+ deleteObject(0);
+}
+
WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
- : WebGLObject(ctx)
+ : WebGLSharedObject(ctx)
, m_internalFormat(GraphicsContext3D::RGBA4)
, m_initialized(false)
, m_width(0)
@@ -47,12 +53,12 @@ WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
, m_isValid(true)
, m_hasEverBeenBound(false)
{
- setObject(context()->graphicsContext3D()->createRenderbuffer());
+ setObject(ctx->graphicsContext3D()->createRenderbuffer());
}
-void WebGLRenderbuffer::deleteObjectImpl(Platform3DObject object)
+void WebGLRenderbuffer::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- context()->graphicsContext3D()->deleteRenderbuffer(object);
+ context3d->deleteRenderbuffer(object);
}
}
diff --git a/Source/WebCore/html/canvas/WebGLRenderbuffer.h b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
index 4b47bf5d3..e169e2e8b 100644
--- a/Source/WebCore/html/canvas/WebGLRenderbuffer.h
+++ b/Source/WebCore/html/canvas/WebGLRenderbuffer.h
@@ -26,16 +26,16 @@
#ifndef WebGLRenderbuffer_h
#define WebGLRenderbuffer_h
-#include "WebGLObject.h"
+#include "WebGLSharedObject.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLRenderbuffer : public WebGLObject {
+class WebGLRenderbuffer : public WebGLSharedObject {
public:
- virtual ~WebGLRenderbuffer() { deleteObject(); }
+ virtual ~WebGLRenderbuffer();
static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
@@ -67,7 +67,7 @@ public:
protected:
WebGLRenderbuffer(WebGLRenderingContext*);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
private:
virtual bool isRenderbuffer() const { return true; }
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
index d17741fb3..945c17e74 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp
@@ -57,6 +57,7 @@
#include "WebGLCompressedTextures.h"
#include "WebGLContextAttributes.h"
#include "WebGLContextEvent.h"
+#include "WebGLContextGroup.h"
#include "WebGLDebugRendererInfo.h"
#include "WebGLDebugShaders.h"
#include "WebGLFramebuffer.h"
@@ -373,6 +374,15 @@ private:
WebGLRenderingContext* m_context;
};
+class WebGLRenderingContextErrorMessageCallback : public GraphicsContext3D::ErrorMessageCallback {
+public:
+ explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
+ virtual void onErrorMessage(const String& message, GC3Dint) { m_context->printWarningToConsole(message); }
+ virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+ WebGLRenderingContext* m_context;
+};
+
PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
{
HostWindow* hostWindow = canvas->document()->view()->root()->hostWindow();
@@ -414,8 +424,11 @@ WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, Pa
, m_contextLost(false)
, m_contextLostMode(SyntheticLostContext)
, m_attributes(attributes)
+ , m_synthesizedErrorsToConsole(false)
{
ASSERT(m_context);
+ m_contextGroup = WebGLContextGroup::create();
+ m_contextGroup->addContext(this);
#if PLATFORM(CHROMIUM)
// Create the DrawingBuffer and initialize the platform layer.
@@ -480,7 +493,7 @@ void WebGLRenderingContext::initializeNewContext()
m_context->getIntegerv(GraphicsContext3D::MAX_VIEWPORT_DIMS, m_maxViewportDims);
m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
- addObject(m_defaultVertexArrayObject.get());
+ addContextObject(m_defaultVertexArrayObject.get());
m_boundVertexArrayObject = m_defaultVertexArrayObject;
m_vertexAttribValue.resize(m_maxVertexAttribs);
@@ -497,6 +510,7 @@ void WebGLRenderingContext::initializeNewContext()
m_context->viewport(0, 0, canvas()->width(), canvas()->height());
m_context->setContextLostCallback(adoptPtr(new WebGLRenderingContextLostCallback(this)));
+ m_context->setErrorMessageCallback(adoptPtr(new WebGLRenderingContextErrorMessageCallback(this)));
}
void WebGLRenderingContext::setupFlags()
@@ -525,8 +539,28 @@ bool WebGLRenderingContext::allowPrivilegedExtensions() const
WebGLRenderingContext::~WebGLRenderingContext()
{
+ // Remove all references to WebGLObjects so if they are the last reference
+ // they will be freed before the last context is removed from the context group.
+ m_boundArrayBuffer = 0;
+ m_defaultVertexArrayObject = 0;
+ m_boundVertexArrayObject = 0;
+ m_vertexAttrib0Buffer = 0;
+ m_currentProgram = 0;
+ m_framebufferBinding = 0;
+ m_renderbufferBinding = 0;
+
+ for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+ m_textureUnits[i].m_texture2DBinding = 0;
+ m_textureUnits[i].m_textureCubeMapBinding = 0;
+ }
+
+ m_blackTexture2D = 0;
+ m_blackTextureCubeMap = 0;
+
detachAndRemoveAllObjects();
m_context->setContextLostCallback(nullptr);
+ m_context->setErrorMessageCallback(nullptr);
+ m_contextGroup->removeContext(this);
}
void WebGLRenderingContext::markContextChanged()
@@ -753,7 +787,7 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
if (isContextLost())
return;
if (texture - GraphicsContext3D::TEXTURE0 >= m_textureUnits.size()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "activeTexture", "texture unit out of range");
return;
}
m_activeTextureUnit = texture - GraphicsContext3D::TEXTURE0;
@@ -768,10 +802,10 @@ void WebGLRenderingContext::activeTexture(GC3Denum texture, ExceptionCode& ec)
void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
return;
if (!program->attachShader(shader)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "attachShader", "shader attachment already has shader");
return;
}
m_context->attachShader(objectOrZero(program), objectOrZero(shader));
@@ -782,24 +816,24 @@ void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* sha
void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GC3Duint index, const String& name, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
return;
- if (!validateLocationLength(name))
+ if (!validateLocationLength("bindAttribLocation", name))
return;
- if (!validateString(name))
+ if (!validateString("bindAttribLocation", name))
return;
m_context->bindAttribLocation(objectOrZero(program), index, name);
cleanupAfterGraphicsCall(false);
}
-bool WebGLRenderingContext::checkObjectToBeBound(WebGLObject* object, bool& deleted)
+bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
{
deleted = false;
if (isContextLost())
return false;
if (object) {
- if (object->context() != this) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object not from this context");
return false;
}
deleted = !object->object();
@@ -811,12 +845,12 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc
{
UNUSED_PARAM(ec);
bool deleted;
- if (!checkObjectToBeBound(buffer, deleted))
+ if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
return;
if (deleted)
buffer = 0;
if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
return;
}
if (target == GraphicsContext3D::ARRAY_BUFFER)
@@ -824,7 +858,7 @@ void WebGLRenderingContext::bindBuffer(GC3Denum target, WebGLBuffer* buffer, Exc
else if (target == GraphicsContext3D::ELEMENT_ARRAY_BUFFER)
m_boundVertexArrayObject->setElementArrayBuffer(buffer);
else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindBuffer", "invalid target");
return;
}
@@ -838,12 +872,12 @@ void WebGLRenderingContext::bindFramebuffer(GC3Denum target, WebGLFramebuffer* b
{
UNUSED_PARAM(ec);
bool deleted;
- if (!checkObjectToBeBound(buffer, deleted))
+ if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
return;
if (deleted)
buffer = 0;
if (target != GraphicsContext3D::FRAMEBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindFramebuffer", "invalid target");
return;
}
m_framebufferBinding = buffer;
@@ -861,12 +895,12 @@ void WebGLRenderingContext::bindRenderbuffer(GC3Denum target, WebGLRenderbuffer*
{
UNUSED_PARAM(ec);
bool deleted;
- if (!checkObjectToBeBound(renderBuffer, deleted))
+ if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
return;
if (deleted)
renderBuffer = 0;
if (target != GraphicsContext3D::RENDERBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindRenderbuffer", "invalid target");
return;
}
m_renderbufferBinding = renderBuffer;
@@ -880,12 +914,12 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture,
{
UNUSED_PARAM(ec);
bool deleted;
- if (!checkObjectToBeBound(texture, deleted))
+ if (!checkObjectToBeBound("bindTexture", texture, deleted))
return;
if (deleted)
texture = 0;
if (texture && texture->getTarget() && texture->getTarget() != target) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
return;
}
GC3Dint maxLevel = 0;
@@ -900,7 +934,7 @@ void WebGLRenderingContext::bindTexture(GC3Denum target, WebGLTexture* texture,
m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
maxLevel = m_maxCubeMapTextureLevel;
} else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "bindTexture", "invalid target");
return;
}
m_context->bindTexture(target, objectOrZero(texture));
@@ -929,7 +963,7 @@ void WebGLRenderingContext::blendColor(GC3Dfloat red, GC3Dfloat green, GC3Dfloat
void WebGLRenderingContext::blendEquation(GC3Denum mode)
{
- if (isContextLost() || !validateBlendEquation(mode))
+ if (isContextLost() || !validateBlendEquation("blendEquation", mode))
return;
m_context->blendEquation(mode);
cleanupAfterGraphicsCall(false);
@@ -937,7 +971,7 @@ void WebGLRenderingContext::blendEquation(GC3Denum mode)
void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum modeAlpha)
{
- if (isContextLost() || !validateBlendEquation(modeRGB) || !validateBlendEquation(modeAlpha))
+ if (isContextLost() || !validateBlendEquation("blendEquation", modeRGB) || !validateBlendEquation("blendEquation", modeAlpha))
return;
m_context->blendEquationSeparate(modeRGB, modeAlpha);
cleanupAfterGraphicsCall(false);
@@ -946,7 +980,7 @@ void WebGLRenderingContext::blendEquationSeparate(GC3Denum modeRGB, GC3Denum mod
void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
{
- if (isContextLost() || !validateBlendFuncFactors(sfactor, dfactor))
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
return;
m_context->blendFunc(sfactor, dfactor);
cleanupAfterGraphicsCall(false);
@@ -954,7 +988,8 @@ void WebGLRenderingContext::blendFunc(GC3Denum sfactor, GC3Denum dfactor)
void WebGLRenderingContext::blendFuncSeparate(GC3Denum srcRGB, GC3Denum dstRGB, GC3Denum srcAlpha, GC3Denum dstAlpha)
{
- if (isContextLost() || !validateBlendFuncFactors(srcRGB, dstRGB))
+ // Note: Alpha does not have the same restrictions as RGB.
+ if (isContextLost() || !validateBlendFuncFactors("blendFunc", srcRGB, dstRGB))
return;
m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
cleanupAfterGraphicsCall(false);
@@ -965,16 +1000,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, GC3Dsizeiptr size, GC3De
UNUSED_PARAM(ec);
if (isContextLost())
return;
- WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
if (!buffer)
return;
if (size < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "size < 0");
return;
}
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
if (!buffer->associateBufferData(size)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
return;
}
}
@@ -988,16 +1023,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBuffer* data, GC3De
UNUSED_PARAM(ec);
if (isContextLost())
return;
- WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
if (!buffer)
return;
if (!data) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
return;
}
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
if (!buffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
return;
}
}
@@ -1011,16 +1046,16 @@ void WebGLRenderingContext::bufferData(GC3Denum target, ArrayBufferView* data, G
UNUSED_PARAM(ec);
if (isContextLost())
return;
- WebGLBuffer* buffer = validateBufferDataParameters(target, usage);
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
if (!buffer)
return;
if (!data) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "no data");
return;
}
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
if (!buffer->associateBufferData(data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferData", "invalid buffer");
return;
}
}
@@ -1034,18 +1069,18 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar
UNUSED_PARAM(ec);
if (isContextLost())
return;
- WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
if (offset < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
return;
}
if (!data)
return;
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
if (!buffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
return;
}
}
@@ -1059,18 +1094,18 @@ void WebGLRenderingContext::bufferSubData(GC3Denum target, GC3Dintptr offset, Ar
UNUSED_PARAM(ec);
if (isContextLost())
return;
- WebGLBuffer* buffer = validateBufferDataParameters(target, GraphicsContext3D::STATIC_DRAW);
+ WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GraphicsContext3D::STATIC_DRAW);
if (!buffer)
return;
if (offset < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset < 0");
return;
}
if (!data)
return;
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
if (!buffer->associateBufferSubData(offset, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "bufferSubData", "offset out of range");
return;
}
}
@@ -1084,7 +1119,7 @@ GC3Denum WebGLRenderingContext::checkFramebufferStatus(GC3Denum target)
if (isContextLost())
return GraphicsContext3D::FRAMEBUFFER_UNSUPPORTED;
if (target != GraphicsContext3D::FRAMEBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "checkFramebufferStatus", "invalid target");
return 0;
}
if (!m_framebufferBinding || !m_framebufferBinding->object())
@@ -1102,11 +1137,11 @@ void WebGLRenderingContext::clear(GC3Dbitfield mask)
if (isContextLost())
return;
if (mask & ~(GraphicsContext3D::COLOR_BUFFER_BIT | GraphicsContext3D::DEPTH_BUFFER_BIT | GraphicsContext3D::STENCIL_BUFFER_BIT)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "clear", "invalid mask");
return;
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "clear", "can not render to framebuffer");
return;
}
if (!clearIfComposited(mask))
@@ -1167,31 +1202,51 @@ void WebGLRenderingContext::colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dbo
void WebGLRenderingContext::compileShader(WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject("compileShader", shader))
return;
m_context->compileShader(objectOrZero(shader));
cleanupAfterGraphicsCall(false);
}
+void WebGLRenderingContext::compressedTexImage2D(GC3Denum /*target*/, GC3Dint /*level*/, GC3Denum /*internalformat*/, GC3Dsizei /*width*/,
+ GC3Dsizei /*height*/, GC3Dint /*border*/, ArrayBufferView* /*data*/)
+{
+ if (isContextLost())
+ return;
+
+ // FIXME: implement this.
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+}
+
+void WebGLRenderingContext::compressedTexSubImage2D(GC3Denum /*target*/, GC3Dint /*level*/, GC3Dint /*xoffset*/, GC3Dint /*yoffset*/,
+ GC3Dsizei /*width*/, GC3Dsizei /*height*/, GC3Denum /*format*/, ArrayBufferView* /*data*/)
+{
+ if (isContextLost())
+ return;
+
+ // FIXME: implement this.
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+}
+
void WebGLRenderingContext::copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border)
{
if (isContextLost())
return;
- if (!validateTexFuncParameters(target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
+ if (!validateTexFuncParameters("copyTexImage2D", target, level, internalformat, width, height, border, internalformat, GraphicsContext3D::UNSIGNED_BYTE))
return;
- WebGLTexture* tex = validateTextureBinding(target, true);
+ WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
if (!tex)
return;
if (!isTexInternalFormatColorBufferCombinationValid(internalformat, getBoundFramebufferColorFormat())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
return;
}
if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
return;
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", "framebuffer not readable");
return;
}
clearIfComposited();
@@ -1221,23 +1276,23 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC
{
if (isContextLost())
return;
- if (!validateTexFuncLevel(target, level))
+ if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
return;
- WebGLTexture* tex = validateTextureBinding(target, true);
+ WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
if (!tex)
return;
- if (!validateSize(xoffset, yoffset) || !validateSize(width, height))
+ if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
return;
if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
return;
}
if (!isTexInternalFormatColorBufferCombinationValid(tex->getInternalFormat(target, level), getBoundFramebufferColorFormat())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
return;
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", "framebuffer not readable");
return;
}
clearIfComposited();
@@ -1255,12 +1310,12 @@ void WebGLRenderingContext::copyTexSubImage2D(GC3Denum target, GC3Dint level, GC
unsigned int size;
GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &size, 0);
if (error != GraphicsContext3D::NO_ERROR) {
- m_context->synthesizeGLError(error);
+ synthesizeGLError(error, "copyTexSubImage2D", "bad dimensions");
return;
}
zero = adoptArrayPtr(new unsigned char[size]);
if (!zero) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "copyTexSubImage2D", "out of memory");
return;
}
memset(zero.get(), 0, size);
@@ -1284,7 +1339,7 @@ PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
if (isContextLost())
return 0;
RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
- addObject(o.get());
+ addSharedObject(o.get());
return o;
}
@@ -1293,7 +1348,7 @@ PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
if (isContextLost())
return 0;
RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
- addObject(o.get());
+ addContextObject(o.get());
return o;
}
@@ -1302,7 +1357,7 @@ PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
if (isContextLost())
return 0;
RefPtr<WebGLTexture> o = WebGLTexture::create(this);
- addObject(o.get());
+ addSharedObject(o.get());
return o;
}
@@ -1311,7 +1366,7 @@ PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
if (isContextLost())
return 0;
RefPtr<WebGLProgram> o = WebGLProgram::create(this);
- addObject(o.get());
+ addSharedObject(o.get());
return o;
}
@@ -1320,7 +1375,7 @@ PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
if (isContextLost())
return 0;
RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
- addObject(o.get());
+ addSharedObject(o.get());
return o;
}
@@ -1330,12 +1385,12 @@ PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GC3Denum type, Excep
if (isContextLost())
return 0;
if (type != GraphicsContext3D::VERTEX_SHADER && type != GraphicsContext3D::FRAGMENT_SHADER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "createShader", "invalid shader type");
return 0;
}
RefPtr<WebGLShader> o = WebGLShader::create(this, type);
- addObject(o.get());
+ addSharedObject(o.get());
return o;
}
@@ -1351,12 +1406,14 @@ bool WebGLRenderingContext::deleteObject(WebGLObject* object)
{
if (isContextLost() || !object)
return false;
- if (object->context() != this) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "delete", "object does not belong to this context");
return false;
}
if (object->object())
- object->deleteObject();
+ // We need to pass in context here because we want
+ // things in this context unbound.
+ object->deleteObject(graphicsContext3D());
return true;
}
@@ -1456,7 +1513,7 @@ void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
if (isContextLost())
return;
if (zNear > zFar) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "depthRange", "zNear > zFar");
return;
}
m_context->depthRange(zNear, zFar);
@@ -1466,20 +1523,20 @@ void WebGLRenderingContext::depthRange(GC3Dfloat zNear, GC3Dfloat zFar)
void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program) || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
return;
if (!program->detachShader(shader)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "detachShader", "shader not attached");
return;
}
m_context->detachShader(objectOrZero(program), objectOrZero(shader));
- shader->onDetached();
+ shader->onDetached(graphicsContext3D());
cleanupAfterGraphicsCall(false);
}
void WebGLRenderingContext::disable(GC3Denum cap)
{
- if (isContextLost() || !validateCapability(cap))
+ if (isContextLost() || !validateCapability("disable", cap))
return;
if (cap == GraphicsContext3D::SCISSOR_TEST) {
m_scissorEnabled = false;
@@ -1496,7 +1553,7 @@ void WebGLRenderingContext::disableVertexAttribArray(GC3Duint index, ExceptionCo
if (isContextLost())
return;
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "disableVertexAttribArray", "index out of range");
return;
}
@@ -1679,14 +1736,14 @@ bool WebGLRenderingContext::validateRenderingState(int numElementsRequired)
return numElementsRequired <= smallestNumElements;
}
-bool WebGLRenderingContext::validateWebGLObject(WebGLObject* object)
+bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
{
if (!object || !object->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no object or object deleted");
return false;
}
- if (object->context() != this) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ if (!object->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "object does not belong to this context");
return false;
}
return true;
@@ -1696,14 +1753,14 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateDrawMode(mode))
+ if (isContextLost() || !validateDrawMode("drawArrays", mode))
return;
- if (!validateStencilSettings())
+ if (!validateStencilSettings("drawArrays"))
return;
if (first < 0 || count < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawArrays", "first or count < 0");
return;
}
@@ -1716,18 +1773,18 @@ void WebGLRenderingContext::drawArrays(GC3Denum mode, GC3Dint first, GC3Dsizei c
CheckedInt<GC3Dint> checkedCount(count);
CheckedInt<GC3Dint> checkedSum = checkedFirst + checkedCount;
if (!checkedSum.valid() || !validateRenderingState(checkedSum.value())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawArrays", "attempt to access out of bounds arrays");
return;
}
} else {
if (!validateRenderingState(0)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawArrays", "attribs not setup correctly");
return;
}
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawArrays", "framebuffer can not be rendered to");
return;
}
@@ -1750,10 +1807,10 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateDrawMode(mode))
+ if (isContextLost() || !validateDrawMode("drawElements", mode))
return;
- if (!validateStencilSettings())
+ if (!validateStencilSettings("drawElements"))
return;
switch (type) {
@@ -1761,12 +1818,12 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
case GraphicsContext3D::UNSIGNED_SHORT:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "drawElements", "invalid type");
return;
}
if (count < 0 || offset < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "drawElements", "count or offset < 0");
return;
}
@@ -1774,7 +1831,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
return;
if (!m_boundVertexArrayObject->getElementArrayBuffer()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "no ELEMENT_ARRAY_BUFFER bound");
return;
}
@@ -1782,26 +1839,26 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
if (!isErrorGeneratedOnOutOfBoundsAccesses()) {
// Ensure we have a valid rendering state
if (!validateElementArraySize(count, type, offset)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "request out of bounds for current ELEMENT_ARRAY_BUFFER");
return;
}
if (!count)
return;
if (!validateIndexArrayConservative(type, numElements) || !validateRenderingState(numElements)) {
if (!validateIndexArrayPrecise(count, type, offset, numElements) || !validateRenderingState(numElements)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "attempt to access out of bounds arrays");
return;
}
}
} else {
if (!validateRenderingState(0)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "drawElements", "attribs not setup correctly");
return;
}
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "drawElements", "framebuffer can not be rendered to");
return;
}
clearIfComposited();
@@ -1824,7 +1881,7 @@ void WebGLRenderingContext::drawElements(GC3Denum mode, GC3Dsizei count, GC3Denu
void WebGLRenderingContext::enable(GC3Denum cap)
{
- if (isContextLost() || !validateCapability(cap))
+ if (isContextLost() || !validateCapability("enable", cap))
return;
if (cap == GraphicsContext3D::SCISSOR_TEST) {
m_scissorEnabled = true;
@@ -1841,7 +1898,7 @@ void WebGLRenderingContext::enableVertexAttribArray(GC3Duint index, ExceptionCod
if (isContextLost())
return;
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "enableVertexAttribArray", "index out of range");
return;
}
@@ -1871,21 +1928,21 @@ void WebGLRenderingContext::flush()
void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum attachment, GC3Denum renderbuffertarget, WebGLRenderbuffer* buffer, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
return;
if (renderbuffertarget != GraphicsContext3D::RENDERBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
return;
}
- if (buffer && buffer->context() != this) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ if (buffer && !buffer->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
return;
}
// Don't allow the default framebuffer to be mutated; all current
// implementations use an FBO internally in place of the default
// FBO.
if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
return;
}
Platform3DObject bufferObject = objectOrZero(buffer);
@@ -1942,21 +1999,21 @@ void WebGLRenderingContext::framebufferRenderbuffer(GC3Denum target, GC3Denum at
void WebGLRenderingContext::framebufferTexture2D(GC3Denum target, GC3Denum attachment, GC3Denum textarget, WebGLTexture* texture, GC3Dint level, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
return;
if (level) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "framebufferTexture2D", "level not 0");
return;
}
- if (texture && texture->context() != this) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ if (texture && !texture->validate(contextGroup(), this)) {
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
return;
}
// Don't allow the default framebuffer to be mutated; all current
// implementations use an FBO internally in place of the default
// FBO.
if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
return;
}
m_context->framebufferTexture2D(target, attachment, textarget, objectOrZero(texture), level);
@@ -1976,11 +2033,11 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target)
{
if (isContextLost())
return;
- WebGLTexture* tex = validateTextureBinding(target, false);
+ WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
if (!tex)
return;
if (!tex->canGenerateMipmaps()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
return;
}
// generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
@@ -2004,7 +2061,7 @@ void WebGLRenderingContext::generateMipmap(GC3Denum target)
PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
return 0;
ActiveInfo info;
if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
@@ -2015,7 +2072,7 @@ PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram*
PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GC3Duint index, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
return 0;
ActiveInfo info;
if (!m_context->getActiveUniform(objectOrZero(program), index, info))
@@ -2030,7 +2087,7 @@ bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<Ref
{
UNUSED_PARAM(ec);
shaderObjects.clear();
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
return false;
const GC3Denum shaderType[] = {
@@ -2049,9 +2106,9 @@ GC3Dint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const St
{
if (isContextLost())
return -1;
- if (!validateLocationLength(name))
+ if (!validateLocationLength("getAttribLocation", name))
return -1;
- if (!validateString(name))
+ if (!validateString("getAttribLocation", name))
return -1;
return m_context->getAttribLocation(objectOrZero(program), name);
}
@@ -2062,12 +2119,12 @@ WebGLGetInfo WebGLRenderingContext::getBufferParameter(GC3Denum target, GC3Denum
if (isContextLost())
return WebGLGetInfo();
if (target != GraphicsContext3D::ARRAY_BUFFER && target != GraphicsContext3D::ELEMENT_ARRAY_BUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid target");
return WebGLGetInfo();
}
if (pname != GraphicsContext3D::BUFFER_SIZE && pname != GraphicsContext3D::BUFFER_USAGE) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getBufferParameter", "invalid parameter name");
return WebGLGetInfo();
}
@@ -2156,21 +2213,21 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name)
WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum target, GC3Denum attachment, GC3Denum pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateFramebufferFuncParameters(target, attachment))
+ if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
return WebGLGetInfo();
if (!m_framebufferBinding || !m_framebufferBinding->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
return WebGLGetInfo();
}
- WebGLObject* object = m_framebufferBinding->getAttachment(attachment);
+ WebGLSharedObject* object = m_framebufferBinding->getAttachment(attachment);
if (!object) {
if (pname == GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
return WebGLGetInfo(GraphicsContext3D::NONE);
// OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
// specifies INVALID_OPERATION.
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
return WebGLGetInfo();
}
@@ -2190,7 +2247,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t
return WebGLGetInfo(value);
}
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
return WebGLGetInfo();
}
} else {
@@ -2200,7 +2257,7 @@ WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GC3Denum t
case GraphicsContext3D::FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(reinterpret_cast<WebGLRenderbuffer*>(object)));
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
return WebGLGetInfo();
}
}
@@ -2395,17 +2452,17 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
case Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
if (m_oesStandardDerivatives)
return getUnsignedIntParameter(Extensions3D::FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
return WebGLGetInfo();
case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
if (m_webglDebugRendererInfo)
return WebGLGetInfo(m_context->getString(GraphicsContext3D::RENDERER));
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
return WebGLGetInfo();
case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
if (m_webglDebugRendererInfo)
return WebGLGetInfo(m_context->getString(GraphicsContext3D::VENDOR));
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
return WebGLGetInfo();
case Extensions3D::VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
if (m_oesVertexArrayObject) {
@@ -2413,10 +2470,10 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
return WebGLGetInfo();
}
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
return WebGLGetInfo();
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getParameter", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2424,7 +2481,7 @@ WebGLGetInfo WebGLRenderingContext::getParameter(GC3Denum pname, ExceptionCode&
WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GC3Denum pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
return WebGLGetInfo();
WebGLStateRestorer(this, false);
@@ -2443,7 +2500,7 @@ WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, G
m_context->getProgramiv(objectOrZero(program), pname, &value);
return WebGLGetInfo(value);
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getProgramParameter", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2453,7 +2510,7 @@ String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program, Exception
UNUSED_PARAM(ec);
if (isContextLost())
return String();
- if (!validateWebGLObject(program))
+ if (!validateWebGLObject("getProgramInfoLog", program))
return "";
WebGLStateRestorer(this, false);
return m_context->getProgramInfoLog(objectOrZero(program));
@@ -2465,11 +2522,11 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
if (isContextLost())
return WebGLGetInfo();
if (target != GraphicsContext3D::RENDERBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid target");
return WebGLGetInfo();
}
if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
return WebGLGetInfo();
}
@@ -2499,7 +2556,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
return WebGLGetInfo();
}
return WebGLGetInfo(value);
@@ -2521,7 +2578,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
case GraphicsContext3D::RENDERBUFFER_INTERNAL_FORMAT:
return WebGLGetInfo(m_renderbufferBinding->getInternalFormat());
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2529,7 +2586,7 @@ WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GC3Denum target, GC
WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3Denum pname, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
return WebGLGetInfo();
WebGLStateRestorer(this, false);
GC3Dint value = 0;
@@ -2543,7 +2600,7 @@ WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GC3D
m_context->getShaderiv(objectOrZero(shader), pname, &value);
return WebGLGetInfo(static_cast<unsigned int>(value));
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getShaderParameter", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2553,7 +2610,7 @@ String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader, ExceptionCod
UNUSED_PARAM(ec);
if (isContextLost())
return String();
- if (!validateWebGLObject(shader))
+ if (!validateWebGLObject("getShaderInfoLog", shader))
return "";
WebGLStateRestorer(this, false);
return m_context->getShaderInfoLog(objectOrZero(shader));
@@ -2564,7 +2621,7 @@ String WebGLRenderingContext::getShaderSource(WebGLShader* shader, ExceptionCode
UNUSED_PARAM(ec);
if (isContextLost())
return String();
- if (!validateWebGLObject(shader))
+ if (!validateWebGLObject("getShaderSource", shader))
return "";
return shader->getSource();
}
@@ -2596,7 +2653,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn
UNUSED_PARAM(ec);
if (isContextLost())
return WebGLGetInfo();
- WebGLTexture* tex = validateTextureBinding(target, false);
+ WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
if (!tex)
return WebGLGetInfo();
WebGLStateRestorer(this, false);
@@ -2609,7 +2666,7 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn
m_context->getTexParameteriv(target, pname, &value);
return WebGLGetInfo(static_cast<unsigned int>(value));
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getTexParameter", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2617,10 +2674,10 @@ WebGLGetInfo WebGLRenderingContext::getTexParameter(GC3Denum target, GC3Denum pn
WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getUniform", program))
return WebGLGetInfo();
if (!uniformLocation || uniformLocation->program() != program) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
return WebGLGetInfo();
}
GC3Dint location = uniformLocation->location();
@@ -2718,7 +2775,7 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
break;
default:
// Can't handle this type
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unhandled type");
return WebGLGetInfo();
}
switch (baseType) {
@@ -2754,18 +2811,18 @@ WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebG
}
}
// If we get here, something went wrong in our unfortunately complex logic above
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getUniform", "unknown error");
return WebGLGetInfo();
}
PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
return 0;
- if (!validateLocationLength(name))
+ if (!validateLocationLength("getUniformLocation", name))
return 0;
- if (!validateString(name))
+ if (!validateString("getUniformLocation", name))
return 0;
WebGLStateRestorer(this, false);
GC3Dint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name);
@@ -2781,7 +2838,7 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna
return WebGLGetInfo();
WebGLStateRestorer(this, false);
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "getVertexAttrib", "index out of range");
return WebGLGetInfo();
}
const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
@@ -2805,7 +2862,7 @@ WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GC3Duint index, GC3Denum pna
case GraphicsContext3D::CURRENT_VERTEX_ATTRIB:
return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
return WebGLGetInfo();
}
}
@@ -2834,7 +2891,7 @@ void WebGLRenderingContext::hint(GC3Denum target, GC3Denum mode)
break;
}
if (!isValid) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "hint", "invalid target");
return;
}
m_context->hint(target, mode);
@@ -2859,7 +2916,7 @@ bool WebGLRenderingContext::isContextLost()
GC3Dboolean WebGLRenderingContext::isEnabled(GC3Denum cap)
{
- if (!validateCapability(cap) || isContextLost())
+ if (isContextLost() || !validateCapability("isEnabled", cap))
return 0;
return m_context->isEnabled(cap);
}
@@ -2924,7 +2981,7 @@ void WebGLRenderingContext::lineWidth(GC3Dfloat width)
void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("linkProgram", program))
return;
if (!isGLES2Compliant()) {
if (!program->getAttachedShader(GraphicsContext3D::VERTEX_SHADER) || !program->getAttachedShader(GraphicsContext3D::FRAGMENT_SHADER)) {
@@ -2940,7 +2997,7 @@ void WebGLRenderingContext::linkProgram(WebGLProgram* program, ExceptionCode& ec
m_context->getProgramiv(objectOrZero(program), GraphicsContext3D::LINK_STATUS, &value);
program->setLinkStatus(static_cast<bool>(value));
// Need to cache link status before caching active attribute locations.
- program->cacheActiveAttribLocations();
+ program->cacheActiveAttribLocations(graphicsContext3D());
cleanupAfterGraphicsCall(false);
}
@@ -2959,7 +3016,7 @@ void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
if (param == GraphicsContext3D::BROWSER_DEFAULT_WEBGL || param == GraphicsContext3D::NONE)
m_unpackColorspaceConversion = static_cast<GC3Denum>(param);
else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
return;
}
break;
@@ -2973,12 +3030,12 @@ void WebGLRenderingContext::pixelStorei(GC3Denum pname, GC3Dint param)
m_context->pixelStorei(pname, param);
cleanupAfterGraphicsCall(false);
} else {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
return;
}
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "pixelStorei", "invalid parameter name");
return;
}
}
@@ -3000,7 +3057,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
ASSERT(canvas()->originClean());
// Validate input parameters.
if (!pixels) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
return;
}
switch (format) {
@@ -3009,7 +3066,7 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
case GraphicsContext3D::RGBA:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid format");
return;
}
switch (type) {
@@ -3019,20 +3076,20 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "readPixels", "invalid type");
return;
}
if (format != GraphicsContext3D::RGBA || type != GraphicsContext3D::UNSIGNED_BYTE) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
return;
}
// Validate array type against pixel type.
if (!pixels->isUnsignedByteArray()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
return;
}
- if (m_framebufferBinding && !m_framebufferBinding->onAccess(!isResourceSafe())) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION);
+ if (m_framebufferBinding && !m_framebufferBinding->onAccess(graphicsContext3D(), !isResourceSafe())) {
+ synthesizeGLError(GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION, "readPixels", "framebuffer not readable");
return;
}
// Calculate array size, taking into consideration of PACK_ALIGNMENT.
@@ -3040,11 +3097,11 @@ void WebGLRenderingContext::readPixels(GC3Dint x, GC3Dint y, GC3Dsizei width, GC
unsigned int padding;
GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
if (error != GraphicsContext3D::NO_ERROR) {
- m_context->synthesizeGLError(error);
+ synthesizeGLError(error, "readPixels", "invalid dimensions");
return;
}
if (pixels->byteLength() < totalBytesRequired) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
return;
}
clearIfComposited();
@@ -3085,14 +3142,14 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern
if (isContextLost())
return;
if (target != GraphicsContext3D::RENDERBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid target");
return;
}
if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
return;
}
- if (!validateSize(width, height))
+ if (!validateSize("renderbufferStorage", width, height))
return;
switch (internalformat) {
case GraphicsContext3D::DEPTH_COMPONENT16:
@@ -3116,7 +3173,7 @@ void WebGLRenderingContext::renderbufferStorage(GC3Denum target, GC3Denum intern
m_renderbufferBinding->setInternalFormat(internalformat);
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
}
}
@@ -3132,7 +3189,7 @@ void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Ds
{
if (isContextLost())
return;
- if (!validateSize(width, height))
+ if (!validateSize("scissor", width, height))
return;
m_context->scissor(x, y, width, height);
cleanupAfterGraphicsCall(false);
@@ -3141,10 +3198,10 @@ void WebGLRenderingContext::scissor(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Ds
void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(shader))
+ if (isContextLost() || !validateWebGLObject("shaderSource", shader))
return;
String stringWithoutComments = StripComments(string).result();
- if (!validateString(stringWithoutComments))
+ if (!validateString("shaderSource", stringWithoutComments))
return;
shader->setSource(string);
m_context->shaderSource(objectOrZero(shader), stringWithoutComments);
@@ -3155,7 +3212,7 @@ void WebGLRenderingContext::stencilFunc(GC3Denum func, GC3Dint ref, GC3Duint mas
{
if (isContextLost())
return;
- if (!validateStencilFunc(func))
+ if (!validateStencilFunc("stencilFunc", func))
return;
m_stencilFuncRef = ref;
m_stencilFuncRefBack = ref;
@@ -3169,7 +3226,7 @@ void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC
{
if (isContextLost())
return;
- if (!validateStencilFunc(func))
+ if (!validateStencilFunc("stencilFuncSeparate", func))
return;
switch (face) {
case GraphicsContext3D::FRONT_AND_BACK:
@@ -3187,7 +3244,7 @@ void WebGLRenderingContext::stencilFuncSeparate(GC3Denum face, GC3Denum func, GC
m_stencilFuncMaskBack = mask;
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilFuncSeparate", "invalid face");
return;
}
m_context->stencilFuncSeparate(face, func, ref, mask);
@@ -3220,7 +3277,7 @@ void WebGLRenderingContext::stencilMaskSeparate(GC3Denum face, GC3Duint mask)
m_stencilMaskBack = mask;
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "stencilMaskSeparate", "invalid face");
return;
}
m_context->stencilMaskSeparate(face, mask);
@@ -3249,14 +3306,14 @@ void WebGLRenderingContext::texImage2DBase(GC3Denum target, GC3Dint level, GC3De
{
// FIXME: For now we ignore any errors returned
ec = 0;
- if (!validateTexFuncParameters(target, level, internalformat, width, height, border, format, type))
+ if (!validateTexFuncParameters("texImage2D", target, level, internalformat, width, height, border, format, type))
return;
- WebGLTexture* tex = validateTextureBinding(target, true);
+ WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
if (!tex)
return;
if (!isGLES2NPOTStrict()) {
if (level && WebGLTexture::isNPOT(width, height)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "level > 0 not power of 2");
return;
}
}
@@ -3280,7 +3337,7 @@ void WebGLRenderingContext::texImage2DImpl(GC3Denum target, GC3Dint level, GC3De
ec = 0;
Vector<uint8_t> data;
if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
return;
}
if (m_unpackAlignment != 1)
@@ -3295,7 +3352,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
GC3Dsizei width, GC3Dsizei height, GC3Dint border,
GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
+ if (isContextLost() || !validateTexFuncData("texImage2D", width, height, format, type, pixels))
return;
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
@@ -3326,7 +3383,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
return;
Vector<uint8_t> data;
if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "bad image data");
return;
}
if (m_unpackAlignment != 1)
@@ -3343,7 +3400,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
ec = 0;
if (isContextLost())
return;
- if (!validateHTMLImageElement(image))
+ if (!validateHTMLImageElement("texImage2D", image))
return;
if (wouldTaintOrigin(image)) {
ec = SECURITY_ERR;
@@ -3361,7 +3418,7 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
if (isContextLost())
return;
if (!canvas || !canvas->buffer()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "no canvas");
return;
}
if (wouldTaintOrigin(canvas)) {
@@ -3380,13 +3437,13 @@ void WebGLRenderingContext::texImage2D(GC3Denum target, GC3Dint level, GC3Denum
PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, ExceptionCode& ec)
{
if (!video || !video->videoWidth() || !video->videoHeight()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texImage2D", "no video");
return 0;
}
IntSize size(video->videoWidth(), video->videoHeight());
ImageBuffer* buf = m_videoCache.imageBuffer(size);
if (!buf) {
- m_context->synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY);
+ synthesizeGLError(GraphicsContext3D::OUT_OF_MEMORY, "texImage2D", "out of memory");
return 0;
}
if (wouldTaintOrigin(video)) {
@@ -3416,7 +3473,7 @@ void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfl
{
if (isContextLost())
return;
- WebGLTexture* tex = validateTextureBinding(target, false);
+ WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
if (!tex)
return;
switch (pname) {
@@ -3427,12 +3484,12 @@ void WebGLRenderingContext::texParameter(GC3Denum target, GC3Denum pname, GC3Dfl
case GraphicsContext3D::TEXTURE_WRAP_T:
if ((isFloat && paramf != GraphicsContext3D::CLAMP_TO_EDGE && paramf != GraphicsContext3D::MIRRORED_REPEAT && paramf != GraphicsContext3D::REPEAT)
|| (!isFloat && parami != GraphicsContext3D::CLAMP_TO_EDGE && parami != GraphicsContext3D::MIRRORED_REPEAT && parami != GraphicsContext3D::REPEAT)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter");
return;
}
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "texParameter", "invalid parameter name");
return;
}
if (isFloat) {
@@ -3463,19 +3520,19 @@ void WebGLRenderingContext::texSubImage2DBase(GC3Denum target, GC3Dint level, GC
ec = 0;
if (isContextLost())
return;
- if (!validateTexFuncParameters(target, level, format, width, height, 0, format, type))
+ if (!validateTexFuncParameters("texSubImage2D", target, level, format, width, height, 0, format, type))
return;
- if (!validateSize(xoffset, yoffset))
+ if (!validateSize("texSubImage2D", xoffset, yoffset))
return;
- WebGLTexture* tex = validateTextureBinding(target, true);
+ WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
if (!tex)
return;
if (xoffset + width > tex->getWidth(target, level) || yoffset + height > tex->getHeight(target, level)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "dimensions out of range");
return;
}
if (tex->getInternalFormat(target, level) != format || tex->getType(target, level) != type) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "texSubImage2D", "type and format do not match texture");
return;
}
m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
@@ -3491,7 +3548,7 @@ void WebGLRenderingContext::texSubImage2DImpl(GC3Denum target, GC3Dint level, GC
return;
Vector<uint8_t> data;
if (!m_context->extractImageData(image, format, type, flipY, premultiplyAlpha, m_unpackColorspaceConversion == GraphicsContext3D::NONE, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image");
return;
}
texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(),
@@ -3502,7 +3559,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
GC3Dsizei width, GC3Dsizei height,
GC3Denum format, GC3Denum type, ArrayBufferView* pixels, ExceptionCode& ec)
{
- if (isContextLost() || !validateTexFuncData(width, height, format, type, pixels))
+ if (isContextLost() || !validateTexFuncData("texSubImage2D", width, height, format, type, pixels))
return;
void* data = pixels ? pixels->baseAddress() : 0;
Vector<uint8_t> tempData;
@@ -3532,7 +3589,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
return;
Vector<uint8_t> data;
if (!m_context->extractImageData(pixels, format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "bad image data");
return;
}
texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(),
@@ -3545,7 +3602,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
ec = 0;
if (isContextLost())
return;
- if (!validateHTMLImageElement(image))
+ if (!validateHTMLImageElement("texSubImage2D", image))
return;
if (wouldTaintOrigin(image)) {
ec = SECURITY_ERR;
@@ -3562,7 +3619,7 @@ void WebGLRenderingContext::texSubImage2D(GC3Denum target, GC3Dint level, GC3Din
if (isContextLost())
return;
if (!canvas || !canvas->buffer()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "texSubImage2D", "no canvas");
return;
}
if (wouldTaintOrigin(canvas)) {
@@ -3598,7 +3655,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1f", "location not for current program");
return;
}
@@ -3609,7 +3666,7 @@ void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 1))
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
return;
m_context->uniform1fv(location->location(), v->data(), v->length());
@@ -3619,7 +3676,7 @@ void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
return;
m_context->uniform1fv(location->location(), v, size);
@@ -3633,7 +3690,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform1i", "location not for current program");
return;
}
@@ -3644,7 +3701,7 @@ void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 1))
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
return;
m_context->uniform1iv(location->location(), v->data(), v->length());
@@ -3654,7 +3711,7 @@ void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 1))
+ if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
return;
m_context->uniform1iv(location->location(), v, size);
@@ -3668,7 +3725,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2f", "location not for current program");
return;
}
@@ -3679,7 +3736,7 @@ void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 2))
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
return;
m_context->uniform2fv(location->location(), v->data(), v->length() / 2);
@@ -3689,7 +3746,7 @@ void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
return;
m_context->uniform2fv(location->location(), v, size / 2);
@@ -3703,7 +3760,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform2i", "location not for current program");
return;
}
@@ -3714,7 +3771,7 @@ void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 2))
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
return;
m_context->uniform2iv(location->location(), v->data(), v->length() / 2);
@@ -3724,7 +3781,7 @@ void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 2))
+ if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
return;
m_context->uniform2iv(location->location(), v, size / 2);
@@ -3738,7 +3795,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3f", "location not for current program");
return;
}
@@ -3749,7 +3806,7 @@ void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 3))
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
return;
m_context->uniform3fv(location->location(), v->data(), v->length() / 3);
@@ -3759,7 +3816,7 @@ void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
return;
m_context->uniform3fv(location->location(), v, size / 3);
@@ -3773,7 +3830,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform3i", "location not for current program");
return;
}
@@ -3784,7 +3841,7 @@ void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 3))
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
return;
m_context->uniform3iv(location->location(), v->data(), v->length() / 3);
@@ -3794,7 +3851,7 @@ void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 3))
+ if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
return;
m_context->uniform3iv(location->location(), v, size / 3);
@@ -3808,7 +3865,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4f", "location not for current program");
return;
}
@@ -3819,7 +3876,7 @@ void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 4))
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
return;
m_context->uniform4fv(location->location(), v->data(), v->length() / 4);
@@ -3829,7 +3886,7 @@ void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Flo
void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
return;
m_context->uniform4fv(location->location(), v, size / 4);
@@ -3843,7 +3900,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3D
return;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "uniform4i", "location not for current program");
return;
}
@@ -3854,7 +3911,7 @@ void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GC3D
void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, 4))
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
return;
m_context->uniform4iv(location->location(), v->data(), v->length() / 4);
@@ -3864,7 +3921,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int
void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3Dint* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformParameters(location, v, size, 4))
+ if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
return;
m_context->uniform4iv(location->location(), v, size / 4);
@@ -3874,7 +3931,7 @@ void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GC3
void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 4))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
return;
m_context->uniformMatrix2fv(location->location(), transpose, v->data(), v->length() / 4);
cleanupAfterGraphicsCall(false);
@@ -3883,7 +3940,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 4))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
return;
m_context->uniformMatrix2fv(location->location(), transpose, v, size / 4);
cleanupAfterGraphicsCall(false);
@@ -3892,7 +3949,7 @@ void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 9))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
return;
m_context->uniformMatrix3fv(location->location(), transpose, v->data(), v->length() / 9);
cleanupAfterGraphicsCall(false);
@@ -3901,7 +3958,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 9))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
return;
m_context->uniformMatrix3fv(location->location(), transpose, v, size / 9);
cleanupAfterGraphicsCall(false);
@@ -3910,7 +3967,7 @@ void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, 16))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
return;
m_context->uniformMatrix4fv(location->location(), transpose, v->data(), v->length() / 16);
cleanupAfterGraphicsCall(false);
@@ -3919,7 +3976,7 @@ void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* locatio
void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GC3Dboolean transpose, GC3Dfloat* v, GC3Dsizei size, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateUniformMatrixParameters(location, transpose, v, size, 16))
+ if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
return;
m_context->uniformMatrix4fv(location->location(), transpose, v, size / 16);
cleanupAfterGraphicsCall(false);
@@ -3929,18 +3986,18 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
bool deleted;
- if (!checkObjectToBeBound(program, deleted))
+ if (!checkObjectToBeBound("useProgram", program, deleted))
return;
if (deleted)
program = 0;
if (program && !program->getLinkStatus()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "useProgram", "program not valid");
cleanupAfterGraphicsCall(false);
return;
}
if (m_currentProgram != program) {
if (m_currentProgram)
- m_currentProgram->onDetached();
+ m_currentProgram->onDetached(graphicsContext3D());
m_currentProgram = program;
m_context->useProgram(objectOrZero(program));
if (program)
@@ -3952,7 +4009,7 @@ void WebGLRenderingContext::useProgram(WebGLProgram* program, ExceptionCode& ec)
void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode& ec)
{
UNUSED_PARAM(ec);
- if (isContextLost() || !validateWebGLObject(program))
+ if (isContextLost() || !validateWebGLObject("validateProgram", program))
return;
m_context->validateProgram(objectOrZero(program));
cleanupAfterGraphicsCall(false);
@@ -3960,62 +4017,62 @@ void WebGLRenderingContext::validateProgram(WebGLProgram* program, ExceptionCode
void WebGLRenderingContext::vertexAttrib1f(GC3Duint index, GC3Dfloat v0)
{
- vertexAttribfImpl(index, 1, v0, 0.0f, 0.0f, 1.0f);
+ vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
}
void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, Float32Array* v)
{
- vertexAttribfvImpl(index, v, 1);
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
}
void WebGLRenderingContext::vertexAttrib1fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
{
- vertexAttribfvImpl(index, v, size, 1);
+ vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
}
void WebGLRenderingContext::vertexAttrib2f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1)
{
- vertexAttribfImpl(index, 2, v0, v1, 0.0f, 1.0f);
+ vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
}
void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, Float32Array* v)
{
- vertexAttribfvImpl(index, v, 2);
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
}
void WebGLRenderingContext::vertexAttrib2fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
{
- vertexAttribfvImpl(index, v, size, 2);
+ vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
}
void WebGLRenderingContext::vertexAttrib3f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2)
{
- vertexAttribfImpl(index, 3, v0, v1, v2, 1.0f);
+ vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
}
void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, Float32Array* v)
{
- vertexAttribfvImpl(index, v, 3);
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
}
void WebGLRenderingContext::vertexAttrib3fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
{
- vertexAttribfvImpl(index, v, size, 3);
+ vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
}
void WebGLRenderingContext::vertexAttrib4f(GC3Duint index, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
{
- vertexAttribfImpl(index, 4, v0, v1, v2, v3);
+ vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
}
void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, Float32Array* v)
{
- vertexAttribfvImpl(index, v, 4);
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
}
void WebGLRenderingContext::vertexAttrib4fv(GC3Duint index, GC3Dfloat* v, GC3Dsizei size)
{
- vertexAttribfvImpl(index, v, size, 4);
+ vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
}
void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC3Denum type, GC3Dboolean normalized, GC3Dsizei stride, GC3Dintptr offset, ExceptionCode& ec)
@@ -4031,29 +4088,29 @@ void WebGLRenderingContext::vertexAttribPointer(GC3Duint index, GC3Dint size, GC
case GraphicsContext3D::FLOAT:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
return;
}
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "index out of range");
return;
}
if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
return;
}
if (!m_boundArrayBuffer) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
return;
}
// Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
unsigned int typeSize = sizeInBytes(type);
if (!typeSize) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, "vertexAttribPointer", "invalid type");
return;
}
if ((stride % typeSize) || (offset % typeSize)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
return;
}
GC3Dsizei bytesPerElement = size * typeSize;
@@ -4077,7 +4134,7 @@ void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3D
{
if (isContextLost())
return;
- if (!validateSize(width, height))
+ if (!validateSize("viewport", width, height))
return;
m_context->viewport(x, y, width, height);
cleanupAfterGraphicsCall(false);
@@ -4086,10 +4143,18 @@ void WebGLRenderingContext::viewport(GC3Dint x, GC3Dint y, GC3Dsizei width, GC3D
void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
{
if (isContextLost()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "loseContext", "context already lost");
return;
}
+ m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
+{
+ if (isContextLost())
+ return;
+
m_contextLost = true;
m_contextLostMode = mode;
@@ -4103,7 +4168,7 @@ void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextM
if (m_context->getError() == GraphicsContext3D::NO_ERROR)
break;
}
- m_context->synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL);
+ synthesizeGLError(GraphicsContext3D::CONTEXT_LOST_WEBGL, "loseContext", "context lost");
// Don't allow restoration unless the context lost event has both been
// dispatched and its default behavior prevented.
@@ -4117,13 +4182,13 @@ void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextM
void WebGLRenderingContext::forceRestoreContext()
{
if (!isContextLost()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context not lost");
return;
}
if (!m_restoreAllowed) {
if (m_contextLostMode == SyntheticLostContext)
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "restoreContext", "context restoration not allowed");
return;
}
@@ -4143,22 +4208,32 @@ PlatformLayer* WebGLRenderingContext::platformLayer() const
}
#endif
-void WebGLRenderingContext::removeObject(WebGLObject* object)
+void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
{
- m_canvasObjects.remove(object);
+ m_contextGroup->removeObject(object);
}
-void WebGLRenderingContext::addObject(WebGLObject* object)
+void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
{
ASSERT(!isContextLost());
- removeObject(object);
- m_canvasObjects.add(object);
+ m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
+{
+ m_contextObjects.remove(object);
+}
+
+void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
+{
+ ASSERT(!isContextLost());
+ m_contextObjects.add(object);
}
void WebGLRenderingContext::detachAndRemoveAllObjects()
{
- while (m_canvasObjects.size() > 0) {
- HashSet<WebGLObject*>::iterator it = m_canvasObjects.begin();
+ while (m_contextObjects.size() > 0) {
+ HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
(*it)->detachContext();
}
}
@@ -4344,7 +4419,7 @@ int WebGLRenderingContext::getBoundFramebufferHeight()
return m_drawingBuffer ? m_drawingBuffer->size().height() : m_context->getInternalFramebufferSize().height();
}
-WebGLTexture* WebGLRenderingContext::validateTextureBinding(GC3Denum target, bool useSixEnumsForCubeMap)
+WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap)
{
WebGLTexture* tex = 0;
switch (target) {
@@ -4358,58 +4433,58 @@ WebGLTexture* WebGLRenderingContext::validateTextureBinding(GC3Denum target, boo
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (!useSixEnumsForCubeMap) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
return 0;
}
tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
break;
case GraphicsContext3D::TEXTURE_CUBE_MAP:
if (useSixEnumsForCubeMap) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
return 0;
}
tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture target");
return 0;
}
if (!tex)
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no texture");
return tex;
}
-bool WebGLRenderingContext::validateLocationLength(const String& string)
+bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
{
const unsigned maxWebGLLocationLength = 256;
if (string.length() > maxWebGLLocationLength) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "location length > 256");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateSize(GC3Dint x, GC3Dint y)
+bool WebGLRenderingContext::validateSize(const char* functionName, GC3Dint x, GC3Dint y)
{
if (x < 0 || y < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "size < 0");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateString(const String& string)
+bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
{
for (size_t i = 0; i < string.length(); ++i) {
if (!validateCharacter(string[i])) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "string not ASCII");
return false;
}
}
return true;
}
-bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Denum type)
+bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type)
{
switch (format) {
case GraphicsContext3D::ALPHA:
@@ -4419,7 +4494,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
case GraphicsContext3D::RGBA:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture format");
return false;
}
@@ -4432,10 +4507,10 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
case GraphicsContext3D::FLOAT:
if (m_oesTextureFloat)
break;
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
return false;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid texture type");
return false;
}
@@ -4446,7 +4521,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
case GraphicsContext3D::LUMINANCE_ALPHA:
if (type != GraphicsContext3D::UNSIGNED_BYTE
&& type != GraphicsContext3D::FLOAT) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for format");
return false;
}
break;
@@ -4454,7 +4529,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
if (type != GraphicsContext3D::UNSIGNED_BYTE
&& type != GraphicsContext3D::UNSIGNED_SHORT_5_6_5
&& type != GraphicsContext3D::FLOAT) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGB format");
return false;
}
break;
@@ -4463,7 +4538,7 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
&& type != GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4
&& type != GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1
&& type != GraphicsContext3D::FLOAT) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "invalid type for RGBA format");
return false;
}
break;
@@ -4474,16 +4549,16 @@ bool WebGLRenderingContext::validateTexFuncFormatAndType(GC3Denum format, GC3Den
return true;
}
-bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level)
+bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level)
{
if (level < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level < 0");
return false;
}
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
if (level > m_maxTextureLevel) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
return false;
}
break;
@@ -4494,7 +4569,7 @@ bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level)
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (level > m_maxCubeMapTextureLevel) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "level out of range");
return false;
}
break;
@@ -4504,7 +4579,8 @@ bool WebGLRenderingContext::validateTexFuncLevel(GC3Denum target, GC3Dint level)
return true;
}
-bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint level,
+bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName,
+ GC3Denum target, GC3Dint level,
GC3Denum internalformat,
GC3Dsizei width, GC3Dsizei height, GC3Dint border,
GC3Denum format, GC3Denum type)
@@ -4512,18 +4588,18 @@ bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint l
// We absolutely have to validate the format and type combination.
// The texImage2D entry points taking HTMLImage, etc. will produce
// temporary data based on this combination, so it must be legal.
- if (!validateTexFuncFormatAndType(format, type) || !validateTexFuncLevel(target, level))
+ if (!validateTexFuncFormatAndType(functionName, format, type) || !validateTexFuncLevel(functionName, target, level))
return false;
if (width < 0 || height < 0) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height < 0");
return false;
}
switch (target) {
case GraphicsContext3D::TEXTURE_2D:
if (width > m_maxTextureSize || height > m_maxTextureSize) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width or height out of range");
return false;
}
break;
@@ -4534,42 +4610,43 @@ bool WebGLRenderingContext::validateTexFuncParameters(GC3Denum target, GC3Dint l
case GraphicsContext3D::TEXTURE_CUBE_MAP_POSITIVE_Z:
case GraphicsContext3D::TEXTURE_CUBE_MAP_NEGATIVE_Z:
if (width != height || width > m_maxCubeMapTextureSize) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "width != height or width or height out of range for cube map");
return false;
}
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
return false;
}
if (format != internalformat) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "format != internalformat");
return false;
}
if (border) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "border != 0");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei height,
+bool WebGLRenderingContext::validateTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
GC3Denum format, GC3Denum type,
ArrayBufferView* pixels)
{
if (!pixels)
return true;
- if (!validateTexFuncFormatAndType(format, type))
+ if (!validateTexFuncFormatAndType(functionName, format, type))
return false;
switch (type) {
case GraphicsContext3D::UNSIGNED_BYTE:
if (!pixels->isUnsignedByteArray()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
return false;
}
break;
@@ -4577,13 +4654,13 @@ bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei heigh
case GraphicsContext3D::UNSIGNED_SHORT_4_4_4_4:
case GraphicsContext3D::UNSIGNED_SHORT_5_5_5_1:
if (!pixels->isUnsignedShortArray()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
return false;
}
break;
case GraphicsContext3D::FLOAT: // OES_texture_float
if (!pixels->isFloatArray()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
return false;
}
break;
@@ -4594,17 +4671,17 @@ bool WebGLRenderingContext::validateTexFuncData(GC3Dsizei width, GC3Dsizei heigh
unsigned int totalBytesRequired;
GC3Denum error = m_context->computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
if (error != GraphicsContext3D::NO_ERROR) {
- m_context->synthesizeGLError(error);
+ synthesizeGLError(error, functionName, "invalid texture dimensions");
return false;
}
if (pixels->byteLength() < totalBytesRequired) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateDrawMode(GC3Denum mode)
+bool WebGLRenderingContext::validateDrawMode(const char* functionName, GC3Denum mode)
{
switch (mode) {
case GraphicsContext3D::POINTS:
@@ -4616,21 +4693,21 @@ bool WebGLRenderingContext::validateDrawMode(GC3Denum mode)
case GraphicsContext3D::TRIANGLES:
return true;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid draw mode");
return false;
}
}
-bool WebGLRenderingContext::validateStencilSettings()
+bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
{
if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "front and back stencils settings do not match");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateStencilFunc(GC3Denum func)
+bool WebGLRenderingContext::validateStencilFunc(const char* functionName, GC3Denum func)
{
switch (func) {
case GraphicsContext3D::NEVER:
@@ -4643,21 +4720,20 @@ bool WebGLRenderingContext::validateStencilFunc(GC3Denum func)
case GraphicsContext3D::ALWAYS:
return true;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid function");
return false;
}
}
void WebGLRenderingContext::printWarningToConsole(const String& message)
{
- canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel,
- message, 0, canvas()->document()->url().string());
+ canvas()->document()->frame()->domWindow()->console()->addMessage(HTMLMessageSource, LogMessageType, WarningMessageLevel, message, canvas()->document()->url().string());
}
-bool WebGLRenderingContext::validateFramebufferFuncParameters(GC3Denum target, GC3Denum attachment)
+bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment)
{
if (target != GraphicsContext3D::FRAMEBUFFER) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
return false;
}
switch (attachment) {
@@ -4667,13 +4743,13 @@ bool WebGLRenderingContext::validateFramebufferFuncParameters(GC3Denum target, G
case GraphicsContext3D::DEPTH_STENCIL_ATTACHMENT:
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid attachment");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateBlendEquation(GC3Denum mode)
+bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GC3Denum mode)
{
switch (mode) {
case GraphicsContext3D::FUNC_ADD:
@@ -4681,24 +4757,24 @@ bool WebGLRenderingContext::validateBlendEquation(GC3Denum mode)
case GraphicsContext3D::FUNC_REVERSE_SUBTRACT:
return true;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid mode");
return false;
}
}
-bool WebGLRenderingContext::validateBlendFuncFactors(GC3Denum src, GC3Denum dst)
+bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst)
{
if (((src == GraphicsContext3D::CONSTANT_COLOR || src == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
&& (dst == GraphicsContext3D::CONSTANT_ALPHA || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))
|| ((dst == GraphicsContext3D::CONSTANT_COLOR || dst == GraphicsContext3D::ONE_MINUS_CONSTANT_COLOR)
&& (src == GraphicsContext3D::CONSTANT_ALPHA || src == GraphicsContext3D::ONE_MINUS_CONSTANT_ALPHA))) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "incompatible src and dst");
return false;
}
return true;
}
-bool WebGLRenderingContext::validateCapability(GC3Denum cap)
+bool WebGLRenderingContext::validateCapability(const char* functionName, GC3Denum cap)
{
switch (cap) {
case GraphicsContext3D::BLEND:
@@ -4712,67 +4788,67 @@ bool WebGLRenderingContext::validateCapability(GC3Denum cap)
case GraphicsContext3D::STENCIL_TEST:
return true;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid capability");
return false;
}
}
-bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GC3Dsizei requiredMinSize)
{
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return false;
}
- return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
}
-bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GC3Dsizei requiredMinSize)
{
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return false;
}
- return validateUniformMatrixParameters(location, false, v->data(), v->length(), requiredMinSize);
+ return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
}
-bool WebGLRenderingContext::validateUniformParameters(const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
{
- return validateUniformMatrixParameters(location, false, v, size, requiredMinSize);
+ return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
}
-bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, Float32Array* v, GC3Dsizei requiredMinSize)
{
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return false;
}
- return validateUniformMatrixParameters(location, transpose, v->data(), v->length(), requiredMinSize);
+ return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
}
-bool WebGLRenderingContext::validateUniformMatrixParameters(const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
+bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GC3Dboolean transpose, void* v, GC3Dsizei size, GC3Dsizei requiredMinSize)
{
if (!location)
return false;
if (location->program() != m_currentProgram) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "location is not from current program");
return false;
}
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return false;
}
if (transpose) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "transpose not FALSE");
return false;
}
if (size < requiredMinSize || (size % requiredMinSize)) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
return false;
}
return true;
}
-WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target, GC3Denum usage)
+WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage)
{
WebGLBuffer* buffer = 0;
switch (target) {
@@ -4783,11 +4859,11 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target
buffer = m_boundArrayBuffer.get();
break;
default:
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid target");
return 0;
}
if (!buffer) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, functionName, "no buffer");
return 0;
}
switch (usage) {
@@ -4796,30 +4872,30 @@ WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(GC3Denum target
case GraphicsContext3D::DYNAMIC_DRAW:
return buffer;
}
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_ENUM);
+ synthesizeGLError(GraphicsContext3D::INVALID_ENUM, functionName, "invalid usage");
return 0;
}
-bool WebGLRenderingContext::validateHTMLImageElement(HTMLImageElement* image)
+bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image)
{
if (!image || !image->cachedImage()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no image");
return false;
}
const KURL& url = image->cachedImage()->response().url();
if (url.isNull() || url.isEmpty() || !url.isValid()) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid image");
return false;
}
return true;
}
-void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
+void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat v0, GC3Dfloat v1, GC3Dfloat v2, GC3Dfloat v3)
{
if (isContextLost())
return;
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
return;
}
// In GL, we skip setting vertexAttrib0 values.
@@ -4847,31 +4923,31 @@ void WebGLRenderingContext::vertexAttribfImpl(GC3Duint index, GC3Dsizei expected
attribValue.value[3] = v3;
}
-void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
+void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array* v, GC3Dsizei expectedSize)
{
if (isContextLost())
return;
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return;
}
- vertexAttribfvImpl(index, v->data(), v->length(), expectedSize);
+ vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
}
-void WebGLRenderingContext::vertexAttribfvImpl(GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
+void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat* v, GC3Dsizei size, GC3Dsizei expectedSize)
{
if (isContextLost())
return;
if (!v) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "no array");
return;
}
if (size < expectedSize) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "invalid size");
return;
}
if (index >= m_maxVertexAttribs) {
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_VALUE);
+ synthesizeGLError(GraphicsContext3D::INVALID_VALUE, functionName, "index out of range");
return;
}
// In GL, we skip setting vertexAttrib0 values.
@@ -5030,7 +5106,7 @@ void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
else
// This likely shouldn't happen but is the best way to report it to the WebGL app.
- m_context->synthesizeGLError(GraphicsContext3D::INVALID_OPERATION);
+ synthesizeGLError(GraphicsContext3D::INVALID_OPERATION, "", "error restoring context");
return;
}
@@ -5083,6 +5159,40 @@ void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
m_buffers[i].swap(m_buffers[i-1]);
}
+namespace {
+
+ String GetErrorString(GC3Denum error)
+ {
+ switch (error) {
+ case GraphicsContext3D::INVALID_ENUM:
+ return "INVALID_ENUM";
+ case GraphicsContext3D::INVALID_VALUE:
+ return "INVALID_VALUE";
+ case GraphicsContext3D::INVALID_OPERATION:
+ return "INVALID_OPERATION";
+ case GraphicsContext3D::OUT_OF_MEMORY:
+ return "OUT_OF_MEMORY";
+ case GraphicsContext3D::INVALID_FRAMEBUFFER_OPERATION:
+ return "INVALID_FRAMEBUFFER_OPERATION";
+ case GraphicsContext3D::CONTEXT_LOST_WEBGL:
+ return "CONTEXT_LOST_WEBGL";
+ default:
+ return String::format("WebGL ERROR(%04x)", error);
+ }
+ }
+
+} // namespace anonymous
+
+void WebGLRenderingContext::synthesizeGLError(GC3Denum error, const char* functionName, const char* description)
+{
+ if (m_synthesizedErrorsToConsole) {
+ String str = String("WebGL: ") + GetErrorString(error) + ": " + String(functionName) + ": " + String(description);
+ printWarningToConsole(str);
+ }
+ m_context->synthesizeGLError(error);
+}
+
+
} // namespace WebCore
#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.h b/Source/WebCore/html/canvas/WebGLRenderingContext.h
index 8f1efd9b0..620b4d4e6 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.h
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.h
@@ -50,6 +50,8 @@ class OESTextureFloat;
class OESVertexArrayObject;
class WebGLActiveInfo;
class WebGLBuffer;
+class WebGLContextGroup;
+class WebGLContextObject;
class WebGLCompressedTextures;
class WebGLContextAttributes;
class WebGLDebugRendererInfo;
@@ -61,6 +63,7 @@ class WebGLObject;
class WebGLProgram;
class WebGLRenderbuffer;
class WebGLShader;
+class WebGLSharedObject;
class WebGLTexture;
class WebGLUniformLocation;
class WebGLVertexArrayObjectOES;
@@ -106,8 +109,10 @@ public:
void colorMask(GC3Dboolean red, GC3Dboolean green, GC3Dboolean blue, GC3Dboolean alpha);
void compileShader(WebGLShader*, ExceptionCode&);
- // void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width, GC3Dsizei height, GC3Dint border, GC3Dsizei imageSize, const void* data);
- // void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dsizei width, GC3Dsizei GC3Dsizei height, GC3Denum format, GC3Dsizei imageSize, const void* data);
+ void compressedTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dsizei width,
+ GC3Dsizei height, GC3Dint border, ArrayBufferView* data);
+ void compressedTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset,
+ GC3Dsizei width, GC3Dsizei height, GC3Denum format, ArrayBufferView* data);
void copyTexImage2D(GC3Denum target, GC3Dint level, GC3Denum internalformat, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height, GC3Dint border);
void copyTexSubImage2D(GC3Denum target, GC3Dint level, GC3Dint xoffset, GC3Dint yoffset, GC3Dint x, GC3Dint y, GC3Dsizei width, GC3Dsizei height);
@@ -292,8 +297,10 @@ public:
};
void forceLostContext(LostContextMode);
void forceRestoreContext();
+ void loseContextImpl(LostContextMode);
GraphicsContext3D* graphicsContext3D() const { return m_context.get(); }
+ WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
#if USE(ACCELERATED_COMPOSITING)
virtual PlatformLayer* platformLayer() const;
#endif
@@ -304,7 +311,8 @@ public:
virtual void paintRenderingResultsToCanvas();
virtual PassRefPtr<ImageData> paintRenderingResultsToImageData();
- void removeObject(WebGLObject*);
+ void removeSharedObject(WebGLSharedObject*);
+ void removeContextObject(WebGLContextObject*);
unsigned getMaxVertexAttribs() const { return m_maxVertexAttribs; }
@@ -314,12 +322,14 @@ public:
friend class OESVertexArrayObject;
friend class WebGLDebugShaders;
friend class WebGLCompressedTextures;
+ friend class WebGLRenderingContextErrorMessageCallback;
WebGLRenderingContext(HTMLCanvasElement*, PassRefPtr<GraphicsContext3D>, GraphicsContext3D::Attributes);
void initializeNewContext();
void setupFlags();
- void addObject(WebGLObject*);
+ void addSharedObject(WebGLSharedObject*);
+ void addContextObject(WebGLContextObject*);
void detachAndRemoveAllObjects();
void markContextChanged();
@@ -355,13 +365,14 @@ public:
// If numElements <= 0, we only check if each enabled vertex attribute is bound to a buffer.
bool validateRenderingState(int numElements);
- bool validateWebGLObject(WebGLObject*);
+ bool validateWebGLObject(const char*, WebGLObject*);
#if ENABLE(VIDEO)
PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, ExceptionCode&);
#endif
RefPtr<GraphicsContext3D> m_context;
+ RefPtr<WebGLContextGroup> m_contextGroup;
// Optional structure for rendering to a DrawingBuffer, instead of directly
// to the back-buffer of m_context.
@@ -378,7 +389,7 @@ public:
bool m_needsUpdate;
bool m_markedCanvasDirty;
- HashSet<WebGLObject*> m_canvasObjects;
+ HashSet<WebGLContextObject*> m_contextObjects;
// List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
RefPtr<WebGLBuffer> m_boundArrayBuffer;
@@ -480,6 +491,8 @@ public:
bool m_isResourceSafe;
bool m_isDepthStencilSupported;
+ bool m_synthesizedErrorsToConsole;
+
// Enabled extension objects.
OwnPtr<OESTextureFloat> m_oesTextureFloat;
OwnPtr<OESStandardDerivatives> m_oesStandardDerivatives;
@@ -536,32 +549,33 @@ public:
int getBoundFramebufferHeight();
// Helper function to verify limits on the length of uniform and attribute locations.
- bool validateLocationLength(const String&);
+ bool validateLocationLength(const char* functionName, const String&);
// Helper function to check if size is non-negative.
// Generate GL error and return false for negative inputs; otherwise, return true.
- bool validateSize(GC3Dint x, GC3Dint y);
+ bool validateSize(const char* functionName, GC3Dint x, GC3Dint y);
// Helper function to check if all characters in the string belong to the
// ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
- bool validateString(const String&);
+ bool validateString(const char* functionName, const String&);
// Helper function to check target and texture bound to the target.
// Generate GL errors and return 0 if target is invalid or texture bound is
// null. Otherwise, return the texture bound to the target.
- WebGLTexture* validateTextureBinding(GC3Denum target, bool useSixEnumsForCubeMap);
+ WebGLTexture* validateTextureBinding(const char* functionName, GC3Denum target, bool useSixEnumsForCubeMap);
// Helper function to check input format/type for functions {copy}Tex{Sub}Image.
// Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncFormatAndType(GC3Denum format, GC3Denum type);
+ bool validateTexFuncFormatAndType(const char* functionName, GC3Denum format, GC3Denum type);
// Helper function to check input level for functions {copy}Tex{Sub}Image.
// Generates GL error and returns false if level is invalid.
- bool validateTexFuncLevel(GC3Denum target, GC3Dint level);
+ bool validateTexFuncLevel(const char* functionName, GC3Denum target, GC3Dint level);
// Helper function to check input parameters for functions {copy}Tex{Sub}Image.
// Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncParameters(GC3Denum target, GC3Dint level,
+ bool validateTexFuncParameters(const char* functionName,
+ GC3Denum target, GC3Dint level,
GC3Denum internalformat,
GC3Dsizei width, GC3Dsizei height, GC3Dint border,
GC3Denum format, GC3Denum type);
@@ -569,18 +583,19 @@ public:
// Helper function to validate that the given ArrayBufferView
// is of the correct type and contains enough data for the texImage call.
// Generates GL error and returns false if parameters are invalid.
- bool validateTexFuncData(GC3Dsizei width, GC3Dsizei height,
+ bool validateTexFuncData(const char* functionName,
+ GC3Dsizei width, GC3Dsizei height,
GC3Denum format, GC3Denum type,
ArrayBufferView* pixels);
// Helper function to validate mode for draw{Arrays/Elements}.
- bool validateDrawMode(GC3Denum);
+ bool validateDrawMode(const char* functionName, GC3Denum);
// Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
- bool validateStencilSettings();
+ bool validateStencilSettings(const char* functionName);
// Helper function to validate stencil func.
- bool validateStencilFunc(GC3Denum);
+ bool validateStencilFunc(const char* functionName, GC3Denum);
// Helper function for texParameterf and texParameteri.
void texParameter(GC3Denum target, GC3Denum pname, GC3Dfloat parami, GC3Dint paramf, bool isFloat);
@@ -591,35 +606,35 @@ public:
// Helper function to validate input parameters for framebuffer functions.
// Generate GL error if parameters are illegal.
- bool validateFramebufferFuncParameters(GC3Denum target, GC3Denum attachment);
+ bool validateFramebufferFuncParameters(const char* functionName, GC3Denum target, GC3Denum attachment);
// Helper function to validate blend equation mode.
- bool validateBlendEquation(GC3Denum);
+ bool validateBlendEquation(const char* functionName, GC3Denum);
// Helper function to validate blend func factors.
- bool validateBlendFuncFactors(GC3Denum src, GC3Denum dst);
+ bool validateBlendFuncFactors(const char* functionName, GC3Denum src, GC3Denum dst);
// Helper function to validate a GL capability.
- bool validateCapability(GC3Denum);
+ bool validateCapability(const char* functionName, GC3Denum);
// Helper function to validate input parameters for uniform functions.
- bool validateUniformParameters(const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
- bool validateUniformParameters(const WebGLUniformLocation*, void*, GC3Dsizei size, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
- bool validateUniformMatrixParameters(const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei size, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GC3Dsizei mod);
+ bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GC3Dsizei, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, Float32Array*, GC3Dsizei mod);
+ bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GC3Dboolean transpose, void*, GC3Dsizei, GC3Dsizei mod);
// Helper function to validate parameters for bufferData.
// Return the current bound buffer to target, or 0 if parameters are invalid.
- WebGLBuffer* validateBufferDataParameters(GC3Denum target, GC3Denum usage);
+ WebGLBuffer* validateBufferDataParameters(const char* functionName, GC3Denum target, GC3Denum usage);
// Helper function for tex{Sub}Image2D to make sure image is ready.
- bool validateHTMLImageElement(HTMLImageElement*);
+ bool validateHTMLImageElement(const char* functionName, HTMLImageElement*);
// Helper functions for vertexAttribNf{v}.
- void vertexAttribfImpl(GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
- void vertexAttribfvImpl(GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
- void vertexAttribfvImpl(GC3Duint index, GC3Dfloat*, GC3Dsizei size, GC3Dsizei expectedSize);
+ void vertexAttribfImpl(const char* functionName, GC3Duint index, GC3Dsizei expectedSize, GC3Dfloat, GC3Dfloat, GC3Dfloat, GC3Dfloat);
+ void vertexAttribfvImpl(const char* functionName, GC3Duint index, Float32Array*, GC3Dsizei expectedSize);
+ void vertexAttribfvImpl(const char* functionName, GC3Duint index, GC3Dfloat*, GC3Dsizei, GC3Dsizei expectedSize);
// Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
// Return false if caller should return without further processing.
@@ -628,7 +643,7 @@ public:
// Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
// If the object has already been deleted, set deleted to true upon return.
// Return false if caller should return without further processing.
- bool checkObjectToBeBound(WebGLObject*, bool& deleted);
+ bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
// Helpers for simulating vertexAttrib0
void initVertexAttrib0();
@@ -643,6 +658,10 @@ public:
// a Safari or Chrome extension.
bool allowPrivilegedExtensions() const;
+ // Wrapper for GraphicsContext3D::synthesizeGLError that sends a message
+ // to the JavaScript console.
+ void synthesizeGLError(GC3Denum, const char* functionName, const char* description);
+
friend class WebGLStateRestorer;
};
diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.idl b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
index 5103af01a..16aae17b0 100644
--- a/Source/WebCore/html/canvas/WebGLRenderingContext.idl
+++ b/Source/WebCore/html/canvas/WebGLRenderingContext.idl
@@ -27,8 +27,6 @@ module html {
interface [
Conditional=WEBGL,
- InterfaceUUID=98fb48ae-7216-489c-862b-8e1217fc4443,
- ImplementationUUID=ab4f0781-152f-450e-9546-5b3987491a54,
CustomMarkFunction,
DontCheckEnums
] WebGLRenderingContext : CanvasRenderingContext {
@@ -478,9 +476,11 @@ module html {
[StrictTypeChecking] void clearStencil(in long s);
[StrictTypeChecking] void colorMask(in boolean red, in boolean green, in boolean blue, in boolean alpha);
[StrictTypeChecking] void compileShader(in WebGLShader shader) raises(DOMException);
-
- //void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in unsigned long width, in unsigned long height, in long border, in unsigned long imageSize, const void* data);
- //void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in unsigned long width, in unsigned long height, in unsigned long format, in unsigned long imageSize, const void* data);
+
+ [StrictTypeChecking] void compressedTexImage2D(in unsigned long target, in long level, in unsigned long internalformat,
+ in long width, in long height, in long border, in ArrayBufferView data);
+ [StrictTypeChecking] void compressedTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset,
+ in long width, in long height, in unsigned long format, in ArrayBufferView data);
[StrictTypeChecking] void copyTexImage2D(in unsigned long target, in long level, in unsigned long internalformat, in long x, in long y, in long width, in long height, in long border);
[StrictTypeChecking] void copyTexSubImage2D(in unsigned long target, in long level, in long xoffset, in long yoffset, in long x, in long y, in long width, in long height);
diff --git a/Source/WebCore/html/canvas/WebGLShader.cpp b/Source/WebCore/html/canvas/WebGLShader.cpp
index 59695e4c9..35068ebcd 100644
--- a/Source/WebCore/html/canvas/WebGLShader.cpp
+++ b/Source/WebCore/html/canvas/WebGLShader.cpp
@@ -29,6 +29,7 @@
#include "WebGLShader.h"
+#include "WebGLContextGroup.h"
#include "WebGLRenderingContext.h"
namespace WebCore {
@@ -39,16 +40,21 @@ PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GC3Denum
}
WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GC3Denum type)
- : WebGLObject(ctx)
+ : WebGLSharedObject(ctx)
, m_type(type)
, m_source("")
{
- setObject(context()->graphicsContext3D()->createShader(type));
+ setObject(ctx->graphicsContext3D()->createShader(type));
}
-void WebGLShader::deleteObjectImpl(Platform3DObject object)
+WebGLShader::~WebGLShader()
{
- context()->graphicsContext3D()->deleteShader(object);
+ deleteObject(0);
+}
+
+void WebGLShader::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ context3d->deleteShader(object);
}
}
diff --git a/Source/WebCore/html/canvas/WebGLShader.h b/Source/WebCore/html/canvas/WebGLShader.h
index 1d7a10c1c..92d1d1c48 100644
--- a/Source/WebCore/html/canvas/WebGLShader.h
+++ b/Source/WebCore/html/canvas/WebGLShader.h
@@ -26,16 +26,16 @@
#ifndef WebGLShader_h
#define WebGLShader_h
-#include "WebGLObject.h"
+#include "WebGLSharedObject.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLShader : public WebGLObject {
+class WebGLShader : public WebGLSharedObject {
public:
- virtual ~WebGLShader() { deleteObject(); }
+ virtual ~WebGLShader();
static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GC3Denum);
@@ -47,7 +47,7 @@ public:
private:
WebGLShader(WebGLRenderingContext*, GC3Denum);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
virtual bool isShader() const { return true; }
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.cpp b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
new file mode 100644
index 000000000..9f76cae77
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.cpp
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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"
+
+#if ENABLE(WEBGL)
+
+#include "WebGLSharedObject.h"
+
+#include "WebGLContextGroup.h"
+#include "WebGLRenderingContext.h"
+
+namespace WebCore {
+
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
+ : WebGLObject(context),
+ m_contextGroup(context->contextGroup())
+{
+}
+
+WebGLSharedObject::~WebGLSharedObject()
+{
+ if (m_contextGroup)
+ m_contextGroup->removeObject(this);
+}
+
+void WebGLSharedObject::detachContextGroup()
+{
+ detach();
+ if (m_contextGroup) {
+ deleteObject(0);
+ m_contextGroup->removeObject(this);
+ m_contextGroup = 0;
+ }
+}
+
+GraphicsContext3D* WebGLSharedObject::getAGraphicsContext3D() const
+{
+ return m_contextGroup ? m_contextGroup->getAGraphicsContext3D() : 0;
+}
+
+}
+
+#endif // ENABLE(WEBGL)
diff --git a/Source/WebCore/html/canvas/WebGLSharedObject.h b/Source/WebCore/html/canvas/WebGLSharedObject.h
new file mode 100644
index 000000000..559661332
--- /dev/null
+++ b/Source/WebCore/html/canvas/WebGLSharedObject.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2011 Apple 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 COMPUTER, INC. ``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 COMPUTER, INC. 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.
+ */
+
+#ifndef WebGLSharedObject_h
+#define WebGLSharedObject_h
+
+#include "WebGLObject.h"
+
+namespace WebCore {
+
+class GraphicsContext3D;
+class WebGLContextGroup;
+class WebGLRenderingContext;
+
+// WebGLSharedObject the base class for objects that can be shared by multiple
+// WebGLRenderingContexts.
+class WebGLSharedObject : public WebGLObject {
+public:
+ virtual ~WebGLSharedObject();
+
+ WebGLContextGroup* contextGroup() const { return m_contextGroup; }
+
+ virtual bool isBuffer() const { return false; }
+ virtual bool isFramebuffer() const { return false; }
+ virtual bool isProgram() const { return false; }
+ virtual bool isRenderbuffer() const { return false; }
+ virtual bool isShader() const { return false; }
+ virtual bool isTexture() const { return false; }
+
+ virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const
+ {
+ return contextGroup == m_contextGroup;
+ }
+
+ void detachContextGroup();
+
+protected:
+ WebGLSharedObject(WebGLRenderingContext*);
+
+ virtual bool hasGroupOrContext() const
+ {
+ return m_contextGroup;
+ }
+
+ virtual GraphicsContext3D* getAGraphicsContext3D() const;
+
+private:
+ WebGLContextGroup* m_contextGroup;
+};
+
+} // namespace WebCore
+
+#endif // WebGLSharedObject_h
diff --git a/Source/WebCore/html/canvas/WebGLTexture.cpp b/Source/WebCore/html/canvas/WebGLTexture.cpp
index e8e8bf824..9ad58b4bc 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.cpp
+++ b/Source/WebCore/html/canvas/WebGLTexture.cpp
@@ -29,6 +29,7 @@
#include "WebGLTexture.h"
+#include "WebGLContextGroup.h"
#include "WebGLFramebuffer.h"
#include "WebGLRenderingContext.h"
@@ -40,7 +41,7 @@ PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
}
WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
- : WebGLObject(ctx)
+ : WebGLSharedObject(ctx)
, m_target(0)
, m_minFilter(GraphicsContext3D::NEAREST_MIPMAP_LINEAR)
, m_magFilter(GraphicsContext3D::LINEAR)
@@ -50,7 +51,12 @@ WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
, m_isComplete(false)
, m_needToUseBlackTexture(false)
{
- setObject(context()->graphicsContext3D()->createTexture());
+ setObject(ctx->graphicsContext3D()->createTexture());
+}
+
+WebGLTexture::~WebGLTexture()
+{
+ deleteObject(0);
}
void WebGLTexture::setTarget(GC3Denum target, GC3Dint maxLevel)
@@ -225,9 +231,9 @@ bool WebGLTexture::needToUseBlackTexture() const
return m_needToUseBlackTexture;
}
-void WebGLTexture::deleteObjectImpl(Platform3DObject object)
+void WebGLTexture::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
{
- context()->graphicsContext3D()->deleteTexture(object);
+ context3d->deleteTexture(object);
}
int WebGLTexture::mapTargetToIndex(GC3Denum target) const
diff --git a/Source/WebCore/html/canvas/WebGLTexture.h b/Source/WebCore/html/canvas/WebGLTexture.h
index 6bd12723c..d1db951ff 100644
--- a/Source/WebCore/html/canvas/WebGLTexture.h
+++ b/Source/WebCore/html/canvas/WebGLTexture.h
@@ -26,7 +26,7 @@
#ifndef WebGLTexture_h
#define WebGLTexture_h
-#include "WebGLObject.h"
+#include "WebGLSharedObject.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -34,9 +34,9 @@
namespace WebCore {
-class WebGLTexture : public WebGLObject {
+class WebGLTexture : public WebGLSharedObject {
public:
- virtual ~WebGLTexture() { deleteObject(); }
+ virtual ~WebGLTexture();
static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
@@ -73,7 +73,7 @@ public:
protected:
WebGLTexture(WebGLRenderingContext*);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
private:
class LevelInfo {
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
index d14c96c01..4aa03b8fe 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -40,7 +40,7 @@ PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRen
}
WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
- : WebGLObject(ctx)
+ : WebGLContextObject(ctx)
, m_type(type)
, m_hasEverBeenBound(false)
, m_boundElementArrayBuffer(0)
@@ -57,9 +57,14 @@ WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx,
}
}
-void WebGLVertexArrayObjectOES::deleteObjectImpl(Platform3DObject object)
+WebGLVertexArrayObjectOES::~WebGLVertexArrayObjectOES()
{
- Extensions3D* extensions = context()->graphicsContext3D()->getExtensions();
+ deleteObject(0);
+}
+
+void WebGLVertexArrayObjectOES::deleteObjectImpl(GraphicsContext3D* context3d, Platform3DObject object)
+{
+ Extensions3D* extensions = context3d->getExtensions();
switch (m_type) {
case VaoTypeDefault:
break;
diff --git a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
index f49a78069..75ae42ff7 100644
--- a/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/Source/WebCore/html/canvas/WebGLVertexArrayObjectOES.h
@@ -27,21 +27,21 @@
#define WebGLVertexArrayObjectOES_h
#include "WebGLBuffer.h"
-#include "WebGLObject.h"
+#include "WebGLContextObject.h"
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
namespace WebCore {
-class WebGLVertexArrayObjectOES : public WebGLObject {
+class WebGLVertexArrayObjectOES : public WebGLContextObject {
public:
enum VaoType {
VaoTypeDefault,
VaoTypeUser,
};
- virtual ~WebGLVertexArrayObjectOES() { deleteObject(); }
+ virtual ~WebGLVertexArrayObjectOES();
static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
@@ -83,7 +83,7 @@ public:
private:
WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
- virtual void deleteObjectImpl(Platform3DObject);
+ virtual void deleteObjectImpl(GraphicsContext3D*, Platform3DObject);
virtual bool isVertexArray() const { return true; }
diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
index f91190d91..29f1ccd46 100644
--- a/Source/WebCore/html/parser/CSSPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp
@@ -38,6 +38,7 @@ namespace WebCore {
CSSPreloadScanner::CSSPreloadScanner(Document* document)
: m_state(Initial)
+ , m_scanningBody(false)
, m_document(document)
{
}
diff --git a/Source/WebCore/html/parser/HTMLConstructionSite.cpp b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
index 8cd8f40fd..0ee89f152 100644
--- a/Source/WebCore/html/parser/HTMLConstructionSite.cpp
+++ b/Source/WebCore/html/parser/HTMLConstructionSite.cpp
@@ -118,9 +118,10 @@ void HTMLConstructionSite::attachLater(ContainerNode* parent, PassRefPtr<Node> p
}
// Add as a sibling of the parent if we have reached the maximum depth allowed.
- if (m_openElements.stackDepth() > m_maximumDOMTreeDepth)
+ if (m_openElements.stackDepth() > m_maximumDOMTreeDepth && task.parent->parentNode())
task.parent = task.parent->parentNode();
+ ASSERT(task.parent);
m_attachmentQueue.append(task);
}
@@ -196,7 +197,8 @@ void HTMLConstructionSite::insertHTMLHtmlStartTagBeforeHTML(AtomicHTMLToken& tok
element->parserSetAttributeMap(token.takeAttributes(), m_fragmentScriptingPermission);
attachLater(m_attachmentRoot, element);
m_openElements.pushHTMLHtmlElement(element);
- // FIXME: We probably need to call executeQueuedTasks() before calling these methods.
+
+ executeQueuedTasks();
element->insertedByParser();
dispatchDocumentElementAvailableIfNeeded();
}
@@ -206,7 +208,7 @@ void HTMLConstructionSite::mergeAttributesFromTokenIntoElement(AtomicHTMLToken&
if (!token.attributes())
return;
- NamedNodeMap* attributes = element->attributes(false);
+ NamedNodeMap* attributes = element->ensureUpdatedAttributes();
for (unsigned i = 0; i < token.attributes()->length(); ++i) {
Attribute* attribute = token.attributes()->attributeItem(i);
if (!attributes->getAttributeItem(attribute->name()))
@@ -423,7 +425,7 @@ namespace {
// FIXME: Move this function to the top of the file.
inline PassOwnPtr<NamedNodeMap> cloneAttributes(Element* element)
{
- NamedNodeMap* attributes = element->attributes(true);
+ NamedNodeMap* attributes = element->updatedAttributes();
if (!attributes)
return nullptr;
@@ -527,6 +529,7 @@ void HTMLConstructionSite::fosterParent(PassRefPtr<Node> node)
HTMLConstructionSiteTask task;
findFosterSite(task);
task.child = node;
+ ASSERT(task.parent);
m_attachmentQueue.append(task);
}
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
index b9421d884..cc1491092 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
@@ -47,7 +47,7 @@ namespace {
class PreloadTask {
public:
- PreloadTask(const HTMLToken& token)
+ explicit PreloadTask(const HTMLToken& token)
: m_tagName(token.name().data(), token.name().size())
, m_linkIsStyleSheet(false)
, m_linkMediaAttributeIsScreen(true)
@@ -61,7 +61,8 @@ public:
if (m_tagName != imgTag
&& m_tagName != inputTag
&& m_tagName != linkTag
- && m_tagName != scriptTag)
+ && m_tagName != scriptTag
+ && m_tagName != baseTag)
return;
for (HTMLToken::AttributeList::const_iterator iter = attributes.begin();
@@ -87,6 +88,9 @@ public:
setUrlToLoad(attributeValue);
else if (attributeName == typeAttr)
m_inputIsImage = equalIgnoringCase(attributeValue, InputTypeNames::image());
+ } else if (m_tagName == baseTag) {
+ if (attributeName == hrefAttr)
+ m_baseElementHref = stripLeadingAndTrailingHTMLSpaces(attributeValue);
}
}
}
@@ -119,13 +123,13 @@ public:
m_urlToLoad = stripLeadingAndTrailingHTMLSpaces(attributeValue);
}
- void preload(Document* document, bool scanningBody)
+ void preload(Document* document, bool scanningBody, const KURL& baseURL)
{
if (m_urlToLoad.isEmpty())
return;
CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
- ResourceRequest request = document->completeURL(m_urlToLoad);
+ ResourceRequest request = document->completeURL(m_urlToLoad, baseURL);
if (m_tagName == scriptTag)
cachedResourceLoader->preload(CachedResource::Script, request, m_charset, scanningBody);
else if (m_tagName == imgTag || (m_tagName == inputTag && m_inputIsImage))
@@ -135,11 +139,13 @@ public:
}
const AtomicString& tagName() const { return m_tagName; }
+ const String& baseElementHref() const { return m_baseElementHref; }
private:
AtomicString m_tagName;
String m_urlToLoad;
String m_charset;
+ String m_baseElementHref;
bool m_linkIsStyleSheet;
bool m_linkMediaAttributeIsScreen;
bool m_inputIsImage;
@@ -163,6 +169,9 @@ void HTMLPreloadScanner::appendToEnd(const SegmentedString& source)
void HTMLPreloadScanner::scan()
{
+ // When we start scanning, our best prediction of the baseElementURL is the real one!
+ m_predictedBaseElementURL = m_document->baseElementURL();
+
// FIXME: We should save and re-use these tokens in HTMLDocumentParser if
// the pending script doesn't end up calling document.write.
while (m_tokenizer->nextToken(m_source, m_token)) {
@@ -194,7 +203,10 @@ void HTMLPreloadScanner::processToken()
if (task.tagName() == styleTag)
m_inStyle = true;
- task.preload(m_document, scanningBody());
+ if (task.tagName() == baseTag)
+ updatePredictedBaseElementURL(KURL(m_document->url(), task.baseElementHref()));
+
+ task.preload(m_document, scanningBody(), m_predictedBaseElementURL.isEmpty() ? m_document->baseURL() : m_predictedBaseElementURL);
}
bool HTMLPreloadScanner::scanningBody() const
@@ -202,4 +214,12 @@ bool HTMLPreloadScanner::scanningBody() const
return m_document->body() || m_bodySeen;
}
+void HTMLPreloadScanner::updatePredictedBaseElementURL(const KURL& baseElementURL)
+{
+ // The first <base> element is the one that wins.
+ if (!m_predictedBaseElementURL.isEmpty())
+ return;
+ m_predictedBaseElementURL = baseElementURL;
+}
+
}
diff --git a/Source/WebCore/html/parser/HTMLPreloadScanner.h b/Source/WebCore/html/parser/HTMLPreloadScanner.h
index bed77fe5b..38f5772d5 100644
--- a/Source/WebCore/html/parser/HTMLPreloadScanner.h
+++ b/Source/WebCore/html/parser/HTMLPreloadScanner.h
@@ -41,7 +41,7 @@ class SegmentedString;
class HTMLPreloadScanner {
WTF_MAKE_NONCOPYABLE(HTMLPreloadScanner); WTF_MAKE_FAST_ALLOCATED;
public:
- HTMLPreloadScanner(Document*);
+ explicit HTMLPreloadScanner(Document*);
void appendToEnd(const SegmentedString&);
void scan();
@@ -49,6 +49,7 @@ public:
private:
void processToken();
bool scanningBody() const;
+ void updatePredictedBaseElementURL(const KURL& baseElementURL);
Document* m_document;
SegmentedString m_source;
@@ -57,6 +58,7 @@ private:
HTMLToken m_token;
bool m_bodySeen;
bool m_inStyle;
+ KURL m_predictedBaseElementURL;
};
}
diff --git a/Source/WebCore/html/shadow/ContentInclusionSelector.cpp b/Source/WebCore/html/shadow/ContentInclusionSelector.cpp
new file mode 100644
index 000000000..6b541a5ae
--- /dev/null
+++ b/Source/WebCore/html/shadow/ContentInclusionSelector.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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 "ContentInclusionSelector.h"
+
+#include "ContentSelectorQuery.h"
+#include "HTMLContentElement.h"
+#include "ShadowRoot.h"
+
+
+namespace WebCore {
+
+void ShadowInclusion::append(PassRefPtr<ShadowInclusion> next)
+{
+ ASSERT(!m_next);
+ ASSERT(!next->previous());
+ m_next = next;
+ m_next->m_previous = this;
+}
+
+void ShadowInclusion::unlink()
+{
+ ASSERT(!m_previous); // Can be called only for a head.
+ RefPtr<ShadowInclusion> item = this;
+ while (item) {
+ ASSERT(!item->previous());
+ RefPtr<ShadowInclusion> nextItem = item->m_next;
+ item->m_next.clear();
+ if (nextItem)
+ nextItem->m_previous.clear();
+ item = nextItem;
+ }
+}
+
+ShadowInclusionList::ShadowInclusionList()
+{
+}
+
+ShadowInclusionList::~ShadowInclusionList()
+{
+ ASSERT(isEmpty());
+}
+
+ShadowInclusion* ShadowInclusionList::find(Node* content) const
+{
+ for (ShadowInclusion* item = first(); item; item = item->next()) {
+ if (content == item->content())
+ return item;
+ }
+
+ return 0;
+}
+
+void ShadowInclusionList::clear()
+{
+ if (isEmpty()) {
+ ASSERT(!m_last);
+ return;
+ }
+
+ m_first->unlink();
+ m_first.clear();
+ m_last.clear();
+}
+
+void ShadowInclusionList::append(PassRefPtr<ShadowInclusion> child)
+{
+ if (isEmpty()) {
+ ASSERT(!m_last);
+ m_first = m_last = child;
+ return;
+ }
+
+ m_last->append(child);
+ m_last = m_last->next();
+}
+
+ContentInclusionSelector::ContentInclusionSelector()
+{
+}
+
+ContentInclusionSelector::~ContentInclusionSelector()
+{
+ ASSERT(m_candidates.isEmpty());
+}
+
+void ContentInclusionSelector::select(HTMLContentElement* contentElement, ShadowInclusionList* inclusions)
+{
+ ASSERT(inclusions->isEmpty());
+
+ ContentSelectorQuery query(contentElement);
+ for (size_t i = 0; i < m_candidates.size(); ++i) {
+ Node* child = m_candidates[i].get();
+ if (!child)
+ continue;
+ if (!query.matches(child))
+ continue;
+
+ RefPtr<ShadowInclusion> inclusion = ShadowInclusion::create(contentElement, child);
+ inclusions->append(inclusion);
+ m_inclusionSet.add(inclusion.get());
+ m_candidates[i] = 0;
+ }
+}
+
+void ContentInclusionSelector::unselect(ShadowInclusionList* list)
+{
+ for (ShadowInclusion* inclusion = list->first(); inclusion; inclusion = inclusion->next())
+ m_inclusionSet.remove(inclusion);
+ list->clear();
+}
+
+ShadowInclusion* ContentInclusionSelector::findFor(Node* key) const
+{
+ return m_inclusionSet.find(key);
+}
+
+void ContentInclusionSelector::didSelect()
+{
+ m_candidates.clear();
+}
+
+void ContentInclusionSelector::willSelectOver(ShadowRoot* scope)
+{
+ if (!m_candidates.isEmpty())
+ return;
+ for (Node* node = scope->shadowHost()->firstChild(); node; node = node->nextSibling())
+ m_candidates.append(node);
+}
+
+}
diff --git a/Source/WebCore/html/shadow/ContentInclusionSelector.h b/Source/WebCore/html/shadow/ContentInclusionSelector.h
new file mode 100644
index 000000000..0f0b1978e
--- /dev/null
+++ b/Source/WebCore/html/shadow/ContentInclusionSelector.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * 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 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.
+ */
+
+#ifndef ContentInclusionSelector_h
+#define ContentInclusionSelector_h
+
+#include <wtf/Forward.h>
+#include <wtf/HashSet.h>
+#include <wtf/RefCounted.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Element;
+class HTMLContentElement;
+class Node;
+class ShadowRoot;
+
+class ShadowInclusion : public RefCounted<ShadowInclusion> {
+public:
+ static PassRefPtr<ShadowInclusion> create(HTMLContentElement*, Node*);
+
+ HTMLContentElement* includer() const { return m_includer; }
+ Node* content() const { return m_content.get(); }
+ ShadowInclusion* next() const { return m_next.get(); }
+ ShadowInclusion* previous() const { return m_previous.get(); }
+
+ void append(PassRefPtr<ShadowInclusion>);
+ void unlink();
+
+private:
+ ShadowInclusion(HTMLContentElement*, Node*);
+
+ HTMLContentElement* m_includer;
+ RefPtr<Node> m_content;
+ RefPtr<ShadowInclusion> m_next;
+ RefPtr<ShadowInclusion> m_previous;
+};
+
+inline ShadowInclusion::ShadowInclusion(HTMLContentElement* includer, Node* content)
+ : m_includer(includer), m_content(content)
+{ }
+
+inline PassRefPtr<ShadowInclusion> ShadowInclusion::create(HTMLContentElement* includer, Node* content)
+{
+ return adoptRef(new ShadowInclusion(includer, content));
+}
+
+class ShadowInclusionList {
+public:
+ ShadowInclusionList();
+ ~ShadowInclusionList();
+
+ ShadowInclusion* first() const { return m_first.get(); }
+ ShadowInclusion* last() const { return m_last.get(); }
+ ShadowInclusion* find(Node*) const;
+ bool isEmpty() const { return !m_first; }
+
+ void clear();
+ void append(PassRefPtr<ShadowInclusion>);
+
+private:
+ RefPtr<ShadowInclusion> m_first;
+ RefPtr<ShadowInclusion> m_last;
+};
+
+
+class ShadowInclusionSet {
+public:
+ void add(ShadowInclusion* value) { m_set.add(value); }
+ void remove(ShadowInclusion* value) { m_set.remove(value); }
+ bool isEmpty() const { return m_set.isEmpty(); }
+ ShadowInclusion* find(Node* key) const;
+
+private:
+ struct Translator {
+ public:
+ static unsigned hash(const Node* key) { return PtrHash<const Node*>::hash(key); }
+ static bool equal(const ShadowInclusion* inclusion, const Node* content) { return inclusion->content() == content; }
+ };
+
+ struct Hash {
+ static unsigned hash(ShadowInclusion* key) { return PtrHash<const Node*>::hash(key->content()); }
+ static bool equal(ShadowInclusion* a, ShadowInclusion* b) { return a->content() == b->content(); }
+ static const bool safeToCompareToEmptyOrDeleted = false;
+ };
+
+ typedef HashSet<ShadowInclusion*, Hash> PointerSet;
+
+ PointerSet m_set;
+};
+
+inline ShadowInclusion* ShadowInclusionSet::find(Node* key) const
+{
+ PointerSet::iterator found = m_set.find<Node*, ShadowInclusionSet::Translator>(key);
+ return found != m_set.end() ? *found : 0;
+}
+
+class ContentInclusionSelector {
+ WTF_MAKE_NONCOPYABLE(ContentInclusionSelector);
+public:
+ ContentInclusionSelector();
+ ~ContentInclusionSelector();
+
+ void select(HTMLContentElement*, ShadowInclusionList*);
+ void unselect(ShadowInclusionList*);
+ ShadowInclusion* findFor(Node* key) const;
+
+ void willSelectOver(ShadowRoot*);
+ void didSelect();
+ bool hasCandidates() const { return !m_candidates.isEmpty(); }
+
+private:
+ void removeFromSet(ShadowInclusionList*);
+ void addToSet(ShadowInclusionList*);
+
+ Vector<RefPtr<Node> > m_candidates;
+ ShadowInclusionSet m_inclusionSet;
+};
+
+}
+
+#endif
diff --git a/Source/WebCore/html/shadow/ContentSelectorQuery.cpp b/Source/WebCore/html/shadow/ContentSelectorQuery.cpp
new file mode 100644
index 000000000..e346d772a
--- /dev/null
+++ b/Source/WebCore/html/shadow/ContentSelectorQuery.cpp
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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 "ContentSelectorQuery.h"
+
+#include "CSSParser.h"
+#include "CSSSelectorList.h"
+#include "HTMLContentElement.h"
+
+namespace WebCore {
+
+ContentSelectorQuery::ContentSelectorQuery(const HTMLContentElement* element)
+ : m_contentElement(element)
+ , m_selectorChecker(element->document(), !element->document()->inQuirksMode())
+{
+ m_selectorChecker.setCollectingRulesOnly(true);
+
+ if (element->select().isNull() || element->select().isEmpty()) {
+ m_isValidSelector = true;
+ return;
+ }
+
+ CSSParser parser(true);
+ parser.parseSelector(element->select(), element->document(), m_selectorList);
+
+ m_isValidSelector = ContentSelectorQuery::validateSelectorList();
+ if (m_isValidSelector)
+ m_selectors.initialize(m_selectorList);
+}
+
+bool ContentSelectorQuery::isValidSelector() const
+{
+ return m_isValidSelector;
+}
+
+bool ContentSelectorQuery::matches(Node* node) const
+{
+ ASSERT(node);
+ if (!node)
+ return false;
+
+ ASSERT(node->parentNode() == m_contentElement->shadowTreeRootNode()->shadowHost());
+
+ if (m_contentElement->select().isNull() || m_contentElement->select().isEmpty())
+ return true;
+
+ if (!m_isValidSelector)
+ return false;
+
+ if (!node->isElementNode())
+ return false;
+
+ return m_selectors.matches(m_selectorChecker, toElement(node));
+}
+
+static bool validateSubSelector(CSSSelector* selector)
+{
+ switch (selector->m_match) {
+ case CSSSelector::None:
+ case CSSSelector::Id:
+ case CSSSelector::Class:
+ case CSSSelector::Exact:
+ case CSSSelector::Set:
+ case CSSSelector::List:
+ case CSSSelector::Hyphen:
+ case CSSSelector::Contain:
+ case CSSSelector::Begin:
+ case CSSSelector::End:
+ return true;
+ case CSSSelector::PseudoElement:
+ return false;
+ case CSSSelector::PagePseudoClass:
+ case CSSSelector::PseudoClass:
+ break;
+ }
+
+ switch (selector->pseudoType()) {
+ case CSSSelector::PseudoEmpty:
+ case CSSSelector::PseudoLink:
+ case CSSSelector::PseudoVisited:
+ case CSSSelector::PseudoTarget:
+ case CSSSelector::PseudoEnabled:
+ case CSSSelector::PseudoDisabled:
+ case CSSSelector::PseudoChecked:
+ case CSSSelector::PseudoIndeterminate:
+ case CSSSelector::PseudoNthChild:
+ case CSSSelector::PseudoNthLastChild:
+ case CSSSelector::PseudoNthOfType:
+ case CSSSelector::PseudoNthLastOfType:
+ case CSSSelector::PseudoFirstChild:
+ case CSSSelector::PseudoLastChild:
+ case CSSSelector::PseudoFirstOfType:
+ case CSSSelector::PseudoLastOfType:
+ case CSSSelector::PseudoOnlyOfType:
+ return true;
+ default:
+ return false;
+ }
+}
+
+static bool validateSelector(CSSSelector* selector)
+{
+ ASSERT(selector);
+
+ if (!validateSubSelector(selector))
+ return false;
+
+ CSSSelector* prevSubSelector = selector;
+ CSSSelector* subSelector = selector->tagHistory();
+
+ while (subSelector) {
+ if (prevSubSelector->relation() != CSSSelector::SubSelector)
+ return false;
+ if (!validateSubSelector(subSelector))
+ return false;
+
+ prevSubSelector = subSelector;
+ subSelector = subSelector->tagHistory();
+ }
+
+ return true;
+}
+
+bool ContentSelectorQuery::validateSelectorList()
+{
+ if (!m_selectorList.first())
+ return false;
+
+ for (CSSSelector* selector = m_selectorList.first(); selector; selector = m_selectorList.next(selector)) {
+ if (!validateSelector(selector))
+ return false;
+ }
+
+ return true;
+}
+
+}
diff --git a/Source/WebCore/html/shadow/ContentSelectorQuery.h b/Source/WebCore/html/shadow/ContentSelectorQuery.h
new file mode 100644
index 000000000..527aa4905
--- /dev/null
+++ b/Source/WebCore/html/shadow/ContentSelectorQuery.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * 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 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.
+ */
+
+#ifndef ContentSelectorQuery_h
+#define ContentSelectorQuery_h
+
+#include "CSSSelectorList.h"
+#include "SelectorChecker.h"
+#include "SelectorQuery.h"
+#include <wtf/Forward.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+class Document;
+class Node;
+class HTMLContentElement;
+
+class ContentSelectorQuery {
+ WTF_MAKE_NONCOPYABLE(ContentSelectorQuery);
+public:
+ explicit ContentSelectorQuery(const HTMLContentElement*);
+
+ bool isValidSelector() const;
+ bool matches(Node*) const;
+private:
+ bool validateSelectorList();
+
+ const HTMLContentElement* m_contentElement;
+ SelectorDataList m_selectors;
+ CSSSelectorList m_selectorList;
+ SelectorChecker m_selectorChecker;
+ bool m_isValidSelector;
+};
+
+}
+
+
+
+#endif
diff --git a/Source/WebCore/html/shadow/HTMLContentElement.cpp b/Source/WebCore/html/shadow/HTMLContentElement.cpp
new file mode 100644
index 000000000..c1a1ef083
--- /dev/null
+++ b/Source/WebCore/html/shadow/HTMLContentElement.cpp
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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 "HTMLContentElement.h"
+
+#include "ContentInclusionSelector.h"
+#include "ContentSelectorQuery.h"
+#include "HTMLNames.h"
+#include "QualifiedName.h"
+#include "ShadowRoot.h"
+#include <wtf/StdLibExtras.h>
+
+namespace WebCore {
+
+using HTMLNames::selectAttr;
+
+static const QualifiedName& contentTagName()
+{
+#if ENABLE(SHADOW_DOM)
+ return HTMLNames::contentTag;
+#else
+ DEFINE_STATIC_LOCAL(QualifiedName, tagName, (nullAtom, "webkitShadowContent", HTMLNames::divTag.namespaceURI()));
+ return tagName;
+#endif
+}
+
+PassRefPtr<HTMLContentElement> HTMLContentElement::create(Document* document)
+{
+ return adoptRef(new HTMLContentElement(contentTagName(), document));
+}
+
+PassRefPtr<HTMLContentElement> HTMLContentElement::create(const QualifiedName& tagName, Document* document)
+{
+ return adoptRef(new HTMLContentElement(tagName, document));
+}
+
+HTMLContentElement::HTMLContentElement(const QualifiedName& name, Document* document)
+ : HTMLElement(name, document)
+ , m_inclusions(adoptPtr(new ShadowInclusionList()))
+{
+}
+
+HTMLContentElement::~HTMLContentElement()
+{
+}
+
+void HTMLContentElement::attach()
+{
+ ShadowRoot* root = toShadowRoot(shadowTreeRootNode());
+
+ // Before calling StyledElement::attach, selector must be calculated.
+ if (root) {
+ ContentInclusionSelector* selector = root->ensureInclusions();
+ selector->unselect(m_inclusions.get());
+ selector->select(this, m_inclusions.get());
+ }
+
+ HTMLElement::attach();
+
+ if (root) {
+ for (ShadowInclusion* inclusion = m_inclusions->first(); inclusion; inclusion = inclusion->next())
+ inclusion->content()->attach();
+ }
+}
+
+void HTMLContentElement::detach()
+{
+ if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode())) {
+ if (ContentInclusionSelector* selector = root->inclusions())
+ selector->unselect(m_inclusions.get());
+
+ // When content element is detached, shadow tree should be recreated to re-calculate inclusions for
+ // other content elements.
+ root->setNeedsReattachHostChildrenAndShadow();
+ }
+
+ ASSERT(m_inclusions->isEmpty());
+ HTMLElement::detach();
+}
+
+const AtomicString& HTMLContentElement::select() const
+{
+ return getAttribute(selectAttr);
+}
+
+bool HTMLContentElement::isSelectValid() const
+{
+ ContentSelectorQuery query(this);
+ return query.isValidSelector();
+}
+
+void HTMLContentElement::setSelect(const AtomicString& selectValue)
+{
+ setAttribute(selectAttr, selectValue);
+}
+
+void HTMLContentElement::parseMappedAttribute(Attribute* attr)
+{
+ if (attr->name() == selectAttr) {
+ if (ShadowRoot* root = toShadowRoot(shadowTreeRootNode()))
+ root->setNeedsReattachHostChildrenAndShadow();
+ } else
+ HTMLElement::parseMappedAttribute(attr);
+}
+
+}
diff --git a/Source/WebCore/html/shadow/HTMLContentElement.h b/Source/WebCore/html/shadow/HTMLContentElement.h
new file mode 100644
index 000000000..7845e0937
--- /dev/null
+++ b/Source/WebCore/html/shadow/HTMLContentElement.h
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2011 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:
+ *
+ * * 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 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.
+ */
+
+#ifndef HTMLContentElement_h
+#define HTMLContentElement_h
+
+#include "ContentInclusionSelector.h"
+#include "HTMLElement.h"
+#include <wtf/Forward.h>
+
+namespace WebCore {
+
+class ContentSelectorQuery;
+class ShadowInclusionList;
+
+// NOTE: Current implementation doesn't support dynamic insertion/deletion of HTMLContentElement.
+// You should create HTMLContentElement during the host construction.
+class HTMLContentElement : public HTMLElement {
+public:
+ static PassRefPtr<HTMLContentElement> create(const QualifiedName&, Document*);
+ static PassRefPtr<HTMLContentElement> create(Document*);
+
+ virtual ~HTMLContentElement();
+ virtual void attach();
+ virtual void detach();
+
+ const AtomicString& select() const;
+
+ // FIXME: Currently this constructor accepts wider query than shadow dom spec.
+ // For example, a selector query should not include contextual selectors.
+ // See https://bugs.webkit.org/show_bug.cgi?id=75946
+ // FIXME: Currently we don't support setting select value dynamically.
+ // See https://bugs.webkit.org/show_bug.cgi?id=76261
+ void setSelect(const AtomicString&);
+
+ const ShadowInclusionList* inclusions() const { return m_inclusions.get(); }
+ bool hasInclusion() const { return inclusions()->first(); }
+
+ virtual bool isSelectValid() const;
+
+protected:
+ HTMLContentElement(const QualifiedName&, Document*);
+
+private:
+ virtual bool isContentElement() const { return true; }
+ virtual bool rendererIsNeeded(const NodeRenderingContext&) { return false; }
+ virtual RenderObject* createRenderer(RenderArena*, RenderStyle*) { return 0; }
+
+ virtual void parseMappedAttribute(Attribute*);
+
+ OwnPtr<ShadowInclusionList> m_inclusions;
+};
+
+inline HTMLContentElement* toHTMLContentElement(Node* node)
+{
+ ASSERT(!node || node->isContentElement());
+ return static_cast<HTMLContentElement*>(node);
+}
+
+}
+
+#endif
diff --git a/Source/WebCore/html/shadow/HTMLContentElement.idl b/Source/WebCore/html/shadow/HTMLContentElement.idl
new file mode 100644
index 000000000..0febfa26b
--- /dev/null
+++ b/Source/WebCore/html/shadow/HTMLContentElement.idl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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 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.
+ */
+
+module html {
+ interface [
+ Conditional=SHADOW_DOM,
+ EnabledAtRuntime=shadowDOM
+ ] HTMLContentElement : HTMLElement {
+ attribute [Reflect] DOMString select;
+ };
+}
diff --git a/Source/WebCore/html/shadow/MediaControlElements.cpp b/Source/WebCore/html/shadow/MediaControlElements.cpp
index d88b87f03..c75b2b78c 100644
--- a/Source/WebCore/html/shadow/MediaControlElements.cpp
+++ b/Source/WebCore/html/shadow/MediaControlElements.cpp
@@ -175,7 +175,7 @@ void MediaControlPanelElement::endDrag()
void MediaControlPanelElement::setPosition(const LayoutPoint& position)
{
- CSSInlineStyleDeclaration* style = ensureInlineStyleDecl();
+ CSSMutableStyleDeclaration* style = ensureInlineStyleDecl();
double left = position.x();
double top = position.y();
@@ -193,7 +193,7 @@ void MediaControlPanelElement::setPosition(const LayoutPoint& position)
void MediaControlPanelElement::resetPosition()
{
- CSSInlineStyleDeclaration* style = ensureInlineStyleDecl();
+ CSSMutableStyleDeclaration* style = ensureInlineStyleDecl();
style->removeProperty(CSSPropertyLeft);
style->removeProperty(CSSPropertyTop);
@@ -208,10 +208,12 @@ void MediaControlPanelElement::makeOpaque()
{
if (m_opaque)
return;
-
- CSSInlineStyleDeclaration* style = ensureInlineStyleDecl();
+
+ double duration = document()->page() ? document()->page()->theme()->mediaControlsFadeInDuration() : 0;
+
+ CSSMutableStyleDeclaration* style = ensureInlineStyleDecl();
style->setProperty(CSSPropertyWebkitTransitionProperty, CSSPropertyOpacity);
- style->setProperty(CSSPropertyWebkitTransitionDuration, document()->page()->theme()->mediaControlsFadeInDuration(), CSSPrimitiveValue::CSS_S);
+ style->setProperty(CSSPropertyWebkitTransitionDuration, duration, CSSPrimitiveValue::CSS_S);
style->setProperty(CSSPropertyOpacity, 1.0, CSSPrimitiveValue::CSS_NUMBER);
m_opaque = true;
@@ -222,7 +224,7 @@ void MediaControlPanelElement::makeTransparent()
if (!m_opaque)
return;
- CSSInlineStyleDeclaration* style = ensureInlineStyleDecl();
+ CSSMutableStyleDeclaration* style = ensureInlineStyleDecl();
style->setProperty(CSSPropertyWebkitTransitionProperty, CSSPropertyOpacity);
style->setProperty(CSSPropertyWebkitTransitionDuration, document()->page()->theme()->mediaControlsFadeOutDuration(), CSSPrimitiveValue::CSS_S);
style->setProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);
diff --git a/Source/WebCore/html/shadow/SliderThumbElement.cpp b/Source/WebCore/html/shadow/SliderThumbElement.cpp
index 1cf4de7d0..60b9e3527 100644
--- a/Source/WebCore/html/shadow/SliderThumbElement.cpp
+++ b/Source/WebCore/html/shadow/SliderThumbElement.cpp
@@ -334,7 +334,7 @@ PassRefPtr<TrackLimiterElement> TrackLimiterElement::create(Document* document)
{
RefPtr<TrackLimiterElement> element = adoptRef(new TrackLimiterElement(document));
- CSSInlineStyleDeclaration* style = element->ensureInlineStyleDecl();
+ CSSMutableStyleDeclaration* style = element->ensureInlineStyleDecl();
style->setProperty(CSSPropertyVisibility, CSSValueHidden);
style->setProperty(CSSPropertyPosition, CSSValueStatic);
diff --git a/Source/WebCore/html/shadow/TextControlInnerElements.cpp b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
index c24931f2c..808ffa31e 100644
--- a/Source/WebCore/html/shadow/TextControlInnerElements.cpp
+++ b/Source/WebCore/html/shadow/TextControlInnerElements.cpp
@@ -39,6 +39,7 @@
#include "Page.h"
#include "RenderLayer.h"
#include "RenderTextControlSingleLine.h"
+#include "RenderView.h"
#include "ScriptController.h"
#include "ScrollbarTheme.h"
#include "SpeechInput.h"
@@ -498,8 +499,13 @@ void InputFieldSpeechButtonElement::setRecognitionResult(int, const SpeechInputR
return;
RefPtr<InputFieldSpeechButtonElement> holdRefButton(this);
- if (document() && document()->domWindow())
+ if (document() && document()->domWindow()) {
+ // Call selectionChanged, causing the element to cache the selection,
+ // so that the text event inserts the text in this element even if
+ // focus has moved away from it.
+ input->selectionChanged(false);
input->dispatchEvent(TextEvent::create(document()->domWindow(), results.isEmpty() ? "" : results[0]->utterance(), TextEventInputOther));
+ }
// This event is sent after the text event so the website can perform actions using the input field content immediately.
// It provides alternative recognition hypotheses and notifies that the results come from speech input.
@@ -544,7 +550,7 @@ void InputFieldSpeechButtonElement::startSpeechInput()
AtomicString language = input->computeInheritedLanguage();
String grammar = input->getAttribute(webkitgrammarAttr);
// FIXME: this should probably respect transforms
- IntRect rect = renderer()->absoluteBoundingBoxRectIgnoringTransforms();
+ IntRect rect = renderer()->view()->frameView()->contentsToWindow(renderer()->absoluteBoundingBoxRectIgnoringTransforms());
if (speechInput()->startRecognition(m_listenerId, rect, language, grammar, document()->securityOrigin()))
setState(Recording);
}
diff --git a/Source/WebCore/html/track/WebVTTParser.cpp b/Source/WebCore/html/track/WebVTTParser.cpp
index 114978f82..050fb2754 100644
--- a/Source/WebCore/html/track/WebVTTParser.cpp
+++ b/Source/WebCore/html/track/WebVTTParser.cpp
@@ -109,6 +109,8 @@ String WebVTTParser::collectWord(const String& input, unsigned* position)
WebVTTParser::WebVTTParser(WebVTTParserClient* client, ScriptExecutionContext* context)
: m_scriptExecutionContext(context)
, m_state(Initial)
+ , m_currentStartTime(0)
+ , m_currentEndTime(0)
, m_tokenizer(WebVTTTokenizer::create())
, m_client(client)
{