Diff
Modified: trunk/Source/WebInspectorUI/ChangeLog (289756 => 289757)
--- trunk/Source/WebInspectorUI/ChangeLog 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/ChangeLog 2022-02-14 21:05:45 UTC (rev 289757)
@@ -1,3 +1,85 @@
+2022-02-14 Razvan Caliman <[email protected]>
+
+ Web Inspector: [Flexbox] List flex containers in Layout sidebar
+ https://bugs.webkit.org/show_bug.cgi?id=235647
+ <rdar://87886241>
+
+ Reviewed by Patrick Angle.
+
+ The representation in the Layout details sidebar of the list of flex containers on the page is very similar to the one for grid containers:
+ a list of nodes identified by selector, with adjacent checkboxes that synchronize state with the visibility of a page overlay, interactive
+ color swatches to decorate the corresponding overlay, and a button to jump to the node in the DOM Tree view.
+
+ Therefore, it makes sense to generalize the code for CSS Grid and reuse it for Flexbox.
+
+ This patch extracts a generic `WI.NodeOverlayListSection` from `WI.CSSGridNodeOverlayListSection`.
+ This is subclassed by `WI.CSSGridNodeOverlayListSection` and `WI.CSSFlexboxSection`.
+ The two rely on the abstract implementations to show/hide overlays, get/set overlay colors, interrogate overlay visibility, and listen to generic overlay show events.
+
+ Which particular type of overlay is the target of each panel is determined in `WI.OverlayManager`
+ by the value of `WI.DomNode.layoutContextType`, either "flex" or "grid". A node cannot have more than one layout context type.
+
+ Where the subclasses differ:
+ - each section has its own label (obviously).
+ - the layout for `WI.CSSGridNodeOverlayListSection` includes a section with settings for the CSS Grid overlay.
+
+ * Localizations/en.lproj/localizedStrings.js:
+ We've received feedback that the latter is more common in web developers' vocabulary when
+ refering to CSS grids. Adopted the same for the flexbox section empty message.
+
+ * UserInterface/Main.html:
+
+ * UserInterface/Views/CSSFlexNodeOverlayListSection.js: Added.
+ (WI.CSSFlexNodeOverlayListSection.prototype.get sectionLabel):
+ (WI.CSSFlexNodeOverlayListSection):
+
+ * UserInterface/Views/CSSGridNodeOverlayListSection.js: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js.
+ (WI.CSSGridNodeOverlayListSection.prototype.get sectionLabel):
+ (WI.CSSGridNodeOverlayListSection.prototype.initialLayout):
+ (WI.CSSGridNodeOverlayListSection):
+ The layout of `WI.CSSFlexNodeOverlayListSection` includes a set of options to configure the CSS Grid overlay.
+
+ * UserInterface/Views/LayoutDetailsSidebarPanel.css:
+ (.details-section:is(.layout-css-flexbox, .layout-css-grid):not(.collapsed) > .content,):
+ (.details-section.layout-css-grid > .content > .group > .row > .css-grid-section): Deleted.
+ (.details-section.layout-css-grid:not(.collapsed) > .content,): Deleted.
+
+ * UserInterface/Views/LayoutDetailsSidebarPanel.js:
+ (WI.LayoutDetailsSidebarPanel):
+ (WI.LayoutDetailsSidebarPanel.prototype.attached):
+ (WI.LayoutDetailsSidebarPanel.prototype.initialLayout):
+ (WI.LayoutDetailsSidebarPanel.prototype.layout):
+ (WI.LayoutDetailsSidebarPanel.prototype._handleLayoutContextTypeChanged):
+ (WI.LayoutDetailsSidebarPanel.prototype._refreshNodeSets):
+ (WI.LayoutDetailsSidebarPanel.prototype._refreshGridNodeSet): Deleted.
+ Added Flexbox section to Layout details sidebar.
+
+ * UserInterface/Views/NodeOverlayListSection.css: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSGridSection.css.
+ (.node-overlay-list-section):
+ (.node-overlay-list-section > .node-overlay-list):
+ (.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container):
+ (.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > label):
+ (.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > label > .node-display-name):
+ (.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > :is(.go-to-arrow, .inline-swatch)):
+ (.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container:not(:hover) > .go-to-arrow):
+ (.node-overlay-list-section > .heading,):
+ (.node-overlay-list-section > .heading > label > .toggle-all):
+ (.node-overlay-list-section :is(.setting-editor, .node-overlay-list-item-container, .heading) input[type="checkbox"]):
+ A full-on replacement of `.css-grid-section` with `.node-overlay-list-section` since the two sections share the same styles.
+
+ * UserInterface/Views/NodeOverlayListSection.js: Copied from Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js.
+ (WI.NodeOverlayListSection):
+ (WI.NodeOverlayListSection.prototype.set nodeSet):
+ (WI.NodeOverlayListSection.prototype.get sectionLabel):
+ (WI.NodeOverlayListSection.prototype.attached):
+ (WI.NodeOverlayListSection.prototype.detached):
+ (WI.NodeOverlayListSection.prototype.initialLayout):
+ (WI.NodeOverlayListSection.prototype.layout):
+ (WI.NodeOverlayListSection.prototype._handleOverlayStateChanged):
+ (WI.NodeOverlayListSection.prototype._handleToggleAllCheckboxChanged):
+ (WI.NodeOverlayListSection.prototype._updateToggleAllCheckbox):
+ Removed all the specific implementations for CSS Grid after generalizing them into `WI.NodeOverlayListSection`.
+
2022-02-11 Devin Rousso <[email protected]>
Web Inspector: Sources: double clicking a breakpoint icon should show the edit popover
Modified: trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js (289756 => 289757)
--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -674,6 +674,8 @@
localizedStrings["Filter:"] = "Filter:";
localizedStrings["Find Next (%s)"] = "Find Next (%s)";
localizedStrings["Find Previous (%s)"] = "Find Previous (%s)";
+/* Flexbox layout section name */
+localizedStrings["Flexbox @ Elements details sidebar"] = "Flexbox";
localizedStrings["Flows"] = "Flows";
localizedStrings["Focus on Subtree"] = "Focus on Subtree";
localizedStrings["Focused"] = "Focused";
@@ -968,8 +970,10 @@
localizedStrings["No Attributes"] = "No Attributes";
localizedStrings["No Box Model Information"] = "No Box Model Information";
localizedStrings["No CSS Changes"] = "No CSS Changes";
-/* Message shown when there are no CSS Grid contexts on the inspected page. */
-localizedStrings["No CSS Grid Contexts @ Layout Details Sidebar Panel"] = "No CSS Grid Contexts";
+/* Message shown when there are no CSS Flex containers on the inspected page. */
+localizedStrings["No CSS Flex Containers @ Layout Details Sidebar Panel"] = "No CSS Flex Containers";
+/* Message shown when there are no CSS Grid containers on the inspected page. */
+localizedStrings["No CSS Grid Containers @ Layout Details Sidebar Panel"] = "No CSS Grid Containers";
localizedStrings["No Canvas Contexts"] = "No Canvas Contexts";
localizedStrings["No Canvas Selected"] = "No Canvas Selected";
localizedStrings["No Chart Available"] = "No Chart Available";
@@ -1075,6 +1079,8 @@
localizedStrings["Page Overlay Options @ Layout Panel Section Header"] = "Page Overlay Options";
/* Heading for list of grid nodes */
localizedStrings["Page Overlays @ Layout Sidebar Section Header"] = "Grid Overlays";
+/* Heading for list of flex container nodes */
+localizedStrings["Page Overlays for Flex containers @ Layout Sidebar Section Header"] = "Flexbox Overlays";
localizedStrings["Page navigated at %s"] = "Page navigated at %s";
localizedStrings["Page reloaded at %s"] = "Page reloaded at %s";
/* Paint (render) phase timeline records */
Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (289756 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Main.html 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html 2022-02-14 21:05:45 UTC (rev 289757)
@@ -92,7 +92,6 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
- <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -171,6 +170,7 @@
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
+ <link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
<link rel="stylesheet" href=""
@@ -614,6 +614,8 @@
<script src=""
<script src=""
+ <script src=""
+
<script src=""
<script src=""
<script src=""
@@ -651,8 +653,9 @@
<script src=""
<script src=""
<script src=""
+ <script src=""
+ <script src=""
<script src=""
- <script src=""
<script src=""
<script src=""
<script src=""
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/CSSFlexNodeOverlayListSection.js (from rev 289756, trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.css) (0 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSFlexNodeOverlayListSection.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSFlexNodeOverlayListSection.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.CSSFlexNodeOverlayListSection = class CSSFlexNodeOverlayListSection extends WI.NodeOverlayListSection
+{
+ // Protected
+
+ get sectionLabel()
+ {
+ return WI.UIString("Flexbox Overlays", "Page Overlays for Flex containers @ Layout Sidebar Section Header", "Heading for list of flex container nodes");
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridNodeOverlayListSection.js (0 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridNodeOverlayListSection.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridNodeOverlayListSection.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.CSSGridNodeOverlayListSection = class CSSGridNodeOverlayListSection extends WI.NodeOverlayListSection
+{
+ // Protected
+
+ get sectionLabel()
+ {
+ return WI.UIString("Grid Overlays", "Page Overlays @ Layout Sidebar Section Header", "Heading for list of grid nodes");
+ }
+
+ initialLayout()
+ {
+ let settingsGroup = new WI.SettingsGroup(WI.UIString("Page Overlay Options", "Page Overlay Options @ Layout Panel Section Header", "Heading for list of grid overlay options"));
+ this.element.append(settingsGroup.element);
+
+ settingsGroup.addSetting(WI.settings.gridOverlayShowTrackSizes, WI.UIString("Track Sizes", "Track sizes @ Layout Panel Overlay Options", "Label for option to toggle the track sizes setting for CSS grid overlays"));
+ settingsGroup.addSetting(WI.settings.gridOverlayShowLineNumbers, WI.UIString("Line Numbers", "Line numbers @ Layout Panel Overlay Options", "Label for option to toggle the line numbers setting for CSS grid overlays"));
+ settingsGroup.addSetting(WI.settings.gridOverlayShowLineNames, WI.UIString("Line Names", "Line names @ Layout Panel Overlay Options", "Label for option to toggle the line names setting for CSS grid overlays"));
+ settingsGroup.addSetting(WI.settings.gridOverlayShowAreaNames, WI.UIString("Area Names", "Area names @ Layout Panel Overlay Options", "Label for option to toggle the area names setting for CSS grid overlays"));
+ settingsGroup.addSetting(WI.settings.gridOverlayShowExtendedGridLines, WI.UIString("Extended Grid Lines", "Show extended lines @ Layout Panel Overlay Options", "Label for option to toggle the extended lines setting for CSS grid overlays"));
+
+ super.initialLayout();
+ }
+};
Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.css (289756 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.css 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.css 2022-02-14 21:05:45 UTC (rev 289757)
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2021 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-.css-grid-section .node-display-name {
- margin-inline: 5px 4px;
-}
-
-.css-grid-section .node-overlay-list {
- list-style: none;
- margin: 0;
- padding: 0;
-}
-
-.css-grid-section .node-overlay-list-item-container {
- display: flex;
- align-items: center;
-}
-
-.css-grid-section .node-overlay-list-item-container label {
- flex-shrink: 1;
- min-width: 0;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.css-grid-section .node-overlay-list-item-container :is(.go-to-arrow, .inline-swatch) {
- flex-shrink: 0;
-}
-
-.css-grid-section .node-overlay-list-item-container:not(:hover) .go-to-arrow {
- opacity: 0;
-}
-
-.css-grid-section :is(.heading, .title) {
- font-size: 11px;
- margin-top: 10px;
- margin-bottom: 5px;
- font-weight: 500;
- color: var(--text-color)
-}
-
-.css-grid-section .toggle-all {
- padding-inline-start: 4px;
-}
-
-.css-grid-section :is(.setting-editor, .node-overlay-list-item-container, .heading) input[type="checkbox"] {
- margin-inline-end: 0;
-}
-
-.css-grid-section .setting-editor > input[type="checkbox"] {
- font-size: revert;
-}
Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js (289756 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -1,207 +0,0 @@
-/*
- * Copyright (C) 2021 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// FIXME: <https://webkit.org/b/152269> convert `WI.CSSGridSection` to be a subclass of `WI.DetailsSectionRow`
-
-WI.CSSGridSection = class CSSGridSection extends WI.View
-{
- constructor()
- {
- super();
-
- this.element.classList.add("css-grid-section");
-
- this._gridNodeSet = new Set;
- this._checkboxElementByNodeMap = new WeakMap;
- this._toggleAllCheckboxElement = null;
- this._suppressUpdateToggleAllCheckbox = false;
- }
-
- // Public
-
- set gridNodeSet(value)
- {
- this._gridNodeSet = value;
- this.needsLayout();
- }
-
- // Protected
-
- attached()
- {
- super.attached();
-
- WI.overlayManager.addEventListener(WI.OverlayManager.Event.OverlayShown, this._handleGridOverlayStateChanged, this);
- WI.overlayManager.addEventListener(WI.OverlayManager.Event.OverlayHidden, this._handleGridOverlayStateChanged, this);
- }
-
- detached()
- {
- WI.overlayManager.removeEventListener(WI.OverlayManager.Event.OverlayShown, this._handleGridOverlayStateChanged, this);
- WI.overlayManager.removeEventListener(WI.OverlayManager.Event.OverlayHidden, this._handleGridOverlayStateChanged, this);
-
- super.detached();
- }
-
- initialLayout()
- {
- super.initialLayout();
-
- let settingsGroup = new WI.SettingsGroup(WI.UIString("Page Overlay Options", "Page Overlay Options @ Layout Panel Section Header", "Heading for list of grid overlay options"));
- this.element.append(settingsGroup.element);
-
- settingsGroup.addSetting(WI.settings.gridOverlayShowTrackSizes, WI.UIString("Track Sizes", "Track sizes @ Layout Panel Overlay Options", "Label for option to toggle the track sizes setting for CSS grid overlays"));
- settingsGroup.addSetting(WI.settings.gridOverlayShowLineNumbers, WI.UIString("Line Numbers", "Line numbers @ Layout Panel Overlay Options", "Label for option to toggle the line numbers setting for CSS grid overlays"));
- settingsGroup.addSetting(WI.settings.gridOverlayShowLineNames, WI.UIString("Line Names", "Line names @ Layout Panel Overlay Options", "Label for option to toggle the line names setting for CSS grid overlays"));
- settingsGroup.addSetting(WI.settings.gridOverlayShowAreaNames, WI.UIString("Area Names", "Area names @ Layout Panel Overlay Options", "Label for option to toggle the area names setting for CSS grid overlays"));
- settingsGroup.addSetting(WI.settings.gridOverlayShowExtendedGridLines, WI.UIString("Extended Grid Lines", "Show extended lines @ Layout Panel Overlay Options", "Label for option to toggle the extended lines setting for CSS grid overlays"));
-
- let listHeading = this.element.appendChild(document.createElement("h2"));
- listHeading.classList.add("heading");
-
- let label = listHeading.createChild("label");
- this._toggleAllCheckboxElement = label.createChild("input");
- this._toggleAllCheckboxElement.type = "checkbox";
- this._toggleAllCheckboxElement.addEventListener("change", this._handleToggleAllCheckboxChanged.bind(this));
-
- let labelInner = label.createChild("span", "toggle-all");
- labelInner.textContent = WI.UIString("Grid Overlays", "Page Overlays @ Layout Sidebar Section Header", "Heading for list of grid nodes");
-
- this._listElement = this.element.appendChild(document.createElement("ul"));
- this._listElement.classList.add("node-overlay-list");
- }
-
- _handleToggleAllCheckboxChanged(event)
- {
- let isChecked = event.target.checked;
- this._suppressUpdateToggleAllCheckbox = true;
- for (let domNode of this._gridNodeSet) {
- if (isChecked)
- WI.overlayManager.showOverlay(domNode, {initiator: WI.GridOverlayDiagnosticEventRecorder.Initiator.Panel});
- else
- WI.overlayManager.hideOverlay(domNode);
- }
- this._suppressUpdateToggleAllCheckbox = false;
- }
-
- layout()
- {
- super.layout();
-
- this._listElement.removeChildren();
-
- for (let domNode of this._gridNodeSet) {
- let itemElement = this._listElement.appendChild(document.createElement("li"));
- let itemContainerElement = itemElement.appendChild(document.createElement("span"));
- itemContainerElement.classList.add("node-overlay-list-item-container");
-
- let labelElement = itemContainerElement.appendChild(document.createElement("label"));
- let checkboxElement = labelElement.appendChild(document.createElement("input"));
- checkboxElement.type = "checkbox";
- checkboxElement.checked = WI.overlayManager.hasVisibleOverlay(domNode);
-
- const nodeDisplayName = labelElement.appendChild(document.createElement("span"));
- nodeDisplayName.classList.add("node-display-name");
- nodeDisplayName.textContent = domNode.displayName;
-
- this._checkboxElementByNodeMap.set(domNode, checkboxElement);
-
- checkboxElement.addEventListener("change", (event) => {
- if (checkboxElement.checked)
- WI.overlayManager.showOverlay(domNode, {color: swatch.value, initiator: WI.GridOverlayDiagnosticEventRecorder.Initiator.Panel});
- else
- WI.overlayManager.hideOverlay(domNode);
- });
-
- let gridColor = WI.overlayManager.getColorForNode(domNode);
- let swatch = new WI.InlineSwatch(WI.InlineSwatch.Type.Color, gridColor);
- swatch.shiftClickColorEnabled = false;
- itemContainerElement.append(swatch.element);
-
- swatch.addEventListener(WI.InlineSwatch.Event.ValueChanged, (event) => {
- if (checkboxElement.checked)
- // While changing the overlay color, WI.OverlayManager.Event.GridOverlayShown is dispatched with high frequency.
- // An initiator is not provided so as not to skew usage count of overlay options when logging diagnostics in WI.GridOverlayDiagnosticEventRecorder.
- WI.overlayManager.showOverlay(domNode, {color: event.data.value});
- }, swatch);
-
- swatch.addEventListener(WI.InlineSwatch.Event.Deactivated, (event) => {
- if (event.target.value === gridColor)
- return;
-
- gridColor = event.target.value;
- WI.overlayManager.setColorForNode(domNode, gridColor);
- }, swatch);
-
- let buttonElement = itemContainerElement.appendChild(WI.createGoToArrowButton());
- buttonElement.title = WI.repeatedUIString.revealInDOMTree();
- WI.bindInteractionsForNodeToElement(domNode, buttonElement);
- }
-
- this._updateToggleAllCheckbox();
- }
-
- // Private
-
- _handleGridOverlayStateChanged(event)
- {
- if (event.data.domNode.layoutContextType !== WI.DOMNode.LayoutContextType.Grid)
- return;
-
- let checkboxElement = this._checkboxElementByNodeMap.get(event.data.domNode);
- if (!checkboxElement)
- return;
-
- checkboxElement.checked = event.type === WI.OverlayManager.Event.OverlayShown;
- this._updateToggleAllCheckbox();
- }
-
- _updateToggleAllCheckbox()
- {
- if (this._suppressUpdateToggleAllCheckbox)
- return;
-
- let hasVisible = false;
- let hasHidden = false;
- for (let domNode of this._gridNodeSet) {
- let isVisible = WI.overlayManager.hasVisibleOverlay(domNode);
- if (isVisible)
- hasVisible = true;
- else
- hasHidden = true;
-
- // Exit early as soon as the partial state is determined.
- if (hasVisible && hasHidden)
- break;
- }
-
- if (hasVisible && hasHidden)
- this._toggleAllCheckboxElement.indeterminate = true;
- else {
- this._toggleAllCheckboxElement.indeterminate = false;
- this._toggleAllCheckboxElement.checked = hasVisible;
- }
- }
-};
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.css (289756 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.css 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.css 2022-02-14 21:05:45 UTC (rev 289757)
@@ -23,12 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
-.details-section.layout-css-grid > .content > .group > .row > .css-grid-section {
- margin-inline: 6px;
- margin-bottom: 4px;
-}
-
-.details-section.layout-css-grid:not(.collapsed) > .content,
-.details-section.layout-css-grid > .content > .group {
+.details-section:is(.layout-css-flexbox, .layout-css-grid):not(.collapsed) > .content,
+.details-section:is(.layout-css-flexbox, .layout-css-grid) > .content > .group {
display: block;
}
Modified: trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.js (289756 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.js 2022-02-14 20:57:22 UTC (rev 289756)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/LayoutDetailsSidebarPanel.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -29,6 +29,7 @@
{
super("layout-details", WI.UIString("Layout", "Layout @ Styles Sidebar", "Title of the CSS style panel."));
+ this._flexNodeSet = new Set;
this._gridNodeSet = new Set;
this._nodeStyles = null;
this.element.classList.add("layout-panel");
@@ -82,7 +83,7 @@
WI.cssManager.layoutContextTypeChangedMode = WI.CSSManager.LayoutContextTypeChangedMode.All;
- this._refreshGridNodeSet();
+ this._refreshNodeSets();
}
detached()
@@ -97,12 +98,22 @@
initialLayout()
{
- this._gridDetailsSectionRow = new WI.DetailsSectionRow(WI.UIString("No CSS Grid Contexts", "No CSS Grid Contexts @ Layout Details Sidebar Panel", "Message shown when there are no CSS Grid contexts on the inspected page."));
+ this._gridDetailsSectionRow = new WI.DetailsSectionRow(WI.UIString("No CSS Grid Containers", "No CSS Grid Containers @ Layout Details Sidebar Panel", "Message shown when there are no CSS Grid containers on the inspected page."));
let gridGroup = new WI.DetailsSectionGroup([this._gridDetailsSectionRow]);
let gridDetailsSection = new WI.DetailsSection("layout-css-grid", WI.UIString("Grid", "Grid @ Elements details sidebar", "CSS Grid layout section name"), [gridGroup]);
this.contentView.element.appendChild(gridDetailsSection.element);
- this._gridSection = new WI.CSSGridSection;
+ this._gridSection = new WI.CSSGridNodeOverlayListSection;
+
+ // FIXME: <https://webkit.org/b/235820> Enable Flexbox Inspector feature
+ if (!WI.settings.engineeringEnableFlexboxInspector.value)
+ return;
+
+ this._flexDetailsSectionRow = new WI.DetailsSectionRow(WI.UIString("No CSS Flex Containers", "No CSS Flex Containers @ Layout Details Sidebar Panel", "Message shown when there are no CSS Flex containers on the inspected page."));
+ let flexDetailsSection = new WI.DetailsSection("layout-css-flexbox", WI.UIString("Flexbox", "Flexbox @ Elements details sidebar", "Flexbox layout section name"), [new WI.DetailsSectionGroup([this._flexDetailsSectionRow])]);
+ this.contentView.element.appendChild(flexDetailsSection.element);
+
+ this._flexSection = new WI.CSSFlexNodeOverlayListSection;
}
layout()
@@ -109,20 +120,38 @@
{
super.layout();
- if (!this._gridNodeSet.size) {
+ if (this._gridNodeSet.size) {
+ this._gridDetailsSectionRow.hideEmptyMessage();
+ this._gridDetailsSectionRow.element.appendChild(this._gridSection.element);
+
+ if (!this._gridSection.isAttached)
+ this.addSubview(this._gridSection);
+
+ this._gridSection.nodeSet = this._gridNodeSet;
+ } else {
this._gridDetailsSectionRow.showEmptyMessage();
if (this._gridSection.isAttached)
this.removeSubview(this._gridSection);
+ }
+ // FIXME: <https://webkit.org/b/235820> Enable Flexbox Inspector feature
+ if (!WI.settings.engineeringEnableFlexboxInspector.value)
+ return;
+
+ if (this._flexNodeSet.size) {
+ this._flexDetailsSectionRow.hideEmptyMessage();
+ this._flexDetailsSectionRow.element.appendChild(this._flexSection.element);
+
+ if (!this._flexSection.isAttached)
+ this.addSubview(this._flexSection);
+
+ this._flexSection.nodeSet = this._flexNodeSet;
} else {
- this._gridDetailsSectionRow.hideEmptyMessage();
- this._gridDetailsSectionRow.element.appendChild(this._gridSection.element);
+ this._flexDetailsSectionRow.showEmptyMessage();
- if (!this._gridSection.isAttached)
- this.addSubview(this._gridSection);
-
- this._gridSection.gridNodeSet = this._gridNodeSet;
+ if (this._flexSection.isAttached)
+ this.removeSubview(this._flexSection);
}
}
@@ -131,11 +160,23 @@
_handleLayoutContextTypeChanged(event)
{
let domNode = event.target;
- if (domNode.layoutContextType === WI.DOMNode.LayoutContextType.Grid)
+
+ // A node may switch layout context type between grid and flex.
+ // Remove it from both node sets in case it was previously added.
+ // It is also the default case when the layout context type switches to something unknown.
+ this._flexNodeSet.delete(domNode);
+ this._gridNodeSet.delete(domNode);
+
+ switch (domNode.layoutContextType) {
+ case WI.DOMNode.LayoutContextType.Grid:
this._gridNodeSet.add(domNode);
- else
- this._gridNodeSet.delete(domNode);
+ break;
+ case WI.DOMNode.LayoutContextType.Flex:
+ this._flexNodeSet.add(domNode);
+ break;
+ }
+
this.needsLayout();
}
@@ -159,8 +200,12 @@
this._nodeStyles?.refresh();
}
- _refreshGridNodeSet()
+ _refreshNodeSets()
{
this._gridNodeSet = new Set(WI.domManager.nodesWithLayoutContextType(WI.DOMNode.LayoutContextType.Grid));
+
+ // FIXME: <https://webkit.org/b/235820> Enable Flexbox Inspector feature
+ if (WI.settings.engineeringEnableFlexboxInspector.value)
+ this._flexNodeSet = new Set(WI.domManager.nodesWithLayoutContextType(WI.DOMNode.LayoutContextType.Flex));
}
};
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.css (from rev 289756, trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.css) (0 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.css (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.css 2022-02-14 21:05:45 UTC (rev 289757)
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+.node-overlay-list-section {
+ margin-inline: 6px;
+ margin-bottom: 4px;
+ padding-inline-start: 6px;
+}
+
+.node-overlay-list-section > .node-overlay-list {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container {
+ display: flex;
+ align-items: center;
+}
+
+.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > label {
+ flex-shrink: 1;
+ min-width: 0;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > label > .node-display-name {
+ margin-inline: 5px 4px;
+}
+
+.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container > :is(.go-to-arrow, .inline-swatch) {
+ flex-shrink: 0;
+}
+
+.node-overlay-list-section > .node-overlay-list > li > .node-overlay-list-item-container:not(:hover) > .go-to-arrow {
+ opacity: 0;
+}
+
+.node-overlay-list-section > .heading,
+.node-overlay-list-section > .container > .title {
+ font-size: 11px;
+ margin-top: 5px;
+ margin-bottom: 5px;
+ font-weight: 500;
+ color: var(--text-color)
+}
+
+.node-overlay-list-section > .heading > label > .toggle-all {
+ padding-inline-start: 4px;
+}
+
+.node-overlay-list-section :is(.setting-editor, .node-overlay-list-item-container, .heading) input[type="checkbox"] {
+ margin-inline-end: 0;
+}
Copied: trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.js (from rev 289756, trunk/Source/WebInspectorUI/UserInterface/Views/CSSGridSection.js) (0 => 289757)
--- trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NodeOverlayListSection.js 2022-02-14 21:05:45 UTC (rev 289757)
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2022 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.NodeOverlayListSection = class NodeOverlayListSection extends WI.View
+{
+ constructor()
+ {
+ super();
+
+ this.element.classList.add("node-overlay-list-section");
+
+ this._nodeSet = new Set;
+ this._checkboxElementByNodeMap = new WeakMap;
+ this._toggleAllCheckboxElement = null;
+ this._suppressUpdateToggleAllCheckbox = false;
+ }
+
+ // Public
+
+ set nodeSet(value)
+ {
+ this._nodeSet = value;
+ this.needsLayout();
+ }
+
+ // Protected
+
+ get sectionLabel()
+ {
+ throw WI.NotImplementedError.subclassMustOverride();
+ }
+
+ attached()
+ {
+ super.attached();
+
+ WI.overlayManager.addEventListener(WI.OverlayManager.Event.OverlayShown, this._handleOverlayStateChanged, this);
+ WI.overlayManager.addEventListener(WI.OverlayManager.Event.OverlayHidden, this._handleOverlayStateChanged, this);
+ }
+
+ detached()
+ {
+ WI.overlayManager.removeEventListener(WI.OverlayManager.Event.OverlayShown, this._handleOverlayStateChanged, this);
+ WI.overlayManager.removeEventListener(WI.OverlayManager.Event.OverlayHidden, this._handleOverlayStateChanged, this);
+
+ super.detached();
+ }
+
+ initialLayout()
+ {
+ super.initialLayout();
+
+ let listHeading = this.element.appendChild(document.createElement("h2"));
+ listHeading.classList.add("heading");
+
+ let label = listHeading.createChild("label");
+ this._toggleAllCheckboxElement = label.createChild("input");
+ this._toggleAllCheckboxElement.type = "checkbox";
+ this._toggleAllCheckboxElement.addEventListener("change", this._handleToggleAllCheckboxChanged.bind(this));
+
+ let labelInner = label.createChild("span", "toggle-all");
+ labelInner.textContent = this.sectionLabel;
+
+ this._listElement = this.element.appendChild(document.createElement("ul"));
+ this._listElement.classList.add("node-overlay-list");
+ }
+
+
+ layout()
+ {
+ super.layout();
+
+ this._listElement.removeChildren();
+
+ for (let domNode of this._nodeSet) {
+ let itemElement = this._listElement.appendChild(document.createElement("li"));
+ let itemContainerElement = itemElement.appendChild(document.createElement("span"));
+ itemContainerElement.classList.add("node-overlay-list-item-container");
+
+ let labelElement = itemContainerElement.appendChild(document.createElement("label"));
+ let nodeDisplayName = labelElement.appendChild(document.createElement("span"));
+ nodeDisplayName.classList.add("node-display-name");
+ nodeDisplayName.textContent = domNode.displayName;
+
+ let checkboxElement = labelElement.appendChild(document.createElement("input"));
+ labelElement.insertBefore(checkboxElement, nodeDisplayName);
+ checkboxElement.type = "checkbox";
+ checkboxElement.checked = WI.overlayManager.hasVisibleOverlay(domNode);
+
+ this._checkboxElementByNodeMap.set(domNode, checkboxElement);
+
+ let initiator;
+ if (domNode.layoutContextType === WI.DOMNode.LayoutContextType.Grid)
+ initiator = WI.GridOverlayDiagnosticEventRecorder.Initiator.Panel;
+
+ checkboxElement.addEventListener("change", (event) => {
+ if (checkboxElement.checked)
+ WI.overlayManager.showOverlay(domNode, {color: swatch?.value, initiator});
+ else
+ WI.overlayManager.hideOverlay(domNode);
+ });
+
+ let color = WI.overlayManager.getColorForNode(domNode);
+ let swatch = new WI.InlineSwatch(WI.InlineSwatch.Type.Color, color);
+ swatch.shiftClickColorEnabled = false;
+ itemContainerElement.append(swatch.element);
+
+ swatch.addEventListener(WI.InlineSwatch.Event.ValueChanged, (event) => {
+ if (checkboxElement?.checked)
+ WI.overlayManager.showOverlay(domNode, {color: event.data.value});
+ }, swatch);
+
+ swatch.addEventListener(WI.InlineSwatch.Event.Deactivated, (event) => {
+ if (event.target.value === color)
+ return;
+
+ color = event.target.value;
+ WI.overlayManager.setColorForNode(domNode, color);
+ }, swatch);
+
+ let buttonElement = itemContainerElement.appendChild(WI.createGoToArrowButton());
+ buttonElement.title = WI.repeatedUIString.revealInDOMTree();
+ WI.bindInteractionsForNodeToElement(domNode, buttonElement);
+ }
+
+ this._updateToggleAllCheckbox();
+ }
+
+ // Private
+
+ _handleOverlayStateChanged(event)
+ {
+ let checkboxElement = this._checkboxElementByNodeMap.get(event.data.domNode);
+ if (!checkboxElement)
+ return;
+
+ checkboxElement.checked = event.type === WI.OverlayManager.Event.OverlayShown;
+ this._updateToggleAllCheckbox();
+ }
+
+ _handleToggleAllCheckboxChanged(event)
+ {
+ let isChecked = event.target.checked;
+ this._suppressUpdateToggleAllCheckbox = true;
+
+ for (let domNode of this._nodeSet) {
+ if (isChecked)
+ WI.overlayManager.showOverlay(domNode);
+ else
+ WI.overlayManager.hideOverlay(domNode);
+ }
+
+ this._suppressUpdateToggleAllCheckbox = false;
+ }
+
+ _updateToggleAllCheckbox()
+ {
+ if (this._suppressUpdateToggleAllCheckbox)
+ return;
+
+ let hasVisible = false;
+ let hasHidden = false;
+ for (let domNode of this._nodeSet) {
+ let isVisible = WI.overlayManager.hasVisibleOverlay(domNode);
+ if (isVisible)
+ hasVisible = true;
+ else
+ hasHidden = true;
+
+ // Exit early as soon as the partial state is determined.
+ if (hasVisible && hasHidden)
+ break;
+ }
+
+ if (hasVisible && hasHidden)
+ this._toggleAllCheckboxElement.indeterminate = true;
+ else {
+ this._toggleAllCheckboxElement.indeterminate = false;
+ this._toggleAllCheckboxElement.checked = hasVisible;
+ }
+ }
+};