Title: [117086] trunk/Source/WebCore
Revision
117086
Author
[email protected]
Date
2012-05-15 09:59:12 -0700 (Tue, 15 May 2012)

Log Message

Refactor SVG parts of Node::addEventListener/removeEventListener
https://bugs.webkit.org/show_bug.cgi?id=86426

Reviewed by Nikolas Zimmermann.

Move SVG parts of Node::addEventListener/removeEventListener into svg/. Now we do not
have to check in Node::addEventListener/removeEventListener if we are dealing with an SVG
element. Make tryAddEventListener/tryRemoveEventListener protected methods on Node to be able to use
it in SVGElement.

No new tests, since no change in behavior, just refactoring.

* dom/Node.cpp:
(WebCore::tryAddEventListener):
(WebCore::Node::addEventListener):
(WebCore::tryRemoveEventListener):
(WebCore::Node::removeEventListener):
* svg/SVGElement.cpp:
(WebCore::collectInstancesForSVGElement):
(WebCore):
(WebCore::SVGElement::addEventListener):
(WebCore::SVGElement::removeEventListener):
* svg/SVGElement.h:
(SVGElement):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (117085 => 117086)


--- trunk/Source/WebCore/ChangeLog	2012-05-15 16:38:03 UTC (rev 117085)
+++ trunk/Source/WebCore/ChangeLog	2012-05-15 16:59:12 UTC (rev 117086)
@@ -1,3 +1,30 @@
+2012-05-15  Rob Buis  <[email protected]>
+
+        Refactor SVG parts of Node::addEventListener/removeEventListener
+        https://bugs.webkit.org/show_bug.cgi?id=86426
+
+        Reviewed by Nikolas Zimmermann.
+
+        Move SVG parts of Node::addEventListener/removeEventListener into svg/. Now we do not
+        have to check in Node::addEventListener/removeEventListener if we are dealing with an SVG
+        element. Make tryAddEventListener/tryRemoveEventListener protected methods on Node to be able to use
+        it in SVGElement.
+
+        No new tests, since no change in behavior, just refactoring.
+
+        * dom/Node.cpp:
+        (WebCore::tryAddEventListener):
+        (WebCore::Node::addEventListener):
+        (WebCore::tryRemoveEventListener):
+        (WebCore::Node::removeEventListener):
+        * svg/SVGElement.cpp:
+        (WebCore::collectInstancesForSVGElement):
+        (WebCore):
+        (WebCore::SVGElement::addEventListener):
+        (WebCore::SVGElement::removeEventListener):
+        * svg/SVGElement.h:
+        (SVGElement):
+
 2012-05-15  Andreas Kling  <[email protected]>
 
         RuleSet::addToRuleSet wastes a bit of Vector capacity.

Modified: trunk/Source/WebCore/dom/Node.cpp (117085 => 117086)


--- trunk/Source/WebCore/dom/Node.cpp	2012-05-15 16:38:03 UTC (rev 117085)
+++ trunk/Source/WebCore/dom/Node.cpp	2012-05-15 16:59:12 UTC (rev 117086)
@@ -112,11 +112,6 @@
 #include "InspectorController.h"
 #endif
 
-#if ENABLE(SVG)
-#include "SVGElementInstance.h"
-#include "SVGUseElement.h"
-#endif
-
 #if USE(JSC)
 #include <runtime/JSGlobalData.h>
 #endif
@@ -2443,26 +2438,6 @@
 #endif
 }
 
-#if ENABLE(SVG)
-static inline HashSet<SVGElementInstance*> instancesForSVGElement(Node* node)
-{
-    HashSet<SVGElementInstance*> instances;
- 
-    ASSERT(node);
-    if (!node->isSVGElement() || node->shadowTreeRootNode())
-        return HashSet<SVGElementInstance*>();
-
-    SVGElement* element = static_cast<SVGElement*>(node);
-    if (!element->isStyled())
-        return HashSet<SVGElementInstance*>();
-
-    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element);
-    ASSERT(!styledElement->instanceUpdatesBlocked());
-
-    return styledElement->instancesForElement();
-}
-#endif
-
 static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
     if (!targetNode->EventTarget::addEventListener(eventType, listener, useCapture))
