Generate bindings code for EventTarget.addEventListener() / removeEventListener()
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2016 00:17:04 +0000 (00:17 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 May 2016 00:17:04 +0000 (00:17 +0000)
https://bugs.webkit.org/show_bug.cgi?id=157882

Reviewed by Darin Adler.

Generate bindings code for EventTarget.addEventListener() / removeEventListener()
instead of hardcoding them in the bindings generator.

Source/WebCore:

No new tests, rebaselined existing test, no web-exposed behavior change.

* Modules/webaudio/AudioScheduledSourceNode.cpp:
(WebCore::AudioScheduledSourceNode::addEventListener):
(WebCore::AudioScheduledSourceNode::removeEventListener):
* Modules/webaudio/AudioScheduledSourceNode.h:
* Modules/webaudio/ScriptProcessorNode.cpp:
(WebCore::ScriptProcessorNode::addEventListener):
(WebCore::ScriptProcessorNode::removeEventListener):
* Modules/webaudio/ScriptProcessorNode.h:
* bindings/gobject/GObjectEventListener.cpp:
(WebCore::GObjectEventListener::operator==):
* bindings/gobject/GObjectEventListener.h:
* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::operator==):
(WebCore::eventHandlerAttribute): Deleted.
* bindings/js/JSEventListener.h:
(WebCore::JSEventListener::create):
(WebCore::JSEventListener::cast): Deleted.
(WebCore::JSEventListener::jsFunction): Deleted.
* bindings/objc/ObjCEventListener.h:
* bindings/objc/ObjCEventListener.mm:
(WebCore::ObjCEventListener::operator==):
* bindings/scripts/CodeGeneratorJS.pm:
(GenerateImplementation):
(JSValueToNative):
(GetParentClassName): Deleted.
(GetCallbackClassName): Deleted.
(GetJSCallbackDataType): Deleted.
* dom/EventListener.h:
* dom/EventListenerMap.cpp:
(WebCore::addListenerToVector):
(WebCore::EventListenerMap::add):
(WebCore::removeListenerFromVector):
(WebCore::EventListenerMap::remove):
(WebCore::copyListenersNotCreatedFromMarkupToTarget):
* dom/EventListenerMap.h:
* dom/EventTarget.cpp:
(WebCore::EventTarget::addEventListener):
(WebCore::EventTarget::addEventListenerForBindings):
(WebCore::EventTarget::removeEventListenerForBindings):
(WebCore::EventTarget::removeEventListener):
(WebCore::EventTarget::setAttributeEventListener):
(WebCore::EventTarget::clearAttributeEventListener):
* dom/EventTarget.h:
* dom/EventTarget.idl:
* dom/MessagePort.cpp:
(WebCore::MessagePort::addEventListener):
* dom/MessagePort.h:
* dom/Node.cpp:
(WebCore::tryAddEventListener):
(WebCore::Node::addEventListener):
(WebCore::tryRemoveEventListener):
(WebCore::Node::removeEventListener):
* dom/Node.h:
* dom/RegisteredEventListener.h:
(WebCore::RegisteredEventListener::RegisteredEventListener):
* html/HTMLMediaElement.cpp:
(WebCore::HTMLMediaElement::addEventListener):
(WebCore::HTMLMediaElement::removeEventListener):
* html/HTMLMediaElement.h:
* html/ImageDocument.cpp:
(WebCore::ImageDocument::createDocumentStructure):
(WebCore::ImageEventListener::operator==):
* html/shadow/MediaControlsApple.cpp:
(WebCore::MediaControlsApple::showClosedCaptionTrackList):
(WebCore::MediaControlsApple::hideClosedCaptionTrackList):
(WebCore::MediaControlsAppleEventListener::operator==):
* html/shadow/MediaControlsApple.h:
* inspector/InspectorIndexedDBAgent.cpp:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::addEventListener):
(WebCore::DOMWindow::removeEventListener):
* page/DOMWindow.h:
* platform/cocoa/WebPlaybackSessionModelMediaElement.h:
* platform/cocoa/WebVideoFullscreenModelVideoElement.h:
* svg/SVGElement.cpp:
(WebCore::SVGElement::addEventListener):
(WebCore::SVGElement::removeEventListener):
* svg/SVGElement.h:
* svg/SVGTRefElement.cpp:
(WebCore::SVGTRefTargetEventListener::attach):
(WebCore::SVGTRefTargetEventListener::detach):
(WebCore::SVGTRefTargetEventListener::operator==):
* svg/animation/SVGSMILElement.cpp:
(WebCore::ConditionEventListener::operator==):
(WebCore::SVGSMILElement::connectConditions):
(WebCore::SVGSMILElement::disconnectConditions):

Source/WebKit/win:

* DOMEventsClasses.cpp:
(WebEventListener::operator==):
* DOMEventsClasses.h:

Source/WebKit2:

* WebProcess/Plugins/PDF/PDFPluginAnnotation.h:
* WebProcess/Plugins/PDF/PDFPluginAnnotation.mm:
(WebKit::PDFPluginAnnotation::attach):
(WebKit::PDFPluginAnnotation::~PDFPluginAnnotation):
* WebProcess/Plugins/PDF/PDFPluginPasswordField.mm:
(WebKit::PDFPluginPasswordField::~PDFPluginPasswordField):
(WebKit::PDFPluginPasswordField::createAnnotationElement):
* WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm:
(WebKit::PDFPluginTextAnnotation::~PDFPluginTextAnnotation):
(WebKit::PDFPluginTextAnnotation::createAnnotationElement):

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

49 files changed:
Source/WebCore/ChangeLog
Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.cpp
Source/WebCore/Modules/webaudio/AudioScheduledSourceNode.h
Source/WebCore/Modules/webaudio/ScriptProcessorNode.cpp
Source/WebCore/Modules/webaudio/ScriptProcessorNode.h
Source/WebCore/bindings/gobject/GObjectEventListener.cpp
Source/WebCore/bindings/gobject/GObjectEventListener.h
Source/WebCore/bindings/js/JSEventListener.cpp
Source/WebCore/bindings/js/JSEventListener.h
Source/WebCore/bindings/objc/ObjCEventListener.h
Source/WebCore/bindings/objc/ObjCEventListener.mm
Source/WebCore/bindings/scripts/CodeGeneratorJS.pm
Source/WebCore/bindings/scripts/test/JS/JSTestObj.cpp
Source/WebCore/dom/EventListener.h
Source/WebCore/dom/EventListenerMap.cpp
Source/WebCore/dom/EventListenerMap.h
Source/WebCore/dom/EventTarget.cpp
Source/WebCore/dom/EventTarget.h
Source/WebCore/dom/EventTarget.idl
Source/WebCore/dom/MessagePort.cpp
Source/WebCore/dom/MessagePort.h
Source/WebCore/dom/Node.cpp
Source/WebCore/dom/Node.h
Source/WebCore/dom/RegisteredEventListener.h
Source/WebCore/html/HTMLMediaElement.cpp
Source/WebCore/html/HTMLMediaElement.h
Source/WebCore/html/ImageDocument.cpp
Source/WebCore/html/shadow/MediaControlsApple.cpp
Source/WebCore/html/shadow/MediaControlsApple.h
Source/WebCore/inspector/InspectorIndexedDBAgent.cpp
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/DOMWindow.h
Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.h
Source/WebCore/platform/cocoa/WebPlaybackSessionModelMediaElement.mm
Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.h
Source/WebCore/platform/cocoa/WebVideoFullscreenModelVideoElement.mm
Source/WebCore/svg/SVGElement.cpp
Source/WebCore/svg/SVGElement.h
Source/WebCore/svg/SVGTRefElement.cpp
Source/WebCore/svg/animation/SVGSMILElement.cpp
Source/WebKit/win/ChangeLog
Source/WebKit/win/DOMCoreClasses.cpp
Source/WebKit/win/DOMEventsClasses.cpp
Source/WebKit/win/DOMEventsClasses.h
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.h
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginAnnotation.mm
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginPasswordField.mm
Source/WebKit2/WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm

