Title: [125147] trunk
Revision
125147
Author
morr...@google.com
Date
2012-08-08 21:16:38 -0700 (Wed, 08 Aug 2012)

Log Message

[SVG] load events shouldn't be fired during Node::insrtedInto()
https://bugs.webkit.org/show_bug.cgi?id=92969

Reviewed by Ryosuke Niwa.

Source/WebCore:

Event dispatches during insertedInto() allow event handlers to
break DOM tree cosistency. This chagne makes them async for load
events which are dispatched during insertedInto() call. This
prevents event handlers from breaking tree consistency while the
notification traversal.

Test: svg/custom/loadevents-async.html

* svg/SVGElement.cpp:
(WebCore::SVGElement::sendSVGLoadEventIfPossibleAsynchronously): Added.
(WebCore):
(WebCore::SVGElement::svgLoadEventTimerFired): Added.
(WebCore::SVGElement::svgLoadEventTimer):
- Added a stub. Implemented in SVGScriptElement, SVGStopElement, SVGUseElement
  where the load event happens.
* svg/SVGElement.h:
(SVGElement):
* svg/SVGExternalResourcesRequired.cpp:
(WebCore::SVGExternalResourcesRequired::insertedIntoDocument):
- Replaces event dispatch call with async version.
* svg/SVGScriptElement.h:
* svg/SVGStyleElement.h:
* svg/SVGUseElement.h:

LayoutTests:

* svg/custom/loadevents-async-expected.txt: Added.
* svg/custom/loadevents-async.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (125146 => 125147)


--- trunk/LayoutTests/ChangeLog	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/LayoutTests/ChangeLog	2012-08-09 04:16:38 UTC (rev 125147)
@@ -1,3 +1,13 @@
+2012-08-08  MORITA Hajime  <morr...@google.com>
+
+        [SVG] load events shouldn't be fired during Node::insrtedInto()
+        https://bugs.webkit.org/show_bug.cgi?id=92969
+
+        Reviewed by Ryosuke Niwa.
+
+        * svg/custom/loadevents-async-expected.txt: Added.
+        * svg/custom/loadevents-async.html: Added.
+
 2012-08-08  Tony Chang  <t...@chromium.org>
 
         css3/flexbox/content-height-with-scrollbars.html failing on non-fractional pixel layout machines

Added: trunk/LayoutTests/svg/custom/loadevents-async-expected.txt (0 => 125147)


--- trunk/LayoutTests/svg/custom/loadevents-async-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/loadevents-async-expected.txt	2012-08-09 04:16:38 UTC (rev 125147)
@@ -0,0 +1,11 @@
+This test ensures that tree mutation on the load doesn't break consistency.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS invoked is false
+PASS invoked is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/svg/custom/loadevents-async.html (0 => 125147)


--- trunk/LayoutTests/svg/custom/loadevents-async.html	                        (rev 0)
+++ trunk/LayoutTests/svg/custom/loadevents-async.html	2012-08-09 04:16:38 UTC (rev 125147)
@@ -0,0 +1,31 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script>
+description("This test ensures that tree mutation on the load doesn't break consistency.");
+var invoked = false;
+var spanElement = document.createElementNS("http://www.w3.org/1999/xhtml", "span");
+var divElement = document.createElementNS("http://www.w3.org/1999/xhtml", "div");
+var useElement = document.createElementNS("http://www.w3.org/2000/svg", "use");
+var emptyDocument = document.implementation.createDocument("", "", null);
+
+document.body.appendChild(spanElement);
+divElement.appendChild(useElement);
+useElement.addEventListener("load", function () { emptyDocument.adoptNode(useElement); invoked = true; }, false);
+spanElement.appendChild(divElement);
+document.body.appendChild(useElement);
+shouldBeFalse("invoked");
+
+jsTestIsAsync = true;
+setTimeout(function() {
+    shouldBeTrue("invoked");
+    finishJSTest();
+}, 1);
+
+</script>
+<script src=""
+<body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (125146 => 125147)


