Title: [248052] trunk/Source/WebInspectorUI
Revision
248052
Author
[email protected]
Date
2019-07-31 13:43:32 -0700 (Wed, 31 Jul 2019)

Log Message

Web Inspector: DOM: provide a way to disable/breakpoint all event listeners for a given DOM node or event type
https://bugs.webkit.org/show_bug.cgi?id=200233

Reviewed by Joseph Pecoraro.

Often, when trying to debug issues with DOM events, it's extremely tedious to have to go
through event listeners one by one and disable them (or set a breakpoint). This patch adds
a way of performing these "state modifications" in batch operations, based on the current
grouping method of the Event Listeners section.

* UserInterface/Controllers/DOMManager.js:
(WI.DOMManager.supportsDisablingEventListeners): Added.
(WI.DOMManager.supportsEventListenerBreakpoints): Added.
Common convenience functions for checking for protocol support.

* UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
(WI.DOMNodeDetailsSidebarPanel.prototype._refreshEventListeners.createEventListenerSection):
* UserInterface/Views/DOMNodeDetailsSidebarPanel.css:
(.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section > .header > .event-listener-options): Added.
(.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section:hover > .header > .event-listener-options): Added.
Add an options element that shows a context menu:
 - "Disable Event Listeners"/"Enable Event Listeners"
 - "Add Breakpoints"/"Delete Breakpoints"
Each action applies the corresponding state to all event listeners in that section.

* UserInterface/Views/EventListenerSectionGroup.js:
(WI.EventListenerSectionGroup):
(WI.EventListenerSectionGroup.prototype.get supportsStateModification): Added.
(WI.EventListenerSectionGroup.prototype.get isEventListenerDisabled): Added.
(WI.EventListenerSectionGroup.prototype.set isEventListenerDisabled): Added.
(WI.EventListenerSectionGroup.prototype.get hasEventListenerBreakpoint): Added.
(WI.EventListenerSectionGroup.prototype.set hasEventListenerBreakpoint): Added.
(WI.EventListenerSectionGroup.prototype._updateDisabledToggle): Added.
(WI.EventListenerSectionGroup.prototype._updateBreakpointToggle): Added.
(WI.EventListenerSectionGroup.prototype._createDisabledToggleRow): Deleted.
(WI.EventListenerSectionGroup.prototype._createBreakpointToggleRow): Deleted.
Expose a way to modify the event listener's state so that the UI (e.g. checkbox and title)
also get's updated.

* Localizations/en.lproj/localizedStrings.js:

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (248051 => 248052)


--- trunk/Source/WebInspectorUI/ChangeLog	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/ChangeLog	2019-07-31 20:43:32 UTC (rev 248052)
@@ -1,3 +1,46 @@
+2019-07-31  Devin Rousso  <[email protected]>
+
+        Web Inspector: DOM: provide a way to disable/breakpoint all event listeners for a given DOM node or event type
+        https://bugs.webkit.org/show_bug.cgi?id=200233
+
+        Reviewed by Joseph Pecoraro.
+
+        Often, when trying to debug issues with DOM events, it's extremely tedious to have to go
+        through event listeners one by one and disable them (or set a breakpoint). This patch adds
+        a way of performing these "state modifications" in batch operations, based on the current
+        grouping method of the Event Listeners section.
+
+        * UserInterface/Controllers/DOMManager.js:
+        (WI.DOMManager.supportsDisablingEventListeners): Added.
+        (WI.DOMManager.supportsEventListenerBreakpoints): Added.
+        Common convenience functions for checking for protocol support.
+
+        * UserInterface/Views/DOMNodeDetailsSidebarPanel.js:
+        (WI.DOMNodeDetailsSidebarPanel.prototype._refreshEventListeners.createEventListenerSection):
+        * UserInterface/Views/DOMNodeDetailsSidebarPanel.css:
+        (.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section > .header > .event-listener-options): Added.
+        (.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section:hover > .header > .event-listener-options): Added.
+        Add an options element that shows a context menu:
+         - "Disable Event Listeners"/"Enable Event Listeners"
+         - "Add Breakpoints"/"Delete Breakpoints"
+        Each action applies the corresponding state to all event listeners in that section.
+
+        * UserInterface/Views/EventListenerSectionGroup.js:
+        (WI.EventListenerSectionGroup):
+        (WI.EventListenerSectionGroup.prototype.get supportsStateModification): Added.
+        (WI.EventListenerSectionGroup.prototype.get isEventListenerDisabled): Added.
+        (WI.EventListenerSectionGroup.prototype.set isEventListenerDisabled): Added.
+        (WI.EventListenerSectionGroup.prototype.get hasEventListenerBreakpoint): Added.
+        (WI.EventListenerSectionGroup.prototype.set hasEventListenerBreakpoint): Added.
+        (WI.EventListenerSectionGroup.prototype._updateDisabledToggle): Added.
+        (WI.EventListenerSectionGroup.prototype._updateBreakpointToggle): Added.
+        (WI.EventListenerSectionGroup.prototype._createDisabledToggleRow): Deleted.
+        (WI.EventListenerSectionGroup.prototype._createBreakpointToggleRow): Deleted.
+        Expose a way to modify the event listener's state so that the UI (e.g. checkbox and title)
+        also get's updated.
+
+        * Localizations/en.lproj/localizedStrings.js:
+
 2019-07-30  Nikita Vasilyev  <[email protected]>
 
         Web Inspector: Resources: Display outline around images when viewing image collections

Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (248051 => 248052)


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2019-07-31 20:43:32 UTC (rev 248052)
@@ -84,6 +84,7 @@
 localizedStrings["Add"] = "Add";
 localizedStrings["Add Action"] = "Add Action";
 localizedStrings["Add Breakpoint"] = "Add Breakpoint";