index 138c2ad..50e2b94 100644 (file)
@@ -1,5 +1,104 @@
 2016-05-23  Chris Dumez  <cdumez@apple.com>
 
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        https://bugs.webkit.org/show_bug.cgi?id=157882
+
+        Reviewed by Darin Adler.
+
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        instead of hardcoding them in the bindings generator.
+
+        No new tests, rebaselined existing test, no web-exposed behavior change.
+
+        * Modules/webaudio/AudioScheduledSourceNode.cpp:
+        (WebCore::AudioScheduledSourceNode::addEventListener):
+        (WebCore::AudioScheduledSourceNode::removeEventListener):
+        * Modules/webaudio/AudioScheduledSourceNode.h:
+        * Modules/webaudio/ScriptProcessorNode.cpp:
+        (WebCore::ScriptProcessorNode::addEventListener):
+        (WebCore::ScriptProcessorNode::removeEventListener):
+        * Modules/webaudio/ScriptProcessorNode.h:
+        * bindings/gobject/GObjectEventListener.cpp:
+        (WebCore::GObjectEventListener::operator==):
+        * bindings/gobject/GObjectEventListener.h:
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::operator==):
+        (WebCore::eventHandlerAttribute): Deleted.
+        * bindings/js/JSEventListener.h:
+        (WebCore::JSEventListener::create):
+        (WebCore::JSEventListener::cast): Deleted.
+        (WebCore::JSEventListener::jsFunction): Deleted.
+        * bindings/objc/ObjCEventListener.h:
+        * bindings/objc/ObjCEventListener.mm:
+        (WebCore::ObjCEventListener::operator==):
+        * bindings/scripts/CodeGeneratorJS.pm:
+        (GenerateImplementation):
+        (JSValueToNative):
+        (GetParentClassName): Deleted.
+        (GetCallbackClassName): Deleted.
+        (GetJSCallbackDataType): Deleted.
+        * dom/EventListener.h:
+        * dom/EventListenerMap.cpp:
+        (WebCore::addListenerToVector):
+        (WebCore::EventListenerMap::add):
+        (WebCore::removeListenerFromVector):
+        (WebCore::EventListenerMap::remove):
+        (WebCore::copyListenersNotCreatedFromMarkupToTarget):
+        * dom/EventListenerMap.h:
+        * dom/EventTarget.cpp:
+        (WebCore::EventTarget::addEventListener):
+        (WebCore::EventTarget::addEventListenerForBindings):
+        (WebCore::EventTarget::removeEventListenerForBindings):
+        (WebCore::EventTarget::removeEventListener):
+        (WebCore::EventTarget::setAttributeEventListener):
+        (WebCore::EventTarget::clearAttributeEventListener):
+        * dom/EventTarget.h:
+        * dom/EventTarget.idl:
+        * dom/MessagePort.cpp:
+        (WebCore::MessagePort::addEventListener):
+        * dom/MessagePort.h:
+        * dom/Node.cpp:
+        (WebCore::tryAddEventListener):
+        (WebCore::Node::addEventListener):
+        (WebCore::tryRemoveEventListener):
+        (WebCore::Node::removeEventListener):
+        * dom/Node.h:
+        * dom/RegisteredEventListener.h:
+        (WebCore::RegisteredEventListener::RegisteredEventListener):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::addEventListener):
+        (WebCore::HTMLMediaElement::removeEventListener):
+        * html/HTMLMediaElement.h:
+        * html/ImageDocument.cpp:
+        (WebCore::ImageDocument::createDocumentStructure):
+        (WebCore::ImageEventListener::operator==):
+        * html/shadow/MediaControlsApple.cpp:
+        (WebCore::MediaControlsApple::showClosedCaptionTrackList):
+        (WebCore::MediaControlsApple::hideClosedCaptionTrackList):
+        (WebCore::MediaControlsAppleEventListener::operator==):
+        * html/shadow/MediaControlsApple.h:
+        * inspector/InspectorIndexedDBAgent.cpp:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::addEventListener):
+        (WebCore::DOMWindow::removeEventListener):
+        * page/DOMWindow.h:
+        * platform/cocoa/WebPlaybackSessionModelMediaElement.h:
+        * platform/cocoa/WebVideoFullscreenModelVideoElement.h:
+        * svg/SVGElement.cpp:
+        (WebCore::SVGElement::addEventListener):
+        (WebCore::SVGElement::removeEventListener):
+        * svg/SVGElement.h:
+        * svg/SVGTRefElement.cpp:
+        (WebCore::SVGTRefTargetEventListener::attach):
+        (WebCore::SVGTRefTargetEventListener::detach):
+        (WebCore::SVGTRefTargetEventListener::operator==):
+        * svg/animation/SVGSMILElement.cpp:
+        (WebCore::ConditionEventListener::operator==):
+        (WebCore::SVGSMILElement::connectConditions):
+        (WebCore::SVGSMILElement::disconnectConditions):
+
+2016-05-23  Chris Dumez  <cdumez@apple.com>
+
         Fix undefined behavior introduced in r201290.
         https://bugs.webkit.org/show_bug.cgi?id=157961
 
index bc4efb4..4ca6a04 100644 (file)
@@ -201,7 +201,7 @@ void AudioScheduledSourceNode::finish()
     }
 }
 
-bool AudioScheduledSourceNode::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool AudioScheduledSourceNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     bool success = AudioNode::addEventListener(eventType, WTFMove(listener), useCapture);
     if (success && eventType == eventNames().endedEvent)
@@ -209,7 +209,7 @@ bool AudioScheduledSourceNode::addEventListener(const AtomicString& eventType, R
     return success;
 }
 
-bool AudioScheduledSourceNode::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool AudioScheduledSourceNode::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     bool success = AudioNode::removeEventListener(eventType, listener, useCapture);
     if (success && eventType == eventNames().endedEvent)
index ecede38..cb4dd3c 100644 (file)
@@ -101,8 +101,8 @@ protected:
     static const double UnknownTime;
 
 private:
-    bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-    bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+    bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
     void removeAllEventListeners() override;
 };
 
index 685c673..0cc41b7 100644 (file)
@@ -273,7 +273,7 @@ double ScriptProcessorNode::latencyTime() const
     return std::numeric_limits<double>::infinity();
 }
 
-bool ScriptProcessorNode::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool ScriptProcessorNode::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     bool success = AudioNode::addEventListener(eventType, WTFMove(listener), useCapture);
     if (success && eventType == eventNames().audioprocessEvent)
@@ -281,7 +281,7 @@ bool ScriptProcessorNode::addEventListener(const AtomicString& eventType, RefPtr
     return success;
 }
 
-bool ScriptProcessorNode::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool ScriptProcessorNode::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     bool success = AudioNode::removeEventListener(eventType, listener, useCapture);
     if (success && eventType == eventNames().audioprocessEvent)
index 6b65d01..1306259 100644 (file)
@@ -73,8 +73,8 @@ private:
 
     void fireProcessEvent();
 
-    bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-    bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+    bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
     void removeAllEventListeners() override;
 
     // Double buffering
index d4a1d18..f2ed932 100644 (file)
@@ -57,9 +57,9 @@ void GObjectEventListener::gobjectDestroyed()
     // and later use-after-free with the m_handler = 0; assignment.
     RefPtr<GObjectEventListener> protectedThis(this);
 
-    m_coreTarget->removeEventListener(m_domEventName.data(), this, m_capture);
-    m_coreTarget = 0;
-    m_handler = 0;
+    m_coreTarget->removeEventListener(m_domEventName.data(), *this, m_capture);
+    m_coreTarget = nullptr;
+    m_handler = nullptr;
 }
 
 void GObjectEventListener::handleEvent(ScriptExecutionContext*, Event* event)
@@ -77,7 +77,7 @@ void GObjectEventListener::handleEvent(ScriptExecutionContext*, Event* event)
     g_value_unset(parameters + 1);
 }
 
