Title: [205754] trunk/Source/WebInspectorUI
Revision
205754
Author
[email protected]
Date
2016-09-09 11:25:14 -0700 (Fri, 09 Sep 2016)

Log Message

Web Inspector: Command-Z doesn't work when editing CSS selectors in Styles sidebar
https://bugs.webkit.org/show_bug.cgi?id=159734

Patch by Devin Rousso <[email protected]> on 2016-09-09
Reviewed by Brian Burg.

Replace the current usage of -webkit-user-select with a textarea sized exactly the same as
the selector text which holds the current value of the selector.

* UserInterface/Test.html: Add WrappedPromise.

* UserInterface/Models/DOMNodeStyles.js:
(WebInspector.DOMNodeStyles.prototype.refresh.fetchedMatchedStyles):
(WebInspector.DOMNodeStyles.prototype.refresh.fetchedInlineStyles):
(WebInspector.DOMNodeStyles.prototype.refresh.fetchedComputedStyle):
(WebInspector.DOMNodeStyles.prototype.refresh):
(WebInspector.DOMNodeStyles.prototype.changeRuleSelector.ruleSelectorChanged):
(WebInspector.DOMNodeStyles.prototype.changeRuleSelector):
Ensure that the promise returned by changeRuleSelector is only resolved once the initiated
refresh has completed, ensuring that all matched selectors are parsed and available.

* UserInterface/Views/CSSStyleDeclarationSection.css:
(.style-declaration-section > .header):
(.style-declaration-section.locked > .header::before):
(.style-declaration-section.rule-disabled > .header > .icon):
(.style-declaration-section > .header > textarea):
(.style-declaration-section > .header > textarea:focus):
(.style-declaration-section > .header > textarea:focus + .selector):
(.style-declaration-section > .header > .selector):
(.style-declaration-section > .header > .selector:empty):
(.style-declaration-section > .header > .selector .matched):
(.style-declaration-section:not(.invalid-selector).rule-disabled > .header > .icon): Deleted.
(.style-declaration-section > .header > .selector:empty::before): Deleted.
(.style-declaration-section > .header > .selector:focus): Deleted.
(.style-declaration-section:matches(.locked, .selector-locked) > .header > .selector): Deleted.
(.style-declaration-section > .header > .selector > .matched): Deleted.
(.style-declaration-section.invalid-selector > .header > .icon): Deleted.
(.style-declaration-section.invalid-selector > .header > .selector): Deleted.
Added styling to make textarea invisible when not focused.
Also removed the .invalid-selector styles as the section now refreshed on all changes.

* UserInterface/Views/CSSStyleDeclarationSection.js:
(WebInspector.CSSStyleDeclarationSection):
(WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelector):
(WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelectorTextKnownToMatch):
(WebInspector.CSSStyleDeclarationSection.prototype.refresh):
(WebInspector.CSSStyleDeclarationSection.prototype.focusRuleSelector):
(WebInspector.CSSStyleDeclarationSection.prototype.get selectorEditable):
(WebInspector.CSSStyleDeclarationSection.prototype.get _currentSelectorText):
(WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste.parseTextForRule):
(WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste):
(WebInspector.CSSStyleDeclarationSection.prototype.get selectorLocked): Deleted.
Added a hidden textarea for modifying the selector of the represented style.

* UserInterface/Views/RulesStyleDetailsPanel.js:
(WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionEditorPreviousRule):
Now use new getters on CSSSTyleDeclarationSection for determining if a selector is editable.

* UserInterface/Views/Variables.css:
(:root):
Added --style-declaration-section-header-padding CSS variable.

Modified Paths

Diff

Modified: trunk/Source/WebInspectorUI/ChangeLog (205753 => 205754)