+localizedStrings["Add Breakpoints"] = "Add Breakpoints";
 localizedStrings["Add New"] = "Add New";
 localizedStrings["Add New Class"] = "Add New Class";
 localizedStrings["Add New Probe _expression_"] = "Add New Probe _expression_";
@@ -337,6 +338,7 @@
 localizedStrings["Disable Descendant Breakpoints"] = "Disable Descendant Breakpoints";
 localizedStrings["Disable Encryption"] = "Disable Encryption";
 localizedStrings["Disable Event Listener"] = "Disable Event Listener";
+localizedStrings["Disable Event Listeners"] = "Disable Event Listeners";
 localizedStrings["Disable ICE Candidate Restrictions"] = "Disable ICE Candidate Restrictions";
 localizedStrings["Disable Program"] = "Disable Program";
 localizedStrings["Disable all breakpoints (%s)"] = "Disable all breakpoints (%s)";
@@ -411,6 +413,7 @@
 localizedStrings["Enable Breakpoints"] = "Enable Breakpoints";
 localizedStrings["Enable Descendant Breakpoints"] = "Enable Descendant Breakpoints";
 localizedStrings["Enable Event Listener"] = "Enable Event Listener";
+localizedStrings["Enable Event Listeners"] = "Enable Event Listeners";
 localizedStrings["Enable Layers Tab"] = "Enable Layers Tab";
 localizedStrings["Enable New Tab Bar"] = "Enable New Tab Bar";
 localizedStrings["Enable Program"] = "Enable Program";

Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js (248051 => 248052)


--- trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/DOMManager.js	2019-07-31 20:43:32 UTC (rev 248052)
@@ -75,6 +75,18 @@
         this._documentUpdated();
     }
 
+    // Static
+
+    static supportsDisablingEventListeners()
+    {
+        return !!(InspectorBackend.domains.DOM && InspectorBackend.domains.DOM.setEventListenerDisabled);
+    }
+
+    static supportsEventListenerBreakpoints()
+    {
+        return !!(InspectorBackend.domains.DOM && InspectorBackend.domains.DOM.setBreakpointForEventListener && InspectorBackend.domains.DOM.removeBreakpointForEventListener);
+    }
+
     // Public
 
     get inspectedNode() { return this._inspectedNode; }

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.css (248051 => 248052)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.css	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.css	2019-07-31 20:43:32 UTC (rev 248052)
@@ -61,6 +61,16 @@
     -webkit-appearance: none;
 }
 