-bool GObjectEventListener::operator==(const EventListener& listener)
+bool GObjectEventListener::operator==(const EventListener& listener) const
 {
     if (const GObjectEventListener* gobjectEventListener = GObjectEventListener::cast(&listener))
         return m_target == gobjectEventListener->m_target
index e117f40..206bbd7 100644 (file)
@@ -35,14 +35,14 @@ public:
 
     static bool addEventListener(GObject* target, EventTarget* coreTarget, const char* domEventName, GClosure* handler, bool useCapture)
     {
-        RefPtr<GObjectEventListener> listener(adoptRef(new GObjectEventListener(target, coreTarget, domEventName, handler, useCapture)));
-        return coreTarget->addEventListener(domEventName, listener.release(), useCapture);
+        Ref<GObjectEventListener> listener(adoptRef(*new GObjectEventListener(target, coreTarget, domEventName, handler, useCapture)));
+        return coreTarget->addEventListener(domEventName, WTFMove(listener), useCapture);
     }
 
     static bool removeEventListener(GObject* target, EventTarget* coreTarget, const char* domEventName, GClosure* handler, bool useCapture)
     {
         GObjectEventListener key(target, coreTarget, domEventName, handler, useCapture);
-        return coreTarget->removeEventListener(domEventName, &key, useCapture);
+        return coreTarget->removeEventListener(domEventName, key, useCapture);
     }
 
     static void gobjectDestroyedCallback(GObjectEventListener* listener, GObject*)
@@ -57,7 +57,7 @@ public:
             : 0;
     }
 
-    virtual bool operator==(const EventListener& other);
+    bool operator==(const EventListener& other) const override;
 
 private:
     GObjectEventListener(GObject*, EventTarget*, const char* domEventName, GClosure*, bool capture);
index cc54fd4..bfd78a8 100644 (file)
@@ -163,20 +163,13 @@ bool JSEventListener::virtualisAttribute() const
     return m_isAttribute;
 }
 
-bool JSEventListener::operator==(const EventListener& listener)
+bool JSEventListener::operator==(const EventListener& listener) const
 {
     if (const JSEventListener* jsEventListener = JSEventListener::cast(&listener))
         return m_jsFunction == jsEventListener->m_jsFunction && m_isAttribute == jsEventListener->m_isAttribute;
     return false;
 }
 
-Ref<JSEventListener> createJSEventListenerForAdd(JSC::ExecState& state, JSC::JSObject& listener, JSC::JSObject& wrapper)
-{
-    // FIXME: This abstraction is no longer needed. It was part of support for SVGElementInstance.
-    // We should remove it and simplify the bindings generation scripts.
-    return JSEventListener::create(&listener, &wrapper, false, currentWorld(&state));
-}
-
 static inline JSC::JSValue eventHandlerAttribute(EventListener* abstractListener, ScriptExecutionContext& context)
 {
     if (!abstractListener)
index a039553..e55a25b 100644 (file)
@@ -43,6 +43,14 @@ public:
         return adoptRef(*new JSEventListener(listener, wrapper, isAttribute, world));
     }
 
