Web Inspector: Add VisualStyleDetailsPanel
authordrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Aug 2015 01:07:36 +0000 (01:07 +0000)
committerdrousso@apple.com <drousso@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 15 Aug 2015 01:07:36 +0000 (01:07 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147570

Reviewed by Timothy Hatcher.

Added VisualStyleDetailsPanel and inclusions to forthcoming classes
that will be used in this visual sidebar panel.

* Localizations/en.lproj/localizedStrings.js:
* UserInterface/Main.html:
Added files for all new classes used in the VisualStyleDetailsPanel.

* UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
(WebInspector.CSSStyleDetailsSidebarPanel):
* UserInterface/Views/DetailsSection.js:
(WebInspector.DetailsSection):
(WebInspector.DetailsSection.prototype.set collapsed):
(WebInspector.DetailsSection.prototype.get expandedByUser):
(WebInspector.DetailsSection.prototype._headerElementClicked):
Track whether or not the expanded state was caused by the user.

* UserInterface/Views/VisualStyleDetailsPanel.css: Added.
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > .visual-style-section-clear):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section:not(.modified) > .header > .visual-style-section-clear):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > span):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section.modified > .header > span::after):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row:last-child):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row.visual-style-separated-row):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container > .visual-style-property-title):
(.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container:not(.layout-reversed):last-child):
(.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section)):
(.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section) input):

* UserInterface/Views/VisualStyleDetailsPanel.js: Added.
(WebInspector.VisualStyleDetailsPanel):
(WebInspector.VisualStyleDetailsPanel.prototype.refresh):
(WebInspector.VisualStyleDetailsPanel.prototype._generateSection.replaceDashWithCapital):
(WebInspector.VisualStyleDetailsPanel.prototype._generateSection.createOptionsElement):
(WebInspector.VisualStyleDetailsPanel.prototype._generateSection):
(WebInspector.VisualStyleDetailsPanel.prototype._prepareForChange):
(WebInspector.VisualStyleDetailsPanel.prototype._updateSections):
(WebInspector.VisualStyleDetailsPanel.prototype._updateProperties):
(WebInspector.VisualStyleDetailsPanel.prototype._updateAutocompleteCompatiblePropertyEditor):
(WebInspector.VisualStyleDetailsPanel.prototype._sectionModified):
(WebInspector.VisualStyleDetailsPanel.prototype._clearModifiedSection):
(WebInspector.VisualStyleDetailsPanel.prototype.get _initialTextList):
(WebInspector.VisualStyleDetailsPanel.prototype._initialPropertyTextModified):
(WebInspector.VisualStyleDetailsPanel.prototype._populateSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateDisplaySection):
(WebInspector.VisualStyleDetailsPanel.prototype._generateMetricSectionRows):
(WebInspector.VisualStyleDetailsPanel.prototype._populatePositionSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateFloatSection):
(WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners.onEditorMouseover):
(WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners.onEditorMouseout):
(WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners):
(WebInspector.VisualStyleDetailsPanel.prototype._populateDimensionsSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateMarginSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populatePaddingSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateFlexboxSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTextStyleSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateFontSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTextSpacingSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTextShadowSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBackgroundStyleSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBorderSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateOutlineSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.noRemainingTreeItems):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.selectedBoxShadowItemValueChanged):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.boxShadowItemSelected):
(WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.noRemainingTreeItems):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.selectedtransitionItemValueChanged):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.transitionItemSelected):
(WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@188503 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js
Source/WebInspectorUI/UserInterface/Views/DetailsSection.js
Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.css [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js [new file with mode: 0644]

index 18133cb..c9e538b 100644 (file)
@@ -1,5 +1,85 @@
 2015-08-14  Devin Rousso  <drousso@apple.com>
 
+        Web Inspector: Add VisualStyleDetailsPanel
+        https://bugs.webkit.org/show_bug.cgi?id=147570
+
+        Reviewed by Timothy Hatcher.
+
+        Added VisualStyleDetailsPanel and inclusions to forthcoming classes
+        that will be used in this visual sidebar panel.
+
+        * Localizations/en.lproj/localizedStrings.js:
+        * UserInterface/Main.html:
+        Added files for all new classes used in the VisualStyleDetailsPanel.
+
+        * UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
+        (WebInspector.CSSStyleDetailsSidebarPanel):
+        * UserInterface/Views/DetailsSection.js:
+        (WebInspector.DetailsSection):
+        (WebInspector.DetailsSection.prototype.set collapsed):
+        (WebInspector.DetailsSection.prototype.get expandedByUser):
+        (WebInspector.DetailsSection.prototype._headerElementClicked):
+        Track whether or not the expanded state was caused by the user.
+
+        * UserInterface/Views/VisualStyleDetailsPanel.css: Added.
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > .visual-style-section-clear):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section:not(.modified) > .header > .visual-style-section-clear):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > span):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section.modified > .header > span::after):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row:last-child):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row.visual-style-separated-row):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container > .visual-style-property-title):
+        (.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container:not(.layout-reversed):last-child):
+        (.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section)):
+        (.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section) input):
+
+        * UserInterface/Views/VisualStyleDetailsPanel.js: Added.
+        (WebInspector.VisualStyleDetailsPanel):
+        (WebInspector.VisualStyleDetailsPanel.prototype.refresh):
+        (WebInspector.VisualStyleDetailsPanel.prototype._generateSection.replaceDashWithCapital):
+        (WebInspector.VisualStyleDetailsPanel.prototype._generateSection.createOptionsElement):
+        (WebInspector.VisualStyleDetailsPanel.prototype._generateSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._prepareForChange):
+        (WebInspector.VisualStyleDetailsPanel.prototype._updateSections):
+        (WebInspector.VisualStyleDetailsPanel.prototype._updateProperties):
+        (WebInspector.VisualStyleDetailsPanel.prototype._updateAutocompleteCompatiblePropertyEditor):
+        (WebInspector.VisualStyleDetailsPanel.prototype._sectionModified):
+        (WebInspector.VisualStyleDetailsPanel.prototype._clearModifiedSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype.get _initialTextList):
+        (WebInspector.VisualStyleDetailsPanel.prototype._initialPropertyTextModified):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateDisplaySection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._generateMetricSectionRows):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populatePositionSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateFloatSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners.onEditorMouseover):
+        (WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners.onEditorMouseout):
+        (WebInspector.VisualStyleDetailsPanel.prototype._addMetricsMouseListeners):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateDimensionsSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateMarginSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populatePaddingSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateFlexboxSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTextStyleSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateFontSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTextSpacingSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTextShadowSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBackgroundStyleSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBorderSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateOutlineSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.noRemainingTreeItems):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.selectedBoxShadowItemValueChanged):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection.boxShadowItemSelected):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateBoxShadowSection):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.noRemainingTreeItems):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.selectedtransitionItemValueChanged):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection.transitionItemSelected):
+        (WebInspector.VisualStyleDetailsPanel.prototype._populateTransitionSection):
+
+2015-08-14  Devin Rousso  <drousso@apple.com>
+
         Web Inspector: Highlight DOM node attribute changes in parallel, not sequentially
         https://bugs.webkit.org/show_bug.cgi?id=148019
 
index c5df37f..7a90a95 100644 (file)
Binary files a/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js and b/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js differ
index 9f34c66..0b0dc00 100644 (file)
     <link rel="stylesheet" href="Views/TypeTokenView.css">
     <link rel="stylesheet" href="Views/TypeTreeElement.css">
     <link rel="stylesheet" href="Views/TypeTreeView.css">
+    <link rel="stylesheet" href="Views/VisualStyleColorPicker.css">
+    <link rel="stylesheet" href="Views/VisualStyleCommaSeparatedKeywordEditor.css">
+    <link rel="stylesheet" href="Views/VisualStyleDetailsPanel.css">
+    <link rel="stylesheet" href="Views/VisualStyleKeywordCheckbox.css">
+    <link rel="stylesheet" href="Views/VisualStyleKeywordIconList.css">
+    <link rel="stylesheet" href="Views/VisualStyleNumberInputBox.css">
+    <link rel="stylesheet" href="Views/VisualStylePropertyEditor.css">
+    <link rel="stylesheet" href="Views/VisualStylePropertyEditorLink.css">
+    <link rel="stylesheet" href="Views/VisualStyleRelativeNumberSlider.css">
+    <link rel="stylesheet" href="Views/VisualStyleSelectorSection.css">
+    <link rel="stylesheet" href="Views/VisualStyleSelectorTreeItem.css">
+    <link rel="stylesheet" href="Views/VisualStyleTabbedPropertiesRow.css">
+    <link rel="stylesheet" href="Views/VisualStyleTimingEditor.css">
+    <link rel="stylesheet" href="Views/VisualStyleUnitSlider.css">
 
     <link rel="stylesheet" href="Controllers/CodeMirrorCompletionController.css">
     <link rel="stylesheet" href="Controllers/CodeMirrorDragToAdjustNumberController.css">
     <script src="Views/TypeTreeElement.js"></script>
     <script src="Views/TypeTreeView.js"></script>
 