--- trunk/Source/WebInspectorUI/ChangeLog	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/ChangeLog	2016-09-09 18:25:14 UTC (rev 205754)
@@ -1,3 +1,66 @@
+2016-09-09  Devin Rousso  <[email protected]>
+
+        Web Inspector: Command-Z doesn't work when editing CSS selectors in Styles sidebar
+        https://bugs.webkit.org/show_bug.cgi?id=159734
+
+        Reviewed by Brian Burg.
+
+        Replace the current usage of -webkit-user-select with a textarea sized exactly the same as
+        the selector text which holds the current value of the selector.
+
+        * UserInterface/Test.html: Add WrappedPromise.
+
+        * UserInterface/Models/DOMNodeStyles.js:
+        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedMatchedStyles):
+        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedInlineStyles):
+        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedComputedStyle):
+        (WebInspector.DOMNodeStyles.prototype.refresh):
+        (WebInspector.DOMNodeStyles.prototype.changeRuleSelector.ruleSelectorChanged):
+        (WebInspector.DOMNodeStyles.prototype.changeRuleSelector):
+        Ensure that the promise returned by changeRuleSelector is only resolved once the initiated
+        refresh has completed, ensuring that all matched selectors are parsed and available.
+
+        * UserInterface/Views/CSSStyleDeclarationSection.css:
+        (.style-declaration-section > .header):
+        (.style-declaration-section.locked > .header::before):
+        (.style-declaration-section.rule-disabled > .header > .icon):
+        (.style-declaration-section > .header > textarea):
+        (.style-declaration-section > .header > textarea:focus):
+        (.style-declaration-section > .header > textarea:focus + .selector):
+        (.style-declaration-section > .header > .selector):
+        (.style-declaration-section > .header > .selector:empty):
+        (.style-declaration-section > .header > .selector .matched):
+        (.style-declaration-section:not(.invalid-selector).rule-disabled > .header > .icon): Deleted.
+        (.style-declaration-section > .header > .selector:empty::before): Deleted.
+        (.style-declaration-section > .header > .selector:focus): Deleted.
+        (.style-declaration-section:matches(.locked, .selector-locked) > .header > .selector): Deleted.
+        (.style-declaration-section > .header > .selector > .matched): Deleted.
+        (.style-declaration-section.invalid-selector > .header > .icon): Deleted.
+        (.style-declaration-section.invalid-selector > .header > .selector): Deleted.
+        Added styling to make textarea invisible when not focused.
+        Also removed the .invalid-selector styles as the section now refreshed on all changes.
+
+        * UserInterface/Views/CSSStyleDeclarationSection.js:
+        (WebInspector.CSSStyleDeclarationSection):
+        (WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelector):
+        (WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelectorTextKnownToMatch):
+        (WebInspector.CSSStyleDeclarationSection.prototype.refresh):
+        (WebInspector.CSSStyleDeclarationSection.prototype.focusRuleSelector):
+        (WebInspector.CSSStyleDeclarationSection.prototype.get selectorEditable):
+        (WebInspector.CSSStyleDeclarationSection.prototype.get _currentSelectorText):
+        (WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste.parseTextForRule):
+        (WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste):
+        (WebInspector.CSSStyleDeclarationSection.prototype.get selectorLocked): Deleted.
+        Added a hidden textarea for modifying the selector of the represented style.
+
+        * UserInterface/Views/RulesStyleDetailsPanel.js:
+        (WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionEditorPreviousRule):
+        Now use new getters on CSSSTyleDeclarationSection for determining if a selector is editable.
+
+        * UserInterface/Views/Variables.css:
+        (:root):
+        Added --style-declaration-section-header-padding CSS variable.
+
 2016-09-08  Brian Burg  <[email protected]>
 
         Web Inspector: make copy-user-interface-resources.pl easier to read

Modified: trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js	2016-09-09 18:25:14 UTC (rev 205754)
@@ -45,6 +45,7 @@
 
         this._propertyNameToEffectivePropertyMap = {};
 
+        this._pendingRefreshTask = null;
         this.refresh();
     }
 
@@ -57,7 +58,7 @@
 
     get needsRefresh()
     {
-        return this._refreshPending || this._needsRefresh;
+        return this._pendingRefreshTask || this._needsRefresh;
     }
 
     refreshIfNeeded()
@@ -69,12 +70,15 @@
 
     refresh()
     {
-        if (this._refreshPending)
-            return;
+        if (this._pendingRefreshTask)
+            return this._pendingRefreshTask;
 
         this._needsRefresh = false;
-        this._refreshPending = true;
 
+        let fetchedMatchedStylesPromise = new WebInspector.WrappedPromise;
+        let fetchedInlineStylesPromise = new WebInspector.WrappedPromise;
+        let fetchedComputedStylesPromise = new WebInspector.WrappedPromise;
+
         function parseRuleMatchArrayPayload(matchArray, node, inherited)
         {
             var result = [];
@@ -130,6 +134,8 @@
                 currentNode = currentNode.parentNode;
                 ++i;
             }
+
+            fetchedMatchedStylesPromise.resolve();
         }
 
         function fetchedInlineStyles(error, inlineStylePayload, attributesStylePayload)