+    static RefPtr<JSEventListener> create(JSC::JSValue listener, JSC::JSObject& wrapper, bool isAttribute, DOMWrapperWorld& world)
+    {
+        if (UNLIKELY(!listener.isObject()))
+            return nullptr;
+
+        return adoptRef(new JSEventListener(JSC::asObject(listener), &wrapper, isAttribute, world));
+    }
+
     static const JSEventListener* cast(const EventListener* listener)
     {
         return listener->type() == JSEventListenerType
@@ -52,7 +60,7 @@ public:
 
     virtual ~JSEventListener();
 
-    bool operator==(const EventListener& other) override;
+    bool operator==(const EventListener& other) const override;
 
     // Returns true if this event listener was created for an event handler attribute, like "onload" or "onclick".
     bool isAttribute() const { return m_isAttribute; }
@@ -99,9 +107,6 @@ void setDocumentEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, HTMLEleme
 JSC::JSValue documentEventHandlerAttribute(Document&, const AtomicString& eventType);
 void setDocumentEventHandlerAttribute(JSC::ExecState&, JSC::JSObject&, Document&, const AtomicString& eventType, JSC::JSValue);
 
-Ref<JSEventListener> createJSEventListenerForAdd(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
-Ref<JSEventListener> createJSEventListenerForRemove(JSC::ExecState&, JSC::JSObject& listener, JSC::JSObject& wrapper);
-
 inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* scriptExecutionContext) const
 {
     // initializeJSFunction can trigger code that deletes this event listener
@@ -133,11 +138,6 @@ inline JSC::JSObject* JSEventListener::jsFunction(ScriptExecutionContext* script
     return m_jsFunction.get();
 }
 
-inline Ref<JSEventListener> createJSEventListenerForRemove(JSC::ExecState& state, JSC::JSObject& listener, JSC::JSObject& wrapper)
-{
-    return createJSEventListenerForAdd(state, listener, wrapper);
-}
-
 } // namespace WebCore
 
 #endif // JSEventListener_h
index f3e9843..23c9845 100644 (file)
@@ -52,7 +52,7 @@ namespace WebCore {
 
         ObjCEventListener(ObjCListener);
         virtual ~ObjCEventListener();
-        virtual bool operator==(const EventListener&);
+        virtual bool operator==(const EventListener&) const;
         virtual void handleEvent(ScriptExecutionContext*, Event*);
 
         RetainPtr<ObjCListener> m_listener;
index 099d455..32fe6e6 100644 (file)
@@ -79,7 +79,7 @@ void ObjCEventListener::handleEvent(ScriptExecutionContext*, Event* event)
     [listener handleEvent:kit(event)];
 }
 
-bool ObjCEventListener::operator==(const EventListener& listener)
+bool ObjCEventListener::operator==(const EventListener& listener) const
 {
     if (const ObjCEventListener* objCEventListener = ObjCEventListener::cast(&listener))
         return m_listener == objCEventListener->m_listener;
index 65d36f9..db5257f 100644 (file)
@@ -143,26 +143,6 @@ sub EventHandlerAttributeEventName
     return "eventNames().${eventType}Event";
 }
 
-sub GenerateEventListenerCall
-{
-    my $functionName = shift;
-    my $suffix = ucfirst $functionName;
-    my $passRefPtrHandling = ($functionName eq "add") ? "" : ".ptr()";
-
-    $implIncludes{"JSEventListener.h"} = 1;
-
-    my @GenerateEventListenerImpl = ();
-
-    push(@GenerateEventListenerImpl, <<END);
-    JSValue listener = state->argument(1);
-    if (UNLIKELY(!listener.isObject()))
-        return JSValue::encode(jsUndefined());
-    impl.${functionName}EventListener(state->argument(0).toString(state)->toAtomicString(state), createJSEventListenerFor$suffix(*state, *asObject(listener), *castedThis)$passRefPtrHandling, state->argument(2).toBoolean(state));
-    return JSValue::encode(jsUndefined());
-END
-    return @GenerateEventListenerImpl;
-}
-
 sub GetParentClassName
 {
     my $interface = shift;
@@ -1722,6 +1702,9 @@ sub GetFunctionLength
 {
     my $function = shift;
 
+    # FIXME: EventTarget.addEventListener() / removeEventListener() currently specifies all the parameters as optional.
+    return 2 if $function->signature->name eq "addEventListener" || $function->signature->name eq "removeEventListener";
+
     my $length = 0;
     foreach my $parameter (@{$function->parameters}) {
         # Abort as soon as we find the first optional parameter as no mandatory
@@ -3214,30 +3197,24 @@ END
                         push(@implContent, "            return JSValue::encode(jsUndefined());\n");
                         push(@implContent, "    }\n");
                     }
-                    # For compatibility with legacy content, the EventListener calls are generated without GenerateArgumentsCountCheck.
-                    if ($function->signature->name eq "addEventListener") {
-                        push(@implContent, GenerateEventListenerCall("add"));
-                    } elsif ($function->signature->name eq "removeEventListener") {
-                        push(@implContent, GenerateEventListenerCall("remove"));
-                    } else {
-                        GenerateArgumentsCountCheck(\@implContent, $function, $interface);
 
-                        if ($raisesExceptionWithMessage) {
-                            push(@implContent, "    ExceptionCodeWithMessage ec;\n");
-                        } elsif ($raisesException) {
-                            push(@implContent, "    ExceptionCode ec = 0;\n");
-                        }
+                    GenerateArgumentsCountCheck(\@implContent, $function, $interface);
 
-                        if ($function->signature->extendedAttributes->{"CheckSecurityForNode"}) {
-                            push(@implContent, "    if (!shouldAllowAccessToNode(state, impl." . $function->signature->name . "(" . ($raisesException ? "ec" : "") .")))\n");
-                            push(@implContent, "        return JSValue::encode(jsNull());\n");
-                            $implIncludes{"JSDOMBinding.h"} = 1;
-                        }
+                    if ($raisesExceptionWithMessage) {
+                        push(@implContent, "    ExceptionCodeWithMessage ec;\n");
+                    } elsif ($raisesException) {
+                        push(@implContent, "    ExceptionCode ec = 0;\n");
+                    }
 
-                        my $numParameters = @{$function->parameters};
-                        my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $interface, $numParameters, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
-                        GenerateImplementationFunctionCall($function, $functionString, "    ", $svgPropertyType, $interface);
+                    if ($function->signature->extendedAttributes->{"CheckSecurityForNode"}) {
+                        push(@implContent, "    if (!shouldAllowAccessToNode(state, impl." . $function->signature->name . "(" . ($raisesException ? "ec" : "") .")))\n");
+                        push(@implContent, "        return JSValue::encode(jsNull());\n");
+                        $implIncludes{"JSDOMBinding.h"} = 1;
                     }
+
+                    my $numParameters = @{$function->parameters};
+                    my ($functionString, $dummy) = GenerateParametersCheck(\@implContent, $function, $interface, $numParameters, $functionImplementationName, $svgPropertyType, $svgPropertyOrListPropertyType, $svgListPropertyType);
+                    GenerateImplementationFunctionCall($function, $functionString, "    ", $svgPropertyType, $interface);
                 }
             }
 
@@ -4436,6 +4413,9 @@ sub JSValueToNative
 
     AddToImplIncludes("JS$type.h", $conditional);
 
+    # FIXME: EventListener should be a callback interface.
+    return "JSEventListener::create($value, *castedThis, false, currentWorld(state))" if $type eq "EventListener";
+
     my $extendedAttributes = $codeGenerator->getInterfaceExtendedAttributesFromName($type);
     return ("JS${type}::toWrapped(*state, $value)", 1) if $extendedAttributes->{"JSCustomToNativeObject"};
     return ("JS${type}::toWrapped($value)", 0);
index ef9586c..acd9b32 100644 (file)
@@ -4390,10 +4390,18 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionAddEventListener(ExecStat
         return throwThisTypeError(*state, "TestObj", "addEventListener");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    JSValue listener = state->argument(1);
-    if (UNLIKELY(!listener.isObject()))
+    if (UNLIKELY(state->argumentCount() < 2))
+        return throwVMError(state, createNotEnoughArgumentsError(state));
+    auto type = state->argument(0).toWTFString(state);
+    if (UNLIKELY(state->hadException()))
+        return JSValue::encode(jsUndefined());
+    auto listener = JSEventListener::create(state->argument(1), *castedThis, false, currentWorld(state));
+    if (UNLIKELY(!listener))
+        return throwArgumentTypeError(*state, 1, "listener", "TestObj", "addEventListener", "EventListener");
+    auto useCapture = state->argument(2).toBoolean(state);
+    if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
-    impl.addEventListener(state->argument(0).toString(state)->toAtomicString(state), createJSEventListenerForAdd(*state, *asObject(listener), *castedThis), state->argument(2).toBoolean(state));
+    impl.addEventListener(WTFMove(type), *listener, WTFMove(useCapture));
     return JSValue::encode(jsUndefined());
 }
 
@@ -4405,10 +4413,18 @@ EncodedJSValue JSC_HOST_CALL jsTestObjPrototypeFunctionRemoveEventListener(ExecS
         return throwThisTypeError(*state, "TestObj", "removeEventListener");
     ASSERT_GC_OBJECT_INHERITS(castedThis, JSTestObj::info());
     auto& impl = castedThis->wrapped();
-    JSValue listener = state->argument(1);
-    if (UNLIKELY(!listener.isObject()))
+    if (UNLIKELY(state->argumentCount() < 2))
+        return throwVMError(state, createNotEnoughArgumentsError(state));
+    auto type = state->argument(0).toWTFString(state);
+    if (UNLIKELY(state->hadException()))
+        return JSValue::encode(jsUndefined());
+    auto listener = JSEventListener::create(state->argument(1), *castedThis, false, currentWorld(state));
+    if (UNLIKELY(!listener))
+        return throwArgumentTypeError(*state, 1, "listener", "TestObj", "removeEventListener", "EventListener");
+    auto useCapture = state->argument(2).toBoolean(state);
+    if (UNLIKELY(state->hadException()))
         return JSValue::encode(jsUndefined());
-    impl.removeEventListener(state->argument(0).toString(state)->toAtomicString(state), createJSEventListenerForRemove(*state, *asObject(listener), *castedThis).ptr(), state->argument(2).toBoolean(state));
+    impl.removeEventListener(WTFMove(type), *listener, WTFMove(useCapture));
     return JSValue::encode(jsUndefined());
 }
 
index bb4f9f0..2243529 100644 (file)
@@ -48,7 +48,7 @@ public:
     };
 
     virtual ~EventListener() { }
-    virtual bool operator==(const EventListener&) = 0;
+    virtual bool operator==(const EventListener&) const = 0;
     virtual void handleEvent(ScriptExecutionContext*, Event*) = 0;
     virtual bool wasCreatedFromMarkup() const { return false; }
 
index f197c20..b04e121 100644 (file)
@@ -95,9 +95,9 @@ Vector<AtomicString> EventListenerMap::eventTypes() const
     return types;
 }
 
