Abstract ImageEventSender into a general purpose EventSender
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 23:28:15 +0000 (23:28 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 22 Feb 2012 23:28:15 +0000 (23:28 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78840

Reviewed by Adam Barth.

Abstract the functionality in ImageEventSender so that it can be used again.
This functionality may be useful in fixing WebKit Bug #38995.

No functionality was changed; no new tests.

* GNUmakefile.list.am: Added EventSender.h.
* Target.pri: Ditto.
* WebCore.gypi: Ditto.
* WebCore.vcproj/WebCore.vcproj: Ditto.
* WebCore.xcodeproj/project.pbxproj: Ditto.
* dom/EventSender.h: Added.
(WebCore):
(EventSender):
(WebCore::EventSender::eventType):
(WebCore::EventSender::hasPendingEvents):
(WebCore::EventSender::timerFired):
(WebCore::::EventSender):
(WebCore::::dispatchEventSoon):
(WebCore::::cancelEvent):
(WebCore::::dispatchPendingEvents):
* loader/ImageLoader.cpp: Modified to use EventSender.
(WebCore):
(WebCore::ImageLoader::dispatchPendingEvent): Added; called by EventSender when the ImageLoader
should dispatch a pending BeforeLoad or Load event.
* loader/ImageLoader.h:
(WebCore):
(ImageLoader):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@108561 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/GNUmakefile.list.am
Source/WebCore/Target.pri
Source/WebCore/WebCore.gypi
Source/WebCore/WebCore.vcproj/WebCore.vcproj
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/dom/EventSender.h [new file with mode: 0644]
Source/WebCore/loader/ImageLoader.cpp
Source/WebCore/loader/ImageLoader.h

index c57841ae679b882a5080db1dfff32f0788291832..905bff32a5e3adf9701400ea8a649cadd2b92bd7 100644 (file)
@@ -1,3 +1,38 @@
+2012-02-22  Daniel Bates  <dbates@webkit.org>
+
+        Abstract ImageEventSender into a general purpose EventSender
+        https://bugs.webkit.org/show_bug.cgi?id=78840
+
+        Reviewed by Adam Barth.
+
+        Abstract the functionality in ImageEventSender so that it can be used again.
+        This functionality may be useful in fixing WebKit Bug #38995.
+
+        No functionality was changed; no new tests.
+
+        * GNUmakefile.list.am: Added EventSender.h.
+        * Target.pri: Ditto.
+        * WebCore.gypi: Ditto.
+        * WebCore.vcproj/WebCore.vcproj: Ditto.
+        * WebCore.xcodeproj/project.pbxproj: Ditto.
+        * dom/EventSender.h: Added.
+        (WebCore):
+        (EventSender):
+        (WebCore::EventSender::eventType):
+        (WebCore::EventSender::hasPendingEvents):
+        (WebCore::EventSender::timerFired):
+        (WebCore::::EventSender):
+        (WebCore::::dispatchEventSoon):
+        (WebCore::::cancelEvent):
+        (WebCore::::dispatchPendingEvents):
+        * loader/ImageLoader.cpp: Modified to use EventSender.
+        (WebCore):
+        (WebCore::ImageLoader::dispatchPendingEvent): Added; called by EventSender when the ImageLoader
+        should dispatch a pending BeforeLoad or Load event.
+        * loader/ImageLoader.h:
+        (WebCore):
+        (ImageLoader):
+
 2012-02-22  Max Vujovic  <mvujovic@adobe.com>
 
         Paddings and borders on root SVG element with viewbox causes child SVG elements to be rendered with the incorrect size
index ead6d39dfd98412d433e2d28b7ba89ad2b1296e8..974da1e44a4e2b20335cc897156ea9384a88ee54 100644 (file)
@@ -1578,6 +1578,7 @@ webcore_sources += \
        Source/WebCore/dom/EventTarget.cpp \
        Source/WebCore/dom/EventTarget.h \
        Source/WebCore/dom/EventQueue.h \
+       Source/WebCore/dom/EventSender.h \
        Source/WebCore/dom/ExceptionBase.cpp \
        Source/WebCore/dom/ExceptionBase.h \
        Source/WebCore/dom/ExceptionCode.h \
index f185b7c3680251f7d48d9f04b1b504e927e0d128..9cce035c9c407b52b46c8baee6537634da5336dd 100644 (file)
@@ -1647,6 +1647,7 @@ HEADERS += \
     dom/EventListenerMap.h \
     dom/EventNames.h \
     dom/EventQueue.h \
+    dom/EventSender.h \
     dom/EventTarget.h \
     dom/ExceptionBase.h \
     dom/ExceptionCode.h \
index bb7c30816fe5a520c171e3519875a33934f7655f..2698179869483b62df7b4f1f2850a93980aba639 100644 (file)
             'dom/EventListenerMap.cpp',
             'dom/EventNames.cpp',
             'dom/EventQueue.h',
+            'dom/EventSender.h',
             'dom/EventTarget.cpp',
             'dom/ExceptionBase.cpp',
             'dom/ExceptionBase.h',
index 0b8ce15c50d96b865e4bd34bef281a63f0cc8240..1e7c6f0601bfd017687dcd67d3871d35981a1581 100755 (executable)
                                RelativePath="..\dom\EventQueue.h"
                                >
                        </File>
+                       <File
+                               RelativePath="..\dom\EventSender.h"
+                               >
+                       </File>
                        <File
                                RelativePath="..\dom\EventTarget.cpp"
                                >
index 85ca93d830384956cb22ec500f175fbbd48533a3..6a31327b9c774de13311505f07a01a1661a034c8 100644 (file)
                CE057FA31220731100A476D5 /* DocumentMarkerController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentMarkerController.cpp; sourceTree = "<group>"; };
                CE057FA41220731100A476D5 /* DocumentMarkerController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DocumentMarkerController.h; sourceTree = "<group>"; };
                CE54FD371016D9A6008B44C8 /* ScriptSourceProvider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScriptSourceProvider.h; sourceTree = "<group>"; };
+               CE5CB1B314EDAB6F00BB2795 /* EventSender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventSender.h; sourceTree = "<group>"; };
                CEA3949A11D45CDA003094CF /* StaticHashSetNodeList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StaticHashSetNodeList.cpp; sourceTree = "<group>"; };
                CEA3949B11D45CDA003094CF /* StaticHashSetNodeList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StaticHashSetNodeList.h; sourceTree = "<group>"; };
                CECCFC3A141973D5002A0AC1 /* DecodeEscapeSequences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DecodeEscapeSequences.h; sourceTree = "<group>"; };
                                939885C108B7E3D100E707C4 /* EventNames.cpp */,
                                939885C208B7E3D100E707C4 /* EventNames.h */,
                                8F6756191288B17B0047ACA3 /* EventQueue.h */,
+                               CE5CB1B314EDAB6F00BB2795 /* EventSender.h */,
                                E12EDBE90B308E0B002704B6 /* EventTarget.cpp */,
                                E12EDB7A0B308A78002704B6 /* EventTarget.h */,
                                85AFA7420AAF298400E84305 /* EventTarget.idl */,
diff --git a/Source/WebCore/dom/EventSender.h b/Source/WebCore/dom/EventSender.h
new file mode 100644 (file)
index 0000000..646034c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef EventSender_h
+#define EventSender_h
+
+#include "Timer.h"
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+template<typename T> class EventSender {
+    WTF_MAKE_NONCOPYABLE(EventSender); WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit EventSender(const AtomicString& eventType);
+
+    const AtomicString& eventType() const { return m_eventType; }
+    void dispatchEventSoon(T*);
+    void cancelEvent(T*);
+    void dispatchPendingEvents();
+
+#ifndef NDEBUG
+    bool hasPendingEvents(T* sender) const
+    {
+        return m_dispatchSoonList.find(sender) != notFound || m_dispatchingList.find(sender) != notFound;
+    }
+#endif
+
+private:
+    void timerFired(Timer<EventSender<T> >*) { dispatchPendingEvents(); }
+
+    AtomicString m_eventType;
+    Timer<EventSender<T> > m_timer;
+    Vector<T*> m_dispatchSoonList;
+    Vector<T*> m_dispatchingList;
+};
+
+template<typename T> EventSender<T>::EventSender(const AtomicString& eventType)
+    : m_eventType(eventType)
+    , m_timer(this, &EventSender::timerFired)
+{
+}
+
+template<typename T> void EventSender<T>::dispatchEventSoon(T* sender)
+{
+    m_dispatchSoonList.append(sender);
+    if (!m_timer.isActive())
+        m_timer.startOneShot(0);
+}
+
+template<typename T> void EventSender<T>::cancelEvent(T* sender)
+{
+    // Remove instances of this sender from both lists.
+    // Use loops because we allow multiple instances to get into the lists.
+    size_t size = m_dispatchSoonList.size();
+    for (size_t i = 0; i < size; ++i) {
+        if (m_dispatchSoonList[i] == sender)
+            m_dispatchSoonList[i] = 0;
+    }
+    size = m_dispatchingList.size();
+    for (size_t i = 0; i < size; ++i) {
+        if (m_dispatchingList[i] == sender)
+            m_dispatchingList[i] = 0;
+    }
+}
+
+template<typename T> void EventSender<T>::dispatchPendingEvents()
+{
+    // Need to avoid re-entering this function; if new dispatches are
+    // scheduled before the parent finishes processing the list, they
+    // will set a timer and eventually be processed.
+    if (!m_dispatchingList.isEmpty())
+        return;
+
+    m_timer.stop();
+
+    m_dispatchSoonList.checkConsistency();
+
+    m_dispatchingList.swap(m_dispatchSoonList);
+    size_t size = m_dispatchingList.size();
+    for (size_t i = 0; i < size; ++i) {
+        if (T* sender = m_dispatchingList[i]) {
+            m_dispatchingList[i] = 0;
+            sender->dispatchPendingEvent(this);
+        }
+    }
+    m_dispatchingList.clear();
+}
+
+} // namespace WebCore
+
+#endif // EventSender_h
index 56e675145e183addb1feba9f91d52728560c5dd2..842175b5e47607057cbc13f2e8ec83a6580a36fd 100644 (file)
@@ -28,6 +28,7 @@
 #include "Document.h"
 #include "Element.h"
 #include "Event.h"
+#include "EventSender.h"
 #include "HTMLNames.h"
 #include "HTMLObjectElement.h"
 #include "HTMLParserIdioms.h"
@@ -62,32 +63,6 @@ template<> struct ValueCheck<WebCore::ImageLoader*> {
 
 namespace WebCore {
 
-class ImageEventSender {
-    WTF_MAKE_NONCOPYABLE(ImageEventSender); WTF_MAKE_FAST_ALLOCATED;
-public:
-    ImageEventSender(const AtomicString& eventType);
-
-    void dispatchEventSoon(ImageLoader*);
-    void cancelEvent(ImageLoader*);
-
-    void dispatchPendingEvents();
-
-#ifndef NDEBUG
-    bool hasPendingEvents(ImageLoader* loader) const
-    {
-        return m_dispatchSoonList.find(loader) != notFound || m_dispatchingList.find(loader) != notFound;
-    }
-#endif
-
-private:
-    void timerFired(Timer<ImageEventSender>*);
-
-    AtomicString m_eventType;
-    Timer<ImageEventSender> m_timer;
-    Vector<ImageLoader*> m_dispatchSoonList;
-    Vector<ImageLoader*> m_dispatchingList;
-};
-
 static ImageEventSender& beforeLoadEventSender()
 {
     DEFINE_STATIC_LOCAL(ImageEventSender, sender, (eventNames().beforeloadEvent));
@@ -302,6 +277,16 @@ void ImageLoader::updateRenderer()
         imageResource->setCachedImage(m_image.get());
 }
 
+void ImageLoader::dispatchPendingEvent(ImageEventSender* eventSender)
+{
+    ASSERT(eventSender == &beforeLoadEventSender() || eventSender == &loadEventSender());
+    const AtomicString& eventType = eventSender->eventType();
+    if (eventType == eventNames().beforeloadEvent)
+        dispatchPendingBeforeLoadEvent();
+    if (eventType == eventNames().loadEvent)
+        dispatchPendingLoadEvent();
+}
+
 void ImageLoader::dispatchPendingBeforeLoadEvent()
 {
     if (m_firedBeforeLoad)
@@ -354,66 +339,4 @@ void ImageLoader::elementDidMoveToNewDocument()
     setImage(0);
 }
 
-ImageEventSender::ImageEventSender(const AtomicString& eventType)
-    : m_eventType(eventType)
-    , m_timer(this, &ImageEventSender::timerFired)
-{
-}
-
-void ImageEventSender::dispatchEventSoon(ImageLoader* loader)
-{
-    m_dispatchSoonList.append(loader);
-    if (!m_timer.isActive())
-        m_timer.startOneShot(0);
-}
-
-void ImageEventSender::cancelEvent(ImageLoader* loader)
-{
-    // Remove instances of this loader from both lists.
-    // Use loops because we allow multiple instances to get into the lists.
-    size_t size = m_dispatchSoonList.size();
-    for (size_t i = 0; i < size; ++i) {
-        if (m_dispatchSoonList[i] == loader)
-            m_dispatchSoonList[i] = 0;
-    }
-    size = m_dispatchingList.size();
-    for (size_t i = 0; i < size; ++i) {
-        if (m_dispatchingList[i] == loader)
-            m_dispatchingList[i] = 0;
-    }
-    if (m_dispatchSoonList.isEmpty())
-        m_timer.stop();
-}
-
-void ImageEventSender::dispatchPendingEvents()
-{
-    // Need to avoid re-entering this function; if new dispatches are
-    // scheduled before the parent finishes processing the list, they
-    // will set a timer and eventually be processed.
-    if (!m_dispatchingList.isEmpty())
-        return;
-
-    m_timer.stop();
-
-    m_dispatchSoonList.checkConsistency();
-
-    m_dispatchingList.swap(m_dispatchSoonList);
-    size_t size = m_dispatchingList.size();
-    for (size_t i = 0; i < size; ++i) {
-        if (ImageLoader* loader = m_dispatchingList[i]) {
-            m_dispatchingList[i] = 0;
-            if (m_eventType == eventNames().beforeloadEvent)
-                loader->dispatchPendingBeforeLoadEvent();
-            else
-                loader->dispatchPendingLoadEvent();
-        }
-    }
-    m_dispatchingList.clear();
-}
-
-void ImageEventSender::timerFired(Timer<ImageEventSender>*)
-{
-    dispatchPendingEvents();
-}
-
 }
index 5f48189971219d8ed85296091f46a2be9ef24ba3..0667b3dc4f80da2ab26427b105a6c7c2d98fc44c 100644 (file)
 namespace WebCore {
 
 class Element;
-class ImageLoadEventSender;
+class ImageLoader;
 class RenderImageResource;
 
+template<typename T> class EventSender;
+typedef EventSender<ImageLoader> ImageEventSender;
+
 class ImageLoader : public CachedImageClient {
 public:
     ImageLoader(Element*);
@@ -59,6 +62,8 @@ public:
     bool haveFiredBeforeLoadEvent() const { return m_firedBeforeLoad; }
     bool haveFiredLoadEvent() const { return m_firedLoad; }
 
+    void dispatchPendingEvent(ImageEventSender*);
+
     static void dispatchPendingBeforeLoadEvents();
     static void dispatchPendingLoadEvents();
 
@@ -69,7 +74,6 @@ private:
     virtual void dispatchLoadEvent() = 0;
     virtual String sourceURI(const AtomicString&) const = 0;
 
-    friend class ImageEventSender;
     void dispatchPendingBeforeLoadEvent();
     void dispatchPendingLoadEvent();