Title: [239987] trunk
Revision
239987
Author
[email protected]
Date
2019-01-15 08:31:05 -0800 (Tue, 15 Jan 2019)

Log Message

Web Inspector: Audit: provide a way to determine whether a give node has event listeners
https://bugs.webkit.org/show_bug.cgi?id=193226
<rdar://problem/46800005>

Reviewed by Joseph Pecoraro.

Source/WebCore:

Test: inspector/audit/run-dom.html

* inspector/InspectorAuditDOMObject.idl:
* inspector/InspectorAuditDOMObject.h:
* inspector/InspectorAuditDOMObject.cpp:
(WebCore::InspectorAuditDOMObject::hasEventListeners): Added.

LayoutTests:

* inspector/audit/run-dom.html: Added.
* inspector/audit/run-dom-expected.txt: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (239986 => 239987)


--- trunk/LayoutTests/ChangeLog	2019-01-15 16:28:37 UTC (rev 239986)
+++ trunk/LayoutTests/ChangeLog	2019-01-15 16:31:05 UTC (rev 239987)
@@ -1,5 +1,16 @@
 2019-01-15  Devin Rousso  <[email protected]>
 
+        Web Inspector: Audit: provide a way to determine whether a give node has event listeners
+        https://bugs.webkit.org/show_bug.cgi?id=193226
+        <rdar://problem/46800005>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/audit/run-dom.html: Added.
+        * inspector/audit/run-dom-expected.txt: Added.
+
+2019-01-15  Devin Rousso  <[email protected]>
+
         Web Inspector: Audit: provide a way to query for all nodes with a given computed Accessibility role
         https://bugs.webkit.org/show_bug.cgi?id=193228
         <rdar://problem/46787787>

Added: trunk/LayoutTests/inspector/audit/run-dom-expected.txt (0 => 239987)


--- trunk/LayoutTests/inspector/audit/run-dom-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/inspector/audit/run-dom-expected.txt	2019-01-15 16:31:05 UTC (rev 239987)
@@ -0,0 +1,61 @@
+Tests for the injected WebInspectorAudit.DOM functions.
+
+
+
+== Running test suite: Audit.run.DOM
+-- Running test case: Audit.run.DOM.hasEventListeners.noListeners
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#noListeners"))`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners.noListeners.WithArgs
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#noListeners"), ["FakeEvent"])`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners.attributeListener
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#attributeListener"))`...
+Result: true
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners.attributeListener.WithArgs
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#attributeListener"), ["FakeEvent"])`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners._javascript_Listener
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#_javascript_Listener"))`...
+Result: true
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners._javascript_Listener.WithArgs
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#_javascript_Listener"), ["FakeEvent"])`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners.builtinListener
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#builtinListener"))`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.hasEventListeners.builtinListener.WithArgs
+Audit setup...
+Audit run `WebInspectorAudit.DOM.hasEventListeners(document.querySelector("#builtinListener"), ["FakeEvent"])`...
+Result: false
+Audit teardown...
+
+-- Running test case: Audit.run.DOM.InvalidCopiedFunctionCall
+Audit setup...
+Copying WebInspectorAudit to window...
+Audit teardown...
+Testing copied hasEventListeners...
+PASS: Should produce an exception.
+Error: NotAllowedError: Cannot be called outside of a Web Inspector Audit
+

Added: trunk/LayoutTests/inspector/audit/run-dom.html (0 => 239987)