+    <script src="Views/VisualStyleDetailsPanel.js"></script>
+    <script src="Views/VisualStylePropertyEditor.js"></script>
+    <script src="Views/VisualStyleColorPicker.js"></script>
+    <script src="Views/VisualStyleCommaSeparatedKeywordEditor.js"></script>
+    <script src="Views/VisualStyleFontFamilyListEditor.js"></script>
+    <script src="Views/VisualStyleFontFamilyTreeElement.js"></script>
+    <script src="Views/VisualStyleKeywordCheckbox.js"></script>
+    <script src="Views/VisualStyleKeywordIconList.js"></script>
+    <script src="Views/VisualStyleKeywordPicker.js"></script>
+    <script src="Views/VisualStyleNumberInputBox.js"></script>
+    <script src="Views/VisualStylePropertyCombiner.js"></script>
+    <script src="Views/VisualStylePropertyEditorLink.js"></script>
+    <script src="Views/VisualStylePropertyNameInput.js"></script>
+    <script src="Views/VisualStyleRelativeNumberSlider.js"></script>
+    <script src="Views/VisualStyleSelectorSection.js"></script>
+    <script src="Views/VisualStyleSelectorTreeItem.js"></script>
+    <script src="Views/VisualStyleTabbedPropertiesRow.js"></script>
+    <script src="Views/VisualStyleTimingEditor.js"></script>
+    <script src="Views/VisualStyleUnitSlider.js"></script>
+    <script src="Views/VisualStyleURLInput.js"></script>
+
     <script src="Controllers/Annotator.js"></script>
     <script src="Controllers/CodeMirrorEditingController.js"></script>
 
     <script src="Controllers/StorageManager.js"></script>
     <script src="Controllers/TimelineManager.js"></script>
     <script src="Controllers/TypeTokenAnnotator.js"></script>
+    <script src="Controllers/VisualStyleCompletionsController.js"></script>
 
     <script src="Base/Main.js"></script>
 
index 3d3f766..2b034b6 100644 (file)
@@ -68,12 +68,13 @@ WebInspector.CSSStyleDetailsSidebarPanel = class CSSStyleDetailsSidebarPanel ext
 
         this._computedStyleDetailsPanel = new WebInspector.ComputedStyleDetailsPanel(this);
         this._rulesStyleDetailsPanel = new WebInspector.RulesStyleDetailsPanel(this);
+        this._visualStyleDetailsPanel = new WebInspector.VisualStyleDetailsPanel(this);
 
         this._computedStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
         this._rulesStyleDetailsPanel.addEventListener(WebInspector.StyleDetailsPanel.Event.Refreshed, this._filterDidChange, this);
 
-        this._panels = [this._computedStyleDetailsPanel, this._rulesStyleDetailsPanel];
-        this._panelNavigationInfo = [this._computedStyleDetailsPanel.navigationInfo, this._rulesStyleDetailsPanel.navigationInfo];
+        this._panels = [this._computedStyleDetailsPanel, this._rulesStyleDetailsPanel, this._visualStyleDetailsPanel];
+        this._panelNavigationInfo = [this._computedStyleDetailsPanel.navigationInfo, this._rulesStyleDetailsPanel.navigationInfo, this._visualStyleDetailsPanel.navigationInfo];
 
         this._lastSelectedSectionSetting = new WebInspector.Setting("last-selected-style-details-panel", this._rulesStyleDetailsPanel.navigationInfo.identifier);
 
index 84b3a39..d8a24ee 100644 (file)
@@ -61,6 +61,7 @@ WebInspector.DetailsSection = class DetailsSection extends WebInspector.Object
 
         this._collapsedSetting = new WebInspector.Setting(identifier + "-details-section-collapsed", !!defaultCollapsedSettingValue);
         this.collapsed = this._collapsedSetting.value;
+        this._expandedByUser = false;
     }
 
     // Public
@@ -115,6 +116,11 @@ WebInspector.DetailsSection = class DetailsSection extends WebInspector.Object
             this._contentElement.appendChild(this._groups[i].element);
     }
 
+    get expandedByUser()
+    {
+        return this._expandedByUser;
+    }
+
     // Private
 
     _headerElementClicked(event)
@@ -122,7 +128,9 @@ WebInspector.DetailsSection = class DetailsSection extends WebInspector.Object
         if (event.target.isSelfOrDescendant(this._optionsElement))
             return;
 
-        this.collapsed = !this.collapsed;
+        var collapsed = this.collapsed;
+        this.collapsed = !collapsed;
+        this._expandedByUser = collapsed;
 
         this._element.scrollIntoViewIfNeeded(false);
     }
