Changeset 205754 in webkit


Ignore:
Timestamp:
Sep 9, 2016 11:25:14 AM (8 years ago)
Author:
commit-queue@webkit.org
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 <Devin Rousso> 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.

Location:
trunk/Source/WebInspectorUI
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r205693 r205754  
     12016-09-09  Devin Rousso  <dcrousso+webkit@gmail.com>
     2
     3        Web Inspector: Command-Z doesn't work when editing CSS selectors in Styles sidebar
     4        https://bugs.webkit.org/show_bug.cgi?id=159734
     5
     6        Reviewed by Brian Burg.
     7
     8        Replace the current usage of -webkit-user-select with a textarea sized exactly the same as
     9        the selector text which holds the current value of the selector.
     10
     11        * UserInterface/Test.html: Add WrappedPromise.
     12
     13        * UserInterface/Models/DOMNodeStyles.js:
     14        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedMatchedStyles):
     15        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedInlineStyles):
     16        (WebInspector.DOMNodeStyles.prototype.refresh.fetchedComputedStyle):
     17        (WebInspector.DOMNodeStyles.prototype.refresh):
     18        (WebInspector.DOMNodeStyles.prototype.changeRuleSelector.ruleSelectorChanged):
     19        (WebInspector.DOMNodeStyles.prototype.changeRuleSelector):
     20        Ensure that the promise returned by changeRuleSelector is only resolved once the initiated
     21        refresh has completed, ensuring that all matched selectors are parsed and available.
     22
     23        * UserInterface/Views/CSSStyleDeclarationSection.css:
     24        (.style-declaration-section > .header):
     25        (.style-declaration-section.locked > .header::before):
     26        (.style-declaration-section.rule-disabled > .header > .icon):
     27        (.style-declaration-section > .header > textarea):
     28        (.style-declaration-section > .header > textarea:focus):
     29        (.style-declaration-section > .header > textarea:focus + .selector):
     30        (.style-declaration-section > .header > .selector):
     31        (.style-declaration-section > .header > .selector:empty):
     32        (.style-declaration-section > .header > .selector .matched):
     33        (.style-declaration-section:not(.invalid-selector).rule-disabled > .header > .icon): Deleted.
     34        (.style-declaration-section > .header > .selector:empty::before): Deleted.
     35        (.style-declaration-section > .header > .selector:focus): Deleted.
     36        (.style-declaration-section:matches(.locked, .selector-locked) > .header > .selector): Deleted.
     37        (.style-declaration-section > .header > .selector > .matched): Deleted.
     38        (.style-declaration-section.invalid-selector > .header > .icon): Deleted.
     39        (.style-declaration-section.invalid-selector > .header > .selector): Deleted.
     40        Added styling to make textarea invisible when not focused.
     41        Also removed the .invalid-selector styles as the section now refreshed on all changes.
     42
     43        * UserInterface/Views/CSSStyleDeclarationSection.js:
     44        (WebInspector.CSSStyleDeclarationSection):
     45        (WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelector):
     46        (WebInspector.CSSStyleDeclarationSection.prototype.refresh.appendSelectorTextKnownToMatch):
     47        (WebInspector.CSSStyleDeclarationSection.prototype.refresh):
     48        (WebInspector.CSSStyleDeclarationSection.prototype.focusRuleSelector):
     49        (WebInspector.CSSStyleDeclarationSection.prototype.get selectorEditable):
     50        (WebInspector.CSSStyleDeclarationSection.prototype.get _currentSelectorText):
     51        (WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste.parseTextForRule):
     52        (WebInspector.CSSStyleDeclarationSection.prototype._handleSelectorPaste):
     53        (WebInspector.CSSStyleDeclarationSection.prototype.get selectorLocked): Deleted.
     54        Added a hidden textarea for modifying the selector of the represented style.
     55
     56        * UserInterface/Views/RulesStyleDetailsPanel.js:
     57        (WebInspector.RulesStyleDetailsPanel.prototype.cssStyleDeclarationSectionEditorPreviousRule):
     58        Now use new getters on CSSSTyleDeclarationSection for determining if a selector is editable.
     59
     60        * UserInterface/Views/Variables.css:
     61        (:root):
     62        Added --style-declaration-section-header-padding CSS variable.
     63
    1642016-09-08  Brian Burg  <bburg@apple.com>
    265
  • trunk/Source/WebInspectorUI/UserInterface/Models/DOMNodeStyles.js

    r205426 r205754  
    4646        this._propertyNameToEffectivePropertyMap = {};
    4747
     48        this._pendingRefreshTask = null;
    4849        this.refresh();
    4950    }
     
    5859    get needsRefresh()
    5960    {
    60         return this._refreshPending || this._needsRefresh;
     61        return this._pendingRefreshTask || this._needsRefresh;
    6162    }
    6263
     
    7071    refresh()
    7172    {
    72         if (this._refreshPending)
    73             return;
     73        if (this._pendingRefreshTask)
     74            return this._pendingRefreshTask;
    7475
    7576        this._needsRefresh = false;
    76         this._refreshPending = true;
     77
     78        let fetchedMatchedStylesPromise = new WebInspector.WrappedPromise;
     79        let fetchedInlineStylesPromise = new WebInspector.WrappedPromise;
     80        let fetchedComputedStylesPromise = new WebInspector.WrappedPromise;
    7781
    7882        function parseRuleMatchArrayPayload(matchArray, node, inherited)
     
    131135                ++i;
    132136            }
     137
     138            fetchedMatchedStylesPromise.resolve();
    133139        }
    134140
     
    139145
    140146            this._updateStyleCascade();
     147
     148            fetchedComputedStylesPromise.resolve();
    141149        }
    142150
     
    160168            else
    161169                this._computedStyle = new WebInspector.CSSStyleDeclaration(this, null, null, WebInspector.CSSStyleDeclaration.Type.Computed, this._node, false, null, properties);
    162 
    163             this._refreshPending = false;
    164170
    165171            let significantChange = false;
     
    227233
    228234            this.dispatchEventToListeners(WebInspector.DOMNodeStyles.Event.Refreshed, {significantChange});
     235
     236            fetchedComputedStylesPromise.resolve();
    229237        }
    230238
     
    235243        CSSAgent.getInlineStylesForNode.invoke({nodeId: this._node.id}, fetchedInlineStyles.bind(this));
    236244        CSSAgent.getComputedStyleForNode.invoke({nodeId: this._node.id}, fetchedComputedStyle.bind(this));
     245
     246        this._pendingRefreshTask = Promise.all([fetchedMatchedStylesPromise, fetchedInlineStylesPromise, fetchedComputedStylesPromise])
     247        .then(() => {
     248            this._pendingRefreshTask = null;
     249        });
     250
     251        return this._pendingRefreshTask;
    237252    }
    238253
     
    409424    {
    410425        selector = selector || "";
    411         var result = new WebInspector.WrappedPromise;
     426        let result = new WebInspector.WrappedPromise;
    412427
    413428        function ruleSelectorChanged(error, rulePayload)
     
    422437            // Do a full refresh incase the rule no longer matches the node or the
    423438            // matched selector indices changed.
    424             this.refresh();
    425 
    426             result.resolve(rulePayload);
     439            this.refresh().then(() => {
     440                result.resolve(rulePayload);
     441            });
    427442        }
    428443
  • trunk/Source/WebInspectorUI/UserInterface/Test.html

    r205418 r205754  
    162162    <script src="Models/TimelineMarker.js"></script>
    163163    <script src="Models/TimelineRecording.js"></script>
     164    <script src="Models/WrappedPromise.js"></script>
    164165
    165166    <script src="Proxies/FormatterWorkerProxy.js"></script>
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.css

    r194437 r205754  
    5656.style-declaration-section > .header {
    5757    position: relative;
    58 
    59     padding: 4px 5px 3px 25px;
    60 
     58    padding: var(--style-declaration-section-header-padding);
    6159    font-size: 11px;
    6260    line-height: 12px;
     61}
     62
     63.style-declaration-section.locked > .header::before {
     64    float: right;
     65    width: 8px;
     66    height: 10px;
     67    margin-left: 5px;
     68    content: "";
     69    background-image: url(../Images/Locked.svg);
     70    background-repeat: no-repeat;
     71    background-position: center;
     72    background-size: 8px 10px;
    6373}
    6474
     
    8191}
    8292
    83 .style-declaration-section:not(.invalid-selector).rule-disabled > .header > .icon {
     93.style-declaration-section.rule-disabled > .header > .icon {
    8494    opacity: 0.5;
     95}
     96
     97.style-declaration-section > .header > textarea {
     98    display: block;
     99    position: absolute;
     100    top: 0;
     101    right: 0;
     102    bottom: 0;
     103    left: 0;
     104    width: 100%;
     105    height: 100%;
     106    margin: 0;
     107    padding: var(--style-declaration-section-header-padding);
     108    font-family: Menlo, monospace;
     109    color: black;
     110    background: transparent;
     111    border: none;
     112    outline: none;
     113    opacity: 0;
     114    resize: none;
     115    -webkit-appearance: none;
     116}
     117
     118.style-declaration-section > .header > textarea:focus {
     119    opacity: 1;
     120}
     121
     122.style-declaration-section > .header > textarea:focus + .selector {
     123    opacity: 0;
    85124}
    86125
     
    88127    font-family: Menlo, monospace;
    89128    color: hsl(0, 0%, 50%);
    90 
    91     outline: none;
    92 
    93     cursor: text;
    94 
    95129    word-wrap: break-word;
    96 
    97     -webkit-user-select: text;
    98     -webkit-user-modify: read-write-plaintext-only;
    99 }
    100 
    101 .style-declaration-section > .header > .selector:empty {
    102     /* This prevents the cursor from disappearing when empty. */
    103     display: inline-block;
    104     min-width: 1px;
    105 }
    106 
    107 .style-declaration-section > .header > .selector:empty::before {
    108     /* This prevents the cursor from positioning badly when empty. */
    109     content: "";
    110 }
    111 
    112 .style-declaration-section > .header > .selector:focus {
    113     color: black;
    114 }
    115 
    116 .style-declaration-section:matches(.locked, .selector-locked) > .header > .selector {
    117     -webkit-user-modify: read-only;
    118 }
    119 
    120 .style-declaration-section.locked > .header::before {
    121     float: right;
    122 
    123     content: "";
    124 
    125     width: 8px;
    126     height: 10px;
    127 
    128     background-image: url(../Images/Locked.svg);
    129     background-repeat: no-repeat;
    130     background-position: center;
    131     background-size: 8px 10px;
    132 
    133     margin-left: 5px;
    134130}
    135131
     
    155151}
    156152
    157 .style-declaration-section.invalid-selector > .header > .icon {
    158     top: 4px;
    159     left: 6px;
    160     width: 12px;
    161     height: 12px;
    162     content: url(../Images/Error.svg);
    163 }
    164 
    165 .style-declaration-section.invalid-selector > .header > .selector,
    166 .style-declaration-section.invalid-selector > .header > .selector> * {
    167     color: red;
    168 }
    169 
    170153@media (-webkit-min-device-pixel-ratio: 2) {
    171154    .style-declaration-section,
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDeclarationSection.js

    r205425 r205754  
    3737        this._selectorElements = [];
    3838        this._ruleDisabled = false;
    39         this._hasInvalidSelector = false;
    4039
    4140        this._element = document.createElement("div");
     
    4847        this._headerElement.classList.add("header");
    4948
    50         this._iconElement = document.createElement("img");
    51         this._iconElement.classList.add("icon");
    52         this._headerElement.appendChild(this._iconElement);
    53 
    54         this._selectorElement = document.createElement("span");
    55         this._selectorElement.classList.add("selector");
    56         this._selectorElement.setAttribute("spellcheck", "false");
    57         this._selectorElement.addEventListener("mouseover", this._handleMouseOver.bind(this));
    58         this._selectorElement.addEventListener("mouseout", this._handleMouseOut.bind(this));
    59         this._selectorElement.addEventListener("keydown", this._handleKeyDown.bind(this));
    60         this._selectorElement.addEventListener("keyup", this._handleKeyUp.bind(this));
    61         this._selectorElement.addEventListener("paste", this._handleSelectorPaste.bind(this));
    62         this._headerElement.appendChild(this._selectorElement);
    63 
    64         this._originElement = document.createElement("span");
    65         this._originElement.classList.add("origin");
    66         this._headerElement.appendChild(this._originElement);
     49        this._iconElement = this._headerElement.createChild("img", "icon");
     50
     51        if (this.selectorEditable) {
     52            this._selectorInput = this._headerElement.createChild("textarea");
     53            this._selectorInput.spellcheck = false;
     54            this._selectorInput.tabIndex = -1;
     55            this._selectorInput.addEventListener("mouseover", this._handleMouseOver.bind(this));
     56            this._selectorInput.addEventListener("mouseout", this._handleMouseOut.bind(this));
     57            this._selectorInput.addEventListener("keydown", this._handleKeyDown.bind(this));
     58            this._selectorInput.addEventListener("keypress", this._handleKeyPress.bind(this));
     59            this._selectorInput.addEventListener("input", this._handleInput.bind(this));
     60            this._selectorInput.addEventListener("paste", this._handleSelectorPaste.bind(this));
     61            this._selectorInput.addEventListener("blur", this._handleBlur.bind(this));
     62        }
     63
     64        this._selectorElement = this._headerElement.createChild("span", "selector");
     65        if (!this.selectorEditable) {
     66            this._selectorElement.addEventListener("mouseover", this._handleMouseOver.bind(this));
     67            this._selectorElement.addEventListener("mouseout", this._handleMouseOut.bind(this));
     68        }
     69
     70        this._originElement = this._headerElement.createChild("span", "origin");
    6771
    6872        this._propertiesElement = document.createElement("div");
     
    7882        this._element.appendChild(this._propertiesElement);
    7983
    80         var iconClassName;
     84        let iconClassName = null;
    8185        switch (style.type) {
    8286        case WebInspector.CSSStyleDeclaration.Type.Rule:
     
    115119        if (!style.editable)
    116120            this._element.classList.add(WebInspector.CSSStyleDeclarationSection.LockedStyleClassName);
    117         else if (style.ownerRule) {
    118             this._style.ownerRule.addEventListener(WebInspector.CSSRule.Event.SelectorChanged, this._updateSelectorIcon.bind(this));
    119             this._commitSelectorKeyboardShortcut = new WebInspector.KeyboardShortcut(null, WebInspector.KeyboardShortcut.Key.Enter, this._commitSelector.bind(this), this._selectorElement);
    120             this._selectorElement.addEventListener("blur", this._commitSelector.bind(this));
    121         } else
     121        else if (style.ownerRule)
     122            this._style.ownerRule.addEventListener(WebInspector.CSSRule.Event.SelectorChanged, this.refresh.bind(this));
     123        else
    122124            this._element.classList.add(WebInspector.CSSStyleDeclarationSection.SelectorLockedStyleClassName);
    123125
     
    168170        this._selectorElements = [];
    169171
    170         this._originElement.append(" \u2014 ");
     172        this._originElement.append(` ${emDash} `);
    171173
    172174        function appendSelector(selector, matched)
     
    174176            console.assert(selector instanceof WebInspector.CSSSelector);
    175177
    176             var selectorElement = document.createElement("span");
     178            let selectorElement = document.createElement("span");
    177179            selectorElement.textContent = selector.text;
    178180
     
    180182                selectorElement.classList.add(WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
    181183
    182             var specificity = selector.specificity;
     184            let specificity = selector.specificity;
    183185            if (specificity) {
    184                 var tooltip = WebInspector.UIString("Specificity: (%d, %d, %d)").format(specificity[0], specificity[1], specificity[2]);
     186                let tooltip = WebInspector.UIString("Specificity: (%d, %d, %d)").format(specificity[0], specificity[1], specificity[2]);
    185187                if (selector.dynamic) {
    186188                    tooltip += "\n";
     
    192194                selectorElement.title = tooltip;
    193195            } else if (selector.dynamic) {
    194                 var tooltip = WebInspector.UIString("Specificity: No value for selected element");
     196                let tooltip = WebInspector.UIString("Specificity: No value for selected element");
    195197                tooltip += "\n";
    196198                tooltip += WebInspector.UIString("Dynamically calculated for the selected element and did not match");
     
    204206        function appendSelectorTextKnownToMatch(selectorText)
    205207        {
    206             var selectorElement = document.createElement("span");
     208            let selectorElement = document.createElement("span");
    207209            selectorElement.textContent = selectorText;
    208210            selectorElement.classList.add(WebInspector.CSSStyleDeclarationSection.MatchedSelectorElementStyleClassName);
     
    214216            console.assert(this._style.ownerRule);
    215217
    216             var selectors = this._style.ownerRule.selectors;
    217             var matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
    218             var alwaysMatch = !matchedSelectorIndices.length;
     218            let selectors = this._style.ownerRule.selectors;
     219            let matchedSelectorIndices = this._style.ownerRule.matchedSelectorIndices;
     220            let alwaysMatch = !matchedSelectorIndices.length;
    219221            if (selectors.length) {
    220                 var hasMatchingPseudoElementSelector = false;
    221                 for (var i = 0; i < selectors.length; ++i) {
     222                let hasMatchingPseudoElementSelector = false;
     223                for (let i = 0; i < selectors.length; ++i) {
    222224                    appendSelector.call(this, selectors[i], alwaysMatch || matchedSelectorIndices.includes(i));
    223225                    if (i < selectors.length - 1)
     
    232234
    233235            if (this._style.ownerRule.sourceCodeLocation) {
    234                 var sourceCodeLink = WebInspector.createSourceCodeLocationLink(this._style.ownerRule.sourceCodeLocation, true);
     236                let sourceCodeLink = WebInspector.createSourceCodeLocationLink(this._style.ownerRule.sourceCodeLocation, true);
    235237                this._originElement.appendChild(sourceCodeLink);
    236238            } else {
    237                 var originString;
     239                let originString;
    238240                switch (this._style.ownerRule.type) {
    239241                case WebInspector.CSSStyleSheet.Type.Author:
     
    272274        }
    273275
    274         this._updateSelectorIcon();
     276        if (this._selectorInput)
     277            this._selectorInput.value = this._selectorElement.textContent;
    275278    }
    276279
     
    344347    focusRuleSelector(reverse)
    345348    {
    346         if (this.selectorLocked) {
     349        if (!this.selectorEditable && !this.locked) {
    347350            this.focus();
    348351            return;
     
    354357        }
    355358
    356         var selection = window.getSelection();
     359        let selection = window.getSelection();
    357360        selection.removeAllRanges();
    358361
    359362        this._element.scrollIntoViewIfNeeded();
    360363
    361         var range = document.createRange();
    362         range.selectNodeContents(this._selectorElement);
    363         selection.addRange(range);
     364        if (this._selectorInput) {
     365            this._selectorInput.focus();
     366            this._selectorInput.selectionStart = 0;
     367            this._selectorInput.selectionEnd = this._selectorInput.value.length;
     368        } else {
     369            let range = document.createRange();
     370            range.selectNodeContents(this._selectorElement);
     371            selection.addRange(range);
     372        }
    364373    }
    365374
     
    369378    }
    370379
    371     get selectorLocked()
    372     {
    373         return !this.locked && !this._style.ownerRule;
     380    get selectorEditable()
     381    {
     382        return !this.locked && this._style.ownerRule;
    374383    }
    375384
     
    388397    get _currentSelectorText()
    389398    {
    390         var selectorText = this._selectorElement.textContent;
     399        let selectorText = this.selectorEditable ? this._selectorInput.value : this._selectorElement.textContent;
    391400        if (!selectorText || !selectorText.length) {
    392401            if (!this._style.ownerRule)
     
    407416            return;
    408417
    409         var data = event.clipboardData.getData("text/plain");
     418        let data = event.clipboardData.getData("text/plain");
    410419        if (!data)
    411420            return;
     
    413422        function parseTextForRule(text)
    414423        {
    415             var containsBraces = /[\{\}]/;
     424            let containsBraces = /[\{\}]/;
    416425            if (!containsBraces.test(text))
    417426                return null;
    418427
    419             var match = text.match(/([^{]+){(.*)}/);
     428            let match = text.match(/([^{]+){(.*)}/);
    420429            if (!match)
    421430                return null;
     
    426435        }
    427436
    428         var match = parseTextForRule(data);
    429         if (!match)
    430             return;
    431 
    432         var selector = match[1].trim();
    433         this._selectorElement.textContent = selector;
    434         this._style.nodeStyles.changeRule(this._style.ownerRule, selector, match[2]);
     437        let [selector, value] = parseTextForRule(data);
     438        if (!selector || !value)
     439            return;
     440
     441        this._style.nodeStyles.changeRule(this._style.ownerRule, selector.trim(), value);
    435442        event.preventDefault();
    436443    }
     
    526533    _handleIconElementClicked()
    527534    {
    528         if (this._hasInvalidSelector) {
    529             // This will revert the selector text to the original valid value.
    530             this.refresh();
    531             return;
    532         }
    533 
    534535        this._ruleDisabled = this._ruleDisabled ? !this._propertiesTextEditor.uncommentAllProperties() : this._propertiesTextEditor.commentAllProperties();
    535536        this._iconElement.title = this._ruleDisabled ? WebInspector.UIString("Uncomment All Properties") : WebInspector.UIString("Comment All Properties");
     
    597598    _handleKeyDown(event)
    598599    {
    599         if (event.keyCode !== 9) {
     600        if (event.keyCode === WebInspector.KeyboardShortcut.Key.Enter.keyCode) {
     601            this._selectorInput.blur();
     602            return;
     603        }
     604
     605        if (event.keyCode !== WebInspector.KeyboardShortcut.Key.Tab.keyCode) {
    600606            this._highlightNodesWithSelector();
    601607            return;
     
    616622    }
    617623
    618     _handleKeyUp(event)
    619     {
     624    _handleKeyPress(event)
     625    {
     626        if (!event.altGraphKey && !event.altKey && !event.ctrlKey && !event.metaKey) {
     627            // Ensures that <textarea> does not scroll with added characters.  Since a
     628            // <textarea> does not expand to fit its content, appending the pressed character to the
     629            // end of the original (non-editable) selector element will ensure that the <textarea>
     630            // will be large enough to fit the selector without scrolling.
     631            this._selectorElement.append(String.fromCharCode(event.keyCode));
     632        }
     633    }
     634
     635    _handleInput(event)
     636    {
     637        this._selectorElement.textContent = this._selectorInput.value;
     638
    620639        this._highlightNodesWithSelector();
    621640    }
    622641
    623     _commitSelector(mutations)
    624     {
    625         console.assert(this._style.ownerRule);
    626         if (!this._style.ownerRule)
    627             return;
    628 
    629         var newSelectorText = this._selectorElement.textContent.trim();
     642    _handleBlur()
     643    {
     644        this._hideDOMNodeHighlight();
     645
     646        let newSelectorText = this._currentSelectorText.trim();
    630647        if (!newSelectorText) {
    631648            // Revert to the current selector (by doing a refresh) since the new selector is empty.
     
    635652
    636653        this._style.ownerRule.selectorText = newSelectorText;
    637     }
    638 
    639     _updateSelectorIcon(event)
    640     {
    641         if (!this._style.ownerRule || !this._style.editable)
    642             return;
    643 
    644         this._hasInvalidSelector = event && event.data && !event.data.valid;
    645         this._element.classList.toggle("invalid-selector", !!this._hasInvalidSelector);
    646         if (!this._hasInvalidSelector) {
    647             this._iconElement.title = this._ruleDisabled ? WebInspector.UIString("Uncomment All Properties") : WebInspector.UIString("Comment All Properties");
    648             this._selectorElement.title = null;
    649             return;
    650         }
    651 
    652         this._iconElement.title = WebInspector.UIString("The selector “%s” is invalid.\nClick to revert to the previous selector.").format(this._selectorElement.textContent.trim());
    653         this._selectorElement.title = WebInspector.UIString("Using the previous selector “%s”.").format(this._style.ownerRule.selectorText);
    654         for (let i = 0; i < this._selectorElement.children.length; ++i)
    655             this._selectorElement.children[i].title = null;
    656654    }
    657655
  • trunk/Source/WebInspectorUI/UserInterface/Views/RulesStyleDetailsPanel.js

    r205425 r205754  
    317317    }
    318318
    319     cssStyleDeclarationSectionBlurActiveEditor()
    320     {
    321     }
    322 
    323319    cssStyleDeclarationSectionEditorNextRule(currentSection)
    324320    {
     
    332328        currentSection.clearSelection();
    333329
    334         if (selectLastProperty || currentSection.selectorLocked) {
     330        if (selectLastProperty || !currentSection.selectorEditable) {
    335331            var index = this._sections.indexOf(currentSection);
    336332            index = index > 0 ? index - 1 : this._sections.length - 1;
  • trunk/Source/WebInspectorUI/UserInterface/Views/Variables.css

    r202064 r205754  
    7777    --tab-bar-height: 24px;
    7878    --navigation-bar-height: 29px;
     79
     80    --style-declaration-section-header-padding: 4px 5px 3px 25px;
    7981}
    8082
Note: See TracChangeset for help on using the changeset viewer.