-static bool addListenerToVector(EventListenerVector* vector, PassRefPtr<EventListener> listener, bool useCapture)
+static bool addListenerToVector(EventListenerVector* vector, Ref<EventListener>&& listener, bool useCapture)
 {
-    RegisteredEventListener registeredListener(listener, useCapture);
+    RegisteredEventListener registeredListener(WTFMove(listener), useCapture);
 
     if (vector->find(registeredListener) != notFound)
         return false; // Duplicate listener.
@@ -106,20 +106,20 @@ static bool addListenerToVector(EventListenerVector* vector, PassRefPtr<EventLis
     return true;
 }
 
-bool EventListenerMap::add(const AtomicString& eventType, PassRefPtr<EventListener> listener, bool useCapture)
+bool EventListenerMap::add(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     assertNoActiveIterators();
 
     for (auto& entry : m_entries) {
         if (entry.first == eventType)
-            return addListenerToVector(entry.second.get(), listener, useCapture);
+            return addListenerToVector(entry.second.get(), WTFMove(listener), useCapture);
     }
 
     m_entries.append(std::make_pair(eventType, std::make_unique<EventListenerVector>()));
-    return addListenerToVector(m_entries.last().second.get(), listener, useCapture);
+    return addListenerToVector(m_entries.last().second.get(), WTFMove(listener), useCapture);
 }
 
-static bool removeListenerFromVector(EventListenerVector* listenerVector, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
+static bool removeListenerFromVector(EventListenerVector* listenerVector, EventListener& listener, bool useCapture, size_t& indexOfRemovedListener)
 {
     RegisteredEventListener registeredListener(listener, useCapture);
     indexOfRemovedListener = listenerVector->find(registeredListener);
@@ -129,7 +129,7 @@ static bool removeListenerFromVector(EventListenerVector* listenerVector, EventL
     return true;
 }
 
-bool EventListenerMap::remove(const AtomicString& eventType, EventListener* listener, bool useCapture, size_t& indexOfRemovedListener)
+bool EventListenerMap::remove(const AtomicString& eventType, EventListener& listener, bool useCapture, size_t& indexOfRemovedListener)
 {
     assertNoActiveIterators();
 
@@ -185,7 +185,7 @@ static void copyListenersNotCreatedFromMarkupToTarget(const AtomicString& eventT
         // Event listeners created from markup have already been transfered to the shadow tree during cloning.
         if (listener.listener->wasCreatedFromMarkup())
             continue;
-        target->addEventListener(eventType, listener.listener.copyRef(), listener.useCapture);
+        target->addEventListener(eventType, *listener.listener, listener.useCapture);
     }
 }
 
index 89ff666..1efe6ab 100644 (file)
@@ -54,8 +54,8 @@ public:
     bool containsCapturing(const AtomicString& eventType) const;
 
     void clear();
-    bool add(const AtomicString& eventType, PassRefPtr<EventListener>, bool useCapture);
-    bool remove(const AtomicString& eventType, EventListener*, bool useCapture, size_t& indexOfRemovedListener);
+    bool add(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture);
+    bool remove(const AtomicString& eventType, EventListener&, bool useCapture, size_t& indexOfRemovedListener);
     EventListenerVector* find(const AtomicString& eventType);
     Vector<AtomicString> eventTypes() const;
 
index ec21098..d248385 100644 (file)
@@ -75,12 +75,28 @@ bool EventTarget::isMessagePort() const
     return false;
 }
 
-bool EventTarget::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     return ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), useCapture);
 }
 
-bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+void EventTarget::addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+{
+    // FIXME: listener is not supposed to be nullable.
+    if (!listener)
+        return;
+    addEventListener(eventType, listener.releaseNonNull(), useCapture);
+}
+
+void EventTarget::removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+{
+    // FIXME: listener is not supposed to be nullable.
+    if (!listener)
+        return;
+    removeEventListener(eventType, *listener, useCapture);
+}
+
+bool EventTarget::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     EventTargetData* d = eventTargetData();
     if (!d)
@@ -110,12 +126,12 @@ bool EventTarget::removeEventListener(const AtomicString& eventType, EventListen
     return true;
 }
 
-bool EventTarget::setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener> listener)
+bool EventTarget::setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener)
 {
     clearAttributeEventListener(eventType);
     if (!listener)
         return false;
-    return addEventListener(eventType, listener, false);
+    return addEventListener(eventType, listener.releaseNonNull(), false);
 }
 
 EventListener* EventTarget::getAttributeEventListener(const AtomicString& eventType)
@@ -132,7 +148,7 @@ bool EventTarget::clearAttributeEventListener(const AtomicString& eventType)
     EventListener* listener = getAttributeEventListener(eventType);
     if (!listener)
         return false;
-    return removeEventListener(eventType, listener, false);
+    return removeEventListener(eventType, *listener, false);
 }
 
 bool EventTarget::dispatchEventForBindings(Event* event, ExceptionCode& ec)
index f9b0f21..1b1ded1 100644 (file)
@@ -121,15 +121,18 @@ public:
     virtual DOMWindow* toDOMWindow();
     virtual bool isMessagePort() const;
 
-    virtual bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
-    virtual bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture);
+    void addEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
+    void removeEventListenerForBindings(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture);
+    virtual bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture);
+    virtual bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture);
+
     virtual void removeAllEventListeners();
     virtual bool dispatchEvent(Event&);
     bool dispatchEventForBindings(Event*, ExceptionCode&); // DOM API
     virtual void uncaughtExceptionInEventHandler();
 
     // Used for legacy "onEvent" attribute APIs.
-    bool setAttributeEventListener(const AtomicString& eventType, PassRefPtr<EventListener>);
+    bool setAttributeEventListener(const AtomicString& eventType, RefPtr<EventListener>&&);
     bool clearAttributeEventListener(const AtomicString& eventType);
     EventListener* getAttributeEventListener(const AtomicString& eventType);
 
index 593e4c0..c594589 100644 (file)
     JSCustomToNativeObject,
     ObjCProtocol,
 ] interface EventTarget {
-    [ObjCLegacyUnnamedParameters] void addEventListener(DOMString type, EventListener? listener, optional boolean useCapture = false);
-    [ObjCLegacyUnnamedParameters] void removeEventListener(DOMString type, EventListener? listener, optional boolean useCapture = false);
+    // FIXME: The 'type' and 'listener' parameters should not be optional.
+    [ObjCLegacyUnnamedParameters, ImplementedAs=addEventListenerForBindings] void addEventListener([AtomicString] optional DOMString type = "undefined", optional EventListener? listener, optional boolean useCapture = false);
+    [ObjCLegacyUnnamedParameters, ImplementedAs=removeEventListenerForBindings] void removeEventListener([AtomicString] optional DOMString type = "undefined", optional EventListener? listener, optional boolean useCapture = false);
+
     // FIXME: event should not be nullable.
     [ImplementedAs=dispatchEventForBindings, RaisesException] boolean dispatchEvent(Event? event);
 };
index 5a84a44..3d7847c 100644 (file)
@@ -221,9 +221,9 @@ std::unique_ptr<MessagePortArray> MessagePort::entanglePorts(ScriptExecutionCont
     return portArray;
 }
 
-bool MessagePort::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool MessagePort::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
-    if (listener && listener->isAttribute() && eventType == eventNames().messageEvent)
+    if (listener->isAttribute() && eventType == eventNames().messageEvent)
         start();
     return EventTargetWithInlineData::addEventListener(eventType, WTFMove(listener), useCapture);
 }
index bae01d5..9ca124f 100644 (file)
@@ -92,7 +92,7 @@ namespace WebCore {
         // A port gets neutered when it is transferred to a new owner via postMessage().
         bool isNeutered() { return !m_entangledChannel; }
 
-        bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
+        bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
 
     private:
         explicit MessagePort(ScriptExecutionContext&);
index f47bab7..04b9218 100644 (file)
@@ -1902,7 +1902,7 @@ void Node::didMoveToNewDocument(Document* oldDocument)
     }
 }
 
-static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     if (!targetNode->EventTarget::addEventListener(eventType, listener.copyRef(), useCapture))
         return false;
@@ -1938,12 +1938,12 @@ static inline bool tryAddEventListener(Node* targetNode, const AtomicString& eve
     return true;
 }
 
-bool Node::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool Node::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     return tryAddEventListener(this, eventType, WTFMove(listener), useCapture);
 }
 
-static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener* listener, bool useCapture)
+static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     if (!targetNode->EventTarget::removeEventListener(eventType, listener, useCapture))
         return false;
@@ -1979,7 +1979,7 @@ static inline bool tryRemoveEventListener(Node* targetNode, const AtomicString&
     return true;
 }
 
-bool Node::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool Node::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     return tryRemoveEventListener(this, eventType, listener, useCapture);
 }
index 1dbdc75..8dee1c0 100644 (file)
@@ -506,8 +506,8 @@ public:
     EventTargetInterface eventTargetInterface() const override;
     ScriptExecutionContext* scriptExecutionContext() const final; // Implemented in Document.h
 
-    bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-    bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+    bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
 
     using EventTarget::dispatchEvent;
     bool dispatchEvent(Event&) override;
