Diff
Modified: trunk/LayoutTests/ChangeLog (244266 => 244267)
--- trunk/LayoutTests/ChangeLog 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/LayoutTests/ChangeLog 2019-04-15 17:26:39 UTC (rev 244267)
@@ -1,3 +1,17 @@
+2019-04-15 Devin Rousso <[email protected]>
+
+ Web Inspector: Elements: event listener change events should only be fired for the selected node and it's ancestors
+ https://bugs.webkit.org/show_bug.cgi?id=196887
+ <rdar://problem/49870627>
+
+ Reviewed by Timothy Hatcher.
+
+ * inspector/dom/event-listener-inspected-node.html: Added.
+ * inspector/dom/event-listener-inspected-node-expected.txt: Added.
+
+ * inspector/dom/event-listener-add-remove.html:
+ * inspector/dom/event-listener-add-remove-expected.txt:
+
2019-04-15 Shawn Roberts <[email protected]>
inspector/canvas/recording-webgl-snapshots.html is a flaky failure
Modified: trunk/LayoutTests/inspector/dom/event-listener-add-remove-expected.txt (244266 => 244267)
--- trunk/LayoutTests/inspector/dom/event-listener-add-remove-expected.txt 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/LayoutTests/inspector/dom/event-listener-add-remove-expected.txt 2019-04-15 17:26:39 UTC (rev 244267)
@@ -1,5 +1,6 @@
Testing events for adding and removing event listeners.
+Changing inspected node to #document...
== Running test suite: DOM.eventListeners
-- Running test case: DOM.eventListeners.Initial
Modified: trunk/LayoutTests/inspector/dom/event-listener-add-remove.html (244266 => 244267)
--- trunk/LayoutTests/inspector/dom/event-listener-add-remove.html 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/LayoutTests/inspector/dom/event-listener-add-remove.html 2019-04-15 17:26:39 UTC (rev 244267)
@@ -209,15 +209,15 @@
addAttribute("onload", 2);
});
- } else if (eventCount === 2)
+ } else if (eventCount === 2) {
InspectorTest.log("Attribute event listener replaced.");
- else if (eventCount === 3) {
+
logListeners(1).then(() => {
InspectorTest.log("");
removeAttribute("onload");
});
- } else if (eventCount === 4)
+ } else if (eventCount === 3)
logListeners(0).then(resolve, reject);
else
reject("Event listeners changed too many times.");
@@ -227,9 +227,17 @@
}
});
- WI.domManager.requestDocument((documentNode) => {
+ WI.domManager.requestDocument(async (documentNode) => {
node = documentNode;
+ InspectorTest.assert(node !== WI.domManager.inspectedNode);
+ InspectorTest.log("Changing inspected node to #document...");
+ await Promise.all([
+ WI.domManager.awaitEvent(WI.DOMManager.Event.InspectedNodeChanged),
+ WI.domManager.setInspectedNode(node),
+ ]);
+ InspectorTest.assert(node === WI.domManager.inspectedNode);
+
suite.runTestCasesAndFinish();
});
}
Added: trunk/LayoutTests/inspector/dom/event-listener-inspected-node-expected.txt (0 => 244267)
--- trunk/LayoutTests/inspector/dom/event-listener-inspected-node-expected.txt (rev 0)
+++ trunk/LayoutTests/inspector/dom/event-listener-inspected-node-expected.txt 2019-04-15 17:26:39 UTC (rev 244267)
@@ -0,0 +1,56 @@
+Testing that event listener add/remove events are only fired for the inspected node and its ancestors.
+
+Changing inspected node to #child...
+
+== Running test suite: DOM.eventListeners
+-- Running test case: DOM.eventListeners.InspectedNode
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Adding listener to #child...
+PASS: Adding an event listener to the inspected node should notify the frontend.
+PASS: There should be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Removing listener from #child...
+PASS: Removing an event listener from the inspected node should notify the frontend.
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+
+-- Running test case: DOM.eventListeners.InspectedNode.ancestor
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Adding listener to #parent...
+PASS: Adding an event listener to an ancestor of the inspected node should notify the frontend.
+PASS: There should be an event listener for #child.
+PASS: There should be an event listener for #parent.
+Removing listener from #parent...
+PASS: Removing an event listener from an ancestor of the inspected node should notify the frontend.
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+
+-- Running test case: DOM.eventListeners.NotInspectedNode
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Adding listener to #sibling...
+PASS: Adding an event listener to a node other than the inspected node should not notify the frontend.
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Removing listener from #sibling...
+PASS: Removing an event listener from a node other than the inspected node should not notify the frontend.
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+
+-- Running test case: DOM.eventListeners.SubsequentBeforeGet
+PASS: There should not be an event listener for #child.
+PASS: There should not be an event listener for #parent.
+Adding listener to #child...
+PASS: Adding an event listener to the inspected node should notify the frontend.
+Adding listener to #parent...
+PASS: Adding an event listener to an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.
+Requesting event listeners...
+PASS: There should be an event listener for #child.
+PASS: There should be an event listener for #parent.
+Removing listener from #child...
+PASS: Removing an event listener from the inspected node should notify the frontend.
+Removing listener from #parent...
+PASS: Removing an event listener from an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.
+
Added: trunk/LayoutTests/inspector/dom/event-listener-inspected-node.html (0 => 244267)
--- trunk/LayoutTests/inspector/dom/event-listener-inspected-node.html (rev 0)
+++ trunk/LayoutTests/inspector/dom/event-listener-inspected-node.html 2019-04-15 17:26:39 UTC (rev 244267)
@@ -0,0 +1,177 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src=""
+<script>
+const callback = (event) => { };
+
+function addListener(selector) {
+ document.querySelector(selector).addEventListener("click", callback);
+ TestPage.dispatchEventToFrontend("addListener");
+}
+
+function removeListener(selector) {
+ document.querySelector(selector).removeEventListener("click", callback);
+ TestPage.dispatchEventToFrontend("removeListener");
+}
+
+function test() {
+ let parentNode = null;
+ let childNode = null;
+ let siblingNode = null;
+
+ async function addListener(node) {
+ let promise = new WI.WrappedPromise;
+ let listener = node.addEventListener(WI.DOMNode.Event.EventListenersChanged, (event) => {
+ if (!promise.settled)
+ promise.resolve(true);
+ });
+ InspectorTest.singleFireEventListener("addListener", (event) => {
+ node.removeEventListener(WI.DOMNode.Event.EventListenersChanged, listener);
+
+ if (!promise.settled)
+ promise.resolve(false);
+ });
+
+ let selector = node.escapedIdSelector;
+ InspectorTest.log(`Adding listener to ${selector}...`);
+ await InspectorTest.evaluateInPage(`addListener("${selector}")`);
+
+ return promise.promise;
+ }
+
+ async function removeListener(node) {
+ let promise = new WI.WrappedPromise;
+ let listener = node.addEventListener(WI.DOMNode.Event.EventListenersChanged, (event) => {
+ if (!promise.settled)
+ promise.resolve(true);
+ });
+ InspectorTest.singleFireEventListener("removeListener", (event) => {
+ node.removeEventListener(WI.DOMNode.Event.EventListenersChanged, listener);
+
+ if (!promise.settled)
+ promise.resolve(false);
+ });
+
+ let selector = node.escapedIdSelector;
+ InspectorTest.log(`Removing listener from ${selector}...`);
+ await InspectorTest.evaluateInPage(`removeListener("${selector}")`);
+
+ return promise.promise;
+ }
+
+ async function checkTestEventListener(node, expected) {
+ let {listeners} = await DOMAgent.getEventListenersForNode(node.id);
+ listeners = listeners.map((listener) => listener.type);
+
+ let selector = node.escapedIdSelector;
+ if (expected)
+ InspectorTest.expectThat(listeners.includes("click"), `There should be an event listener for ${selector}.`);
+ else
+ InspectorTest.expectFalse(listeners.includes("click"), `There should not be an event listener for ${selector}.`);
+ }
+
+ let suite = InspectorTest.createAsyncSuite("DOM.eventListeners");
+
+ suite.addTestCase({
+ name: "DOM.eventListeners.InspectedNode",
+ description: "Test that event listener add/remove events for the inspected node are sent to the frontend.",
+ async test() {
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectThat(await addListener(childNode), "Adding an event listener to the inspected node should notify the frontend.");
+ await checkTestEventListener(childNode, true);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectThat(await removeListener(childNode), "Removing an event listener from the inspected node should notify the frontend.");
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+ },
+ });
+
+ suite.addTestCase({
+ name: "DOM.eventListeners.InspectedNode.ancestor",
+ description: "Test that event listener add/remove events for ancestors of the inspected node are sent to the frontend.",
+ async test() {
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectThat(await addListener(parentNode), "Adding an event listener to an ancestor of the inspected node should notify the frontend.");
+ await checkTestEventListener(childNode, true);
+ await checkTestEventListener(parentNode, true);
+
+ InspectorTest.expectThat(await removeListener(parentNode), "Removing an event listener from an ancestor of the inspected node should notify the frontend.");
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+ },
+ });
+
+ suite.addTestCase({
+ name: "DOM.eventListeners.NotInspectedNode",
+ description: "Test that event listener add/remove events for nodes other than the inspected node are not sent to the frontend.",
+ async test() {
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectFalse(await addListener(siblingNode), "Adding an event listener to a node other than the inspected node should not notify the frontend.");
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectFalse(await removeListener(siblingNode), "Removing an event listener from a node other than the inspected node should not notify the frontend.");
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+ },
+ });
+
+ suite.addTestCase({
+ name: "DOM.eventListeners.SubsequentBeforeGet",
+ description: "Test that subsequent event listener add/remove events are not sent to the frontend if the frontend hasn't requested the new list since the last update.",
+ async test() {
+ await checkTestEventListener(childNode, false);
+ await checkTestEventListener(parentNode, false);
+
+ InspectorTest.expectThat(await addListener(childNode), "Adding an event listener to the inspected node should notify the frontend.");
+ InspectorTest.expectFalse(await addListener(parentNode), "Adding an event listener to an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.");
+
+ InspectorTest.log("Requesting event listeners...");
+ await checkTestEventListener(childNode, true);
+ await checkTestEventListener(parentNode, true);
+
+ InspectorTest.expectThat(await removeListener(childNode), "Removing an event listener from the inspected node should notify the frontend.");
+ InspectorTest.expectFalse(await removeListener(parentNode), "Removing an event listener from an ancestor of the inspected node should not notify the frontend if the frontend hasn't requested the new list since the last update.");
+ },
+ });
+
+ WI.domManager.requestDocument(async (documentNode) => {
+ let [parentNodeId, childNodeId, siblingNodeId] = await Promise.all([
+ WI.domManager.querySelector(documentNode, "#parent"),
+ WI.domManager.querySelector(documentNode, "#child"),
+ WI.domManager.querySelector(documentNode, "#sibling"),
+ ]);
+
+ parentNode = WI.domManager.nodeForId(parentNodeId);
+ childNode = WI.domManager.nodeForId(childNodeId);
+ siblingNode = WI.domManager.nodeForId(siblingNodeId);
+
+ InspectorTest.assert(childNode !== WI.domManager.inspectedNode);
+ InspectorTest.log(`Changing inspected node to ${childNode.escapedIdSelector}...`);
+ await Promise.all([
+ WI.domManager.awaitEvent(WI.DOMManager.Event.InspectedNodeChanged),
+ WI.domManager.setInspectedNode(childNode),
+ ]);
+ InspectorTest.assert(childNode === WI.domManager.inspectedNode);
+
+ suite.runTestCasesAndFinish();
+ });
+}
+</script>
+</head>
+<body _onload_="runTest()">
+ <p>Testing that event listener add/remove events are only fired for the inspected node and its ancestors.</p>
+ <div id="parent">
+ <div id="child"></div>
+ </div>
+ <div id="sibling"></div>
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (244266 => 244267)
--- trunk/Source/WebCore/ChangeLog 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/Source/WebCore/ChangeLog 2019-04-15 17:26:39 UTC (rev 244267)
@@ -1,3 +1,21 @@
+2019-04-15 Devin Rousso <[email protected]>
+
+ Web Inspector: Elements: event listener change events should only be fired for the selected node and it's ancestors
+ https://bugs.webkit.org/show_bug.cgi?id=196887
+ <rdar://problem/49870627>
+
+ Reviewed by Timothy Hatcher.
+
+ Test: inspector/dom/event-listener-add-remove.html
+ inspector/dom/event-listener-inspected-node.html
+
+ * inspector/agents/InspectorDOMAgent.h:
+ * inspector/agents/InspectorDOMAgent.cpp:
+ (WebCore::InspectorDOMAgent::getEventListenersForNode):
+ (WebCore::InspectorDOMAgent::setInspectedNode):
+ (WebCore::InspectorDOMAgent::didAddEventListener):
+ (WebCore::InspectorDOMAgent::willRemoveEventListener):
+
2019-04-15 Antoine Quint <[email protected]>
Ensure iOS layout traits are used for media controls in modern compatibility mode
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp (244266 => 244267)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.cpp 2019-04-15 17:26:39 UTC (rev 244267)
@@ -952,6 +952,9 @@
addListener(*listener, info);
}
}
+
+ if (m_inspectedNode == node)
+ m_suppressEventListenerChangedEvent = false;
}
void InspectorDOMAgent::setEventListenerDisabled(ErrorString& errorString, int eventListenerId, bool disabled)
@@ -1398,8 +1401,12 @@
return;
}
+ m_inspectedNode = node;
+
if (CommandLineAPIHost* commandLineAPIHost = static_cast<WebInjectedScriptManager&>(m_injectedScriptManager).commandLineAPIHost())
commandLineAPIHost->addInspectedObject(std::make_unique<InspectableNode>(node));
+
+ m_suppressEventListenerChangedEvent = false;
}
void InspectorDOMAgent::resolveNode(ErrorString& errorString, int nodeId, const String* objectGroup, RefPtr<Inspector::Protocol::Runtime::RemoteObject>& result)
@@ -2388,10 +2395,19 @@
if (!is<Node>(target))
return;
- int nodeId = boundNodeId(&downcast<Node>(target));
+ auto& node = downcast<Node>(target);
+ if (!node.contains(m_inspectedNode.get()))
+ return;
+
+ int nodeId = boundNodeId(&node);
if (!nodeId)
return;
+ if (m_suppressEventListenerChangedEvent)
+ return;
+
+ m_suppressEventListenerChangedEvent = true;
+
m_frontendDispatcher->didAddEventListener(nodeId);
}
@@ -2399,7 +2415,10 @@
{
if (!is<Node>(target))
return;
+
auto& node = downcast<Node>(target);
+ if (!node.contains(m_inspectedNode.get()))
+ return;
int nodeId = boundNodeId(&node);
if (!nodeId)
@@ -2420,6 +2439,11 @@
return entry.value.matches(target, eventType, listener, capture);
});
+ if (m_suppressEventListenerChangedEvent)
+ return;
+
+ m_suppressEventListenerChangedEvent = true;
+
m_frontendDispatcher->willRemoveEventListener(nodeId);
}
Modified: trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h (244266 => 244267)
--- trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/Source/WebCore/inspector/agents/InspectorDOMAgent.h 2019-04-15 17:26:39 UTC (rev 244267)
@@ -251,11 +251,13 @@
std::unique_ptr<RevalidateStyleAttributeTask> m_revalidateStyleAttrTask;
RefPtr<Node> m_nodeToFocus;
RefPtr<Node> m_mousedOverNode;
+ RefPtr<Node> m_inspectedNode;
std::unique_ptr<HighlightConfig> m_inspectModeHighlightConfig;
std::unique_ptr<InspectorHistory> m_history;
std::unique_ptr<DOMEditor> m_domEditor;
bool m_searchingForNode { false };
bool m_suppressAttributeModifiedEvent { false };
+ bool m_suppressEventListenerChangedEvent { false };
bool m_documentRequested { false };
#if ENABLE(VIDEO)
Modified: trunk/Source/WebInspectorUI/ChangeLog (244266 => 244267)
--- trunk/Source/WebInspectorUI/ChangeLog 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/Source/WebInspectorUI/ChangeLog 2019-04-15 17:26:39 UTC (rev 244267)
@@ -1,5 +1,16 @@
2019-04-15 Devin Rousso <[email protected]>
+ Web Inspector: Elements: event listener change events should only be fired for the selected node and it's ancestors
+ https://bugs.webkit.org/show_bug.cgi?id=196887
+ <rdar://problem/49870627>
+
+ Reviewed by Timothy Hatcher.
+
+ * UserInterface/Models/DOMNode.js:
+ (WI.DOMNode.prototype.getEventListeners):
+
+2019-04-15 Devin Rousso <[email protected]>
+
Web Inspector: replace all uses of `this` with `WI` in Main.js/Test.js
https://bugs.webkit.org/show_bug.cgi?id=196795
<rdar://problem/49796618>
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js (244266 => 244267)
--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2019-04-15 17:24:54 UTC (rev 244266)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNode.js 2019-04-15 17:26:39 UTC (rev 244267)
@@ -587,6 +587,7 @@
getEventListeners(callback)
{
+ console.assert(WI.domManager.inspectedNode === this);
DOMAgent.getEventListenersForNode(this.id, callback);
}