@@ -2475,42 +2450,13 @@
         else if (eventNames().isTouchEventType(eventType))
             document->didAddTouchEventHandler();
     }
-        
+
     return true;
 }
 
 bool Node::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
 {
-#if !ENABLE(SVG)
     return tryAddEventListener(this, eventType, listener, useCapture);
-#else
-    if (!isSVGElement())
-        return tryAddEventListener(this, eventType, listener, useCapture);
-
-    HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
-    if (instances.isEmpty())
-        return tryAddEventListener(this, eventType, listener, useCapture);
-
-    RefPtr<EventListener> listenerForRegularTree = listener;
-    RefPtr<EventListener> listenerForShadowTree = listenerForRegularTree;
-
-    // Add event listener to regular DOM element
-    if (!tryAddEventListener(this, eventType, listenerForRegularTree.release(), useCapture))
-        return false;
-
-    // Add event listener to all shadow tree DOM element instances
-    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
-    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
-        ASSERT((*it)->shadowTreeElement());
-        ASSERT((*it)->correspondingElement() == this);
-
-        RefPtr<EventListener> listenerForCurrentShadowTreeElement = listenerForShadowTree;
-        bool result = tryAddEventListener((*it)->shadowTreeElement(), eventType, listenerForCurrentShadowTreeElement.release(), useCapture);
-        ASSERT_UNUSED(result, result);
-    }
-
-    return true;
-#endif
 }
 
 static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture)
@@ -2526,61 +2472,13 @@
         else if (eventNames().isTouchEventType(eventType))
             document->didRemoveTouchEventHandler();
     }
-    
+
     return true;
 }
 
 bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
 {
-#if !ENABLE(SVG)
     return tryRemoveEventListener(this, eventType, listener, useCapture);
-#else
-    if (!isSVGElement())
-        return tryRemoveEventListener(this, eventType, listener, useCapture);
-
-    HashSet<SVGElementInstance*> instances = instancesForSVGElement(this);
-    if (instances.isEmpty())
-        return tryRemoveEventListener(this, eventType, listener, useCapture);
-
-    // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
-    // object when creating a temporary RegisteredEventListener object used to look up the
-    // event listener in a cache. If we want to be able to call removeEventListener() multiple
-    // times on different nodes, we have to delay its immediate destruction, which would happen
-    // after the first call below.
-    RefPtr<EventListener> protector(listener);
-
-    // Remove event listener from regular DOM element
-    if (!tryRemoveEventListener(this, eventType, listener, useCapture))
-        return false;
-
-    // Remove event listener from all shadow tree DOM element instances
-    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
-    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
-        ASSERT((*it)->correspondingElement() == this);
-
-        SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
-        ASSERT(shadowTreeElement);
-
-        if (tryRemoveEventListener(shadowTreeElement, eventType, listener, useCapture))
-            continue;
-
-        // This case can only be hit for event listeners created from markup
-        ASSERT(listener->wasCreatedFromMarkup());
-
-        // If the event listener 'listener' has been created from markup and has been fired before
-        // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
-        // has been created (read: it's not 0 anymore). During shadow tree creation, the event
-        // listener DOM attribute has been cloned, and another event listener has been setup in
-        // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
-        // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
-        EventTargetData* data = ""
-        ASSERT(data);
-
-        data->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
-    }
-
-    return true;
-#endif
 }
 
 EventTargetData* Node::eventTargetData()

Modified: trunk/Source/WebCore/svg/SVGElement.cpp (117085 => 117086)


--- trunk/Source/WebCore/svg/SVGElement.cpp	2012-05-15 16:38:03 UTC (rev 117085)
+++ trunk/Source/WebCore/svg/SVGElement.cpp	2012-05-15 16:59:12 UTC (rev 117086)
@@ -348,6 +348,96 @@
     return true;
 }
 