index 12483fa..3f22264 100644 (file)
@@ -31,8 +31,8 @@ namespace WebCore {
 
     class RegisteredEventListener {
     public:
-        RegisteredEventListener(PassRefPtr<EventListener> listener, bool useCapture)
-            : listener(listener)
+        RegisteredEventListener(Ref<EventListener>&& listener, bool useCapture)
+            : listener(WTFMove(listener))
             , useCapture(useCapture)
         {
         }
index 0e410fd..ef6c98a 100644 (file)
@@ -5216,7 +5216,7 @@ bool HTMLMediaElement::dispatchEvent(Event& event)
     return HTMLElement::dispatchEvent(event);
 }
 
-bool HTMLMediaElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool HTMLMediaElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     if (eventType != eventNames().webkitplaybacktargetavailabilitychangedEvent)
         return Node::addEventListener(eventType, WTFMove(listener), useCapture);
@@ -5236,7 +5236,7 @@ bool HTMLMediaElement::addEventListener(const AtomicString& eventType, RefPtr<Ev
     return true;
 }
 
-bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool HTMLMediaElement::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     if (eventType != eventNames().webkitplaybacktargetavailabilitychangedEvent)
         return Node::removeEventListener(eventType, listener, useCapture);
index 372e0ff..04d0dbd 100644 (file)
@@ -344,8 +344,8 @@ public:
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     void webkitShowPlaybackTargetPicker();
-    bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-    bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+    bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
 
     void wirelessRoutesAvailableDidChange() override;
     bool canPlayToWirelessPlaybackTarget() const override;
index 2f35b29..7fd2c7c 100644 (file)
@@ -64,7 +64,7 @@ private:
     {
     }
 
-    bool operator==(const EventListener&) override;
+    bool operator==(const EventListener&) const override;
     void handleEvent(ScriptExecutionContext*, Event*) override;
 
     ImageDocument& m_document;
@@ -237,7 +237,7 @@ void ImageDocument::createDocumentStructure()
         // Set the viewport to be in device pixels (rather than the default of 980).
         processViewport(ASCIILiteral("width=device-width"), ViewportArguments::ImageDocument);
 #else
-        RefPtr<EventListener> listener = ImageEventListener::create(*this);
+        auto listener = ImageEventListener::create(*this);
         if (DOMWindow* window = this->domWindow())
             window->addEventListener("resize", listener.copyRef(), false);
         imageElement->addEventListener("click", WTFMove(listener), false);
@@ -407,7 +407,7 @@ void ImageEventListener::handleEvent(ScriptExecutionContext*, Event* event)
     }
 }
 
-bool ImageEventListener::operator==(const EventListener& other)
+bool ImageEventListener::operator==(const EventListener& other) const
 {
     // All ImageEventListener objects compare as equal; OK since there is only one per document.
     return other.type() == ImageEventListenerType;
index cf7ac4b..d97da78 100644 (file)
@@ -509,15 +509,15 @@ void MediaControlsApple::showClosedCaptionTrackList()
     m_panel->setInlineStyleProperty(CSSPropertyPointerEvents, CSSValueNone);
 
     EventListener& listener = eventListener();
-    m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, &listener, true);
+    m_closedCaptionsContainer->addEventListener(eventNames().wheelEvent, listener, true);
 
     // Track click events in the capture phase at two levels, first at the document level
     // such that a click outside of the <video> may dismiss the track list, second at the
     // media controls level such that a click anywhere outside of the track list hides the
     // track list. These two levels are necessary since it would not be possible to get a
     // reference to the track list when handling the event outside of the shadow tree.
-    document().addEventListener(eventNames().clickEvent, &listener, true);
-    addEventListener(eventNames().clickEvent, &listener, true);
+    document().addEventListener(eventNames().clickEvent, listener, true);
+    addEventListener(eventNames().clickEvent, listener, true);
 }
 
 void MediaControlsApple::hideClosedCaptionTrackList()
@@ -531,9 +531,9 @@ void MediaControlsApple::hideClosedCaptionTrackList()
     m_panel->removeInlineStyleProperty(CSSPropertyPointerEvents);
 
     EventListener& listener = eventListener();
-    m_closedCaptionsContainer->removeEventListener(eventNames().wheelEvent, &listener, true);
-    document().removeEventListener(eventNames().clickEvent, &listener, true);
-    removeEventListener(eventNames().clickEvent, &listener, true);
+    m_closedCaptionsContainer->removeEventListener(eventNames().wheelEvent, listener, true);
+    document().removeEventListener(eventNames().clickEvent, listener, true);
+    removeEventListener(eventNames().clickEvent, listener, true);
 }
 
 void MediaControlsApple::setFullscreenSliderVolume()
@@ -595,7 +595,7 @@ void MediaControlsAppleEventListener::handleEvent(ScriptExecutionContext*, Event
     }
 }
 
-bool MediaControlsAppleEventListener::operator==(const EventListener& listener)
+bool MediaControlsAppleEventListener::operator==(const EventListener& listener) const
 {
     if (const MediaControlsAppleEventListener* mediaControlsAppleEventListener = MediaControlsAppleEventListener::cast(&listener))
         return m_mediaControls == mediaControlsAppleEventListener->m_mediaControls;
index 698cc38..f28dd6b 100644 (file)
@@ -45,7 +45,7 @@ public:
             : 0;
     }
 
-    bool operator==(const EventListener& other) override;
+    bool operator==(const EventListener& other) const override;
 
 private:
     MediaControlsAppleEventListener(MediaControlsApple* mediaControls)
index 4415432..ac0edd4 100644 (file)
@@ -112,7 +112,7 @@ public:
 
     virtual ~OpenDatabaseCallback() { }
 
-    bool operator==(const EventListener& other) override
+    bool operator==(const EventListener& other) const override
     {
         return this == &other;
     }
@@ -371,7 +371,7 @@ public:
 
     virtual ~OpenCursorCallback() { }
 
-    bool operator==(const EventListener& other) override
+    bool operator==(const EventListener& other) const override
     {
         return this == &other;
     }
@@ -660,7 +660,7 @@ public:
 
     virtual ~ClearObjectStoreListener() { }
 
-    bool operator==(const EventListener& other) override
+    bool operator==(const EventListener& other) const override
     {
         return this == &other;
     }
index 78d6fa9..fefdb58 100644 (file)
@@ -1723,7 +1723,7 @@ bool DOMWindow::isSameSecurityOriginAsMainFrame() const
     return false;
 }
 
-bool DOMWindow::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool DOMWindow::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {
     if (!EventTarget::addEventListener(eventType, WTFMove(listener), useCapture))
         return false;
@@ -1826,7 +1826,7 @@ void DOMWindow::resetAllGeolocationPermission()
 #endif
 }
 
-bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool DOMWindow::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     if (!EventTarget::removeEventListener(eventType, listener, useCapture))
         return false;
index 4b24b99..0158e14 100644 (file)
@@ -279,8 +279,8 @@ namespace WebCore {
 
         // Events
         // EventTarget API
-        bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-        bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+        bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+        bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
         void removeAllEventListeners() override;
 
         using EventTarget::dispatchEvent;
index 9b5739c..0bf4146 100644 (file)
@@ -53,7 +53,7 @@ public:
 
     WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) final;
     void updateForEventName(const WTF::AtomicString&);
-    bool operator==(const EventListener& rhs) final { return static_cast<WebCore::EventListener*>(this) == &rhs; }
+    bool operator==(const EventListener& rhs) const final { return static_cast<const WebCore::EventListener*>(this) == &rhs; }
 
     WEBCORE_EXPORT void play() final;
     WEBCORE_EXPORT void pause() final;
