Title: [225547] trunk/Source/WebInspectorUI
Revision
225547
Author
nvasil...@apple.com
Date
2017-12-05 14:28:20 -0800 (Tue, 05 Dec 2017)

Log Message

Web Inspector: Styles: make Computed a top-level sidebar tab
https://bugs.webkit.org/show_bug.cgi?id=174229
<rdar://problem/33170193>

Reviewed by Matt Baker.

Styles dropdown tab selector was removed. Styles and Computed are now top-level sidebar tabs.

Visual styles is no longer visible in the Styles sidebar tabs by default but can be enabled in the settings.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Base/Setting.js:
* UserInterface/Main.html:
* UserInterface/Views/CSSStyleDeclarationSection.js:
(WI.CSSStyleDeclarationSection.prototype.findMatchingPropertiesAndSelectors):
* UserInterface/Views/CSSStyleDeclarationTextEditor.js:
(WI.CSSStyleDeclarationTextEditor.prototype.findMatchingProperties):
(WI.CSSStyleDeclarationTextEditor.prototype.removeNonMatchingProperties):
* UserInterface/Views/ComputedStyleDetailsSidebarPanel.js: Added.
(WI.ComputedStyleDetailsSidebarPanel):
* UserInterface/Views/DOMTreeOutline.js:
(WI.DOMTreeOutline.prototype._ondragover):
(WI.DOMTreeOutline.prototype._ondrop):
* UserInterface/Views/ElementsTabContentView.js:
(WI.ElementsTabContentView):
* UserInterface/Views/GeneralStyleDetailsSidebarPanel.css: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css.
* UserInterface/Views/GeneralStyleDetailsSidebarPanel.js: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js.
(WI.GeneralStyleDetailsSidebarPanel):
(WI.GeneralStyleDetailsSidebarPanel.prototype.get panel):
(WI.GeneralStyleDetailsSidebarPanel.prototype.visibilityDidChange):
(WI.GeneralStyleDetailsSidebarPanel.prototype.computedStyleDetailsPanelShowProperty):
(WI.GeneralStyleDetailsSidebarPanel.prototype.layout):
(WI.GeneralStyleDetailsSidebarPanel.prototype.initialLayout):
(WI.GeneralStyleDetailsSidebarPanel.prototype.sizeDidChange):
(WI.GeneralStyleDetailsSidebarPanel.prototype.get _initialScrollOffset):
(WI.GeneralStyleDetailsSidebarPanel.prototype._updateNoForcedPseudoClassesScrollOffset):
(WI.GeneralStyleDetailsSidebarPanel.prototype._showPanel):
(WI.GeneralStyleDetailsSidebarPanel.prototype._newRuleButtonClicked):
(WI.GeneralStyleDetailsSidebarPanel.prototype._newRuleButtonContextMenu):
(WI.GeneralStyleDetailsSidebarPanel.prototype._populateClassToggles):
(WI.GeneralStyleDetailsSidebarPanel.prototype._createToggleForClassName):
(WI.GeneralStyleDetailsSidebarPanel.prototype._filterDidChange):
Styles and Computed tabs share a few UI components, such as force state (:hover, :focus, etc.),
filter field, and CSS class toggle components. To implement this, CSSStyleDetailsSidebarPanel was renamed
to GeneralStyleDetailsSidebarPanel.

CSSStyleDetailsSidebarPanel used to support several panels. This is no longer the case with GeneralStyleDetailsSidebarPanel:
- _initiallySelectedPanel was removed.
- _selectedPanel was replaced by _panel.

* UserInterface/Views/GroupNavigationItem.js:
(WI.GroupNavigationItem.prototype.get minimumWidth):
* UserInterface/Views/NavigationBar.css:
(.navigation-bar .item,):
(.sidebar-navigation-bar):
(.sidebar-navigation-bar .holder):
* UserInterface/Views/NavigationBar.js:
(WI.NavigationBar.prototype._calculateMinimumWidth):
Minor optimization: don't toggle class names when there are no visible navigation items.

* UserInterface/Views/RulesStyleDetailsPanel.js:
(WI.RulesStyleDetailsPanel.prototype.filterDidChange):
* UserInterface/Views/RulesStyleDetailsSidebarPanel.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
(WI.RulesStyleDetailsSidebarPanel):
* UserInterface/Views/SearchTabContentView.js:
(WI.SearchTabContentView):
* UserInterface/Views/SettingsTabContentView.js:
(WI.SettingsTabContentView.prototype._createExperimentalSettingsView):
* UserInterface/Views/Sidebar.js:
(WI.Sidebar):
* UserInterface/Views/SidebarNavigationBar.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
(WI.SidebarNavigationBar):
(WI.SidebarNavigationBar.prototype.insertNavigationItem):
(WI.SidebarNavigationBar.prototype._calculateMinimumWidth):
SidebarNavigationBar wraps navigation items in an element so it can correctly calculate the width of all items with spacing between them.

* UserInterface/Views/StyleDetailsPanel.js:
(WI.StyleDetailsPanel.prototype.get _initialScrollOffset):
* UserInterface/Views/VisualStyleDetailsSidebarPanel.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
(WI.VisualStyleDetailsSidebarPanel):

Modified Paths

Added Paths

Removed Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (225546 => 225547)


--- trunk/Source/WebInspectorUI/ChangeLog	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/ChangeLog	2017-12-05 22:28:20 UTC (rev 225547)
@@ -1,3 +1,86 @@
+2017-12-05  Nikita Vasilyev  <nvasil...@apple.com>
+
+        Web Inspector: Styles: make Computed a top-level sidebar tab
+        https://bugs.webkit.org/show_bug.cgi?id=174229
+        <rdar://problem/33170193>
+
+        Reviewed by Matt Baker.
+
+        Styles dropdown tab selector was removed. Styles and Computed are now top-level sidebar tabs.
+
+        Visual styles is no longer visible in the Styles sidebar tabs by default but can be enabled in the settings.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Base/Setting.js:
+        * UserInterface/Main.html:
+        * UserInterface/Views/CSSStyleDeclarationSection.js:
+        (WI.CSSStyleDeclarationSection.prototype.findMatchingPropertiesAndSelectors):
+        * UserInterface/Views/CSSStyleDeclarationTextEditor.js:
+        (WI.CSSStyleDeclarationTextEditor.prototype.findMatchingProperties):
+        (WI.CSSStyleDeclarationTextEditor.prototype.removeNonMatchingProperties):
+        * UserInterface/Views/ComputedStyleDetailsSidebarPanel.js: Added.
+        (WI.ComputedStyleDetailsSidebarPanel):
+        * UserInterface/Views/DOMTreeOutline.js:
+        (WI.DOMTreeOutline.prototype._ondragover):
+        (WI.DOMTreeOutline.prototype._ondrop):
+        * UserInterface/Views/ElementsTabContentView.js:
+        (WI.ElementsTabContentView):
+        * UserInterface/Views/GeneralStyleDetailsSidebarPanel.css: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css.
+        * UserInterface/Views/GeneralStyleDetailsSidebarPanel.js: Renamed from Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js.
+        (WI.GeneralStyleDetailsSidebarPanel):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.get panel):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.visibilityDidChange):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.computedStyleDetailsPanelShowProperty):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.layout):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.initialLayout):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.sizeDidChange):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype.get _initialScrollOffset):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._updateNoForcedPseudoClassesScrollOffset):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._showPanel):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._newRuleButtonClicked):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._newRuleButtonContextMenu):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._populateClassToggles):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._createToggleForClassName):
+        (WI.GeneralStyleDetailsSidebarPanel.prototype._filterDidChange):
+        Styles and Computed tabs share a few UI components, such as force state (:hover, :focus, etc.),
+        filter field, and CSS class toggle components. To implement this, CSSStyleDetailsSidebarPanel was renamed
+        to GeneralStyleDetailsSidebarPanel.
+
+        CSSStyleDetailsSidebarPanel used to support several panels. This is no longer the case with GeneralStyleDetailsSidebarPanel:
+        - _initiallySelectedPanel was removed.
+        - _selectedPanel was replaced by _panel.
+
+        * UserInterface/Views/GroupNavigationItem.js:
+        (WI.GroupNavigationItem.prototype.get minimumWidth):
+        * UserInterface/Views/NavigationBar.css:
+        (.navigation-bar .item,):
+        (.sidebar-navigation-bar):
+        (.sidebar-navigation-bar .holder):
+        * UserInterface/Views/NavigationBar.js:
+        (WI.NavigationBar.prototype._calculateMinimumWidth):
+        Minor optimization: don't toggle class names when there are no visible navigation items.
+
+        * UserInterface/Views/RulesStyleDetailsPanel.js:
+        (WI.RulesStyleDetailsPanel.prototype.filterDidChange):
+        * UserInterface/Views/RulesStyleDetailsSidebarPanel.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
+        (WI.RulesStyleDetailsSidebarPanel):
+        * UserInterface/Views/SearchTabContentView.js:
+        (WI.SearchTabContentView):
+        * UserInterface/Views/SettingsTabContentView.js:
+        (WI.SettingsTabContentView.prototype._createExperimentalSettingsView):
+        * UserInterface/Views/Sidebar.js:
+        (WI.Sidebar):
+        * UserInterface/Views/SidebarNavigationBar.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
+        (WI.SidebarNavigationBar):
+        (WI.SidebarNavigationBar.prototype.insertNavigationItem):
+        (WI.SidebarNavigationBar.prototype._calculateMinimumWidth):
+        SidebarNavigationBar wraps navigation items in an element so it can correctly calculate the width of all items with spacing between them.
+
+        * UserInterface/Views/StyleDetailsPanel.js:
+        (WI.StyleDetailsPanel.prototype.get _initialScrollOffset):
+        * UserInterface/Views/VisualStyleDetailsSidebarPanel.js: Copied from Source/WebInspectorUI/UserInterface/Views/NavigationBar.css.
+        (WI.VisualStyleDetailsSidebarPanel):
+
 2017-12-05  Joseph Pecoraro  <pecor...@apple.com>
 
         Web Inspector: content views for resources loaded through XHR do not reflect declared mime-type

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


--- trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -536,6 +536,7 @@
 localizedStrings["Layout Invalidated"] = "Layout Invalidated";
 localizedStrings["Left"] = "Left";
 localizedStrings["Legacy Style Editor"] = "Legacy Style Editor";
+localizedStrings["Legacy Visual Styles Panel"] = "Legacy Visual Styles Panel";
 localizedStrings["Letter"] = "Letter";
 localizedStrings["Ligatures"] = "Ligatures";
 localizedStrings["Line %d"] = "Line %d";
@@ -912,10 +913,9 @@
 localizedStrings["Style Attribute"] = "Style Attribute";
 localizedStrings["Style Rules"] = "Style Rules";
 localizedStrings["Style rule"] = "Style rule";
-localizedStrings["Styles"] = "Styles";
 localizedStrings["Styles Invalidated"] = "Styles Invalidated";
-localizedStrings["Styles Panel:"] = "Styles Panel:";
 localizedStrings["Styles Recalculated"] = "Styles Recalculated";
+localizedStrings["Styles Sidebar:"] = "Styles Sidebar:";
 localizedStrings["Styles \u2014 Computed"] = "Styles \u2014 Computed";
 localizedStrings["Styles \u2014 Rules"] = "Styles \u2014 Rules";
 localizedStrings["Styles \u2014 Visual"] = "Styles \u2014 Visual";

Modified: trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Setting.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -123,6 +123,7 @@
     selectedNetworkDetailContentViewIdentifier: new WI.Setting("network-detail-content-view-identifier", "preview"),
 
     // Experimental
+    experimentalEnableLayersTab: new WI.Setting("experimental-enable-layers-tab", false),
     experimentalLegacyStyleEditor: new WI.Setting("experimental-legacy-style-editor", false),
-    experimentalEnableLayersTab: new WI.Setting("experimental-enable-layers-tab", false),
+    experimentalLegacyVisualSidebar: new WI.Setting("experimental-legacy-visual-sidebar", false),
 };

