Changeset 128746 in webkit


Ignore:
Timestamp:
Sep 17, 2012 5:46:57 AM (12 years ago)
Author:
apavlov@chromium.org
Message:

Web Inspector: Group selectors to highlight matched selector in the Styles pane of Elements Panel
https://bugs.webkit.org/show_bug.cgi?id=96626

Reviewed by Vsevolod Vlasov.

Source/WebCore:

Introduced evaluation of element.webkitMatchesSelector() for every part of a selector group (delimited by commas).
Non-matching selectors in groups are dimmed. If element styles have changed so that the element matches none of the selectors,
the entire group is rendered as matched.

  • inspector/front-end/StylesSidebarPane.js:

(WebInspector.StylesSidebarPane.prototype._innerRebuildUpdate.markCallback):
(WebInspector.StylesSidebarPane.prototype._innerRebuildUpdate):
(WebInspector.StylesSidebarPane.prototype._rebuildStyleRules):
(WebInspector.StylePropertiesSection):
(WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.mycallback):
(WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.trim):
(WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.resolvedCallback):
(WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup):
(WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.matchesCallback):
(WebInspector.StylePropertiesSection.prototype.startEditingSelector):
(WebInspector.StylePropertiesSection.prototype._moveEditorFromSelector.markCallback):
(WebInspector.StylePropertiesSection.prototype._moveEditorFromSelector):
(WebInspector.StylePropertiesSection.prototype.editingSelectorCancelled):

  • inspector/front-end/elementsPanel.css:

(.styles-section .selector):
(.styles-section .selector-matches):

LayoutTests:

  • http/tests/inspector/elements-test.js:

(initialize_ElementTest.InspectorTest.dumpSelectedElementStyles.buildMarkedSelectors):
(initialize_ElementTest.InspectorTest.dumpSelectedElementStyles): Let tests get matched selector markings in dumped data

  • inspector/styles/styles-add-new-rule-expected.txt:
  • inspector/styles/styles-add-new-rule.html:
Location:
trunk
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r128745 r128746  
     12012-09-14  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: Group selectors to highlight matched selector in the Styles pane of Elements Panel
     4        https://bugs.webkit.org/show_bug.cgi?id=96626
     5
     6        Reviewed by Vsevolod Vlasov.
     7
     8        * http/tests/inspector/elements-test.js:
     9        (initialize_ElementTest.InspectorTest.dumpSelectedElementStyles.buildMarkedSelectors):
     10        (initialize_ElementTest.InspectorTest.dumpSelectedElementStyles): Let tests get matched selector markings in dumped data
     11        * inspector/styles/styles-add-new-rule-expected.txt:
     12        * inspector/styles/styles-add-new-rule.html:
     13
    1142012-09-17  Christophe Dumez  <christophe.dumez@intel.com>
    215
  • trunk/LayoutTests/http/tests/inspector/elements-test.js

    r125871 r128746  
    119119}
    120120
    121 InspectorTest.dumpSelectedElementStyles = function(excludeComputed, excludeMatched, omitLonghands)
     121InspectorTest.dumpSelectedElementStyles = function(excludeComputed, excludeMatched, omitLonghands, includeSelectorGroupMarks)
    122122{
    123123    function extractText(element)
     
    128128        element = element.querySelector("[data-uncopyable]");
    129129        return element ? element.getAttribute("data-uncopyable") : "";
     130    }
     131
     132    function buildMarkedSelectors(element)
     133    {
     134        var result = "";
     135        for (var node = element.firstChild; node; node = node.nextSibling) {
     136            if (node.nodeType === Node.ELEMENT_NODE && node.className === "selector-matches")
     137                result += "[$" + node.textContent + "$]";
     138            else
     139                result += node.textContent;
     140        }
     141        return result;
    130142    }
    131143
     
    146158            for (var j = 0; j < chainEntries.length; ++j) {
    147159                var chainEntry = chainEntries[j];
    148                 var entryLine = chainEntry.children[1].textContent;
     160                var entryLine = includeSelectorGroupMarks ? buildMarkedSelectors(chainEntry.children[1]) : chainEntry.children[1].textContent;
    149161                if (chainEntry.children[2])
    150162                    entryLine += " " + chainEntry.children[2].textContent;
  • trunk/LayoutTests/inspector/styles/styles-add-new-rule-expected.txt

    r118367 r128746  
    1010======== Matched CSS Rules ========
    1111[expanded]
    12 #inspected  { (inspector-stylesheet:1)
     12foo, [$#inspected$], bar  { (inspector-stylesheet:1)
    1313color: maroon;
    1414
  • trunk/LayoutTests/inspector/styles/styles-add-new-rule.html

    r122327 r128746  
    1919        document.getElementById("add-style-button-test-id").click();
    2020        var section = WebInspector.panels.elements.sidebarPanes.styles.sections[0][2];
     21        section._selectorElement.textContent = "foo, " + section._selectorElement.textContent + ", bar";
    2122        section._selectorElement.dispatchEvent(InspectorTest.createKeyEvent("Enter"));
    2223        InspectorTest.runAfterPendingDispatches(step2);
     
    4546    {
    4647        InspectorTest.addResult("After adding new rule (inspected):");
    47         InspectorTest.dumpSelectedElementStyles(true, false, true);
     48        InspectorTest.dumpSelectedElementStyles(true, false, true, true);
    4849        InspectorTest.selectNodeAndWaitForStyles("other", step5);
    4950    }
  • trunk/Source/WebCore/ChangeLog

    r128730 r128746  
     12012-09-14  Alexander Pavlov  <apavlov@chromium.org>
     2
     3        Web Inspector: Group selectors to highlight matched selector in the Styles pane of Elements Panel
     4        https://bugs.webkit.org/show_bug.cgi?id=96626
     5
     6        Reviewed by Vsevolod Vlasov.
     7
     8        Introduced evaluation of element.webkitMatchesSelector() for every part of a selector group (delimited by commas).
     9        Non-matching selectors in groups are dimmed. If element styles have changed so that the element matches none of the selectors,
     10        the entire group is rendered as matched.
     11
     12        * inspector/front-end/StylesSidebarPane.js:
     13        (WebInspector.StylesSidebarPane.prototype._innerRebuildUpdate.markCallback):
     14        (WebInspector.StylesSidebarPane.prototype._innerRebuildUpdate):
     15        (WebInspector.StylesSidebarPane.prototype._rebuildStyleRules):
     16        (WebInspector.StylePropertiesSection):
     17        (WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.mycallback):
     18        (WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.trim):
     19        (WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.resolvedCallback):
     20        (WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup):
     21        (WebInspector.StylePropertiesSection.prototype._markMatchedSelectorsInGroup.matchesCallback):
     22        (WebInspector.StylePropertiesSection.prototype.startEditingSelector):
     23        (WebInspector.StylePropertiesSection.prototype._moveEditorFromSelector.markCallback):
     24        (WebInspector.StylePropertiesSection.prototype._moveEditorFromSelector):
     25        (WebInspector.StylePropertiesSection.prototype.editingSelectorCancelled):
     26        * inspector/front-end/elementsPanel.css:
     27        (.styles-section .selector):
     28        (.styles-section .selector-matches):
     29
    1302012-09-17  Mike West  <mkwst@chromium.org>
    231
  • trunk/Source/WebCore/inspector/front-end/StylesSidebarPane.js

    r128407 r128746  
    359359        this._markUsedProperties(styleRules, usedProperties);
    360360        this.sections[0] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, 0, null);
     361        var responsesLeft = this.sections[0].length;
    361362        var anchorElement = this.sections[0].inheritedPropertiesSeparatorElement;
    362363
     
    381382            this._markUsedProperties(styleRules, usedProperties);
    382383            this.sections[pseudoId] = this._rebuildSectionsForStyleRules(styleRules, usedProperties, pseudoId, anchorElement);
    383         }
    384 
    385         this._nodeStylesUpdatedForTest(node, true);
     384            responsesLeft += this.sections[pseudoId].length;
     385        }
     386
     387        // Mark matching selectors in comma-delimited selector groups.
     388        var boundMarkCallback = markCallback.bind(this);
     389        for (var id in this.sections) {
     390            var sectionsForPseudoId = this.sections[id].slice();
     391            for (var j = 0; j < sectionsForPseudoId.length; ++j) {
     392                var section = sectionsForPseudoId[j];
     393                if (!section.styleRule || section.isBlank || section.styleRule.computedStyle || section.styleRule.isAttribute) {
     394                    boundMarkCallback();
     395                    continue;
     396                }
     397                section._markMatchedSelectorsInGroup(boundMarkCallback);
     398            }
     399        }
     400
     401        function markCallback()
     402        {
     403            if (!(--responsesLeft))
     404                this._nodeStylesUpdatedForTest(node, true);
     405        }
    386406    },
    387407
     
    465485            if (parentStyles.inlineStyle) {
    466486                if (this._containsInherited(parentStyles.inlineStyle)) {
    467                     var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: parentStyles.inlineStyle, isAttribute: true, isInherited: true };
     487                    var inlineStyle = { selectorText: WebInspector.UIString("Style Attribute"), style: parentStyles.inlineStyle, isAttribute: true, isInherited: true, parentNode: parentNode };
    468488                    if (!separatorInserted) {
    469489                        insertInheritedNodeSeparator(parentNode);
     
    486506                    separatorInserted = true;
    487507                }
    488                 styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.sourceURL, rule: rule, isInherited: true, editable: !!(rule.style && rule.style.id) });
     508                styleRules.push({ style: rule.style, selectorText: rule.selectorText, media: rule.media, sourceURL: rule.sourceURL, rule: rule, isInherited: true, parentNode: parentNode, editable: !!(rule.style && rule.style.id) });
    489509            }
    490510            parentNode = parentNode.parentNode;
     
    874894    var selectorContainer = document.createElement("div");
    875895    this._selectorElement = document.createElement("span");
     896    this._selectorElement.addStyleClass("selector-matches");
    876897    this._selectorElement.textContent = styleRule.selectorText;
    877898    selectorContainer.appendChild(this._selectorElement);
     
    914935
    915936    if (isInherited)
    916         this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not compted style.
     937        this.element.addStyleClass("show-inherited"); // This one is related to inherited rules, not computed style.
    917938
    918939    if (!this.editable)
     
    11041125    },
    11051126
     1127    /**
     1128     * @param {function()=} callback
     1129     */
     1130    _markMatchedSelectorsInGroup: function(callback)
     1131    {
     1132        var self = this;
     1133        function mycallback()
     1134        {
     1135            if (callback)
     1136                callback();
     1137        }
     1138
     1139        var selectorText = this._selectorElement.textContent;
     1140        if (!selectorText || selectorText.indexOf(",") === -1) {
     1141            mycallback();
     1142            return;
     1143        }
     1144
     1145        var paneNode = this._parentPane.node;
     1146        var relatedNode = this.styleRule.parentNode || paneNode;
     1147        if (!relatedNode) {
     1148            mycallback();
     1149            return;
     1150        }
     1151
     1152        function trim(text)
     1153        {
     1154            return text.trim();
     1155        }
     1156        var selectors = selectorText.split(",").map(trim);
     1157
     1158        WebInspector.RemoteObject.resolveNode(relatedNode, "", resolvedCallback);
     1159        function resolvedCallback(object)
     1160        {
     1161            if (!object) {
     1162                mycallback();
     1163                return;
     1164            }
     1165
     1166            for (var i = 0, size = selectors.length; i < size; ++i) {
     1167                var selector = selectors[i];
     1168                object.callFunctionJSON(matchesSelector, [{ value: selectors[i] }], matchesCallback.bind(this, i));
     1169            }
     1170        }
     1171
     1172        function matchesSelector(selector)
     1173        {
     1174            return this.webkitMatchesSelector(selector);
     1175        }
     1176
     1177        var result = [];
     1178        var matchFound;
     1179        function matchesCallback(selectorIndex, matches)
     1180        {
     1181            var isLast = selectorIndex === selectors.length - 1;
     1182            var fragment = document.createDocumentFragment();
     1183            result[selectorIndex] = fragment;
     1184
     1185            var selectorNode;
     1186            if (matches && paneNode === self._parentPane.node) {
     1187                selectorNode = document.createElement("span");
     1188                selectorNode.className = "selector-matches";
     1189                selectorNode.appendChild(document.createTextNode(selectors[selectorIndex]));
     1190                matchFound = true;
     1191            } else
     1192                selectorNode = document.createTextNode(selectors[selectorIndex]);
     1193
     1194            fragment.appendChild(selectorNode);
     1195            if (!isLast) {
     1196                fragment.appendChild(document.createTextNode(", "));
     1197                return;
     1198            }
     1199
     1200            // This check is here in case the element class has been changed from JS during the roundtrip,
     1201            // so the element matches none of the distinct selectors. Fall back to "all selectors match".
     1202            if (matchFound) {
     1203                self._selectorElement.className = "selector";
     1204                self._selectorElement.removeChildren();
     1205                for (var i = 0; i < result.length; ++i)
     1206                    self._selectorElement.appendChild(result[i]);
     1207            }
     1208            mycallback();
     1209        }
     1210    },
     1211
    11061212    _checkWillCancelEditing: function()
    11071213    {
     
    12341340            return;
    12351341
    1236         this._selectorElement.scrollIntoViewIfNeeded(false);
     1342        element.scrollIntoViewIfNeeded(false);
     1343        element.textContent = element.textContent; // Reset selector marks in group.
    12371344
    12381345        var config = new WebInspector.EditingConfig(this.editingSelectorCommitted.bind(this), this.editingSelectorCancelled.bind(this));
     
    12441351    _moveEditorFromSelector: function(moveDirection)
    12451352    {
    1246         if (!moveDirection)
    1247             return;
    1248 
    1249         if (moveDirection === "forward") {
    1250             this.expand();
    1251             var firstChild = this.propertiesTreeOutline.children[0];
    1252             while (firstChild && firstChild.inherited)
    1253                 firstChild = firstChild.nextSibling;
    1254             if (!firstChild)
    1255                 this.addNewBlankProperty().startEditing();
    1256             else
    1257                 firstChild.startEditing(firstChild.nameElement);
    1258         } else {
    1259             var previousSection = this.previousEditableSibling();
    1260             if (!previousSection)
    1261                 return;
    1262 
    1263             previousSection.expand();
    1264             previousSection.addNewBlankProperty().startEditing();
     1353
     1354        if (!moveDirection) {
     1355            this._markMatchedSelectorsInGroup();
     1356            return;
     1357        }
     1358
     1359        this._markMatchedSelectorsInGroup(markCallback.bind(this));
     1360
     1361        function markCallback() {
     1362            if (moveDirection === "forward") {
     1363                this.expand();
     1364                var firstChild = this.propertiesTreeOutline.children[0];
     1365                while (firstChild && firstChild.inherited)
     1366                    firstChild = firstChild.nextSibling;
     1367                if (!firstChild)
     1368                    this.addNewBlankProperty().startEditing();
     1369                else
     1370                    firstChild.startEditing(firstChild.nameElement);
     1371            } else {
     1372                var previousSection = this.previousEditableSibling();
     1373                if (!previousSection)
     1374                    return;
     1375
     1376                previousSection.expand();
     1377                previousSection.addNewBlankProperty().startEditing();
     1378            }
    12651379        }
    12661380    },
     
    13001414    editingSelectorCancelled: function()
    13011415    {
    1302         // Do nothing, this is overridden by BlankStylePropertiesSection.
     1416        // Do nothing but mark the selectors in group if necessary.
     1417        // This is overridden by BlankStylePropertiesSection.
     1418        this._markMatchedSelectorsInGroup();
    13031419    }
    13041420}
  • trunk/Source/WebCore/inspector/front-end/elementsPanel.css

    r126193 r128746  
    224224}
    225225
     226.styles-section .selector {
     227    color: #777;
     228}
     229
     230.styles-section .selector-matches {
     231    color: black;
     232}
     233
    226234.styles-section a[data-uncopyable] {
    227235    display: inline-block;
Note: See TracChangeset for help on using the changeset viewer.