index 136ddce..8f405db 100644 (file)
@@ -90,7 +90,7 @@ void WebPlaybackSessionModelMediaElement::setMediaElement(HTMLMediaElement* medi
 
     if (m_mediaElement && m_isListening) {
         for (auto& eventName : observedEventNames())
-            m_mediaElement->removeEventListener(eventName, this, false);
+            m_mediaElement->removeEventListener(eventName, *this, false);
     }
     m_isListening = false;
 
@@ -100,7 +100,7 @@ void WebPlaybackSessionModelMediaElement::setMediaElement(HTMLMediaElement* medi
         return;
 
     for (auto& eventName : observedEventNames())
-        m_mediaElement->addEventListener(eventName, this, false);
+        m_mediaElement->addEventListener(eventName, *this, false);
     m_isListening = true;
 
     updateForEventName(eventNameAll());
index 5accf72..f778221 100644 (file)
@@ -60,8 +60,7 @@ public:
     
     WEBCORE_EXPORT void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*) override;
     void updateForEventName(const WTF::AtomicString&);
-    bool operator==(const EventListener& rhs) override
-        {return static_cast<WebCore::EventListener*>(this) == &rhs;}
+    bool operator==(const EventListener& rhs) const override { return static_cast<const WebCore::EventListener*>(this) == &rhs; }
 
     WEBCORE_EXPORT void requestFullscreenMode(HTMLMediaElementEnums::VideoFullscreenMode) override;
     WEBCORE_EXPORT void setVideoLayerFrame(FloatRect) override;
index 2c5c158..d80de13 100644 (file)
@@ -83,7 +83,7 @@ void WebVideoFullscreenModelVideoElement::setVideoElement(HTMLVideoElement* vide
 
     if (m_videoElement && m_isListening) {
         for (auto& eventName : observedEventNames())
-            m_videoElement->removeEventListener(eventName, this, false);
+            m_videoElement->removeEventListener(eventName, *this, false);
     }
     m_isListening = false;
 
@@ -94,7 +94,7 @@ void WebVideoFullscreenModelVideoElement::setVideoElement(HTMLVideoElement* vide
         return;
 
     for (auto& eventName : observedEventNames())
-        m_videoElement->addEventListener(eventName, this, false);
+        m_videoElement->addEventListener(eventName, *this, false);
     m_isListening = true;
 
     updateForEventName(eventNameAll());
index fc831e6..ab245d5 100644 (file)
@@ -528,7 +528,7 @@ bool SVGElement::haveLoadedRequiredResources()
     return true;
 }
 
-bool SVGElement::addEventListener(const AtomicString& eventType, RefPtr<EventListener>&& listener, bool useCapture)
+bool SVGElement::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, bool useCapture)
 {   
     // Add event listener to regular DOM element
     if (!Node::addEventListener(eventType, listener.copyRef(), useCapture))
@@ -548,7 +548,7 @@ bool SVGElement::addEventListener(const AtomicString& eventType, RefPtr<EventLis
     return true;
 }
 
-bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener* listener, bool useCapture)
+bool SVGElement::removeEventListener(const AtomicString& eventType, EventListener& listener, bool useCapture)
 {
     if (containingShadowRoot())
         return Node::removeEventListener(eventType, listener, useCapture);
@@ -558,7 +558,7 @@ bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
     // 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);
+    Ref<EventListener> protector(listener);
 
     // Remove event listener from regular DOM element
     if (!Node::removeEventListener(eventType, listener, useCapture))
@@ -573,7 +573,7 @@ bool SVGElement::removeEventListener(const AtomicString& eventType, EventListene
             continue;
 
         // This case can only be hit for event listeners created from markup
-        ASSERT(listener->wasCreatedFromMarkup());
+        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
index 3816810..96d6c90 100644 (file)
@@ -133,8 +133,8 @@ public:
 
     virtual bool haveLoadedRequiredResources();
 
-    bool addEventListener(const AtomicString& eventType, RefPtr<EventListener>&&, bool useCapture) override;
-    bool removeEventListener(const AtomicString& eventType, EventListener*, bool useCapture) override;
+    bool addEventListener(const AtomicString& eventType, Ref<EventListener>&&, bool useCapture) override;
+    bool removeEventListener(const AtomicString& eventType, EventListener&, bool useCapture) override;
     bool hasFocusEventListeners() const;
 
 #if ENABLE(CSS_REGIONS)
index c7d846e..6ddbb76 100644 (file)
@@ -73,7 +73,7 @@ private:
     explicit SVGTRefTargetEventListener(SVGTRefElement& trefElement);
 
     void handleEvent(ScriptExecutionContext*, Event*) override;
-    bool operator==(const EventListener&) override;
+    bool operator==(const EventListener&) const override;
 
     SVGTRefElement& m_trefElement;
     RefPtr<Element> m_target;
@@ -92,8 +92,8 @@ void SVGTRefTargetEventListener::attach(RefPtr<Element>&& target)
     ASSERT(target.get());
     ASSERT(target->inDocument());
 
-    target->addEventListener(eventNames().DOMSubtreeModifiedEvent, this, false);
-    target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false);
+    target->addEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false);
+    target->addEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false);
     m_target = WTFMove(target);
 }
 
@@ -102,12 +102,12 @@ void SVGTRefTargetEventListener::detach()
     if (!isAttached())
         return;
 
-    m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, this, false);
-    m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, this, false);
+    m_target->removeEventListener(eventNames().DOMSubtreeModifiedEvent, *this, false);
+    m_target->removeEventListener(eventNames().DOMNodeRemovedFromDocumentEvent, *this, false);
     m_target = nullptr;
 }
 
-bool SVGTRefTargetEventListener::operator==(const EventListener& listener)
+bool SVGTRefTargetEventListener::operator==(const EventListener& listener) const
 {
     if (const SVGTRefTargetEventListener* targetListener = SVGTRefTargetEventListener::cast(&listener))
         return &m_trefElement == &targetListener->m_trefElement;
index 7b29870..0d24a61 100644 (file)
@@ -76,7 +76,7 @@ public:
             : nullptr;
     }
 
-    bool operator==(const EventListener& other) override;
+    bool operator==(const EventListener& other) const override;
     
     void disconnectAnimation()
     {
@@ -97,7 +97,7 @@ private:
     SVGSMILElement::Condition* m_condition;
 };
 
-bool ConditionEventListener::operator==(const EventListener& listener)
+bool ConditionEventListener::operator==(const EventListener& listener) const
 {
     if (const ConditionEventListener* conditionEventListener = ConditionEventListener::cast(&listener))
         return m_animation == conditionEventListener->m_animation && m_condition == conditionEventListener->m_condition;
@@ -545,7 +545,7 @@ void SVGSMILElement::connectConditions()
                 continue;
             ASSERT(!condition.m_eventListener);
             condition.m_eventListener = ConditionEventListener::create(this, &condition);
-            eventBase->addEventListener(condition.m_name, condition.m_eventListener, false);
+            eventBase->addEventListener(condition.m_name, *condition.m_eventListener, false);
         } else if (condition.m_type == Condition::Syncbase) {
             ASSERT(!condition.m_baseID.isEmpty());
             condition.m_syncbase = treeScope().getElementById(condition.m_baseID);
@@ -577,7 +577,7 @@ void SVGSMILElement::disconnectConditions()
             // our condition event listener, in case it later fires.
             Element* eventBase = eventBaseFor(condition);
             if (eventBase)
-                eventBase->removeEventListener(condition.m_name, condition.m_eventListener.get(), false);
+                eventBase->removeEventListener(condition.m_name, *condition.m_eventListener, false);
             condition.m_eventListener->disconnectAnimation();
             condition.m_eventListener = nullptr;
         } else if (condition.m_type == Condition::Syncbase) {
index 64eb4ed..db8b671 100644 (file)
@@ -1,3 +1,17 @@
+2016-05-23  Chris Dumez  <cdumez@apple.com>
+
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        https://bugs.webkit.org/show_bug.cgi?id=157882
+
+        Reviewed by Darin Adler.
+
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        instead of hardcoding them in the bindings generator.
+
+        * DOMEventsClasses.cpp:
+        (WebEventListener::operator==):
+        * DOMEventsClasses.h:
+
 2016-05-20  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove LegacyProfiler
index 5df7838..2a10ade 100644 (file)
@@ -412,8 +412,8 @@ HRESULT DOMNode::setTextContent(_In_ BSTR /*text*/)
 
 HRESULT DOMNode::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener* listener, BOOL useCapture)
 {
-    RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
-    m_node->addEventListener(type, webListener, useCapture);
+    auto webListener = WebEventListener::create(listener);
+    m_node->addEventListener(type, WTFMove(webListener), useCapture);
 
     return S_OK;
 }