--- trunk/Source/WebCore/ChangeLog	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/ChangeLog	2012-08-09 04:16:38 UTC (rev 125147)
@@ -1,3 +1,34 @@
+2012-08-08  MORITA Hajime  <morr...@google.com>
+
+        [SVG] load events shouldn't be fired during Node::insrtedInto()
+        https://bugs.webkit.org/show_bug.cgi?id=92969
+
+        Reviewed by Ryosuke Niwa.
+
+        Event dispatches during insertedInto() allow event handlers to
+        break DOM tree cosistency. This chagne makes them async for load
+        events which are dispatched during insertedInto() call. This
+        prevents event handlers from breaking tree consistency while the
+        notification traversal.
+
+        Test: svg/custom/loadevents-async.html
+
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::sendSVGLoadEventIfPossibleAsynchronously): Added.
+        (WebCore):
+        (WebCore::SVGElement::svgLoadEventTimerFired): Added.
+        (WebCore::SVGElement::svgLoadEventTimer):
+        - Added a stub. Implemented in SVGScriptElement, SVGStopElement, SVGUseElement
+          where the load event happens.
+        * svg/SVGElement.h:
+        (SVGElement):
+        * svg/SVGExternalResourcesRequired.cpp:
+        (WebCore::SVGExternalResourcesRequired::insertedIntoDocument):
+        - Replaces event dispatch call with async version.
+        * svg/SVGScriptElement.h:
+        * svg/SVGStyleElement.h:
+        * svg/SVGUseElement.h:
+
 2012-08-08  Adam Barth  <aba...@webkit.org>
 
         Implement JSDOMWindow*::allowsAccessFrom* in terms of BindingSecurity

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2012-08-09 04:16:38 UTC (rev 125147)
@@ -477,6 +477,22 @@
     }
 }
 