--- trunk/LayoutTests/inspector/audit/run-dom.html	                        (rev 0)
+++ trunk/LayoutTests/inspector/audit/run-dom.html	2019-01-15 16:31:05 UTC (rev 239987)
@@ -0,0 +1,81 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script src=""
+<script>
+function test()
+{
+    let suite = InspectorTest.Audit.createSuite("Audit.run.DOM");
+
+    function evaluateStringForTest(func, target, args) {
+        return `WebInspectorAudit.DOM.${func}(document.querySelector("#${target}")${args ? ", " + JSON.stringify(args) : ""})`;
+    }
+
+    const tests = [
+        { func: "hasEventListeners", target: "noListeners" },
+        { func: "hasEventListeners", target: "noListeners", args: ["FakeEvent"] },
+        { func: "hasEventListeners", target: "attributeListener" },
+        { func: "hasEventListeners", target: "attributeListener", args: ["FakeEvent"] },
+        { func: "hasEventListeners", target: "_javascript_Listener" },
+        { func: "hasEventListeners", target: "_javascript_Listener", args: ["FakeEvent"] },
+        { func: "hasEventListeners", target: "builtinListener" },
+        { func: "hasEventListeners", target: "builtinListener", args: ["FakeEvent"] },
+    ];
+
+    for (let {func, target, args} of tests) {
+        suite.addTestCase({
+            name: "Audit.run.DOM." + func + "." + target + (args ? ".WithArgs" : ""),
+            async test() {
+                let functionString = evaluateStringForTest(func, target, args);
+
+                 await InspectorTest.Audit.setupAudit();
+
+                InspectorTest.log(`Audit run \`${functionString}\`...`);
+                let {result, wasThrown} = await AuditAgent.run(`function() { return ${functionString}; }`);
+                InspectorTest.assert(!wasThrown, "Should not throw an exception.");
+                if (!wasThrown)
+                    InspectorTest.log("Result: " + result.value);
+                else
+                    InspectorTest.log(result.description);
+
+                await InspectorTest.Audit.teardownAudit();
+            },
+        });
+    }
+
+    suite.addTestCase({
+        name: "Audit.run.DOM.InvalidCopiedFunctionCall",
+        description: "Check that WebInspectorAudit.DOM functions throw an error when called outside of an audit.",
+        async test() {
+            let functions = new Map;
+            for (let test of tests)
+                functions.set(test.func, test);
+
+            await InspectorTest.Audit.setupAudit();
+            InspectorTest.log(`Copying WebInspectorAudit to window...`);
+            let {wasThrown} = await AuditAgent.run(`function() { window.CopiedWebInspectorAudit = WebInspectorAudit; }`);
+            InspectorTest.assert(!wasThrown, "Should not throw an exception.");
+            await InspectorTest.Audit.teardownAudit();
+
+            for (let {func, target, args} of functions.values()) {
+                InspectorTest.log(`Testing copied ${func}...`);
+                await InspectorTest.expectException(async function() {
+                    await InspectorTest.evaluateInPage("window.Copied" + evaluateStringForTest(func, target, args));
+                });
+            }
+        },
+    });
+
+    suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="runTest()">
+    <p>Tests for the injected WebInspectorAudit.DOM functions.</p>
+    <div id="noListeners"></div>
+    <div id="attributeListener" _onclick_="void(0);"></div>
+    <div id="_javascript_Listener"><script>document.querySelector("#_javascript_Listener").addEventListener("click", () => {});</script></div>
+    <video id="builtinListener"></video>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (239986 => 239987)


--- trunk/Source/WebCore/ChangeLog	2019-01-15 16:28:37 UTC (rev 239986)
+++ trunk/Source/WebCore/ChangeLog	2019-01-15 16:31:05 UTC (rev 239987)
@@ -1,5 +1,20 @@
 2019-01-15  Devin Rousso  <[email protected]>
 
+        Web Inspector: Audit: provide a way to determine whether a give node has event listeners
+        https://bugs.webkit.org/show_bug.cgi?id=193226
+        <rdar://problem/46800005>
+
+        Reviewed by Joseph Pecoraro.
+
+        Test: inspector/audit/run-dom.html
+
+        * inspector/InspectorAuditDOMObject.idl:
+        * inspector/InspectorAuditDOMObject.h:
+        * inspector/InspectorAuditDOMObject.cpp:
+        (WebCore::InspectorAuditDOMObject::hasEventListeners): Added.
+
+2019-01-15  Devin Rousso  <[email protected]>
+
         Web Inspector: Audit: provide a way to query for all nodes with a given computed Accessibility role
         https://bugs.webkit.org/show_bug.cgi?id=193228
         <rdar://problem/46787787>

Modified: trunk/Source/WebCore/inspector/InspectorAuditDOMObject.cpp (239986 => 239987)


--- trunk/Source/WebCore/inspector/InspectorAuditDOMObject.cpp	2019-01-15 16:28:37 UTC (rev 239986)
+++ trunk/Source/WebCore/inspector/InspectorAuditDOMObject.cpp	2019-01-15 16:31:05 UTC (rev 239987)
@@ -27,12 +27,43 @@
 #include "config.h"
 #include "InspectorAuditDOMObject.h"
 
+#include "Node.h"
+#include <wtf/text/AtomicString.h>
+#include <wtf/text/WTFString.h>
+
 namespace WebCore {
 
 using namespace Inspector;
 
-InspectorAuditDOMObject::InspectorAuditDOMObject()
+#define ERROR_IF_NO_ACTIVE_AUDIT() \
+    if (!m_auditAgent.hasActiveAudit()) \
+        return Exception { NotAllowedError, "Cannot be called outside of a Web Inspector Audit"_s };
+
+InspectorAuditDOMObject::InspectorAuditDOMObject(InspectorAuditAgent& auditAgent)
+    : m_auditAgent(auditAgent)
 {
 }
 
+ExceptionOr<bool> InspectorAuditDOMObject::hasEventListeners(Node& node, const String& type)
+{
+    ERROR_IF_NO_ACTIVE_AUDIT();
+
+    if (EventTargetData* eventTargetData = node.eventTargetData()) {
+        Vector<AtomicString> eventTypes;
+        if (type.isNull())
+            eventTypes = eventTargetData->eventListenerMap.eventTypes();
+        else
+            eventTypes.append(type);
+
+        for (AtomicString& type : eventTypes) {
+            for (const RefPtr<RegisteredEventListener>& listener : node.eventListeners(type)) {
+                if (listener->callback().type() == EventListener::JSEventListenerType)
+                    return true;
+            }
+        }
+    }
+
+    return false;
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/inspector/InspectorAuditDOMObject.h (239986 => 239987)


--- trunk/Source/WebCore/inspector/InspectorAuditDOMObject.h	2019-01-15 16:28:37 UTC (rev 239986)
+++ trunk/Source/WebCore/inspector/InspectorAuditDOMObject.h	2019-01-15 16:31:05 UTC (rev 239987)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "ExceptionOr.h"
 #include <_javascript_Core/InspectorAuditAgent.h>
 #include <wtf/Ref.h>
 #include <wtf/RefCounted.h>
@@ -31,15 +32,21 @@
 
 namespace WebCore {
 
+class Node;
+
 class InspectorAuditDOMObject : public RefCounted<InspectorAuditDOMObject> {
 public:
-    static Ref<InspectorAuditDOMObject> create(Inspector::InspectorAuditAgent&)
+    static Ref<InspectorAuditDOMObject> create(Inspector::InspectorAuditAgent& auditAgent)
     {
-        return adoptRef(*new InspectorAuditDOMObject());
+        return adoptRef(*new InspectorAuditDOMObject(auditAgent));
     }
 
+    ExceptionOr<bool> hasEventListeners(Node&, const String& type);
+
 private:
-    explicit InspectorAuditDOMObject();
+    explicit InspectorAuditDOMObject(Inspector::InspectorAuditAgent&);
+
+    Inspector::InspectorAuditAgent& m_auditAgent;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/inspector/InspectorAuditDOMObject.idl (239986 => 239987)


--- trunk/Source/WebCore/inspector/InspectorAuditDOMObject.idl	2019-01-15 16:28:37 UTC (rev 239986)
+++ trunk/Source/WebCore/inspector/InspectorAuditDOMObject.idl	2019-01-15 16:31:05 UTC (rev 239987)
@@ -28,4 +28,5 @@
     JSGenerateToJSObject,
     NoInterfaceObject,
 ] interface InspectorAuditDOMObject {
+    [MayThrowException] boolean hasEventListeners(Node node, optional DOMString type);
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to