@@ -424,8 +424,8 @@ HRESULT DOMNode::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener*
         return E_POINTER;
     if (!m_node)
         return E_FAIL;
-    RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
-    m_node->removeEventListener(type, webListener.get(), useCapture);
+    auto webListener = WebEventListener::create(listener);
+    m_node->removeEventListener(type, webListener, useCapture);
     return S_OK;
 }
 
@@ -910,8 +910,8 @@ HRESULT DOMWindow::addEventListener(_In_ BSTR type, _In_opt_ IDOMEventListener*
         return E_POINTER;
     if (!m_window)
         return E_FAIL;
-    RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
-    m_window->addEventListener(type, webListener, useCapture);
+    auto webListener = WebEventListener::create(listener);
+    m_window->addEventListener(type, WTFMove(webListener), useCapture);
     return S_OK;
 }
 
@@ -921,8 +921,8 @@ HRESULT DOMWindow::removeEventListener(_In_ BSTR type, _In_opt_ IDOMEventListene
         return E_POINTER;
     if (!m_window)
         return E_FAIL;
-    RefPtr<WebEventListener> webListener = WebEventListener::create(listener);
-    m_window->removeEventListener(type, webListener.get(), useCapture);
+    auto webListener = WebEventListener::create(listener);
+    m_window->removeEventListener(type, webListener, useCapture);
     return S_OK;
 }
 
index 80b4d2e..ad8766b 100644 (file)
@@ -68,7 +68,7 @@ WebEventListener::~WebEventListener()
     m_iDOMEventListener->Release();
 }
 
-bool WebEventListener::operator==(const WebCore::EventListener& other)
+bool WebEventListener::operator==(const WebCore::EventListener& other) const
 {
     return (other.type() == CPPEventListenerType 
         && reinterpret_cast<const WebEventListener*>(&other)->m_iDOMEventListener == m_iDOMEventListener);
@@ -81,9 +81,9 @@ void WebEventListener::handleEvent(WebCore::ScriptExecutionContext* s, WebCore::
     m_iDOMEventListener->handleEvent(domEvent.get());
 }
 
-PassRefPtr<WebEventListener> WebEventListener::create(IDOMEventListener* d)
+Ref<WebEventListener> WebEventListener::create(IDOMEventListener* d)
 {
-    return adoptRef(new WebEventListener(d));
+    return adoptRef(*new WebEventListener(d));
 }
 
 // DOMEvent -------------------------------------------------------------------
index 4ab2cee..7df813b 100644 (file)
@@ -46,9 +46,9 @@ class WebEventListener : public WebCore::EventListener {
 public:
     WebEventListener(IDOMEventListener*);
     ~WebEventListener();
-    virtual bool operator==(const EventListener&);
+    virtual bool operator==(const EventListener&) const;
     virtual void handleEvent(WebCore::ScriptExecutionContext*, WebCore::Event*);
-    static PassRefPtr<WebEventListener> create(IDOMEventListener*);
+    static Ref<WebEventListener> create(IDOMEventListener*);
 private:
     IDOMEventListener* m_iDOMEventListener;
 };
index 66c6dee..29098b6 100644 (file)
@@ -1,3 +1,24 @@
+2016-05-23  Chris Dumez  <cdumez@apple.com>
+
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        https://bugs.webkit.org/show_bug.cgi?id=157882
+
+        Reviewed by Darin Adler.
+
+        Generate bindings code for EventTarget.addEventListener() / removeEventListener()
+        instead of hardcoding them in the bindings generator.
+
+        * WebProcess/Plugins/PDF/PDFPluginAnnotation.h:
+        * WebProcess/Plugins/PDF/PDFPluginAnnotation.mm:
+        (WebKit::PDFPluginAnnotation::attach):
+        (WebKit::PDFPluginAnnotation::~PDFPluginAnnotation):
+        * WebProcess/Plugins/PDF/PDFPluginPasswordField.mm:
+        (WebKit::PDFPluginPasswordField::~PDFPluginPasswordField):
+        (WebKit::PDFPluginPasswordField::createAnnotationElement):
+        * WebProcess/Plugins/PDF/PDFPluginTextAnnotation.mm:
+        (WebKit::PDFPluginTextAnnotation::~PDFPluginTextAnnotation):
+        (WebKit::PDFPluginTextAnnotation::createAnnotationElement):
+
 2016-05-23  Beth Dakin  <bdakin@apple.com>
 
         Need SPI for clients to require a user action to get an editing controls 
index 63a48ac..f633970 100644 (file)
@@ -84,7 +84,7 @@ private:
             return adoptRef(*new PDFPluginAnnotationEventListener(annotation));
         }
 
-        bool operator==(const EventListener& listener) override { return this == &listener; }
+        bool operator==(const EventListener& listener) const override { return this == &listener; }
 
         void setAnnotation(PDFPluginAnnotation* annotation) { m_annotation = annotation; }
 
index 47ba9c2..3ca7e48 100644 (file)
@@ -69,8 +69,8 @@ void PDFPluginAnnotation::attach(Element* parent)
     m_element = createAnnotationElement();
 
     m_element->setAttribute(classAttr, "annotation");
-    m_element->addEventListener(eventNames().changeEvent, m_eventListener, false);
-    m_element->addEventListener(eventNames().blurEvent, m_eventListener, false);
+    m_element->addEventListener(eventNames().changeEvent, *m_eventListener, false);
+    m_element->addEventListener(eventNames().blurEvent, *m_eventListener, false);
 
     updateGeometry();
 
@@ -87,8 +87,8 @@ void PDFPluginAnnotation::commit()
 
 PDFPluginAnnotation::~PDFPluginAnnotation()
 {
-    m_element->removeEventListener(eventNames().changeEvent, m_eventListener.get(), false);
-    m_element->removeEventListener(eventNames().blurEvent, m_eventListener.get(), false);
+    m_element->removeEventListener(eventNames().changeEvent, *m_eventListener, false);
+    m_element->removeEventListener(eventNames().blurEvent, *m_eventListener, false);
 
     m_eventListener->setAnnotation(0);
 
index b2a3c7f..6776475 100644 (file)
@@ -49,14 +49,14 @@ Ref<PDFPluginPasswordField> PDFPluginPasswordField::create(PDFLayerController *p
 
 PDFPluginPasswordField::~PDFPluginPasswordField()
 {
-    element()->removeEventListener(eventNames().keyupEvent, eventListener(), false);
+    element()->removeEventListener(eventNames().keyupEvent, *eventListener(), false);
 }
 
 PassRefPtr<Element> PDFPluginPasswordField::createAnnotationElement()
 {
     RefPtr<Element> element = PDFPluginTextAnnotation::createAnnotationElement();
     element->setAttribute(typeAttr, "password");
-    element->addEventListener(eventNames().keyupEvent, eventListener(), false);
+    element->addEventListener(eventNames().keyupEvent, *eventListener(), false);
     return element;
 }
 
index fbed3a6..8c07469 100644 (file)
@@ -78,7 +78,7 @@ Ref<PDFPluginTextAnnotation> PDFPluginTextAnnotation::create(PDFAnnotation *anno
 
 PDFPluginTextAnnotation::~PDFPluginTextAnnotation()
 {
-    element()->removeEventListener(eventNames().keydownEvent, eventListener(), false);
+    element()->removeEventListener(eventNames().keydownEvent, *eventListener(), false);
 }
 
 PassRefPtr<Element> PDFPluginTextAnnotation::createAnnotationElement()
@@ -97,7 +97,7 @@ PassRefPtr<Element> PDFPluginTextAnnotation::createAnnotationElement()
     else
         element = document.createElement(inputTag, false);
 
-    element->addEventListener(eventNames().keydownEvent, eventListener(), false);
+    element->addEventListener(eventNames().keydownEvent, *eventListener(), false);
 
     StyledElement* styledElement = static_cast<StyledElement*>(element.get());