@@ -138,6 +144,8 @@
             this._attributesStyle = attributesStylePayload ? this._parseStyleDeclarationPayload(attributesStylePayload, this._node, false, WebInspector.CSSStyleDeclaration.Type.Attribute) : null;
 
             this._updateStyleCascade();
+
+            fetchedComputedStylesPromise.resolve();
         }
 
         function fetchedComputedStyle(error, computedPropertiesPayload)
@@ -160,8 +168,6 @@
             else
                 this._computedStyle = new WebInspector.CSSStyleDeclaration(this, null, null, WebInspector.CSSStyleDeclaration.Type.Computed, this._node, false, null, properties);
 
-            this._refreshPending = false;
-
             let significantChange = false;
             for (let key in this._styleDeclarationsMap) {
                 // Check if the same key exists in the previous map and has the same style objects.
@@ -226,6 +232,8 @@
             delete this._previousStyleDeclarationsMap;
 
             this.dispatchEventToListeners(WebInspector.DOMNodeStyles.Event.Refreshed, {significantChange});
+
+            fetchedComputedStylesPromise.resolve();
         }
 
         // FIXME: Convert to pushing StyleSheet information to the frontend. <rdar://problem/13213680>
@@ -234,6 +242,13 @@
         CSSAgent.getMatchedStylesForNode.invoke({nodeId: this._node.id, includePseudo: true, includeInherited: true}, fetchedMatchedStyles.bind(this));
         CSSAgent.getInlineStylesForNode.invoke({nodeId: this._node.id}, fetchedInlineStyles.bind(this));
         CSSAgent.getComputedStyleForNode.invoke({nodeId: this._node.id}, fetchedComputedStyle.bind(this));
+
+        this._pendingRefreshTask = Promise.all([fetchedMatchedStylesPromise, fetchedInlineStylesPromise, fetchedComputedStylesPromise])
+        .then(() => {
+            this._pendingRefreshTask = null;
+        });
+
+        return this._pendingRefreshTask;
     }
 
     addRule(selector, text)