+void SVGElement::sendSVGLoadEventIfPossibleAsynchronously()
+{
+    svgLoadEventTimer()->startOneShot(0);
+}
+
+void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*)
+{
+    sendSVGLoadEventIfPossible();
+}
+
+Timer<SVGElement>* SVGElement::svgLoadEventTimer()
+{
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
 void SVGElement::finishParsingChildren()
 {
     StyledElement::finishParsingChildren();

Modified: trunk/Source/WebCore/svg/SVGElement.h (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGElement.h	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGElement.h	2012-08-09 04:16:38 UTC (rev 125147)
@@ -27,6 +27,7 @@
 #include "SVGParsingError.h"
 #include "SVGPropertyInfo.h"
 #include "StyledElement.h"
+#include "Timer.h"
 #include <wtf/HashMap.h>
 
 namespace WebCore {
@@ -72,6 +73,9 @@
     virtual void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
 
     void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
+    void sendSVGLoadEventIfPossibleAsynchronously();
+    void svgLoadEventTimerFired(Timer<SVGElement>*);
+    virtual Timer<SVGElement>* svgLoadEventTimer();
 
     virtual AffineTransform* supplementalTransform() { return 0; }
 

Modified: trunk/Source/WebCore/svg/SVGExternalResourcesRequired.cpp (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGExternalResourcesRequired.cpp	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGExternalResourcesRequired.cpp	2012-08-09 04:16:38 UTC (rev 125147)
@@ -103,7 +103,7 @@
     if (externalResourcesRequiredBaseValue())
         return;
     setHaveFiredLoadEvent(true);
-    targetElement->sendSVGLoadEventIfPossible();
+    targetElement->sendSVGLoadEventIfPossibleAsynchronously();
 }
 
 void SVGExternalResourcesRequired::finishParsingChildren()

Modified: trunk/Source/WebCore/svg/SVGScriptElement.cpp (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGScriptElement.cpp	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGScriptElement.cpp	2012-08-09 04:16:38 UTC (rev 125147)
@@ -47,6 +47,7 @@
 inline SVGScriptElement::SVGScriptElement(const QualifiedName& tagName, Document* document, bool wasInsertedByParser, bool alreadyStarted)
     : SVGElement(tagName, document)
     , ScriptElement(this, wasInsertedByParser, alreadyStarted)
+    , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
 {
     ASSERT(hasTagName(SVGNames::scriptTag));
     registerAnimatedPropertiesForSVGScriptElement();

Modified: trunk/Source/WebCore/svg/SVGScriptElement.h (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGScriptElement.h	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGScriptElement.h	2012-08-09 04:16:38 UTC (rev 125147)
@@ -75,6 +75,7 @@
     virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) { ScriptElement::setHaveFiredLoadEvent(haveFiredLoadEvent); }
     virtual bool isParserInserted() const { return ScriptElement::isParserInserted(); }
     virtual bool haveFiredLoadEvent() const { return ScriptElement::haveFiredLoadEvent(); }
+    virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
 
     BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGScriptElement)
         DECLARE_ANIMATED_STRING(Href, href)
@@ -82,6 +83,7 @@
     END_DECLARE_ANIMATED_PROPERTIES
 
     String m_type;
+    Timer<SVGElement> m_svgLoadEventTimer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/svg/SVGStyleElement.cpp (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGStyleElement.cpp	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGStyleElement.cpp	2012-08-09 04:16:38 UTC (rev 125147)
@@ -37,6 +37,7 @@
 inline SVGStyleElement::SVGStyleElement(const QualifiedName& tagName, Document* document, bool createdByParser)
     : SVGElement(tagName, document)
     , StyleElement(document, createdByParser)
+    , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
 {
     ASSERT(hasTagName(SVGNames::styleTag));
 }

Modified: trunk/Source/WebCore/svg/SVGStyleElement.h (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGStyleElement.h	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGStyleElement.h	2012-08-09 04:16:38 UTC (rev 125147)
@@ -63,6 +63,9 @@
     virtual bool isLoading() const { return StyleElement::isLoading(); }
     virtual bool sheetLoaded() { return StyleElement::sheetLoaded(document()); }
     virtual void startLoadingDynamicSheet() { StyleElement::startLoadingDynamicSheet(document()); }
+    virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
+
+    Timer<SVGElement> m_svgLoadEventTimer;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/svg/SVGUseElement.cpp (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGUseElement.cpp	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGUseElement.cpp	2012-08-09 04:16:38 UTC (rev 125147)
@@ -89,6 +89,7 @@
     , m_wasInsertedByParser(wasInsertedByParser)
     , m_haveFiredLoadEvent(false)
     , m_needsShadowTreeRecreation(false)
+    , m_svgLoadEventTimer(this, &SVGElement::svgLoadEventTimerFired)
 {
     ASSERT(hasCustomCallbacks());
     ASSERT(hasTagName(SVGNames::useTag));

Modified: trunk/Source/WebCore/svg/SVGUseElement.h (125146 => 125147)


--- trunk/Source/WebCore/svg/SVGUseElement.h	2012-08-09 03:52:41 UTC (rev 125146)
+++ trunk/Source/WebCore/svg/SVGUseElement.h	2012-08-09 04:16:38 UTC (rev 125147)
@@ -124,12 +124,14 @@
     virtual void setHaveFiredLoadEvent(bool haveFiredLoadEvent) { m_haveFiredLoadEvent = haveFiredLoadEvent; }
     virtual bool isParserInserted() const { return m_wasInsertedByParser; }
     virtual bool haveFiredLoadEvent() const { return m_haveFiredLoadEvent; }
+    virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
 
     bool m_wasInsertedByParser;
     bool m_haveFiredLoadEvent;
     bool m_needsShadowTreeRecreation;
     RefPtr<SVGElementInstance> m_targetElementInstance;
     CachedResourceHandle<CachedSVGDocument> m_cachedDocument;
+    Timer<SVGElement> m_svgLoadEventTimer;
 };
 
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to