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);
};