@@ -408,7 +423,7 @@
     changeRuleSelector(rule, selector)
     {
         selector = selector || "";
-        var result = new WebInspector.WrappedPromise;
+        let result = new WebInspector.WrappedPromise;
 
         function ruleSelectorChanged(error, rulePayload)
         {
@@ -421,9 +436,9 @@
 
             // Do a full refresh incase the rule no longer matches the node or the
             // matched selector indices changed.
-            this.refresh();
-
-            result.resolve(rulePayload);
+            this.refresh().then(() => {
+                result.resolve(rulePayload);
+            });
         }
 
         this._needsRefresh = true;

Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Test.html	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html	2016-09-09 18:25:14 UTC (rev 205754)
@@ -161,6 +161,7 @@
     <script src=""
     <script src=""
     <script src=""
+    <script src=""
 
     <script src=""
     <script src=""

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.css (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.css	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.css	2016-09-09 18:25:14 UTC (rev 205754)
@@ -55,13 +55,23 @@
 
 .style-declaration-section > .header {
     position: relative;
-
-    padding: 4px 5px 3px 25px;
-
+    padding: var(--style-declaration-section-header-padding);
     font-size: 11px;
     line-height: 12px;
 }
 
+.style-declaration-section.locked > .header::before {
+    float: right;
+    width: 8px;
+    height: 10px;
+    margin-left: 5px;
+    content: "";
+    background-image: url(../Images/Locked.svg);
+    background-repeat: no-repeat;
+    background-position: center;
+    background-size: 8px 10px;
+}
+
 .style-declaration-section > .header > .icon {
     position: absolute;
 
@@ -80,59 +90,45 @@
     filter: brightness(0.8);
 }
 
-.style-declaration-section:not(.invalid-selector).rule-disabled > .header > .icon {
+.style-declaration-section.rule-disabled > .header > .icon {
     opacity: 0.5;
 }
 
-.style-declaration-section > .header > .selector {
+.style-declaration-section > .header > textarea {
+    display: block;
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    margin: 0;
+    padding: var(--style-declaration-section-header-padding);
     font-family: Menlo, monospace;
-    color: hsl(0, 0%, 50%);
-
+    color: black;
+    background: transparent;
+    border: none;
     outline: none;
-
-    cursor: text;
-
-    word-wrap: break-word;
-
-    -webkit-user-select: text;
-    -webkit-user-modify: read-write-plaintext-only;
+    opacity: 0;
+    resize: none;
+    -webkit-appearance: none;
 }
 
-.style-declaration-section > .header > .selector:empty {
-    /* This prevents the cursor from disappearing when empty. */
-    display: inline-block;
-    min-width: 1px;
+.style-declaration-section > .header > textarea:focus {
+    opacity: 1;
 }
 
-.style-declaration-section > .header > .selector:empty::before {
-    /* This prevents the cursor from positioning badly when empty. */
-    content: "";
+.style-declaration-section > .header > textarea:focus + .selector {
+    opacity: 0;
 }
 
-.style-declaration-section > .header > .selector:focus {
-    color: black;
+.style-declaration-section > .header > .selector {
+    font-family: Menlo, monospace;
+    color: hsl(0, 0%, 50%);
+    word-wrap: break-word;
 }
 
-.style-declaration-section:matches(.locked, .selector-locked) > .header > .selector {
-    -webkit-user-modify: read-only;
-}
-
-.style-declaration-section.locked > .header::before {
-    float: right;
-
-    content: "";
-
-    width: 8px;
-    height: 10px;
-
-    background-image: url(../Images/Locked.svg);
-    background-repeat: no-repeat;
-    background-position: center;
-    background-size: 8px 10px;
-
-    margin-left: 5px;
-}
-
 .style-declaration-section > .header > .selector > .matched {
     color: black;
 }
@@ -154,19 +150,6 @@
     color: inherit !important;
 }
 
-.style-declaration-section.invalid-selector > .header > .icon {
-    top: 4px;
-    left: 6px;
-    width: 12px;
-    height: 12px;
-    content: url(../Images/Error.svg);
-}
-
-.style-declaration-section.invalid-selector > .header > .selector,
-.style-declaration-section.invalid-selector > .header > .selector> * {
-    color: red;
-}
-
 @media (-webkit-min-device-pixel-ratio: 2) {
     .style-declaration-section,
     .sidebar > .panel.details.css-style > .content > .pseudo-classes {

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js	2016-09-09 18:25:14 UTC (rev 205754)
@@ -36,7 +36,6 @@
         this._style = style || null;
         this._selectorElements = [];
         this._ruleDisabled = false;
-        this._hasInvalidSelector = false;
 
         this._element = document.createElement("div");
         this._element.classList.add("style-declaration-section");
@@ -47,24 +46,29 @@
         this._headerElement = document.createElement("div");
         this._headerElement.classList.add("header");
 
-        this._iconElement = document.createElement("img");
-        this._iconElement.classList.add("icon");
-        this._headerElement.appendChild(this._iconElement);
+        this._iconElement = this._headerElement.createChild("img", "icon");
 
-        this._selectorElement = document.createElement("span");
-        this._selectorElement.classList.add("selector");
-        this._selectorElement.setAttribute("spellcheck", "false");
-        this._selectorElement.addEventListener("mouseover", this._handleMouseOver.bind(this));
-        this._selectorElement.addEventListener("mouseout", this._handleMouseOut.bind(this));
-        this._selectorElement.addEventListener("keydown", this._handleKeyDown.bind(this));
-        this._selectorElement.addEventListener("keyup", this._handleKeyUp.bind(this));
-        this._selectorElement.addEventListener("paste", this._handleSelectorPaste.bind(this));
-        this._headerElement.appendChild(this._selectorElement);
+        if (this.selectorEditable) {
+            this._selectorInput = this._headerElement.createChild("textarea");
+            this._selectorInput.spellcheck = false;
+            this._selectorInput.tabIndex = -1;
+            this._selectorInput.addEventListener("mouseover", this._handleMouseOver.bind(this));
+            this._selectorInput.addEventListener("mouseout", this._handleMouseOut.bind(this));
+            this._selectorInput.addEventListener("keydown", this._handleKeyDown.bind(this));
+            this._selectorInput.addEventListener("keypress", this._handleKeyPress.bind(this));
+            this._selectorInput.addEventListener("input", this._handleInput.bind(this));
+            this._selectorInput.addEventListener("paste", this._handleSelectorPaste.bind(this));
+            this._selectorInput.addEventListener("blur", this._handleBlur.bind(this));
+        }
 
-        this._originElement = document.createElement("span");
-        this._originElement.classList.add("origin");
-        this._headerElement.appendChild(this._originElement);
+        this._selectorElement = this._headerElement.createChild("span", "selector");
+        if (!this.selectorEditable) {
+            this._selectorElement.addEventListener("mouseover", this._handleMouseOver.bind(this));
+            this._selectorElement.addEventListener("mouseout", this._handleMouseOut.bind(this));
+        }
 
+        this._originElement = this._headerElement.createChild("span", "origin");
+
         this._propertiesElement = document.createElement("div");
         this._propertiesElement.classList.add("properties");
 
@@ -77,7 +81,7 @@
         this._element.appendChild(this._headerElement);
         this._element.appendChild(this._propertiesElement);
 
-        var iconClassName;
+        let iconClassName = null;
         switch (style.type) {
         case WebInspector.CSSStyleDeclaration.Type.Rule:
             console.assert(style.ownerRule);
@@ -114,11 +118,9 @@
 
         if (!style.editable)
             this._element.classList.add(WebInspector.CSSStyleDeclarationSection.LockedStyleClassName);
-        else if (style.ownerRule) {
-            this._style.ownerRule.addEventListener(WebInspector.CSSRule.Event.SelectorChanged, this._updateSelectorIcon.bind(this));
-            this._commitSelectorKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Enter, this._commitSelector.bind(this), this._selectorElement);
-            this._selectorElement.addEventListener("blur", this._commitSelector.bind(this));
-        } else
+        else if (style.ownerRule)
+            this._style.ownerRule.addEventListener(WebInspector.CSSRule.Event.SelectorChanged, this.refresh.bind(this));
+        else
             this._element.classList.add(WebInspector.CSSStyleDeclarationSection.SelectorLockedStyleClassName);
 
         this.refresh();
@@ -167,21 +169,21 @@
         this._originElement.removeChildren();
         this._selectorElements = [];
 
-        this._originElement.append(" \u2014 ");
+        this._originElement.append(` ${emDash} `);
 
         function appendSelector(selector, matched)
         {
             console.assert(selector instanceof WebInspector.CSSSelector);
 
-            var selectorElement = document.createElement("span");
+            let selectorElement = document.createElement("span");
             selectorElement.textContent = selector.text;
 
             if (matched)
                 selectorElement.classList.add(WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
 
-            var specificity = selector.specificity;
+            let specificity = selector.specificity;
             if (specificity) {
-                var tooltip = WebInspector.UIString("Specificity: (%d, %d, %d)").format(specificity[0], specificity[1], specificity[2]);
+                let tooltip = WebInspector.UIString("Specificity: (%d, %d, %d)").format(specificity[0], specificity[1], specificity[2]);
                 if (selector.dynamic) {
                     tooltip += "\n";
                     if (this._style.inherited)
@@ -191,7 +193,7 @@
                 }
                 selectorElement.title = tooltip;
             } else if (selector.dynamic) {
-                var tooltip = WebInspector.UIString("Specificity: No value for selected element");
+                let tooltip = WebInspector.UIString("Specificity: No value for selected element");
                 tooltip += "\n";
                 tooltip += WebInspector.UIString("Dynamically calculated for the selected element and did not match");
                 selectorElement.title = tooltip;
@@ -203,7 +205,7 @@
 
         function appendSelectorTextKnownToMatch(selectorText)
         {
-            var selectorElement = document.createElement("span");
+            let selectorElement = document.createElement("span");
             selectorElement.textContent = selectorText;
             selectorElement.classList.add(WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
             this._selectorElement.appendChild(selectorElement);
@@ -213,12 +215,12 @@
         case WebInspector.CSSStyleDeclaration.Type.Rule:
             console.assert(this._style.ownerRule);
 
-            var selectors = this._style.ownerRule.selectors;
-            var matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
-            var alwaysMatch = !matchedSelectorIndices.length;
+            let selectors = this._style.ownerRule.selectors;
+            let matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
+            let alwaysMatch = !matchedSelectorIndices.length;
             if (selectors.length) {
-                var hasMatchingPseudoElementSelector = false;
-                for (var i = 0; i < selectors.length; ++i) {
+                let hasMatchingPseudoElementSelector = false;
+                for (let i = 0; i < selectors.length; ++i) {
                     appendSelector.call(this, selectors[i], alwaysMatch || matchedSelectorIndices.includes(i));
                     if (i < selectors.length - 1)
                         this._selectorElement.append(", ");
@@ -231,10 +233,10 @@
                 appendSelectorTextKnownToMatch.call(this, this._style.ownerRule.selectorText);
 
             if (this._style.ownerRule.sourceCodeLocation) {
-                var sourceCodeLink = WebInspector.createSourceCodeLocationLink(this._style.ownerRule.sourceCodeLocation, true);
+                let sourceCodeLink = WebInspector.createSourceCodeLocationLink(this._style.ownerRule.sourceCodeLocation, true);
                 this._originElement.appendChild(sourceCodeLink);
             } else {
-                var originString;
+                let originString;
                 switch (this._style.ownerRule.type) {
                 case WebInspector.CSSStyleSheet.Type.Author:
                     originString = WebInspector.UIString("Author Stylesheet");
@@ -271,7 +273,8 @@
             break;
         }
 
-        this._updateSelectorIcon();
+        if (this._selectorInput)
+            this._selectorInput.value = this._selectorElement.textContent;
     }
 
     highlightProperty(property)
@@ -343,7 +346,7 @@
 
     focusRuleSelector(reverse)
     {
-        if (this.selectorLocked) {
+        if (!this.selectorEditable && !this.locked) {
             this.focus();
             return;
         }
@@ -353,14 +356,20 @@
             return;
         }
 
-        var selection = window.getSelection();
+        let selection = window.getSelection();
         selection.removeAllRanges();
 
         this._element.scrollIntoViewIfNeeded();
 
-        var range = document.createRange();
-        range.selectNodeContents(this._selectorElement);
-        selection.addRange(range);
+        if (this._selectorInput) {
+            this._selectorInput.focus();
+            this._selectorInput.selectionStart = 0;
+            this._selectorInput.selectionEnd = this._selectorInput.value.length;
+        } else {
+            let range = document.createRange();
+            range.selectNodeContents(this._selectorElement);
+            selection.addRange(range);
+        }
     }
 
     selectLastProperty()
@@ -368,9 +377,9 @@
         this._propertiesTextEditor.selectLastProperty();
     }
 
-    get selectorLocked()
+    get selectorEditable()
     {
-        return !this.locked && !this._style.ownerRule;
+        return !this.locked && this._style.ownerRule;
     }
 
     get locked()
@@ -387,7 +396,7 @@
 
     get _currentSelectorText()
     {
-        var selectorText = this._selectorElement.textContent;
+        let selectorText = this.selectorEditable ? this._selectorInput.value : this._selectorElement.textContent;
         if (!selectorText || !selectorText.length) {
             if (!this._style.ownerRule)
                 return "";
@@ -406,17 +415,17 @@
         if (!event || !event.clipboardData)
             return;
 
-        var data = ""
+        let data = ""
         if (!data)
             return;
 
         function parseTextForRule(text)
         {
-            var containsBraces = /[\{\}]/;
+            let containsBraces = /[\{\}]/;
             if (!containsBraces.test(text))
                 return null;
 
-            var match = text.match(/([^{]+){(.*)}/);
+            let match = text.match(/([^{]+){(.*)}/);
             if (!match)
                 return null;
 
@@ -425,13 +434,11 @@
             return containsBraces.test(match[2]) ? parseTextForRule(match[2]) : match;
         }
 
-        var match = parseTextForRule(data);
-        if (!match)
+        let [selector, value] = parseTextForRule(data);
+        if (!selector || !value)
             return;
 
-        var selector = match[1].trim();
-        this._selectorElement.textContent = selector;
-        this._style.nodeStyles.changeRule(this._style.ownerRule, selector, match[2]);
+        this._style.nodeStyles.changeRule(this._style.ownerRule, selector.trim(), value);
         event.preventDefault();
     }
 
@@ -525,12 +532,6 @@
 
     _handleIconElementClicked()
     {
-        if (this._hasInvalidSelector) {
-            // This will revert the selector text to the original valid value.
-            this.refresh();
-            return;
-        }
-
         this._ruleDisabled = this._ruleDisabled ? !this._propertiesTextEditor.uncommentAllProperties() : this._propertiesTextEditor.commentAllProperties();
         this._iconElement.title = this._ruleDisabled ? WebInspector.UIString("Uncomment All Properties") : WebInspector.UIString("Comment All Properties");
         this._element.classList.toggle("rule-disabled", this._ruleDisabled);
@@ -596,7 +597,12 @@
 
     _handleKeyDown(event)
     {
-        if (event.keyCode !== 9) {
+        if (event.keyCode === WebInspector.KeyboardShortcut.Key.Enter.keyCode) {
+            this._selectorInput.blur();
+            return;
+        }
+
+        if (event.keyCode !== WebInspector.KeyboardShortcut.Key.Tab.keyCode) {
             this._highlightNodesWithSelector();
             return;
         }
@@ -615,18 +621,29 @@
         }
     }
 
-    _handleKeyUp(event)
+    _handleKeyPress(event)
     {
+        if (!event.altGraphKey && !event.altKey && !event.ctrlKey && !event.metaKey) {
+            // Ensures that <textarea> does not scroll with added characters.  Since a
+            // <textarea> does not expand to fit its content, appending the pressed character to the
+            // end of the original (non-editable) selector element will ensure that the <textarea>
+            // will be large enough to fit the selector without scrolling.
+            this._selectorElement.append(String.fromCharCode(event.keyCode));
+        }
+    }
+
+    _handleInput(event)
+    {
+        this._selectorElement.textContent = this._selectorInput.value;
+
         this._highlightNodesWithSelector();
     }
 
-    _commitSelector(mutations)
+    _handleBlur()
     {
-        console.assert(this._style.ownerRule);
-        if (!this._style.ownerRule)
-            return;
+        this._hideDOMNodeHighlight();
 
-        var newSelectorText = this._selectorElement.textContent.trim();
+        let newSelectorText = this._currentSelectorText.trim();
         if (!newSelectorText) {
             // Revert to the current selector (by doing a refresh) since the new selector is empty.
             this.refresh();
@@ -636,25 +653,6 @@
         this._style.ownerRule.selectorText = newSelectorText;
     }
 
-    _updateSelectorIcon(event)
-    {
-        if (!this._style.ownerRule || !this._style.editable)
-            return;
-
-        this._hasInvalidSelector = event && event.data && !event.data.valid;
-        this._element.classList.toggle("invalid-selector", !!this._hasInvalidSelector);
-        if (!this._hasInvalidSelector) {
-            this._iconElement.title = this._ruleDisabled ? WebInspector.UIString("Uncomment All Properties") : WebInspector.UIString("Comment All Properties");
-            this._selectorElement.title = null;
-            return;
-        }
-
-        this._iconElement.title = WebInspector.UIString("The selector ā€œ%sā€ is invalid.\nClick to revert to the previous selector.").format(this._selectorElement.textContent.trim());
-        this._selectorElement.title = WebInspector.UIString("Using the previous selector ā€œ%sā€.").format(this._style.ownerRule.selectorText);
-        for (let i = 0; i < this._selectorElement.children.length; ++i)
-            this._selectorElement.children[i].title = null;
-    }
-
     _editorContentChanged(event)
     {
         this._editorActive = true;

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js	2016-09-09 18:25:14 UTC (rev 205754)
@@ -316,10 +316,6 @@
         }
     }
 
-    cssStyleDeclarationSectionBlurActiveEditor()
-    {
-    }
-
     cssStyleDeclarationSectionEditorNextRule(currentSection)
     {
         currentSection.clearSelection();
@@ -331,7 +327,7 @@
     cssStyleDeclarationSectionEditorPreviousRule(currentSection, selectLastProperty) {
         currentSection.clearSelection();
 
-        if (selectLastProperty || currentSection.selectorLocked) {
+        if (selectLastProperty || !currentSection.selectorEditable) {
             var index = this._sections.indexOf(currentSection);
             index = index > 0 ? index - 1 : this._sections.length - 1;
 

Modified: trunk/Source/WebInspectorUI/UserInterface/Views/Variables.css (205753 => 205754)


--- trunk/Source/WebInspectorUI/UserInterface/Views/Variables.css	2016-09-09 18:04:19 UTC (rev 205753)
+++ trunk/Source/WebInspectorUI/UserInterface/Views/Variables.css	2016-09-09 18:25:14 UTC (rev 205754)
@@ -76,6 +76,8 @@
     --toolbar-height: 36px;
     --tab-bar-height: 24px;
     --navigation-bar-height: 29px;
+
+    --style-declaration-section-header-padding: 4px 5px 3px 25px;
 }
 
 body.window-inactive {
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to