+.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section > .header > .event-listener-options {
+    display: none;
+    width: 15px;
+    height: 15px;
+}
+
+.sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners .details-section.event-listener-section:hover > .header > .event-listener-options {
+    display: block;
+}
+
 @media (prefers-color-scheme: dark) {
     .sidebar > .panel.dom-node-details .details-section.dom-node-event-listeners > .header > .filter:hover {
         filter: brightness(1.25);

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js (248051 => 248052)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMNodeDetailsSidebarPanel.js	2019-07-31 20:43:32 UTC (rev 248052)
@@ -346,7 +346,28 @@
         function createEventListenerSection(title, eventListeners, options = {}) {
             let groups = eventListeners.map((eventListener) => new WI.EventListenerSectionGroup(eventListener, options));
 
-            const optionsElement = null;
+            let optionsElement = null;
+            if (WI.DOMManager.supportsDisablingEventListeners() || WI.DOMManager.supportsEventListenerBreakpoints() && groups.some((group) => group.supportsStateModification)) {
+                optionsElement = WI.ImageUtilities.useSVGSymbol("Images/Gear.svg", "event-listener-options", WI.UIString("Options"));
+                WI.addMouseDownContextMenuHandlers(optionsElement, (contextMenu) => {
+                    if (WI.DOMManager.supportsDisablingEventListeners()) {
+                        let shouldDisable = groups.some((eventListener) => !eventListener.isEventListenerDisabled);
+                        contextMenu.appendItem(shouldDisable ? WI.UIString("Disable Event Listeners") : WI.UIString("Enable Event Listeners"), () => {
+                            for (let group of groups)
+                                group.isEventListenerDisabled = shouldDisable;
+                        });
+                    }
+
+                    if (WI.DOMManager.supportsEventListenerBreakpoints()) {
+                        let shouldBreakpoint = groups.some((eventListener) => !eventListener.hasEventListenerBreakpoint);
+                        contextMenu.appendItem(shouldBreakpoint ? WI.UIString("Add Breakpoints") : WI.UIString("Delete Breakpoints"), () => {
+                            for (let group of groups)
+                                group.hasEventListenerBreakpoint = shouldBreakpoint;
+                        });
+                    }
+                });
+            }
+
             const defaultCollapsedSettingValue = true;
             let section = new WI.DetailsSection(`${title}-event-listener-section`, title, groups, optionsElement, defaultCollapsedSettingValue);
             section.element.classList.add("event-listener-section");

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.js (248051 => 248052)


--- trunk/Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.js	2019-07-31 20:34:50 UTC (rev 248051)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/EventListenerSectionGroup.js	2019-07-31 20:43:32 UTC (rev 248052)
@@ -52,17 +52,104 @@
         if (this._eventListener.once)
             rows.push(new WI.DetailsSectionSimpleRow(WI.UIString("Once"), WI.UIString("Yes")));
 
-        if (this._eventListener.eventListenerId) {
-            if (DOMAgent.setEventListenerDisabled)
-                rows.push(this._createDisabledToggleRow());
+        if (this.supportsStateModification) {
+            if (WI.DOMManager.supportsDisablingEventListeners()) {
+                this._eventListenerEnabledToggleElement = document.createElement("input");
+                this._eventListenerEnabledToggleElement.type = "checkbox";
+                this._updateDisabledToggle();
+                this._eventListenerEnabledToggleElement.addEventListener("change", (event) => {
+                    this.isEventListenerDisabled = !this._eventListenerEnabledToggleElement.checked;
+                });
 
-            if (DOMAgent.setBreakpointForEventListener && DOMAgent.removeBreakpointForEventListener)
-                rows.push(this._createBreakpointToggleRow());
+                let toggleLabel = document.createElement("span");
+                toggleLabel.textContent = WI.UIString("Enabled");
+                toggleLabel.addEventListener("click", (event) => {
+                    this._eventListenerEnabledToggleElement.click();
+                });
+
+                rows.push(new WI.DetailsSectionSimpleRow(toggleLabel, this._eventListenerEnabledToggleElement));
+            }
+
+            if (WI.DOMManager.supportsEventListenerBreakpoints()) {
+                this._eventListenerBreakpointToggleElement = document.createElement("input");
+                this._eventListenerBreakpointToggleElement.type = "checkbox";
+                this._updateBreakpointToggle();
+                this._eventListenerBreakpointToggleElement.addEventListener("change", (event) => {
+                    this.hasEventListenerBreakpoint = !!this._eventListenerBreakpointToggleElement.checked;
+                });
+
+                let toggleLabel = document.createElement("span");
+                toggleLabel.textContent = WI.UIString("Breakpoint");
+                toggleLabel.addEventListener("click", (event) => {
+                    this._eventListenerBreakpointToggleElement.click();
+                });
+
+                rows.push(new WI.DetailsSectionSimpleRow(toggleLabel, this._eventListenerBreakpointToggleElement));
+            }
         }
 
         this.rows = rows;
     }
 
+    // Public
+
+    get supportsStateModification()
+    {
+        // COMPATIBILITY (iOS 11): DOM.EventListenerId did not exist.
+        return !!this._eventListener.eventListenerId;
+    }
+
+    get isEventListenerDisabled()
+    {
+        console.assert(WI.DOMManager.supportsDisablingEventListeners());
+        if (!this.supportsStateModification)
+            return false;
+        return this._eventListener.disabled;
+    }
+
+    set isEventListenerDisabled(disabled)
+    {
+        console.assert(WI.DOMManager.supportsDisablingEventListeners());
+        if (!this.supportsStateModification)
+            return;
+
+        if (this._eventListener.disabled === disabled)
+            return;
+
+        this._eventListener.disabled = disabled;
+
+        this._updateDisabledToggle();
+
+        WI.domManager.setEventListenerDisabled(this._eventListener, this._eventListener.disabled);
+    }
+
+    get hasEventListenerBreakpoint()
+    {
+        console.assert(WI.DOMManager.supportsEventListenerBreakpoints());
+        if (!this.supportsStateModification)
+            return false;
+        return this._eventListener.hasBreakpoint;
+    }
+
+    set hasEventListenerBreakpoint(hasBreakpoint)
+    {
+        console.assert(WI.DOMManager.supportsEventListenerBreakpoints());
+        if (!this.supportsStateModification)
+            return;
+
+        if (this._eventListener.hasBreakpoint === hasBreakpoint)
+            return;
+
+        this._eventListener.hasBreakpoint = hasBreakpoint;
+
+        this._updateBreakpointToggle();
+
+        if (this._eventListener.hasBreakpoint)
+            WI.domManager.setBreakpointForEventListener(this._eventListener);
+        else
+            WI.domManager.removeBreakpointForEventListener(this._eventListener);
+    }
+
     // Private
 
     _targetTextOrLink()
@@ -119,67 +206,17 @@
         return fragment;
     }
 
-    _createDisabledToggleRow()
+    _updateDisabledToggle()
     {
-        let toggleElement = document.createElement("input");
-        toggleElement.type = "checkbox";
-        toggleElement.checked = !this._eventListener.disabled;
-
-        let updateTitle = () => {
-            if (this._eventListener.disabled)
-                toggleElement.title = WI.UIString("Enable Event Listener");
-            else
-                toggleElement.title = WI.UIString("Disable Event Listener");
-        };
-
-        updateTitle();
-
-        toggleElement.addEventListener("change", (event) => {
-            this._eventListener.disabled = !toggleElement.checked;
-            WI.domManager.setEventListenerDisabled(this._eventListener, this._eventListener.disabled);
-            updateTitle();
-        });
-
-        let toggleLabel = document.createElement("span");
-        toggleLabel.textContent = WI.UIString("Enabled");
-        toggleLabel.addEventListener("click", (event) => {
-            toggleElement.click();
-        });
-
-        return new WI.DetailsSectionSimpleRow(toggleLabel, toggleElement);
+        console.assert(this._eventListenerEnabledToggleElement);
+        this._eventListenerEnabledToggleElement.checked = !this._eventListener.disabled;
+        this._eventListenerEnabledToggleElement.title = this._eventListener.disabled ? WI.UIString("Enable Event Listener") : WI.UIString("Disable Event Listener");
     }
 
-    _createBreakpointToggleRow()
+    _updateBreakpointToggle()
     {
-        let checkboxElement = document.createElement("input");
-        checkboxElement.type = "checkbox";
-        checkboxElement.checked = !!this._eventListener.hasBreakpoint;
-
-        let updateTitle = () => {
-            if (this._eventListener.hasBreakpoint)
-                checkboxElement.title = WI.UIString("Delete Breakpoint");
-            else
-                checkboxElement.title = WI.UIString("Add Breakpoint");
-        };
-
-        updateTitle();
-
-        checkboxElement.addEventListener("change", (event) => {
-            this._eventListener.hasBreakpoint = !!checkboxElement.checked;
-            if (this._eventListener.hasBreakpoint)
-                WI.domManager.setBreakpointForEventListener(this._eventListener);
-            else
-                WI.domManager.removeBreakpointForEventListener(this._eventListener);
-
-            updateTitle();
-        });
-
-        let labelElement = document.createElement("span");
-        labelElement.textContent = WI.UIString("Breakpoint");
-        labelElement.addEventListener("click", (event) => {
-            checkboxElement.click();
-        });
-
-        return new WI.DetailsSectionSimpleRow(labelElement, checkboxElement);
+        console.assert(this._eventListenerBreakpointToggleElement);
+        this._eventListenerBreakpointToggleElement.checked = this._eventListener.hasBreakpoint;
+        this._eventListenerBreakpointToggleElement.title = this._eventListener.hasBreakpoint ? WI.UIString("Delete Breakpoint") : WI.UIString("Add Breakpoint");
     }
 };
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to