diff --git a/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.css b/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.css
new file mode 100644 (file)
index 0000000..5441afc
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 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.
+ */
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header {
+    font-weight: normal;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > .visual-style-section-clear {
+    position: absolute;
+    right: 5px;
+    width: 15px;
+    height: 15px;
+    background-image: -webkit-canvas(navigation-item-clear-log-normal);
+    background-size: 15px 15px;
+    opacity: 0.7;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section.collapsed > .header > .visual-style-section-clear,
+.sidebar > .panel.details.css-style .visual > .details-section .details-section:not(.modified) > .header > .visual-style-section-clear {
+    display: none;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .header > span {
+    display: flex;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section.modified > .header > span::after {
+    width: 7px;
+    height: 7px;
+    margin: 4px 6px;
+    border-radius: 50%;
+    background-color: hsl(212, 92%, 54%);
+    opacity: 0.5;
+    content: "";
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content {
+    margin-top: 5px;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row {
+    display: flex;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row:last-child {
+    padding-bottom: 3px;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row.visual-style-separated-row {
+    border-bottom: 0.5px solid hsl(0, 0%, 83%);
+    margin-bottom: 5px;
+    padding-bottom: 2px;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container > .visual-style-property-title {
+    width: 55px;
+}
+
+.sidebar > .panel.details.css-style .visual > .details-section .details-section > .content .group > .row > .visual-style-property-container:not(.layout-reversed):last-child {
+    margin-right: 11px;
+}
+
+.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section) {
+    opacity: 0.5;
+    pointer-events: none;
+}
+
+.sidebar > .panel.details.css-style .visual.disabled > .details-section:not(.visual-style-selector-section) input {
+    pointer-events: none;
+}
diff --git a/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js b/Source/WebInspectorUI/UserInterface/Views/VisualStyleDetailsPanel.js
new file mode 100644 (file)
index 0000000..f806125
--- /dev/null
@@ -0,0 +1,1045 @@
+/*
+ * Copyright (C) 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.
+ */
+
+WebInspector.VisualStyleDetailsPanel = class VisualStyleDetailsPanel extends WebInspector.StyleDetailsPanel
+{
+    constructor(delegate)
+    {
+        super(delegate, "visual", "visual", WebInspector.UIString("Styles \u2014 Visual"));
+
+        WebInspector.propertyReferenceInfoTemp = {};
+        this._currentStyle = null;
+        this._forceNextStyleUpdate = false;
+
+        this._sections = {};
+        this._groups = {};
+        this._keywords = {};
+        this._units = {};
+        this._autocompletionPropertyEditors = {};
+
+        // These keywords, as well as the values below, are not localized as they must match the CSS spec.
+        this._keywords.defaults = ["Inherit", "Initial"];
+        this._keywords.boxModel = this._keywords.defaults.concat(["Auto"]);
+        this._keywords.borderStyle = {
+            basic: this._keywords.defaults.concat(["None", "Hidden", "Solid"]),
+            advanced: ["Dashed", "Dotted", "Double", "Groove", "Hidden", "Inset", "None", "Outset", "Ridge"]
+        };
+        this._keywords.borderWidth = this._keywords.defaults.concat(["Medium", "Thick", "Thin"]);
+
+        this._units.defaultsSansPercent = {
+            basic: ["px", "em"],
+            advanced: ["ch", "cm", "ex", "in", "mm", "pc", "pt", "rem", "vh", "vw", "vmax", "vmin"]
+        };
+        this._units.defaults = {
+            basic: ["%"].concat(this._units.defaultsSansPercent.basic),
+            advanced: this._units.defaultsSansPercent.advanced
+        };
+
+        // Selector Section
+        this._selectorSection = new WebInspector.VisualStyleSelectorSection(this);
+        this._selectorSection.addEventListener(WebInspector.VisualStyleSelectorSection.Event.SelectorChanged, this._updateSections, this);
+        this._selectorSection.addEventListener(WebInspector.VisualStyleSelectorSection.Event.StyleTextChanged, this._prepareForChange, this);
+        this._element.appendChild(this._selectorSection.element);
+
+        // Layout Section
+        this._generateSection("display", WebInspector.UIString("Display"));
+        this._generateSection("position", WebInspector.UIString("Position"));
+        this._generateSection("float", WebInspector.UIString("Float and Clear"));
+        this._generateSection("dimensions", WebInspector.UIString("Dimensions"));
+        this._generateSection("margin", WebInspector.UIString("Margin"));
+        this._generateSection("padding", WebInspector.UIString("Padding"));
+        this._generateSection("flexbox", WebInspector.UIString("Flexbox"));
+
+        this._sections.layout = new WebInspector.DetailsSection("layout", WebInspector.UIString("Layout"), [this._groups.display.section, this._groups.position.section, this._groups.float.section, this._groups.dimensions.section, this._groups.margin.section, this._groups.padding.section, this._groups.flexbox.section]);
+        this._element.appendChild(this._sections.layout.element);
+
+        // Text Section
+        this._generateSection("text-style", WebInspector.UIString("Style"));
+        this._generateSection("font", WebInspector.UIString("Font"));
+        this._generateSection("text-spacing", WebInspector.UIString("Spacing"));
+        this._generateSection("text-shadow", WebInspector.UIString("Shadow"));
+
+        this._sections.text = new WebInspector.DetailsSection("text", WebInspector.UIString("Text"), [this._groups.textStyle.section, this._groups.font.section, this._groups.textSpacing.section, this._groups.textShadow.section]);
+        this._element.appendChild(this._sections.text.element);
+
+        // Background Section
+        this._generateSection("background-style", WebInspector.UIString("Style"));
+        this._generateSection("border", WebInspector.UIString("Border"));
+        this._generateSection("outline", WebInspector.UIString("Outline"));
+        this._generateSection("box-shadow", WebInspector.UIString("Shadow"));
+
+        this._sections.background = new WebInspector.DetailsSection("background", WebInspector.UIString("Background"), [this._groups.backgroundStyle.section, this._groups.border.section, this._groups.outline.section, this._groups.boxShadow.section]);
+        this._element.appendChild(this._sections.background.element);
+
+        // Animation Section
+        this._generateSection("transition", WebInspector.UIString("Transition"));
+
+        this._sections.animation = new WebInspector.DetailsSection("animation", WebInspector.UIString("Animation"), [this._groups.transition.section]);
+        this._element.appendChild(this._sections.animation.element);
+    }
+
+    // Public
+
+    refresh(significantChange)
+    {
+        if (significantChange || this._forceNextStyleUpdate) {
+            this._selectorSection.update(this._nodeStyles);
+            this._updateSections();
+            this._forceNextStyleUpdate = false;
+        }
+
+        super.refresh();
+    }
+
+    // Private
+
+    _generateSection(id, displayName)
+    {
+        if (!id || !displayName)
+            return;
+
+        function replaceDashWithCapital(match) {
+            return match.replace("-", "").toUpperCase();
+        }
+
+        let camelCaseId = id.replace(/-\b\w/g, replaceDashWithCapital);
+
+        function createOptionsElement() {
+            let container = document.createElement("div");
+            container.classList.add("visual-style-section-clear");
+            container.title = WebInspector.UIString("Click to clear modified properties");
+            container.addEventListener("click", this._clearModifiedSection.bind(this, camelCaseId));
+            return container;
+        }
+
+        this._groups[camelCaseId] = {
+            section: new WebInspector.DetailsSection(id, displayName, [], createOptionsElement.call(this)),
+            properties: {}
+        };
+
+        let populateFunction = this["_populate" + camelCaseId.capitalize() + "Section"];
+        populateFunction.call(this);
+    }
+
+    _prepareForChange(event)
+    {
+        this._forceNextStyleUpdate = true;
+    }
+
+    _updateSections(event)
+    {
+        this._currentStyle = this._selectorSection.currentStyle();
+        if (!this._currentStyle)
+            return;
+
+        let disabled = this._currentStyle[WebInspector.VisualStyleDetailsPanel.StyleDisabledSymbol];
+        this._element.classList.toggle("disabled", disabled);
+        if (disabled)
+            return;
+
+        for (let key in this._groups)
+            this._updateProperties(this._groups[key], !!event);
+
+        for (let key in this._sections) {
+            let section = this._sections[key];
+            let oneSectionExpanded = false;
+            for (let group of section.groups) {
+                if (!group.collapsed) {
+                    oneSectionExpanded = true;
+                    break;
+                }
+            }
+
+            section.collapsed = !oneSectionExpanded;
+        }
+    }
+
+    _updateProperties(group, forceStyleUpdate)
+    {
+        if (!group.section)
+            return;
+
+        let initialTextList = this._initialTextList;
+        if (!initialTextList)
+            this._currentStyle[WebInspector.VisualStyleDetailsPanel.InitialPropertySectionTextListSymbol] = initialTextList = new WeakMap;
+
+        let initialPropertyText = {};
+        let initialPropertyTextMissing = !initialTextList.has(group);
+        let onePropertyHasValue = false;
+        for (let key in group.properties) {
+            let propertyEditor = group.properties[key];
+            propertyEditor.update(!propertyEditor.style || forceStyleUpdate ? this._currentStyle : null);
+
+            let value = propertyEditor.synthesizedValue;
+            if (value && !propertyEditor.propertyMissing) {
+                onePropertyHasValue = true;
+                if (initialPropertyTextMissing)
+                    initialPropertyText[key] = value;
+            }
+        }
+
+        if (initialPropertyTextMissing)
+            initialTextList.set(group, initialPropertyText);
+
+        group.section.collapsed = !onePropertyHasValue && !group.section.expandedByUser;
+        this._sectionModified(group);
+
+        let autocompleteCompatibleProperties = group.autocompleteCompatibleProperties;
+        if (!autocompleteCompatibleProperties || !autocompleteCompatibleProperties.length)
+            return;
+
+        for (let editor of autocompleteCompatibleProperties)
+            this._updateAutocompleteCompatiblePropertyEditor(editor, forceStyleUpdate);
+    }
+
+    _updateAutocompleteCompatiblePropertyEditor(editor, force)
+    {
+        if (!editor || (editor.hasCompletions && !force))
+            return;
+
+        editor.completions = WebInspector.CSSKeywordCompletions.forProperty(editor.propertyReferenceName);
+    }
+
+    _sectionModified(group)
+    {
+        group.section.element.classList.toggle("modified", this._initialPropertyTextModified(group));
+    }
+
+    _clearModifiedSection(groupId)
+    {
+        let group = this._groups[groupId];
+        group.section.element.classList.remove("modified");
+        let initialPropertyTextList = this._currentStyle[WebInspector.VisualStyleDetailsPanel.InitialPropertySectionTextListSymbol].get(group);
+        if (!initialPropertyTextList)
+            return;
+
+        let newStyleText = this._currentStyle.text;
+        for (let key in group.properties) {
+            let propertyEditor = group.properties[key];
+            let initialValue = initialPropertyTextList[key] || null;
+            newStyleText = propertyEditor.modifyPropertyText(newStyleText, initialValue);
+            propertyEditor.resetEditorValues(initialValue);
+        }
+
+        this._currentStyle.text = newStyleText;
+    }
+
+    get _initialTextList()
+    {
+        return this._currentStyle[WebInspector.VisualStyleDetailsPanel.InitialPropertySectionTextListSymbol];
+    }
+
+    _initialPropertyTextModified(group)
+    {
+        if (!group.properties)
+            return false;
+
+        let initialPropertyTextList = this._initialTextList.get(group);
+        if (!initialPropertyTextList)
+            return false;
+
+        for (let key in group.properties) {
+            let propertyEditor = group.properties[key];
+            if (propertyEditor.propertyMissing)
+                continue;
+
+            let value = propertyEditor.synthesizedValue;
+            if (value && initialPropertyTextList[key] !== value)
+                return true;
+        }
+
+        return false;
+    }
+
+    _populateSection(group, groups)
+    {
+        if (!group || !groups)
+            return;
+
+        group.section.groups = groups;
+        for (let key in group.properties)
+            group.properties[key].addEventListener(WebInspector.VisualStylePropertyEditor.Event.ValueDidChange, this._sectionModified.bind(this, group));
+    }
+
+    _populateDisplaySection()
+    {
+        let group = this._groups.display;
+        let properties = group.properties;
+
+        let displayRow = new WebInspector.DetailsSectionRow;
+
+        properties.display = new WebInspector.VisualStyleKeywordPicker("display", WebInspector.UIString("Type"), {
+            basic: ["None", "Block", "Flex", "Inline", "Inline Block"],
+            advanced: ["Compact", "Inline Flex", "Inline Table", "List Item", "Table", "Table Caption", "Table Cell", "Table Column", "Table Column Group", "Table Footer Group", "Table Header Group", "Table Row", "Table Row Group", " WAP Marquee", " WebKit Box", " WebKit Grid", " WebKit Inline Box", " WebKit Inline Grid"]
+        });
+        properties.visibility = new WebInspector.VisualStyleKeywordPicker("visibility", WebInspector.UIString("Visibility"), {
+            basic: ["Hidden", "Visible"],
+            advanced: ["Collapse"]
+        });
+
+        displayRow.element.appendChild(properties.display.element);
+        displayRow.element.appendChild(properties.visibility.element);
+
+        let sizingRow = new WebInspector.DetailsSectionRow;
+
+        properties.boxSizing = new WebInspector.VisualStyleKeywordPicker("box-sizing", WebInspector.UIString("Sizing"), this._keywords.defaults.concat(["Border Box", "Content Box"]));
+        properties.cursor = new WebInspector.VisualStyleKeywordPicker("cursor", WebInspector.UIString("Cursor"), {
+            basic: ["Auto", "Default", "None", "Pointer", "Crosshair", "Text"],
+            advanced: ["Context Menu", "Help", "Progress", "Wait", "Cell", "Vertical Text", "Alias", "Copy", "Move", "No Drop", "Not Allowed", "All Scroll", "Col Resize", "Row Resize", "N Resize", "E Resize", "S Resize", "W Resize", "NS Resize", "EW Resize", "NE Resize", "NW Resize", "SE Resize", "sW Resize", "NESW Resize", "NWSE Resize"]
+        });
+
+        sizingRow.element.appendChild(properties.boxSizing.element);
+        sizingRow.element.appendChild(properties.cursor.element);
+
+        let overflowRow = new WebInspector.DetailsSectionRow;
+
+        properties.opacity = new WebInspector.VisualStyleUnitSlider("opacity", WebInspector.UIString("Opacity"));
+        properties.overflow = new WebInspector.VisualStyleKeywordPicker(["overflow-x", "overflow-y"], WebInspector.UIString("Overflow"), {
+            basic: ["Initial", "Auto", "Hidden", "Scroll", "Visible"],
+            advanced: ["Marquee", "Overlay", " WebKit Paged X", " WebKit Paged Y"]
+        });
+
+        overflowRow.element.appendChild(properties.opacity.element);
+        overflowRow.element.appendChild(properties.overflow.element);
+
+        let displayGroup = new WebInspector.DetailsSectionGroup([displayRow, sizingRow, overflowRow]);
+        this._populateSection(group, [displayGroup]);
+    }
+
+    _generateMetricSectionRows(group, prefix, allowNegatives)
+    {
+        let properties = group.properties;
+
+        let hasPrefix = prefix && prefix.length;
+        let propertyNamePrefix = hasPrefix ? prefix + "-" : "";
+
+        let top = hasPrefix ? prefix + "Top" : "top";
+        let bottom = hasPrefix ? prefix + "Bottom" : "bottom";
+        let left = hasPrefix ? prefix + "Left" : "left";
+        let right = hasPrefix ? prefix + "Right" : "right";
+
+        let vertical = new WebInspector.DetailsSectionRow;
+
+        properties[top] = new WebInspector.VisualStyleNumberInputBox(propertyNamePrefix + "top", WebInspector.UIString("Top"), this._keywords.boxModel, this._units.defaults, allowNegatives);
+        properties[bottom] = new WebInspector.VisualStyleNumberInputBox(propertyNamePrefix + "bottom", WebInspector.UIString("Bottom"), this._keywords.boxModel, this._units.defaults, allowNegatives, true);
+        let verticalLink = new WebInspector.VisualStylePropertyEditorLink([properties[top], properties[bottom]], "link-vertical");
+
+        vertical.element.appendChild(properties[top].element);
+        vertical.element.appendChild(verticalLink.element);
+        vertical.element.appendChild(properties[bottom].element);
+
+        let horizontal = new WebInspector.DetailsSectionRow;
+
+        properties[left] = new WebInspector.VisualStyleNumberInputBox(propertyNamePrefix + "left", WebInspector.UIString("Left"), this._keywords.boxModel, this._units.defaults, allowNegatives);
+        properties[right] = new WebInspector.VisualStyleNumberInputBox(propertyNamePrefix + "right", WebInspector.UIString("Right"), this._keywords.boxModel, this._units.defaults, allowNegatives, true);
+        let horizontalLink = new WebInspector.VisualStylePropertyEditorLink([properties[left], properties[right]], "link-horizontal");
+
+        horizontal.element.appendChild(properties[left].element);
+        horizontal.element.appendChild(horizontalLink.element);
+        horizontal.element.appendChild(properties[right].element);
+
+        let allLinkRow = new WebInspector.DetailsSectionRow;
+        let allLink = new WebInspector.VisualStylePropertyEditorLink([properties[top], properties[bottom], properties[left], properties[right]], "link-all", [verticalLink, horizontalLink]);
+        allLinkRow.element.appendChild(allLink.element);
+
+        return [vertical, allLinkRow, horizontal];
+    }
+
+    _populatePositionSection()
+    {
+        let group = this._groups.position;
+        let rows = this._generateMetricSectionRows(group, null, true);
+        let properties = group.properties;
+
+        let positionType = new WebInspector.DetailsSectionRow;
+
+        properties.position = new WebInspector.VisualStyleKeywordPicker("position", WebInspector.UIString("Type"), {
+            basic: ["Static", "Relative", "Absolute", "Fixed"],
+            advanced: [" WebKit Sticky"]
+        });
+        properties.zIndex = new WebInspector.VisualStyleNumberInputBox("z-index", WebInspector.UIString("Z-Index"), this._keywords.boxModel, null, true);
+
+        positionType.element.appendChild(properties.position.element);
+        positionType.element.appendChild(properties.zIndex.element);
+        positionType.element.classList.add("visual-style-separated-row");
+
+        rows.unshift(positionType)
+
+        let positionGroup = new WebInspector.DetailsSectionGroup(rows);
+        this._populateSection(group, [positionGroup]);
+    }
+
+    _populateFloatSection()
+    {
+        let group = this._groups.float;
+        let properties = group.properties;
+
+        let floatRow = new WebInspector.DetailsSectionRow;
+
+        properties.float = new WebInspector.VisualStyleKeywordIconList("float", WebInspector.UIString("Float"), ["Left", "Right", "None"]);
+        floatRow.element.appendChild(properties.float.element);
+
+        let clearRow = new WebInspector.DetailsSectionRow;
+
+        properties.clear = new WebInspector.VisualStyleKeywordIconList("clear", WebInspector.UIString("Clear"), ["Left", "Right", "Both", "None"]);
+        clearRow.element.appendChild(properties.clear.element);
+
+        let floatGroup = new WebInspector.DetailsSectionGroup([floatRow, clearRow]);
+        this._populateSection(group, [floatGroup]);
+    }
+
+    _addMetricsMouseListeners(editor, mode)
+    {
+        function onEditorMouseover() {
+            if (!this._style)
+                return;
+
+            if (!this._style.ownerRule) {
+                WebInspector.domTreeManager.highlightDOMNode(this._style.node.id, mode);
+                return;
+            }
+
+            WebInspector.domTreeManager.highlightSelector(this._style.ownerRule.selectorText, this._style.node.ownerDocument.frameIdentifier, mode);
+        }
+
+        function onEditorMouseout() {
+            WebInspector.domTreeManager.hideDOMNodeHighlight();
+        }
+
+        editor.element.addEventListener("mouseover", onEditorMouseover.bind(editor));
+        editor.element.addEventListener("mouseout", onEditorMouseout.bind(editor));
+    }
+
+    _populateDimensionsSection()
+    {
+        let group = this._groups.dimensions;
+        let properties = group.properties;
+
+        let dimensionsWidth = new WebInspector.DetailsSectionRow;
+
+        properties.width = new WebInspector.VisualStyleRelativeNumberSlider("width", WebInspector.UIString("Width"), this._keywords.boxModel, this._units.defaults);
+
+        dimensionsWidth.element.appendChild(properties.width.element);
+
+        let dimensionsHeight = new WebInspector.DetailsSectionRow;
+
+        properties.height = new WebInspector.VisualStyleRelativeNumberSlider("height", WebInspector.UIString("Height"), this._keywords.boxModel, this._units.defaults, true);
+
+        dimensionsHeight.element.appendChild(properties.height.element);
+
+        let dimensionsProperties = [properties.width, properties.height];
+        let dimensionsRegularGroup = new WebInspector.DetailsSectionGroup([dimensionsWidth, dimensionsHeight]);
+
+        let dimensionsMinWidth = new WebInspector.DetailsSectionRow;
+
+        properties.minWidth = new WebInspector.VisualStyleRelativeNumberSlider("min-width", WebInspector.UIString("Width"), this._keywords.boxModel, this._units.defaults);
+
+        dimensionsMinWidth.element.appendChild(properties.minWidth.element);
+
+        let dimensionsMinHeight = new WebInspector.DetailsSectionRow;
+
+        properties.minHeight = new WebInspector.VisualStyleRelativeNumberSlider("min-height", WebInspector.UIString("Height"), this._keywords.boxModel, this._units.defaults);
+
+        dimensionsMinHeight.element.appendChild(properties.minHeight.element);
+
+        let dimensionsMinProperties = [properties.minWidth, properties.minHeight];
+        let dimensionsMinGroup = new WebInspector.DetailsSectionGroup([dimensionsMinWidth, dimensionsMinHeight]);
+
+        let dimensionsMaxKeywords = this._keywords.defaults.concat("None");
+        let dimensionsMaxWidth = new WebInspector.DetailsSectionRow;
+
+        properties.maxWidth = new WebInspector.VisualStyleRelativeNumberSlider("max-width", WebInspector.UIString("Width"), dimensionsMaxKeywords, this._units.defaults);
+
+        dimensionsMaxWidth.element.appendChild(properties.maxWidth.element);
+
+        let dimensionsMaxHeight = new WebInspector.DetailsSectionRow;
+
+        properties.maxHeight = new WebInspector.VisualStyleRelativeNumberSlider("max-height", WebInspector.UIString("Height"), dimensionsMaxKeywords, this._units.defaults);
+
+        dimensionsMaxHeight.element.appendChild(properties.maxHeight.element);
+
+        let dimensionsMaxProperties = [properties.maxWidth, properties.maxHeight];
+        let dimensionsMaxGroup = new WebInspector.DetailsSectionGroup([dimensionsMaxWidth, dimensionsMaxHeight]);
+
+        let dimensionsTabController = new WebInspector.VisualStyleTabbedPropertiesRow({
+            "default": {title: WebInspector.UIString("Default"), element: dimensionsRegularGroup.element, properties: dimensionsProperties},
+            "min": {title: WebInspector.UIString("Min"), element: dimensionsMinGroup.element, properties: dimensionsMinProperties},
+            "max": {title: WebInspector.UIString("Max"), element: dimensionsMaxGroup.element, properties: dimensionsMaxProperties}
+        });
+
+        let highlightMode = "content";
+        this._addMetricsMouseListeners(group.properties.width, highlightMode);
+        this._addMetricsMouseListeners(group.properties.height, highlightMode);
+        this._addMetricsMouseListeners(group.properties.minWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.minHeight, highlightMode);
+        this._addMetricsMouseListeners(group.properties.maxWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.maxHeight, highlightMode);
+
+        let dimensionsGroup = new WebInspector.DetailsSectionGroup([dimensionsTabController, dimensionsRegularGroup, dimensionsMinGroup, dimensionsMaxGroup]);
+        this._populateSection(group, [dimensionsGroup]);
+    }
+
+    _populateMarginSection()
+    {
+        let group = this._groups.margin;
+        let rows = this._generateMetricSectionRows(group, "margin", true);
+
+        let highlightMode = "margin";
+        this._addMetricsMouseListeners(group.properties.marginTop, highlightMode);
+        this._addMetricsMouseListeners(group.properties.marginBottom, highlightMode);
+        this._addMetricsMouseListeners(group.properties.marginLeft, highlightMode);
+        this._addMetricsMouseListeners(group.properties.marginRight, highlightMode);
+
+        let marginGroup = new WebInspector.DetailsSectionGroup(rows);
+        this._populateSection(group, [marginGroup]);
+    }
+
+    _populatePaddingSection()
+    {
+        let group = this._groups.padding;
+        let rows = this._generateMetricSectionRows(group, "padding");
+
+        let highlightMode = "padding";
+        this._addMetricsMouseListeners(group.properties.paddingTop, highlightMode);
+        this._addMetricsMouseListeners(group.properties.paddingBottom, highlightMode);
+        this._addMetricsMouseListeners(group.properties.paddingLeft, highlightMode);
+        this._addMetricsMouseListeners(group.properties.paddingRight, highlightMode);
+
+        let paddingGroup = new WebInspector.DetailsSectionGroup(rows);
+        this._populateSection(group, [paddingGroup]);
+    }
+
+    _populateFlexboxSection()
+    {
+        let group = this._groups.flexbox;
+        let properties = group.properties;
+
+        let flexOrderRow = new WebInspector.DetailsSectionRow;
+
+        properties.order = new WebInspector.VisualStyleNumberInputBox("order", WebInspector.UIString("Order"), this._keywords.defaults);
+        properties.flexBasis = new WebInspector.VisualStyleNumberInputBox("flex-basis", WebInspector.UIString("Basis"), this._keywords.boxModel, this._units.defaults, true);
+
+        flexOrderRow.element.appendChild(properties.order.element);
+        flexOrderRow.element.appendChild(properties.flexBasis.element);
+
+        let flexSizeRow = new WebInspector.DetailsSectionRow;
+
+        properties.flexGrow = new WebInspector.VisualStyleNumberInputBox("flex-grow", WebInspector.UIString("Grow"), this._keywords.defaults, null);
+        properties.flexShrink = new WebInspector.VisualStyleNumberInputBox("flex-shrink", WebInspector.UIString("Shrink"), this._keywords.defaults, null);
+
+        flexSizeRow.element.appendChild(properties.flexGrow.element);
+        flexSizeRow.element.appendChild(properties.flexShrink.element);
+
+        let flexFlowRow = new WebInspector.DetailsSectionRow;
+
+        properties.flexDirection = new WebInspector.VisualStyleKeywordPicker("flex-direction", WebInspector.UIString("Direction"), this._keywords.defaults.concat(["Row", "Row Reverse", "Column", "Column Reverse"]));
+        properties.flexWrap = new WebInspector.VisualStyleKeywordPicker("flex-wrap", WebInspector.UIString("Wrap"), this._keywords.defaults.concat(["Wrap", "Wrap Reverse", "Nowrap"]));
+
+        flexFlowRow.element.appendChild(properties.flexDirection.element);
+        flexFlowRow.element.appendChild(properties.flexWrap.element);
+
+        let flexboxGroup = new WebInspector.DetailsSectionGroup([flexOrderRow, flexSizeRow, flexFlowRow]);
+        this._populateSection(group, [flexboxGroup]);
+    }
+
+    _populateTextStyleSection()
+    {
+        let group = this._groups.textStyle;
+        let properties = group.properties;
+
+        let textAppearanceRow = new WebInspector.DetailsSectionRow;
+
+        properties.color = new WebInspector.VisualStyleColorPicker("color", WebInspector.UIString("Color"));
+        properties.textDirection = new WebInspector.VisualStyleKeywordPicker("direction", WebInspector.UIString("Direction"), this._keywords.defaults.concat(["LTR", "RTL"]));
+
+        textAppearanceRow.element.appendChild(properties.color.element);
+        textAppearanceRow.element.appendChild(properties.textDirection.element);
+
+        let textAlignRow = new WebInspector.DetailsSectionRow;
+
+        properties.textAlign = new WebInspector.VisualStyleKeywordIconList("text-align", WebInspector.UIString("Align"), ["Left", "Center", "Right", "Justify"]);
+
+        textAlignRow.element.appendChild(properties.textAlign.element);
+
+        let textTransformRow = new WebInspector.DetailsSectionRow;
+
+        properties.textTransform = new WebInspector.VisualStyleKeywordIconList("text-transform", WebInspector.UIString("Transform"), ["Capitalize", "Uppercase", "Lowercase", "None"]);
+
+        textTransformRow.element.appendChild(properties.textTransform.element);
+
+        let textDecorationRow = new WebInspector.DetailsSectionRow;
+
+        properties.textDecoration = new WebInspector.VisualStyleKeywordIconList("text-decoration", WebInspector.UIString("Decoration"), ["Underline", "Line Through", "Overline", "None"]);
+
+        textDecorationRow.element.appendChild(properties.textDecoration.element);
+
+        group.autocompleteCompatibleProperties = [properties.color];
+
+        let textStyleGroup = new WebInspector.DetailsSectionGroup([textAppearanceRow, textAlignRow, textTransformRow, textDecorationRow]);
+        this._populateSection(group, [textStyleGroup]);
+    }
+
+    _populateFontSection()
+    {
+        let group = this._groups.font;
+        let properties = group.properties;
+
+        let fontFamilyRow = new WebInspector.DetailsSectionRow;
+
+        properties.fontFamily = new WebInspector.VisualStyleFontFamilyListEditor("font-family", WebInspector.UIString("Family"));
+
+        fontFamilyRow.element.appendChild(properties.fontFamily.element);
+
+        let fontSizeRow = new WebInspector.DetailsSectionRow;
+
+        properties.fontSize = new WebInspector.VisualStyleNumberInputBox("font-size", WebInspector.UIString("Size"), this._keywords.defaults.concat(["Larger", "XX Large", "X Large", "Large", "Medium", "Small", "X Small", "XX Small", "Smaller"]), this._units.defaults);
+
+        properties.fontWeight = new WebInspector.VisualStyleKeywordPicker("font-weight", WebInspector.UIString("Weight"), {
+            basic: this._keywords.defaults.concat(["Bolder", "Bold", "Normal", "Lighter"]),
+            advanced: ["100", "200", "300", "400", "500", "600", "700", "800", "900"]
+        });
+
+        fontSizeRow.element.appendChild(properties.fontSize.element);
+        fontSizeRow.element.appendChild(properties.fontWeight.element);
+
+        let fontStyleRow = new WebInspector.DetailsSectionRow;
+
+        properties.fontStyle = new WebInspector.VisualStyleKeywordIconList("font-style", WebInspector.UIString("Style"), ["Italic", "Normal"]);
+        properties.fontVariant = new WebInspector.VisualStyleKeywordCheckbox("font-variant", WebInspector.UIString("Variant"), "Small Caps")
+
+        fontStyleRow.element.appendChild(properties.fontStyle.element);
+        fontStyleRow.element.appendChild(properties.fontVariant.element);
+
+        group.autocompleteCompatibleProperties = [properties.fontFamily];
+
+        let fontGroup = new WebInspector.DetailsSectionGroup([fontFamilyRow, fontSizeRow, fontStyleRow]);
+        this._populateSection(group, [fontGroup]);
+    }
+
+    _populateTextSpacingSection()
+    {
+        let group = this._groups.textSpacing;
+        let properties = group.properties;
+
+        let defaultTextKeywords = this._keywords.defaults.concat(["Normal"]);
+
+        let textLayoutRow = new WebInspector.DetailsSectionRow;
+
+        properties.lineHeight = new WebInspector.VisualStyleNumberInputBox("line-height", WebInspector.UIString("Height"), defaultTextKeywords, this._units.defaults);
+        properties.verticalAlign = new WebInspector.VisualStyleNumberInputBox("vertical-align", WebInspector.UIString("Align"), ["Baseline", "Bottom"].concat(this._keywords.defaults, ["Middle", "Sub", "Super", "Text Bottom", "Text Top", "Top"]), this._units.defaults);
+
+        textLayoutRow.element.appendChild(properties.lineHeight.element);
+        textLayoutRow.element.appendChild(properties.verticalAlign.element);
+
+        let textSpacingRow = new WebInspector.DetailsSectionRow;
+
+        properties.letterSpacing = new WebInspector.VisualStyleNumberInputBox("letter-spacing", WebInspector.UIString("Letter"), defaultTextKeywords, this._units.defaults);
+        properties.wordSpacing = new WebInspector.VisualStyleNumberInputBox("word-spacing", WebInspector.UIString("Word"), defaultTextKeywords, this._units.defaults);
+
+        textSpacingRow.element.appendChild(properties.letterSpacing.element);
+        textSpacingRow.element.appendChild(properties.wordSpacing.element);
+
+        let textWhitespaceRow = new WebInspector.DetailsSectionRow;
+
+        properties.textIndent = new WebInspector.VisualStyleNumberInputBox("text-indent", WebInspector.UIString("Indent"), this._keywords.defaults, this._units.defaults);
+        properties.whiteSpace = new WebInspector.VisualStyleKeywordPicker("white-space", WebInspector.UIString("Whitespace"), this._keywords.defaults.concat(["Normal", "Nowrap", "Pre", "Pre Line", "Pre Wrap"]));
+
+        textWhitespaceRow.element.appendChild(properties.textIndent.element);
+        textWhitespaceRow.element.appendChild(properties.whiteSpace.element);
+
+        let textSpacingGroup = new WebInspector.DetailsSectionGroup([textLayoutRow, textSpacingRow, textWhitespaceRow]);
+        this._populateSection(group, [textSpacingGroup]);
+    }
+
+    _populateTextShadowSection()
+    {
+        let group = this._groups.textShadow;
+        let properties = group.properties;
+
+        let textShadowSizing = new WebInspector.DetailsSectionRow;
+
+        let textShadowH = new WebInspector.VisualStyleNumberInputBox("text-shadow", WebInspector.UIString("Horizontal"), null, this._units.defaultsSansPercent);
+        let textShadowV = new WebInspector.VisualStyleNumberInputBox("text-shadow", WebInspector.UIString("Vertical"), null, this._units.defaultsSansPercent);
+
+        textShadowSizing.element.appendChild(textShadowH.element);
+        textShadowSizing.element.appendChild(textShadowV.element);
+
+        let textShadowStyle = new WebInspector.DetailsSectionRow;
+
+        let textShadowColor = new WebInspector.VisualStyleColorPicker("text-shadow", WebInspector.UIString("Color"));
+        textShadowColor.colorProperty = true;
+        let textShadowBlur = new WebInspector.VisualStyleNumberInputBox("text-shadow", WebInspector.UIString("Blur"), null, this._units.defaultsSansPercent);
+        textShadowBlur.optionalProperty = true;
+
+        textShadowStyle.element.appendChild(textShadowColor.element);
+        textShadowStyle.element.appendChild(textShadowBlur.element);
+
+        properties.textShadow = new WebInspector.VisualStylePropertyCombiner("text-shadow", [textShadowH, textShadowV, textShadowBlur, textShadowColor]);
+
+        group.autocompleteCompatibleProperties = [textShadowColor];
+
+        let textShadowGroup = new WebInspector.DetailsSectionGroup([textShadowSizing, textShadowStyle]);
+        this._populateSection(group, [textShadowGroup]);
+    }
+
+    _populateBackgroundStyleSection()
+    {
+        let group = this._groups.backgroundStyle;
+        let properties = group.properties;
+
+        let backgroundStyleRow = new WebInspector.DetailsSectionRow;
+
+        properties.backgroundColor = new WebInspector.VisualStyleColorPicker("background-color", WebInspector.UIString("Color"));
+        properties.backgroundImage = new WebInspector.VisualStyleURLInput("background-image", WebInspector.UIString("Image"));
+
+        backgroundStyleRow.element.appendChild(properties.backgroundColor.element);
+        backgroundStyleRow.element.appendChild(properties.backgroundImage.element);
+
+        let backgroundSizeRow = new WebInspector.DetailsSectionRow;
+
+        let backgroundSizeKeywords = this._keywords.boxModel.concat(["Contain", "Cover"]);
+        let backgroundSizeX = new WebInspector.VisualStyleNumberInputBox("background-size", WebInspector.UIString("Width"), backgroundSizeKeywords, this._units.defaults);
+        backgroundSizeX.masterProperty = true;
+        let backgroundSizeY = new WebInspector.VisualStyleNumberInputBox("background-size", WebInspector.UIString("Height"), backgroundSizeKeywords, this._units.defaults);
+        backgroundSizeY.masterProperty = true;
+
+        properties.backgroundSize = new WebInspector.VisualStylePropertyCombiner("background-size", [backgroundSizeX, backgroundSizeY]);
+
+        backgroundSizeRow.element.appendChild(backgroundSizeX.element);
+        backgroundSizeRow.element.appendChild(backgroundSizeY.element);
+
+        let backgroundRepeatRow = new WebInspector.DetailsSectionRow;
+
+        properties.backgroundRepeat = new WebInspector.VisualStyleKeywordPicker("background-repeat", WebInspector.UIString("Repeat"), this._keywords.defaults.concat(["No Repeat", "Repeat", "Repeat X", "Repeat Y"]));
+        properties.backgroundAttachment = new WebInspector.VisualStyleKeywordPicker("background-attachment", WebInspector.UIString("Attach"), this._keywords.defaults.concat(["Fixed", "Local", "Scroll"]));
+
+        backgroundRepeatRow.element.appendChild(properties.backgroundRepeat.element);
+        backgroundRepeatRow.element.appendChild(properties.backgroundAttachment.element);
+
+        let backgroundPositionRow = new WebInspector.DetailsSectionRow;
+
+        let backgroundPositionX = new WebInspector.VisualStyleNumberInputBox("background-position", WebInspector.UIString("Position X"), ["Center", "Left", "Right"], this._units.defaults);
+        let backgroundPositionY = new WebInspector.VisualStyleNumberInputBox("background-position", WebInspector.UIString("Position Y"), ["Bottom", "Center", "Top"], this._units.defaults);
+
+        properties.backgroundPosition = new WebInspector.VisualStylePropertyCombiner("background-position", [backgroundPositionX, backgroundPositionY]);
+
+        backgroundPositionRow.element.appendChild(backgroundPositionX.element);
+        backgroundPositionRow.element.appendChild(backgroundPositionY.element);
+
+        group.autocompleteCompatibleProperties = [properties.backgroundColor];
+
+        let backgroundStyleGroup = new WebInspector.DetailsSectionGroup([backgroundStyleRow, backgroundSizeRow, backgroundRepeatRow, backgroundPositionRow]);
+        this._populateSection(group, [backgroundStyleGroup]);
+    }
+
+    _populateBorderSection()
+    {
+        let group = this._groups.border;
+        let properties = group.properties;
+
+        let borderAllSize = new WebInspector.DetailsSectionRow;
+
+        properties.borderStyle = new WebInspector.VisualStyleKeywordPicker(["border-top-style", "border-right-style", "border-bottom-style", "border-left-style"] , WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.borderStyle.propertyReferenceName = "border-style";
+        properties.borderWidth = new WebInspector.VisualStyleNumberInputBox(["border-top-width", "border-right-width", "border-bottom-width", "border-left-width"], WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+        properties.borderWidth.propertyReferenceName = "border-width";
+
+        borderAllSize.element.appendChild(properties.borderStyle.element);
+        borderAllSize.element.appendChild(properties.borderWidth.element);
+
+        let borderAllStyle = new WebInspector.DetailsSectionRow;
+
+        properties.borderColor = new WebInspector.VisualStyleColorPicker(["border-top-color", "border-right-color", "border-bottom-color", "border-left-color"], WebInspector.UIString("Color"));
+        properties.borderColor.propertyReferenceName = "border-color";
+        properties.borderRadius = new WebInspector.VisualStyleNumberInputBox(["border-top-left-radius", "border-top-right-radius", "border-bottom-left-radius", "border-bottom-right-radius"], WebInspector.UIString("Radius"), this._keywords.defaults, this._units.defaults);
+        properties.borderRadius.propertyReferenceName = "border-radius";
+
+        borderAllStyle.element.appendChild(properties.borderColor.element);
+        borderAllStyle.element.appendChild(properties.borderRadius.element);
+
+        let borderAllProperties = [properties.borderStyle, properties.borderWidth, properties.borderColor, properties.borderRadius];
+        let borderAllGroup = new WebInspector.DetailsSectionGroup([borderAllSize, borderAllStyle]);
+
+        let borderTopSize = new WebInspector.DetailsSectionRow;
+
+        properties.borderTopStyle = new WebInspector.VisualStyleKeywordPicker("border-top-style", WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.borderTopWidth = new WebInspector.VisualStyleNumberInputBox("border-top-width", WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+
+        borderTopSize.element.appendChild(properties.borderTopStyle.element);
+        borderTopSize.element.appendChild(properties.borderTopWidth.element);
+
+        let borderTopStyle = new WebInspector.DetailsSectionRow;
+
+        properties.borderTopColor = new WebInspector.VisualStyleColorPicker("border-top-color", WebInspector.UIString("Color"));
+        properties.borderTopRadius = new WebInspector.VisualStyleNumberInputBox(["border-top-left-radius", "border-top-right-radius"], WebInspector.UIString("Radius"), this._keywords.defaults, this._units.defaults);
+
+        borderTopStyle.element.appendChild(properties.borderTopColor.element);
+        borderTopStyle.element.appendChild(properties.borderTopRadius.element);
+
+        let borderTopProperties = [properties.borderTopStyle, properties.borderTopWidth, properties.borderTopColor, properties.borderTopRadius];
+        let borderTopGroup = new WebInspector.DetailsSectionGroup([borderTopSize, borderTopStyle]);
+
+        let borderRightSize = new WebInspector.DetailsSectionRow;
+
+        properties.borderRightStyle = new WebInspector.VisualStyleKeywordPicker("border-right-style", WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.borderRightWidth = new WebInspector.VisualStyleNumberInputBox("border-right-width", WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+
+        borderRightSize.element.appendChild(properties.borderRightStyle.element);
+        borderRightSize.element.appendChild(properties.borderRightWidth.element);
+
+        let borderRightStyle = new WebInspector.DetailsSectionRow;
+
+        properties.borderRightColor = new WebInspector.VisualStyleColorPicker("border-right-color", WebInspector.UIString("Color"));
+        properties.borderRightRadius = new WebInspector.VisualStyleNumberInputBox(["border-top-right-radius", "border-bottom-right-radius"], WebInspector.UIString("Radius"), this._keywords.defaults, this._units.defaults);
+
+        borderRightStyle.element.appendChild(properties.borderRightColor.element);
+        borderRightStyle.element.appendChild(properties.borderRightRadius.element);
+
+        let borderRightProperties = [properties.borderRightStyle, properties.borderRightWidth, properties.borderRightColor, properties.borderRightRadius];
+        let borderRightGroup = new WebInspector.DetailsSectionGroup([borderRightSize, borderRightStyle]);
+
+        let borderBottomSize = new WebInspector.DetailsSectionRow;
+
+        properties.borderBottomStyle = new WebInspector.VisualStyleKeywordPicker("border-bottom-style", WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.borderBottomWidth = new WebInspector.VisualStyleNumberInputBox("border-bottom-width", WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+
+        borderBottomSize.element.appendChild(properties.borderBottomStyle.element);
+        borderBottomSize.element.appendChild(properties.borderBottomWidth.element);
+
+        let borderBottomStyle = new WebInspector.DetailsSectionRow;
+
+        properties.borderBottomColor = new WebInspector.VisualStyleColorPicker("border-bottom-color", WebInspector.UIString("Color"));
+        properties.borderBottomRadius = new WebInspector.VisualStyleNumberInputBox(["border-bottom-left-radius", "border-bottom-right-radius"], WebInspector.UIString("Radius"), this._keywords.defaults, this._units.defaults);
+
+        borderBottomStyle.element.appendChild(properties.borderBottomColor.element);
+        borderBottomStyle.element.appendChild(properties.borderBottomRadius.element);
+
+        let borderBottomProperties = [properties.borderBottomStyle, properties.borderBottomWidth, properties.borderBottomColor, properties.borderBottomRadius];
+        let borderBottomGroup = new WebInspector.DetailsSectionGroup([borderBottomSize, borderBottomStyle]);
+
+        let borderLeftSize = new WebInspector.DetailsSectionRow;
+
+        properties.borderLeftStyle = new WebInspector.VisualStyleKeywordPicker("border-left-style", WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.borderLeftWidth = new WebInspector.VisualStyleNumberInputBox("border-left-width", WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+
+        borderLeftSize.element.appendChild(properties.borderLeftStyle.element);
+        borderLeftSize.element.appendChild(properties.borderLeftWidth.element);
+
+        let borderLeftStyle = new WebInspector.DetailsSectionRow;
+
+        properties.borderLeftColor = new WebInspector.VisualStyleColorPicker("border-left-color", WebInspector.UIString("Color"));
+        properties.borderLeftRadius = new WebInspector.VisualStyleNumberInputBox(["border-top-left-radius", "border-bottom-left-radius"], WebInspector.UIString("Radius"), this._keywords.defaults, this._units.defaults);
+
+        borderLeftStyle.element.appendChild(properties.borderLeftColor.element);
+        borderLeftStyle.element.appendChild(properties.borderLeftRadius.element);
+
+        let borderLeftProperties = [properties.borderLeftStyle, properties.borderLeftWidth, properties.borderLeftColor, properties.borderLeftRadius];
+        let borderLeftGroup = new WebInspector.DetailsSectionGroup([borderLeftSize, borderLeftStyle]);
+
+        let borderTabController = new WebInspector.VisualStyleTabbedPropertiesRow({
+            "all": {title: WebInspector.UIString("All"), element: borderAllGroup.element, properties: borderAllProperties},
+            "top": {title: WebInspector.UIString("Top"), element: borderTopGroup.element, properties: borderTopProperties},
+            "right": {title: WebInspector.UIString("Right"), element: borderRightGroup.element, properties: borderRightProperties},
+            "bottom": {title: WebInspector.UIString("Bottom"), element: borderBottomGroup.element, properties: borderBottomProperties},
+            "left": {title: WebInspector.UIString("Left"), element: borderLeftGroup.element, properties: borderLeftProperties}
+        });
+
+        let highlightMode = "border";
+        this._addMetricsMouseListeners(group.properties.borderWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.borderTopWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.borderBottomWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.borderLeftWidth, highlightMode);
+        this._addMetricsMouseListeners(group.properties.borderRightWidth, highlightMode);
+
+        group.autocompleteCompatibleProperties = [properties.borderColor, properties.borderTopColor, properties.borderBottomColor, properties.borderLeftColor, properties.borderRightColor];
+
+        let borderGroup = new WebInspector.DetailsSectionGroup([borderTabController, borderAllGroup, borderTopGroup, borderRightGroup, borderBottomGroup, borderLeftGroup]);
+        this._populateSection(group, [borderGroup]);
+    }
+
+    _populateOutlineSection()
+    {
+        let group = this._groups.outline;
+        let properties = group.properties;
+
+        let outlineSizeRow = new WebInspector.DetailsSectionRow;
+
+        properties.outlineWidth = new WebInspector.VisualStyleNumberInputBox("outline-width", WebInspector.UIString("Width"), this._keywords.borderWidth, this._units.defaults);
+        properties.outlineOffset = new WebInspector.VisualStyleNumberInputBox("outline-offset", WebInspector.UIString("Offset"), this._keywords.defaults, this._units.defaults, true);
+
+        outlineSizeRow.element.appendChild(properties.outlineWidth.element);
+        outlineSizeRow.element.appendChild(properties.outlineOffset.element);
+
+        let outlineStyleRow = new WebInspector.DetailsSectionRow;
+
+        properties.outlineStyle = new WebInspector.VisualStyleKeywordPicker("outline-style" , WebInspector.UIString("Style"), this._keywords.borderStyle);
+        properties.outlineColor = new WebInspector.VisualStyleColorPicker("outline-color", WebInspector.UIString("Color"));
+
+        outlineStyleRow.element.appendChild(properties.outlineStyle.element);
+        outlineStyleRow.element.appendChild(properties.outlineColor.element);
+
+        group.autocompleteCompatibleProperties = [properties.outlineColor];
+
+        let outlineGroup = new WebInspector.DetailsSectionGroup([outlineSizeRow, outlineStyleRow]);
+        this._populateSection(group, [outlineGroup]);
+    }
+
+    _populateBoxShadowSection()
+    {
+        let group = this._groups.boxShadow;
+        let properties = group.properties;
+
+        let boxShadowRow = new WebInspector.DetailsSectionRow;
+
+        properties.boxShadow = new WebInspector.VisualStyleCommaSeparatedKeywordEditor("box-shadow");
+        properties.boxShadow.element.style.marginLeft = "11px";
+
+        boxShadowRow.element.appendChild(properties.boxShadow.element);
+
+        let boxShadowHRow = new WebInspector.DetailsSectionRow;
+
+        let boxShadowH = new WebInspector.VisualStyleRelativeNumberSlider("box-shadow", WebInspector.UIString("Left"), null, this._units.defaultsSansPercent, true);
+
+        boxShadowHRow.element.appendChild(boxShadowH.element);
+
+        let boxShadowVRow = new WebInspector.DetailsSectionRow;
+
+        let boxShadowV = new WebInspector.VisualStyleRelativeNumberSlider("box-shadow", WebInspector.UIString("Top"), null, this._units.defaultsSansPercent, true);
+
+        boxShadowVRow.element.appendChild(boxShadowV.element);
+
+        let boxShadowBlurRow = new WebInspector.DetailsSectionRow;
+
+        let boxShadowBlur = new WebInspector.VisualStyleNumberInputBox("box-shadow", WebInspector.UIString("Blur"), null, this._units.defaultsSansPercent);
+        boxShadowBlur.optionalProperty = true;
+        let boxShadowSpread = new WebInspector.VisualStyleNumberInputBox("box-shadow", WebInspector.UIString("Spread"), null, this._units.defaultsSansPercent, true);
+        boxShadowSpread.optionalProperty = true;
+
+        boxShadowBlurRow.element.appendChild(boxShadowBlur.element);
+        boxShadowBlurRow.element.appendChild(boxShadowSpread.element);
+
+        let boxShadowColorRow = new WebInspector.DetailsSectionRow;
+
+        let boxShadowColor = new WebInspector.VisualStyleColorPicker("box-shadow", WebInspector.UIString("Color"));
+        boxShadowColor.colorProperty = true;
+        let boxShadowInset = new WebInspector.VisualStyleKeywordCheckbox("box-shadow", WebInspector.UIString("Inset"), "Inset");
+        boxShadowInset.optionalProperty = true;
+
+        boxShadowColorRow.element.appendChild(boxShadowColor.element);
+        boxShadowColorRow.element.appendChild(boxShadowInset.element);
+
+        let boxShadowPropertyCombiner = new WebInspector.VisualStylePropertyCombiner("box-shadow", [boxShadowH, boxShadowV, boxShadowBlur, boxShadowSpread, boxShadowColor, boxShadowInset]);
+
+        function noRemainingTreeItems() {
+            boxShadowPropertyCombiner.updateValuesFromText("");
+            boxShadowH.disabled = true;
+            boxShadowV.disabled = true;
+            boxShadowBlur.disabled = true;
+            boxShadowSpread.disabled = true;
+            boxShadowColor.disabled = true;
+            boxShadowInset.disabled = true;
+        }
+        properties.boxShadow.addEventListener(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.NoRemainingTreeItems, noRemainingTreeItems, this);
+
+        function selectedBoxShadowItemValueChanged() {
+            properties.boxShadow.selectedTreeElementValue = boxShadowPropertyCombiner.synthesizedValue;
+        }
+        boxShadowPropertyCombiner.addEventListener(WebInspector.VisualStylePropertyEditor.Event.ValueDidChange, selectedBoxShadowItemValueChanged, this);
+
+        function boxShadowItemSelected(event) {
+            boxShadowPropertyCombiner.updateValuesFromText(event.data.text || "");
+        }
+        properties.boxShadow.addEventListener(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.TreeItemSelected, boxShadowItemSelected, this);
+
+        group.autocompleteCompatibleProperties = [boxShadowColor];
+
+        let boxShadow = new WebInspector.DetailsSectionGroup([boxShadowRow, boxShadowHRow, boxShadowVRow, boxShadowBlurRow, boxShadowColorRow]);
+        this._populateSection(group, [boxShadow]);
+    }
+
+    _populateTransitionSection()
+    {
+        let group = this._groups.transition;
+        let properties = group.properties;
+
+        let transitionRow = new WebInspector.DetailsSectionRow;
+
+        properties.transition = new WebInspector.VisualStyleCommaSeparatedKeywordEditor("transition");
+        properties.transition.element.style.marginLeft = "11px";
+
+        transitionRow.element.appendChild(properties.transition.element);
+
+        let transitionPropertyRow = new WebInspector.DetailsSectionRow;
+
+        let transitionProperty = new WebInspector.VisualStylePropertyNameInput("transition-property", WebInspector.UIString("Property"));
+        let transitionTiming = new WebInspector.VisualStyleTimingEditor("transition-timing-function", WebInspector.UIString("Timing"), ["Linear", "Ease", "Ease In", "Ease Out", "Ease In Out"]);
+
+        transitionPropertyRow.element.appendChild(transitionProperty.element);
+        transitionPropertyRow.element.appendChild(transitionTiming.element);
+
+        let transitionDurationRow = new WebInspector.DetailsSectionRow;
+
+        let transitionTimeKeywords = ["s", "ms"];
+        let transitionDuration = new WebInspector.VisualStyleNumberInputBox("transition-duration", WebInspector.UIString("Duration"), null, transitionTimeKeywords);
+        let transitionDelay = new WebInspector.VisualStyleNumberInputBox("transition-delay", WebInspector.UIString("Delay"), null, transitionTimeKeywords);
+        transitionDelay.optionalProperty = true;
+
+        transitionDurationRow.element.appendChild(transitionDuration.element);
+        transitionDurationRow.element.appendChild(transitionDelay.element);
+
+        let transitionPropertyCombiner = new WebInspector.VisualStylePropertyCombiner("transition", [transitionProperty, transitionTiming, transitionDuration, transitionDelay]);
+
+        function noRemainingTreeItems() {
+            transitionPropertyCombiner.updateValuesFromText("");
+            transitionProperty.disabled = true;
+            transitionTiming.disabled = true;
+            transitionDuration.disabled = true;
+            transitionDelay.disabled = true;
+        }
+        properties.transition.addEventListener(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.NoRemainingTreeItems, noRemainingTreeItems, this);
+
+        function selectedtransitionItemValueChanged() {
+            properties.transition.selectedTreeElementValue = transitionPropertyCombiner.synthesizedValue;
+        }
+        transitionPropertyCombiner.addEventListener(WebInspector.VisualStylePropertyEditor.Event.ValueDidChange, selectedtransitionItemValueChanged, this);
+
+        function transitionItemSelected(event) {
+            transitionPropertyCombiner.updateValuesFromText(event.data.text || "");
+        }
+        properties.transition.addEventListener(WebInspector.VisualStyleCommaSeparatedKeywordEditor.Event.TreeItemSelected, transitionItemSelected, this);
+
+        group.autocompleteCompatibleProperties = [transitionProperty];
+
+        let transitionGroup = new WebInspector.DetailsSectionGroup([transitionRow, transitionPropertyRow, transitionDurationRow]);
+        this._populateSection(group, [transitionGroup]);
+    }
+};
+
+WebInspector.VisualStyleDetailsPanel.StyleDisabledSymbol = Symbol("visual-style-style-disabled");
+WebInspector.VisualStyleDetailsPanel.InitialPropertySectionTextListSymbol = Symbol("visual-style-initial-property-section-text");
+
+// FIXME: Add information about each property as a form of documentation.  This is currently empty as
+// we do not have permission to use the info on sites like MDN and have not written anything ourselves.
+WebInspector.VisualStyleDetailsPanel.propertyReferenceInfo = {};