+static inline void collectInstancesForSVGElement(SVGElement* element, HashSet<SVGElementInstance*>& instances)
+{
+    ASSERT(element);
+    if (element->shadowTreeRootNode())
+        return;
+
+    if (!element->isStyled())
+        return;
+
+    SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(element);
+    ASSERT(!styledElement->instanceUpdatesBlocked());
+
+    instances = styledElement->instancesForElement();
+}
+
+bool SVGElement::addEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+{
+    HashSet<SVGElementInstance*> instances;
+    collectInstancesForSVGElement(this, instances);
+    if (instances.isEmpty())
+        return Node::addEventListener(eventType, listener, useCapture);
+
+    RefPtr<EventListener> listenerForRegularTree = listener;
+    RefPtr<EventListener> listenerForShadowTree = listenerForRegularTree;
+
+    // Add event listener to regular DOM element
+    if (!Node::addEventListener(eventType, listenerForRegularTree.release(), useCapture))
+        return false;
+
+    // Add event listener to all shadow tree DOM element instances
+    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+        ASSERT((*it)->shadowTreeElement());
+        ASSERT((*it)->correspondingElement() == this);
+
+        RefPtr<EventListener> listenerForCurrentShadowTreeElement = listenerForShadowTree;
+        bool result = (*it)->shadowTreeElement()->Node::addEventListener(eventType, listenerForCurrentShadowTreeElement.release(), useCapture);
+        ASSERT_UNUSED(result, result);
+    }
+
+    return true;
+}
+
+bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+{
+    HashSet<SVGElementInstance*> instances;
+    collectInstancesForSVGElement(this, instances);
+    if (instances.isEmpty())
+        return Node::removeEventListener(eventType, listener, useCapture);
+
+    // EventTarget::removeEventListener creates a PassRefPtr around the given EventListener
+    // object when creating a temporary RegisteredEventListener object used to look up the
+    // event listener in a cache. If we want to be able to call removeEventListener() multiple
+    // times on different nodes, we have to delay its immediate destruction, which would happen
+    // after the first call below.
+    RefPtr<EventListener> protector(listener);
+
+    // Remove event listener from regular DOM element
+    if (!Node::removeEventListener(eventType, listener, useCapture))
+        return false;
+
+    // Remove event listener from all shadow tree DOM element instances
+    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+        ASSERT((*it)->correspondingElement() == this);
+
+        SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
+        ASSERT(shadowTreeElement);
+
+        if (shadowTreeElement->Node::removeEventListener(eventType, listener, useCapture))
+            continue;
+
+        // This case can only be hit for event listeners created from markup
+        ASSERT(listener->wasCreatedFromMarkup());
+
+        // If the event listener 'listener' has been created from markup and has been fired before
+        // then JSLazyEventListener::parseCode() has been called and m_jsFunction of that listener
+        // has been created (read: it's not 0 anymore). During shadow tree creation, the event
+        // listener DOM attribute has been cloned, and another event listener has been setup in
+        // the shadow tree. If that event listener has not been used yet, m_jsFunction is still 0,
+        // and tryRemoveEventListener() above will fail. Work around that very seldom problem.
+        EventTargetData* data = ""
+        ASSERT(data);
+
+        data->eventListenerMap.removeFirstEventListenerCreatedFromMarkup(eventType);
+    }
+
+    return true;
+}
+
 static bool hasLoadListener(Element* element)
 {
     if (element->hasEventListeners(eventNames().loadEvent))

Modified: trunk/Source/WebCore/svg/SVGElement.h (117085 => 117086)


--- trunk/Source/WebCore/svg/SVGElement.h	2012-05-15 16:38:03 UTC (rev 117085)
+++ trunk/Source/WebCore/svg/SVGElement.h	2012-05-15 16:59:12 UTC (rev 117086)
@@ -113,6 +113,9 @@
 
     virtual bool haveLoadedRequiredResources();
 
+    virtual bool addEventListener(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture) OVERRIDE;
+    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) OVERRIDE;
+
 protected:
     SVGElement(const QualifiedName&, Document*, ConstructionType = CreateSVGElement);
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to