Modified: trunk/Source/WebInspectorUI/UserInterface/Main.html (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Main.html	2017-12-05 22:28:20 UTC (rev 225547)
@@ -40,7 +40,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=""
@@ -91,6 +90,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=""
@@ -464,7 +464,6 @@
     <script src=""
     <script src=""
     <script src=""
-    <script src=""
     <script src=""
     <script src=""
     <script src=""
@@ -507,6 +506,12 @@
     <script src=""
     <script src=""
 
+    <script src=""
+    <script src=""
+    <script src=""
+    <script src=""
+    <script src=""
+
     <script src=""
     <script src=""
     <script src=""
@@ -544,7 +549,6 @@
     <script src=""
     <script src=""
     <script src=""
-    <script src=""
     <script src=""
     <script src=""
     <script src=""
@@ -723,6 +727,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
     <script src=""
     <script src=""
     <script src=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -320,15 +320,15 @@
 
     findMatchingPropertiesAndSelectors(needle)
     {
-        this._element.classList.remove(WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName, WI.CSSStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName);
+        this._element.classList.remove(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName, WI.GeneralStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName);
 
         var hasMatchingSelector = false;
 
         for (var selectorElement of this._selectorElements) {
-            selectorElement.classList.remove(WI.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName);
+            selectorElement.classList.remove(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
 
             if (needle && selectorElement.textContent.includes(needle)) {
-                selectorElement.classList.add(WI.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName);
+                selectorElement.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName);
                 hasMatchingSelector = true;
             }
         }
@@ -341,7 +341,7 @@
         var hasMatchingProperty = this._propertiesTextEditor.findMatchingProperties(needle);
 
         if (!hasMatchingProperty && !hasMatchingSelector) {
-            this._element.classList.add(WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);
+            this._element.classList.add(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);
             return false;
         }
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationTextEditor.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -250,9 +250,9 @@
             var property = propertiesList[i];
 
             if (matchingProperties[i])
-                property.__filterResultClassName = WI.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName;
+                property.__filterResultClassName = WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName;
             else
-                property.__filterResultClassName = WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInPropertyClassName;
+                property.__filterResultClassName = WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInPropertyClassName;
 
             this._updateTextMarkerForPropertyIfNeeded(property);
         }
@@ -288,7 +288,7 @@
 
             if (indexesOfNeedle.length) {
                 matchingPropertyNames.push(property.name);
-                property.__filterResultClassName = WI.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName;
+                property.__filterResultClassName = WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName;
                 property.__filterResultNeedlePosition = {start: indexesOfNeedle, length: needle.length};
             }
         }

Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css	2017-12-05 22:28:20 UTC (rev 225547)
@@ -1,214 +0,0 @@
-/*
- * Copyright (C) 2013 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.
- */
-
-.sidebar > .panel.details.css-style > .content {
-    position: absolute;
-    top: 0;
-    left: 0;
-    right: 0;
-    bottom: 0;
-    overflow-y: auto;
-    overflow-x: hidden;
-}
-
-.sidebar > .panel.details.css-style > .content.has-filter-bar {
-    bottom: calc(var(--navigation-bar-height) - 1px);
-}
-
-.sidebar > .panel.details.css-style > .content > .pseudo-classes {
-    padding: 6px 10px;
-    border-bottom: 1px solid var(--border-color);
-
-    display: flex;
-    flex-flow: row wrap;
-    justify-content: space-around;
-}
-
-.sidebar > .panel.details.css-style > .content > .pseudo-classes > .group {
-    display: inline-flex;
-    flex-flow: row wrap;
-    justify-content: space-around;
-    flex: 1;
-}
-
-.sidebar > .panel.details.css-style > .content > .pseudo-classes > .group > label {
-    color: hsl(0, 0%, 37%);
-
-    margin: 0 5px;
-    min-width: 55px;
-
-    display: inline-block;
-    white-space: nowrap;
-}
-
-.sidebar > .panel.details.css-style > .content ~ :matches(.options-container, .class-list-container) {
-    display: flex;
-    align-items: center;
-    position: absolute;
-    z-index: 1;
-    width: 100%;
-    border-top: 1px solid var(--border-color);
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container {
-    bottom: 0;
-    height: calc(var(--console-prompt-min-height) - 1px);
-    padding-top: 1px;
-}
-
-.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :matches(.options-container, .class-list-container) {
-    display: none;
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
-    width: 15px;
-    min-width: 15px;
-    height: 15px;
-    content: url(../Images/Plus15.svg);
-    opacity: 0.7;
-
-    --panel-details-css-style-content-options-container-new-rule-margin-start: 6px;
-}
-
-body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
-    margin-left: var(--panel-details-css-style-content-options-container-new-rule-margin-start);
-}
-
-body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
-    margin-right: var(--panel-details-css-style-content-options-container-new-rule-margin-start);
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container > .filter-bar {
-    width: -webkit-fill-available;
-    background-color: transparent;
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
-    margin: 0 0 1px;
-    padding: 2px 4px 3px;
-    background: none;
-    border: none;
-    border-radius: 3px;
-    white-space: nowrap;
-    -webkit-appearance: none;
-
-    --panel-details-css-style-content-options-container-toggle-class-toggle-margin-end: 5px;
-}
-
-body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
-    margin-right: var(--panel-details-css-style-content-options-container-toggle-class-toggle-margin-end);
-}
-
-body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
-    margin-left: var(--panel-details-css-style-content-options-container-toggle-class-toggle-margin-end);
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected {
-    color: var(--selected-foreground-color);
-    background-color: var(--selected-background-color);
-}
-
-.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover {
-    color: var(--selected-foreground-color);
-    background-color: var(--selected-background-color-hover);
-}
-
-.sidebar > .panel.details.css-style > .content:not(.supports-new-rule) ~ .options-container > .new-rule,
-.sidebar > .panel.details.css-style > .content:not(.has-filter-bar) ~ .options-container > .filter-bar {
-    display: none;
-}
-
-.sidebar > .panel.details.css-style > .content ~ .class-list-container {
-    flex-wrap: wrap;
-    bottom: calc(var(--console-prompt-min-height) - 1px);
-    max-height: 75px;
-    padding: 3px 2px;
-    background-color: var(--panel-background-color);
-    overflow-y: scroll;
-}
-
-/* FIXME: <https://webkit.org/b/152674> Elements with the "hidden" attribute still show up if "display: flex;" */
-.sidebar > .panel.details.css-style > .content ~ .class-list-container[hidden] {
-    display: none;
-}
-
-.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class {
-    display: flex;
-    width: 100%;
-}
-
-.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
-    flex-grow: 1;
-    height: 18px;
-    margin: 0;
-
-    --panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start: 2px;
-}
-
-body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
-    margin-left: var(--panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start);
-}
-
-body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
-    margin-right: var(--panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start);
-}
-
-.sidebar > .panel.details.css-style > .content ~ .class-list-container > *:matches(.new-class, .class-toggle) {
-    margin: 1px 3px;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-matching {
-    display: inline;
-    background-color: hsla(53, 83%, 53%, 0.5);
-    border-bottom: 1px solid hsl(47, 82%, 60%);
-    opacity: 1;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section {
-    margin-bottom: 0;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section.last-in-group.filter-section-non-matching + .style-declaration-section.filter-section-has-label {
-    margin-top: 0;
-    border-top: none;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section:not(.filter-section-has-label) {
-    margin-top: 0;
-    border-top: none;
-    border-bottom: 1px solid var(--border-color);
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section > .header > .selector > .filter-matching {
-    color: black;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-section-non-matching {
-    display: none;
-}
-
-.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-property-non-matching {
-    opacity: 0.5;
-}

Deleted: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -1,459 +0,0 @@
-/*
- * Copyright (C) 2013, 2015 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.CSSStyleDetailsSidebarPanel = class CSSStyleDetailsSidebarPanel extends WI.DOMDetailsSidebarPanel
-{
-    constructor()
-    {
-        const dontCreateNavigationItem = true;
-        super("css-style", WI.UIString("Styles"), dontCreateNavigationItem);
-
-        this._selectedPanel = null;
-        this._computedStyleDetailsPanel = new WI.ComputedStyleDetailsPanel(this);
-        this._rulesStyleDetailsPanel = new WI.RulesStyleDetailsPanel(this);
-        this._visualStyleDetailsPanel = new WI.VisualStyleDetailsPanel(this);
-
-        if (WI.settings.experimentalLegacyStyleEditor.value)
-            this._activeRulesStyleDetailsPanel = this._rulesStyleDetailsPanel;
-        else
-            this._activeRulesStyleDetailsPanel = new WI.SpreadsheetRulesStyleDetailsPanel(this);
-
-        this._panels = [this._computedStyleDetailsPanel, this._activeRulesStyleDetailsPanel, this._visualStyleDetailsPanel];
-        this._panelNavigationInfo = [this._computedStyleDetailsPanel.navigationInfo, this._activeRulesStyleDetailsPanel.navigationInfo, this._visualStyleDetailsPanel.navigationInfo];
-
-        this._lastSelectedPanelSetting = new WI.Setting("last-selected-style-details-panel", this._activeRulesStyleDetailsPanel.navigationInfo.identifier);
-        this._classListContainerToggledSetting = new WI.Setting("class-list-container-toggled", false);
-
-        this._initiallySelectedPanel = this._panelMatchingIdentifier(this._lastSelectedPanelSetting.value) || this._activeRulesStyleDetailsPanel;
-
-        this._navigationItem = new WI.ScopeRadioButtonNavigationItem(this.identifier, this.displayName, this._panelNavigationInfo, this._initiallySelectedPanel.navigationInfo);
-        this._navigationItem.addEventListener(WI.ScopeRadioButtonNavigationItem.Event.SelectedItemChanged, this._handleSelectedItemChanged, this);
-
-        this._forcedPseudoClassCheckboxes = {};
-    }
-
-    // Public
-
-    supportsDOMNode(nodeToInspect)
-    {
-        return nodeToInspect.nodeType() === Node.ELEMENT_NODE;
-    }
-
-    visibilityDidChange()
-    {
-        super.visibilityDidChange();
-
-        if (!this._selectedPanel)
-            return;
-
-        if (!this.visible) {
-            this._selectedPanel.hidden();
-            return;
-        }
-
-        this._updateNoForcedPseudoClassesScrollOffset();
-
-        this._selectedPanel.shown();
-        this._selectedPanel.markAsNeedsRefresh(this.domNode);
-    }
-
-    computedStyleDetailsPanelShowProperty(property)
-    {
-        this._activeRulesStyleDetailsPanel.scrollToSectionAndHighlightProperty(property);
-        this._switchPanels(this._activeRulesStyleDetailsPanel);
-
-        this._navigationItem.selectedItemIdentifier = this._lastSelectedPanelSetting.value;
-    }
-
-    // Protected
-
-    layout()
-    {
-        let domNode = this.domNode;
-        if (!domNode)
-            return;
-
-        this.contentView.element.scrollTop = this._initialScrollOffset;
-
-        for (let panel of this._panels) {
-            panel.element._savedScrollTop = undefined;
-            panel.markAsNeedsRefresh(domNode);
-        }
-
-        this._updatePseudoClassCheckboxes();
-
-        if (!this._classListContainer.hidden)
-            this._populateClassToggles();
-    }
-
-    addEventListeners()
-    {
-        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
-        if (!effectiveDOMNode)
-            return;
-
-        effectiveDOMNode.addEventListener(WI.DOMNode.Event.EnabledPseudoClassesChanged, this._updatePseudoClassCheckboxes, this);
-        effectiveDOMNode.addEventListener(WI.DOMNode.Event.AttributeModified, this._handleNodeAttributeModified, this);
-        effectiveDOMNode.addEventListener(WI.DOMNode.Event.AttributeRemoved, this._handleNodeAttributeRemoved, this);
-    }
-
-    removeEventListeners()
-    {
-        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
-        if (!effectiveDOMNode)
-            return;
-
-        effectiveDOMNode.removeEventListener(null, null, this);
-    }
-
-    initialLayout()
-    {
-        if (WI.cssStyleManager.canForcePseudoClasses()) {
-            this._forcedPseudoClassContainer = document.createElement("div");
-            this._forcedPseudoClassContainer.className = "pseudo-classes";
-
-            let groupElement = null;
-
-            WI.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
-                // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
-                let label = pseudoClass.capitalize();
-
-                let labelElement = document.createElement("label");
-
-                let checkboxElement = document.createElement("input");
-                checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
-                checkboxElement.type = "checkbox";
-
-                this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
-
-                labelElement.appendChild(checkboxElement);
-                labelElement.append(label);
-
-                if (!groupElement || groupElement.children.length === 2) {
-                    groupElement = document.createElement("div");
-                    groupElement.className = "group";
-                    this._forcedPseudoClassContainer.appendChild(groupElement);
-                }
-
-                groupElement.appendChild(labelElement);
-            }, this);
-
-            this.contentView.element.appendChild(this._forcedPseudoClassContainer);
-        }
-
-        this._computedStyleDetailsPanel.addEventListener(WI.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
-        this._rulesStyleDetailsPanel.addEventListener(WI.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
-
-        console.assert(this._initiallySelectedPanel, "Should have an initially selected panel.");
-
-        this._switchPanels(this._initiallySelectedPanel);
-        this._initiallySelectedPanel = null;
-
-        let optionsContainer = this.element.createChild("div", "options-container");
-
-        let newRuleButton = optionsContainer.createChild("img", "new-rule");
-        newRuleButton.title = WI.UIString("Add new rule");
-        newRuleButton.addEventListener("click", this._newRuleButtonClicked.bind(this));
-        newRuleButton.addEventListener("contextmenu", this._newRuleButtonContextMenu.bind(this));
-
-        this._filterBar = new WI.FilterBar;
-        this._filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
-        optionsContainer.appendChild(this._filterBar.element);
-
-        this._classToggleButton = optionsContainer.createChild("button", "toggle-class-toggle");
-        this._classToggleButton.textContent = WI.UIString("Classes");
-        this._classToggleButton.title = WI.UIString("Toggle Classes");
-        this._classToggleButton.addEventListener("click", this._classToggleButtonClicked.bind(this));
-
-        this._classListContainer = this.element.createChild("div", "class-list-container");
-        this._classListContainer.hidden = true;
-
-        this._addClassContainer = this._classListContainer.createChild("div", "new-class");
-        this._addClassContainer.title = WI.UIString("Add a Class");
-        this._addClassContainer.addEventListener("click", this._addClassContainerClicked.bind(this));
-
-        this._addClassInput = this._addClassContainer.createChild("input", "class-name-input");
-        this._addClassInput.setAttribute("placeholder", WI.UIString("Add New Class"));
-        this._addClassInput.addEventListener("keypress", this._addClassInputKeyPressed.bind(this));
-        this._addClassInput.addEventListener("blur", this._addClassInputBlur.bind(this));
-
-        WI.cssStyleManager.addEventListener(WI.CSSStyleManager.Event.StyleSheetAdded, this._styleSheetAddedOrRemoved, this);
-        WI.cssStyleManager.addEventListener(WI.CSSStyleManager.Event.StyleSheetRemoved, this._styleSheetAddedOrRemoved, this);
-
-        if (this._classListContainerToggledSetting.value)
-            this._classToggleButtonClicked();
-    }
-
-    sizeDidChange()
-    {
-        super.sizeDidChange();
-
-        this._updateNoForcedPseudoClassesScrollOffset();
-
-        if (this._selectedPanel)
-            this._selectedPanel.sizeDidChange();
-    }
-
-    // Private
-
-    get _initialScrollOffset()
-    {
-        if (!WI.cssStyleManager.canForcePseudoClasses())
-            return 0;
-        return this.domNode && this.domNode.enabledPseudoClasses.length ? 0 : WI.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset;
-    }
-
-    _updateNoForcedPseudoClassesScrollOffset()
-    {
-        if (this._forcedPseudoClassContainer)
-            WI.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = this._forcedPseudoClassContainer.offsetHeight;
-    }
-
-    _panelMatchingIdentifier(identifier)
-    {
-        let selectedPanel = null;
-        for (let panel of this._panels) {
-            if (panel.navigationInfo.identifier !== identifier)
-                continue;
-
-            selectedPanel = panel;
-            break;
-        }
-
-        return selectedPanel;
-    }
-
-    _handleSelectedItemChanged()
-    {
-        let selectedIdentifier = this._navigationItem.selectedItemIdentifier;
-        let selectedPanel = this._panelMatchingIdentifier(selectedIdentifier);
-        this._switchPanels(selectedPanel);
-    }
-
-    _switchPanels(selectedPanel)
-    {
-        console.assert(selectedPanel);
-
-        if (this._selectedPanel) {
-            this._selectedPanel.hidden();
-            this._selectedPanel.element._savedScrollTop = this.contentView.element.scrollTop;
-            this.contentView.removeSubview(this._selectedPanel);
-        }
-
-        this._selectedPanel = selectedPanel;
-        if (!this._selectedPanel)
-            return;
-
-        this.contentView.addSubview(this._selectedPanel);
-
-        if (typeof this._selectedPanel.element._savedScrollTop === "number")
-            this.contentView.element.scrollTop = this._selectedPanel.element._savedScrollTop;
-        else
-            this.contentView.element.scrollTop = this._initialScrollOffset;
-
-        let hasFilter = typeof this._selectedPanel.filterDidChange === "function";
-        this.contentView.element.classList.toggle("has-filter-bar", hasFilter);
-        if (this._filterBar)
-            this.contentView.element.classList.toggle(WI.CSSStyleDetailsSidebarPanel.FilterInProgressClassName, hasFilter && this._filterBar.hasActiveFilters());
-
-        this.contentView.element.classList.toggle("supports-new-rule", typeof this._selectedPanel.newRuleButtonClicked === "function");
-        this._selectedPanel.shown();
-
-        this._lastSelectedPanelSetting.value = selectedPanel.navigationInfo.identifier;
-    }
-
-    _forcedPseudoClassCheckboxChanged(pseudoClass, event)
-    {
-        if (!this.domNode)
-            return;
-
-        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
-
-        effectiveDOMNode.setPseudoClassEnabled(pseudoClass, event.target.checked);
-    }
-
-    _updatePseudoClassCheckboxes()
-    {
-        if (!this.domNode)
-            return;
-
-        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
-
-        let enabledPseudoClasses = effectiveDOMNode.enabledPseudoClasses;
-
-        for (let pseudoClass in this._forcedPseudoClassCheckboxes) {
-            let checkboxElement = this._forcedPseudoClassCheckboxes[pseudoClass];
-            checkboxElement.checked = enabledPseudoClasses.includes(pseudoClass);
-        }
-    }
-
-    _handleNodeAttributeModified(event)
-    {
-        if (event && event.data && event.data.name === "class")
-            this._populateClassToggles();
-    }
-
-    _handleNodeAttributeRemoved(event)
-    {
-        if (event && event.data && event.data.name === "class")
-            this._populateClassToggles();
-    }
-
-
-    _newRuleButtonClicked()
-    {
-        if (this._selectedPanel && typeof this._selectedPanel.newRuleButtonClicked === "function")
-            this._selectedPanel.newRuleButtonClicked();
-    }
-
-    _newRuleButtonContextMenu(event)
-    {
-        if (this._selectedPanel && typeof this._selectedPanel.newRuleButtonContextMenu === "function")
-            this._selectedPanel.newRuleButtonContextMenu(event);
-    }
-
-    _classToggleButtonClicked(event)
-    {
-        this._classToggleButton.classList.toggle("selected");
-        this._classListContainer.hidden = !this._classListContainer.hidden;
-        this._classListContainerToggledSetting.value = !this._classListContainer.hidden;
-        if (this._classListContainer.hidden)
-            return;
-
-        this._populateClassToggles();
-    }
-
-    _addClassContainerClicked(event)
-    {
-        this._addClassContainer.classList.add("active");
-        this._addClassInput.focus();
-    }
-
-    _addClassInputKeyPressed(event)
-    {
-        if (event.keyCode !== WI.KeyboardShortcut.Key.Enter.keyCode)
-            return;
-
-        this._addClassInput.blur();
-    }
-
-    _addClassInputBlur(event)
-    {
-        this.domNode.toggleClass(this._addClassInput.value, true);
-        this._addClassContainer.classList.remove("active");
-        this._addClassInput.value = null;
-    }
-
-    _populateClassToggles()
-    {
-        // Ensure that _addClassContainer is the first child of _classListContainer.
-        while (this._classListContainer.children.length > 1)
-            this._classListContainer.children[1].remove();
-
-        let classes = this.domNode.getAttribute("class");
-        let classToggledMap = this.domNode[WI.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol];
-        if (!classToggledMap)
-            classToggledMap = this.domNode[WI.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol] = new Map;
-
-        if (classes && classes.length) {
-            for (let className of classes.split(/\s+/))
-                classToggledMap.set(className, true);
-        }
-
-        for (let [className, toggled] of classToggledMap) {
-            if ((toggled && !classes.includes(className)) || (!toggled && classes.includes(className))) {
-                toggled = !toggled;
-                classToggledMap.set(className, toggled);
-            }
-
-            this._createToggleForClassName(className);
-        }
-    }
-
-    _createToggleForClassName(className)
-    {
-        if (!className || !className.length)
-            return;
-
-        let classToggledMap = this.domNode[WI.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol];
-        if (!classToggledMap)
-            return;
-
-        if (!classToggledMap.has(className))
-            classToggledMap.set(className, true);
-
-        let toggled = classToggledMap.get(className);
-
-        let classNameContainer = document.createElement("div");
-        classNameContainer.classList.add("class-toggle");
-
-        let classNameToggle = classNameContainer.createChild("input");
-        classNameToggle.type = "checkbox";
-        classNameToggle.checked = toggled;
-
-        let classNameTitle = classNameContainer.createChild("span");
-        classNameTitle.textContent = className;
-        classNameTitle.draggable = true;
-        classNameTitle.addEventListener("dragstart", (event) => {
-            event.dataTransfer.setData(WI.CSSStyleDetailsSidebarPanel.ToggledClassesDragType, className);
-            event.dataTransfer.effectAllowed = "copy";
-        });
-
-        let classNameToggleChanged = (event) => {
-            this.domNode.toggleClass(className, classNameToggle.checked);
-            classToggledMap.set(className, classNameToggle.checked);
-        };
-
-        classNameToggle.addEventListener("click", classNameToggleChanged);
-        classNameTitle.addEventListener("click", (event) => {
-            classNameToggle.checked = !classNameToggle.checked;
-            classNameToggleChanged();
-        });
-
-        this._classListContainer.appendChild(classNameContainer);
-    }
-
-    _filterDidChange()
-    {
-        this.contentView.element.classList.toggle(WI.CSSStyleDetailsSidebarPanel.FilterInProgressClassName, this._filterBar.hasActiveFilters());
-
-        this._selectedPanel.filterDidChange(this._filterBar);
-    }
-
-    _styleSheetAddedOrRemoved()
-    {
-        this.needsLayout();
-    }
-};
-
-WI.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 30; // Default height of the forced pseudo classes container. Updated in sizeDidChange.
-WI.CSSStyleDetailsSidebarPanel.FilterInProgressClassName = "filter-in-progress";
-WI.CSSStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName = "filter-section-has-label";
-WI.CSSStyleDetailsSidebarPanel.FilterMatchSectionClassName = "filter-matching";
-WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName = "filter-section-non-matching";
-WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInPropertyClassName = "filter-property-non-matching";
-
-WI.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol = Symbol("css-style-details-sidebar-panel-toggled-classes-symbol");
-WI.CSSStyleDetailsSidebarPanel.ToggledClassesDragType = "text/classname";

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsSidebarPanel.js (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsSidebarPanel.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ComputedStyleDetailsSidebarPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.ComputedStyleDetailsSidebarPanel = class ComputedStyleDetailsSidebarPanel extends WI.GeneralStyleDetailsSidebarPanel
+{
+    constructor()
+    {
+        super("style-computed", "Computed", WI.ComputedStyleDetailsPanel);
+    }
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/DOMTreeOutline.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -362,7 +362,7 @@
 
     _ondragover(event)
     {
-        if (event.dataTransfer.types.includes(WI.CSSStyleDetailsSidebarPanel.ToggledClassesDragType)) {
+        if (event.dataTransfer.types.includes(WI.GeneralStyleDetailsSidebarPanel.ToggledClassesDragType)) {
             event.preventDefault();
             event.dataTransfer.dropEffect = "copy";
             return false;
@@ -444,7 +444,7 @@
 
             this._nodeBeingDragged.moveTo(parentNode, anchorNode, callback.bind(this));
         } else {
-            let className = event.dataTransfer.getData(WI.CSSStyleDetailsSidebarPanel.ToggledClassesDragType);
+            let className = event.dataTransfer.getData(WI.GeneralStyleDetailsSidebarPanel.ToggledClassesDragType);
             if (className && treeElement)
                 treeElement.representedObject.toggleClass(className, true);
         }

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/ElementsTabContentView.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -29,11 +29,14 @@
     {
         let {image, title} = WI.ElementsTabContentView.tabInfo();
         let tabBarItem = new WI.GeneralTabBarItem(image, title);
-        let detailsSidebarPanelConstructors = [WI.DOMNodeDetailsSidebarPanel, WI.CSSStyleDetailsSidebarPanel];
+        let detailsSidebarPanelConstructors = [WI.RulesStyleDetailsSidebarPanel, WI.ComputedStyleDetailsSidebarPanel, WI.DOMNodeDetailsSidebarPanel];
 
         if (window.LayerTreeAgent && !WI.settings.experimentalEnableLayersTab.value)
             detailsSidebarPanelConstructors.push(WI.LayerTreeDetailsSidebarPanel);
 
+        if (WI.settings.experimentalLegacyVisualSidebar.value)
+            detailsSidebarPanelConstructors.push(WI.VisualStyleDetailsSidebarPanel);
+
         super(identifier || "elements", "elements", tabBarItem, null, detailsSidebarPanelConstructors, true);
 
         WI.frameResourceManager.addEventListener(WI.FrameResourceManager.Event.MainFrameDidChange, this._mainFrameDidChange, this);

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.css (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.css	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.css	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2013 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.
+ */
+
+.sidebar > .panel.details.css-style > .content {
+    position: absolute;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    overflow-y: auto;
+    overflow-x: hidden;
+}
+
+.sidebar > .panel.details.css-style > .content.has-filter-bar {
+    bottom: calc(var(--navigation-bar-height) - 1px);
+}
+
+.sidebar > .panel.details.css-style > .content > .pseudo-classes {
+    padding: 6px 10px;
+    border-bottom: 1px solid var(--border-color);
+
+    display: flex;
+    flex-flow: row wrap;
+    justify-content: space-around;
+}
+
+.sidebar > .panel.details.css-style > .content > .pseudo-classes > .group {
+    display: inline-flex;
+    flex-flow: row wrap;
+    justify-content: space-around;
+    flex: 1;
+}
+
+.sidebar > .panel.details.css-style > .content > .pseudo-classes > .group > label {
+    color: hsl(0, 0%, 37%);
+
+    margin: 0 5px;
+    min-width: 55px;
+
+    display: inline-block;
+    white-space: nowrap;
+}
+
+.sidebar > .panel.details.css-style > .content ~ :matches(.options-container, .class-list-container) {
+    display: flex;
+    align-items: center;
+    position: absolute;
+    z-index: 1;
+    width: 100%;
+    border-top: 1px solid var(--border-color);
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container {
+    bottom: 0;
+    height: calc(var(--console-prompt-min-height) - 1px);
+    padding-top: 1px;
+}
+
+.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :matches(.options-container, .class-list-container) {
+    display: none;
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
+    width: 15px;
+    min-width: 15px;
+    height: 15px;
+    content: url(../Images/Plus15.svg);
+    opacity: 0.7;
+
+    --panel-details-css-style-content-options-container-new-rule-margin-start: 6px;
+}
+
+body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
+    margin-left: var(--panel-details-css-style-content-options-container-new-rule-margin-start);
+}
+
+body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
+    margin-right: var(--panel-details-css-style-content-options-container-new-rule-margin-start);
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container > .filter-bar {
+    width: -webkit-fill-available;
+    background-color: transparent;
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
+    margin: 0 0 1px;
+    padding: 2px 4px 3px;
+    background: none;
+    border: none;
+    border-radius: 3px;
+    white-space: nowrap;
+    -webkit-appearance: none;
+
+    --panel-details-css-style-content-options-container-toggle-class-toggle-margin-end: 5px;
+}
+
+body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
+    margin-right: var(--panel-details-css-style-content-options-container-toggle-class-toggle-margin-end);
+}
+
+body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
+    margin-left: var(--panel-details-css-style-content-options-container-toggle-class-toggle-margin-end);
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected {
+    color: var(--selected-foreground-color);
+    background-color: var(--selected-background-color);
+}
+
+.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover {
+    color: var(--selected-foreground-color);
+    background-color: var(--selected-background-color-hover);
+}
+
+.sidebar > .panel.details.css-style > .content:not(.supports-new-rule) ~ .options-container > .new-rule,
+.sidebar > .panel.details.css-style > .content:not(.has-filter-bar) ~ .options-container > .filter-bar {
+    display: none;
+}
+
+.sidebar > .panel.details.css-style > .content ~ .class-list-container {
+    flex-wrap: wrap;
+    bottom: calc(var(--console-prompt-min-height) - 1px);
+    max-height: 75px;
+    padding: 3px 2px;
+    background-color: var(--panel-background-color);
+    overflow-y: scroll;
+}
+
+/* FIXME: <https://webkit.org/b/152674> Elements with the "hidden" attribute still show up if "display: flex;" */
+.sidebar > .panel.details.css-style > .content ~ .class-list-container[hidden] {
+    display: none;
+}
+
+.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class {
+    display: flex;
+    width: 100%;
+}
+
+.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
+    flex-grow: 1;
+    height: 18px;
+    margin: 0;
+
+    --panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start: 2px;
+}
+
+body[dir=ltr] .sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
+    margin-left: var(--panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start);
+}
+
+body[dir=rtl] .sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
+    margin-right: var(--panel-details-css-style-content-class-list-container-new-class-class-name-input-margin-start);
+}
+
+.sidebar > .panel.details.css-style > .content ~ .class-list-container > *:matches(.new-class, .class-toggle) {
+    margin: 1px 3px;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-matching {
+    display: inline;
+    background-color: hsla(53, 83%, 53%, 0.5);
+    border-bottom: 1px solid hsl(47, 82%, 60%);
+    opacity: 1;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section {
+    margin-bottom: 0;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section.last-in-group.filter-section-non-matching + .style-declaration-section.filter-section-has-label {
+    margin-top: 0;
+    border-top: none;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section:not(.filter-section-has-label) {
+    margin-top: 0;
+    border-top: none;
+    border-bottom: 1px solid var(--border-color);
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .style-declaration-section > .header > .selector > .filter-matching {
+    color: black;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-section-non-matching {
+    display: none;
+}
+
+.sidebar > .panel.details.css-style > .content.filter-in-progress .filter-property-non-matching {
+    opacity: 0.5;
+}

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.js (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/GeneralStyleDetailsSidebarPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2013, 2015 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.GeneralStyleDetailsSidebarPanel = class GeneralStyleDetailsSidebarPanel extends WI.DOMDetailsSidebarPanel
+{
+    constructor(identifier, displayName, panelConstructor)
+    {
+        super(identifier, displayName);
+
+        this.element.classList.add("css-style");
+        this._panel = new panelConstructor(this);
+
+        this._classListContainerToggledSetting = new WI.Setting("class-list-container-toggled", false);
+        this._forcedPseudoClassCheckboxes = {};
+    }
+
+    // Public
+
+    get panel() { return this._panel; }
+
+    supportsDOMNode(nodeToInspect)
+    {
+        return nodeToInspect.nodeType() === Node.ELEMENT_NODE;
+    }
+
+    visibilityDidChange()
+    {
+        super.visibilityDidChange();
+
+        if (!this._panel)
+            return;
+
+        if (!this.visible) {
+            this._panel.hidden();
+            return;
+        }
+
+        this._updateNoForcedPseudoClassesScrollOffset();
+
+        this._panel.shown();
+        this._panel.markAsNeedsRefresh(this.domNode);
+    }
+
+    computedStyleDetailsPanelShowProperty(property)
+    {
+        this.parentSidebar.selectedSidebarPanel = "style-rules";
+
+        let styleRulesPanel = null;
+        for (let sidebarPanel of this.parentSidebar.sidebarPanels) {
+            if (!(sidebarPanel instanceof WI.RulesStyleDetailsSidebarPanel))
+                continue;
+
+            styleRulesPanel = sidebarPanel;
+            break;
+        }
+
+        console.assert(styleRulesPanel, "Styles panel is missing.");
+        styleRulesPanel.panel.scrollToSectionAndHighlightProperty(property);
+    }
+
+    // Protected
+
+    layout()
+    {
+        let domNode = this.domNode;
+        if (!domNode)
+            return;
+
+        this.contentView.element.scrollTop = this._initialScrollOffset;
+        this._panel.markAsNeedsRefresh(domNode);
+
+        this._updatePseudoClassCheckboxes();
+
+        if (!this._classListContainer.hidden)
+            this._populateClassToggles();
+    }
+
+    addEventListeners()
+    {
+        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
+        if (!effectiveDOMNode)
+            return;
+
+        effectiveDOMNode.addEventListener(WI.DOMNode.Event.EnabledPseudoClassesChanged, this._updatePseudoClassCheckboxes, this);
+        effectiveDOMNode.addEventListener(WI.DOMNode.Event.AttributeModified, this._handleNodeAttributeModified, this);
+        effectiveDOMNode.addEventListener(WI.DOMNode.Event.AttributeRemoved, this._handleNodeAttributeRemoved, this);
+    }
+
+    removeEventListeners()
+    {
+        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
+        if (!effectiveDOMNode)
+            return;
+
+        effectiveDOMNode.removeEventListener(null, null, this);
+    }
+
+    initialLayout()
+    {
+        if (WI.cssStyleManager.canForcePseudoClasses()) {
+            this._forcedPseudoClassContainer = document.createElement("div");
+            this._forcedPseudoClassContainer.className = "pseudo-classes";
+
+            let groupElement = null;
+
+            WI.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
+                // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
+                let label = pseudoClass.capitalize();
+
+                let labelElement = document.createElement("label");
+
+                let checkboxElement = document.createElement("input");
+                checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
+                checkboxElement.type = "checkbox";
+
+                this._forcedPseudoClassCheckboxes[pseudoClass] = checkboxElement;
+
+                labelElement.appendChild(checkboxElement);
+                labelElement.append(label);
+
+                if (!groupElement || groupElement.children.length === 2) {
+                    groupElement = document.createElement("div");
+                    groupElement.className = "group";
+                    this._forcedPseudoClassContainer.appendChild(groupElement);
+                }
+
+                groupElement.appendChild(labelElement);
+            }, this);
+
+            this.contentView.element.appendChild(this._forcedPseudoClassContainer);
+        }
+
+        this._panel.addEventListener(WI.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
+
+        this._showPanel(this._panel);
+
+        let optionsContainer = this.element.createChild("div", "options-container");
+
+        let newRuleButton = optionsContainer.createChild("img", "new-rule");
+        newRuleButton.title = WI.UIString("Add new rule");
+        newRuleButton.addEventListener("click", this._newRuleButtonClicked.bind(this));
+        newRuleButton.addEventListener("contextmenu", this._newRuleButtonContextMenu.bind(this));
+
+        this._filterBar = new WI.FilterBar;
+        this._filterBar.addEventListener(WI.FilterBar.Event.FilterDidChange, this._filterDidChange, this);
+        optionsContainer.appendChild(this._filterBar.element);
+
+        this._classToggleButton = optionsContainer.createChild("button", "toggle-class-toggle");
+        this._classToggleButton.textContent = WI.UIString("Classes");
+        this._classToggleButton.title = WI.UIString("Toggle Classes");
+        this._classToggleButton.addEventListener("click", this._classToggleButtonClicked.bind(this));
+
+        this._classListContainer = this.element.createChild("div", "class-list-container");
+        this._classListContainer.hidden = true;
+
+        this._addClassContainer = this._classListContainer.createChild("div", "new-class");
+        this._addClassContainer.title = WI.UIString("Add a Class");
+        this._addClassContainer.addEventListener("click", this._addClassContainerClicked.bind(this));
+
+        this._addClassInput = this._addClassContainer.createChild("input", "class-name-input");
+        this._addClassInput.setAttribute("placeholder", WI.UIString("Add New Class"));
+        this._addClassInput.addEventListener("keypress", this._addClassInputKeyPressed.bind(this));
+        this._addClassInput.addEventListener("blur", this._addClassInputBlur.bind(this));
+
+        WI.cssStyleManager.addEventListener(WI.CSSStyleManager.Event.StyleSheetAdded, this._styleSheetAddedOrRemoved, this);
+        WI.cssStyleManager.addEventListener(WI.CSSStyleManager.Event.StyleSheetRemoved, this._styleSheetAddedOrRemoved, this);
+
+        if (this._classListContainerToggledSetting.value)
+            this._classToggleButtonClicked();
+    }
+
+    sizeDidChange()
+    {
+        super.sizeDidChange();
+
+        this._updateNoForcedPseudoClassesScrollOffset();
+
+        if (this._panel)
+            this._panel.sizeDidChange();
+    }
+
+    // Private
+
+    get _initialScrollOffset()
+    {
+        if (!WI.cssStyleManager.canForcePseudoClasses())
+            return 0;
+        return this.domNode && this.domNode.enabledPseudoClasses.length ? 0 : WI.GeneralStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset;
+    }
+
+    _updateNoForcedPseudoClassesScrollOffset()
+    {
+        if (this._forcedPseudoClassContainer)
+            WI.GeneralStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = this._forcedPseudoClassContainer.offsetHeight;
+    }
+
+    _showPanel()
+    {
+        this.contentView.addSubview(this._panel);
+
+        let hasFilter = typeof this._panel.filterDidChange === "function";
+        this.contentView.element.classList.toggle("has-filter-bar", hasFilter);
+        if (this._filterBar)
+            this.contentView.element.classList.toggle(WI.GeneralStyleDetailsSidebarPanel.FilterInProgressClassName, hasFilter && this._filterBar.hasActiveFilters());
+
+        this.contentView.element.classList.toggle("supports-new-rule", typeof this._panel.newRuleButtonClicked === "function");
+        this._panel.shown();
+    }
+
+    _forcedPseudoClassCheckboxChanged(pseudoClass, event)
+    {
+        if (!this.domNode)
+            return;
+
+        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
+
+        effectiveDOMNode.setPseudoClassEnabled(pseudoClass, event.target.checked);
+    }
+
+    _updatePseudoClassCheckboxes()
+    {
+        if (!this.domNode)
+            return;
+
+        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
+
+        let enabledPseudoClasses = effectiveDOMNode.enabledPseudoClasses;
+
+        for (let pseudoClass in this._forcedPseudoClassCheckboxes) {
+            let checkboxElement = this._forcedPseudoClassCheckboxes[pseudoClass];
+            checkboxElement.checked = enabledPseudoClasses.includes(pseudoClass);
+        }
+    }
+
+    _handleNodeAttributeModified(event)
+    {
+        if (event && event.data && event.data.name === "class")
+            this._populateClassToggles();
+    }
+
+    _handleNodeAttributeRemoved(event)
+    {
+        if (event && event.data && event.data.name === "class")
+            this._populateClassToggles();
+    }
+
+    _newRuleButtonClicked()
+    {
+        if (this._panel && typeof this._panel.newRuleButtonClicked === "function")
+            this._panel.newRuleButtonClicked();
+    }
+
+    _newRuleButtonContextMenu(event)
+    {
+        if (this._panel && typeof this._panel.newRuleButtonContextMenu === "function")
+            this._panel.newRuleButtonContextMenu(event);
+    }
+
+    _classToggleButtonClicked(event)
+    {
+        this._classToggleButton.classList.toggle("selected");
+        this._classListContainer.hidden = !this._classListContainer.hidden;
+        this._classListContainerToggledSetting.value = !this._classListContainer.hidden;
+        if (this._classListContainer.hidden)
+            return;
+
+        this._populateClassToggles();
+    }
+
+    _addClassContainerClicked(event)
+    {
+        this._addClassContainer.classList.add("active");
+        this._addClassInput.focus();
+    }
+
+    _addClassInputKeyPressed(event)
+    {
+        if (event.keyCode !== WI.KeyboardShortcut.Key.Enter.keyCode)
+            return;
+
+        this._addClassInput.blur();
+    }
+
+    _addClassInputBlur(event)
+    {
+        this.domNode.toggleClass(this._addClassInput.value, true);
+        this._addClassContainer.classList.remove("active");
+        this._addClassInput.value = null;
+    }
+
+    _populateClassToggles()
+    {
+        // Ensure that _addClassContainer is the first child of _classListContainer.
+        while (this._classListContainer.children.length > 1)
+            this._classListContainer.children[1].remove();
+
+        let classes = this.domNode.getAttribute("class");
+        let classToggledMap = this.domNode[WI.GeneralStyleDetailsSidebarPanel.ToggledClassesSymbol];
+        if (!classToggledMap)
+            classToggledMap = this.domNode[WI.GeneralStyleDetailsSidebarPanel.ToggledClassesSymbol] = new Map;
+
+        if (classes && classes.length) {
+            for (let className of classes.split(/\s+/))
+                classToggledMap.set(className, true);
+        }
+
+        for (let [className, toggled] of classToggledMap) {
+            if ((toggled && !classes.includes(className)) || (!toggled && classes.includes(className))) {
+                toggled = !toggled;
+                classToggledMap.set(className, toggled);
+            }
+
+            this._createToggleForClassName(className);
+        }
+    }
+
+    _createToggleForClassName(className)
+    {
+        if (!className || !className.length)
+            return;
+
+        let classToggledMap = this.domNode[WI.GeneralStyleDetailsSidebarPanel.ToggledClassesSymbol];
+        if (!classToggledMap)
+            return;
+
+        if (!classToggledMap.has(className))
+            classToggledMap.set(className, true);
+
+        let toggled = classToggledMap.get(className);
+
+        let classNameContainer = document.createElement("div");
+        classNameContainer.classList.add("class-toggle");
+
+        let classNameToggle = classNameContainer.createChild("input");
+        classNameToggle.type = "checkbox";
+        classNameToggle.checked = toggled;
+
+        let classNameTitle = classNameContainer.createChild("span");
+        classNameTitle.textContent = className;
+        classNameTitle.draggable = true;
+        classNameTitle.addEventListener("dragstart", (event) => {
+            event.dataTransfer.setData(WI.GeneralStyleDetailsSidebarPanel.ToggledClassesDragType, className);
+            event.dataTransfer.effectAllowed = "copy";
+        });
+
+        let classNameToggleChanged = (event) => {
+            this.domNode.toggleClass(className, classNameToggle.checked);
+            classToggledMap.set(className, classNameToggle.checked);
+        };
+
+        classNameToggle.addEventListener("click", classNameToggleChanged);
+        classNameTitle.addEventListener("click", (event) => {
+            classNameToggle.checked = !classNameToggle.checked;
+            classNameToggleChanged();
+        });
+
+        this._classListContainer.appendChild(classNameContainer);
+    }
+
+    _filterDidChange()
+    {
+        this.contentView.element.classList.toggle(WI.GeneralStyleDetailsSidebarPanel.FilterInProgressClassName, this._filterBar.hasActiveFilters());
+
+        this._panel.filterDidChange(this._filterBar);
+    }
+
+    _styleSheetAddedOrRemoved()
+    {
+        this.needsLayout();
+    }
+};
+
+WI.GeneralStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset = 30; // Default height of the forced pseudo classes container. Updated in sizeDidChange.
+WI.GeneralStyleDetailsSidebarPanel.FilterInProgressClassName = "filter-in-progress";
+WI.GeneralStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName = "filter-section-has-label";
+WI.GeneralStyleDetailsSidebarPanel.FilterMatchSectionClassName = "filter-matching";
+WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName = "filter-section-non-matching";
+WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInPropertyClassName = "filter-property-non-matching";
+
+WI.GeneralStyleDetailsSidebarPanel.ToggledClassesSymbol = Symbol("css-style-details-sidebar-panel-toggled-classes-symbol");
+WI.GeneralStyleDetailsSidebarPanel.ToggledClassesDragType = "text/classname";

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css	2017-12-05 22:28:20 UTC (rev 225547)
@@ -39,7 +39,8 @@
     outline: none;
 }
 
-.navigation-bar .item {
+.navigation-bar .item,
+.sidebar-navigation-bar > .holder .item {
     display: flex;
     align-items: center;
     flex-wrap: wrap;
@@ -51,3 +52,18 @@
 .navigation-bar .item.force-hidden {
     display: none;
 }
+
+.sidebar-navigation-bar {
+    display: block;
+    text-align: center;
+    height: var(--navigation-bar-height);
+    border-bottom: 1px solid var(--border-color);
+}
+
+.sidebar-navigation-bar .holder {
+    display: inline-flex;
+    align-items: center;
+    height: var(--navigation-bar-height);
+    padding: 0 2px;
+    border-bottom: none;
+}

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -421,6 +421,10 @@
 
     _calculateMinimumWidth()
     {
+        let visibleNavigationItems = this._visibleNavigationItems;
+        if (!visibleNavigationItems.length)
+            return 0;
+
         const wasCollapsed = this.element.classList.contains(WI.NavigationBar.CollapsedStyleClassName);
 
         // Add the collapsed style class to calculate the width of the items when they are collapsed.
@@ -427,7 +431,7 @@
         if (!wasCollapsed)
             this.element.classList.add(WI.NavigationBar.CollapsedStyleClassName);
 
-        let totalItemWidth = this._visibleNavigationItems.reduce((total, item) => total + item.minimumWidth, 0);
+        let totalItemWidth = visibleNavigationItems.reduce((total, item) => total + item.minimumWidth, 0);
 
         // Remove the collapsed style class if we were not collapsed before.
         if (!wasCollapsed)

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -355,7 +355,7 @@
     {
         for (var labels of this._ruleMediaAndInherticanceList) {
             for (var i = 0; i < labels.length; ++i) {
-                labels[i].classList.toggle(WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName, filterBar.hasActiveFilters());
+                labels[i].classList.toggle(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName, filterBar.hasActiveFilters());
 
                 if (i === labels.length - 1)
                     labels[i].classList.toggle("filter-matching-label", filterBar.hasActiveFilters());
@@ -369,9 +369,9 @@
             if (section.findMatchingPropertiesAndSelectors(filterBar.filters.text) && filterBar.hasActiveFilters()) {
                 if (this._ruleMediaAndInherticanceList[i].length) {
                     for (var label of this._ruleMediaAndInherticanceList[i])
-                        label.classList.remove(WI.CSSStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);
+                        label.classList.remove(WI.GeneralStyleDetailsSidebarPanel.NoFilterMatchInSectionClassName);
                 } else
-                    section.element.classList.add(WI.CSSStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName);
+                    section.element.classList.add(WI.GeneralStyleDetailsSidebarPanel.FilterMatchingSectionHasLabelClassName);
 
                 matchFound = true;
             }

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsSidebarPanel.js (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsSidebarPanel.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsSidebarPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2017 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.RulesStyleDetailsSidebarPanel = class RulesStyleDetailsSidebarPanel extends WI.GeneralStyleDetailsSidebarPanel
+{
+    constructor()
+    {
+        let rulesStyleDetailsPanelConstructor;
+
+        if (WI.settings.experimentalLegacyStyleEditor.value)
+            rulesStyleDetailsPanelConstructor = WI.RulesStyleDetailsPanel;
+        else
+            rulesStyleDetailsPanelConstructor = WI.SpreadsheetRulesStyleDetailsPanel;
+
+        super("style-rules", "Styles", rulesStyleDetailsPanelConstructor);
+    }
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SearchTabContentView.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -30,7 +30,7 @@
         let {image, title} = WI.SearchTabContentView.tabInfo();
         let tabBarItem = new WI.GeneralTabBarItem(image, title);
         let detailsSidebarPanelConstructors = [WI.ResourceDetailsSidebarPanel, WI.ProbeDetailsSidebarPanel,
-            WI.DOMNodeDetailsSidebarPanel, WI.CSSStyleDetailsSidebarPanel];
+            WI.DOMNodeDetailsSidebarPanel, WI.ComputedStyleDetailsSidebarPanel, WI.RulesStyleDetailsSidebarPanel];
 
         if (window.LayerTreeAgent && !WI.settings.experimentalEnableLayersTab.value)
             detailsSidebarPanelConstructors.push(WI.LayerTreeDetailsSidebarPanel);

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -247,8 +247,9 @@
         let experimentalSettingsView = new WI.SettingsView("experimental", WI.UIString("Experimental"));
 
         if (window.CSSAgent) {
-            experimentalSettingsView.addSetting(WI.UIString("Styles Panel:"), WI.settings.experimentalLegacyStyleEditor, WI.UIString("Legacy Style Editor"));
-            experimentalSettingsView.addSeparator();
+            let stylesGroup = experimentalSettingsView.addGroup(WI.UIString("Styles Sidebar:"));
+            stylesGroup.addSetting(WI.settings.experimentalLegacyStyleEditor, WI.UIString("Legacy Style Editor"));
+            stylesGroup.addSetting(WI.settings.experimentalLegacyVisualSidebar, WI.UIString("Legacy Visual Styles Panel"));
         }
 
         if (window.LayerTreeAgent) {
@@ -271,6 +272,7 @@
         }
 
         listenForChange(WI.settings.experimentalLegacyStyleEditor);
+        listenForChange(WI.settings.experimentalLegacyVisualSidebar);
         listenForChange(WI.settings.experimentalEnableLayersTab);
 
         this.addSettingsView(experimentalSettingsView);

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/Sidebar.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -42,7 +42,7 @@
         if (hasNavigationBar) {
             this.element.classList.add("has-navigation-bar");
 
-            this._navigationBar = new WI.NavigationBar(null, null, "tablist");
+            this._navigationBar = new WI.SidebarNavigationBar(null, null, "tablist");
             this._navigationBar.addEventListener(WI.NavigationBar.Event.NavigationItemSelected, this._navigationItemSelected, this);
             this.addSubview(this._navigationBar);
         }

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/SidebarNavigationBar.js (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/SidebarNavigationBar.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/SidebarNavigationBar.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2017 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.SidebarNavigationBar = class SidebarNavigationBar extends WI.NavigationBar
+{
+    constructor(element, navigationItems, role, label)
+    {
+        super(element, navigationItems, role, label);
+
+        this.element.classList.add("sidebar-navigation-bar");
+        this._holderElement = this.element.appendChild(document.createElement("div"));
+        this._holderElement.className = "holder";
+    }
+
+    // Public
+
+    insertNavigationItem(navigationItem, index)
+    {
+        return super.insertNavigationItem(navigationItem, index, this._holderElement);
+    }
+
+    // Private
+
+    _calculateMinimumWidth()
+    {
+        return this._holderElement.offsetWidth;
+    }
+};

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js (225546 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js	2017-12-05 22:09:36 UTC (rev 225546)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/StyleDetailsPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -125,7 +125,7 @@
     {
         if (!WI.cssStyleManager.canForcePseudoClasses())
             return 0;
-        return this.nodeStyles.node.enabledPseudoClasses.length ? 0 : WI.CSSStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset;
+        return this.nodeStyles.node.enabledPseudoClasses.length ? 0 : WI.GeneralStyleDetailsSidebarPanel.NoForcedPseudoClassesScrollOffset;
     }
 
     _refreshNodeStyles()

Copied: trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsSidebarPanel.js (from rev 225546, trunk/Source/WebInspectorUI/UserInterface/Views/NavigationBar.css) (0 => 225547)


--- trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsSidebarPanel.js	                        (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsSidebarPanel.js	2017-12-05 22:28:20 UTC (rev 225547)
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2017 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.VisualStyleDetailsSidebarPanel = class VisualStyleDetailsSidebarPanel extends WI.GeneralStyleDetailsSidebarPanel
+{
+    constructor()
+    {
+        super("style-visual", "Visual", WI.VisualStyleDetailsPanel);
+    }
+};
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to