Changeset 195432 in webkit


Ignore:
Timestamp:
Jan 21, 2016 6:06:49 PM (8 years ago)
Author:
commit-queue@webkit.org
Message:

Web Inspector: Add toggle-able list of classes for each element
https://bugs.webkit.org/show_bug.cgi?id=152678

Patch by Devin Rousso <Devin Rousso> on 2016-01-21
Reviewed by Timothy Hatcher.

Adds a button to the CSS sidebar that, when toggled, displays a section
directly above it containing all the classes for the selected node that,
when toggled, adds or removes the class from the node.

  • Localizations/en.lproj/localizedStrings.js:
  • UserInterface/Protocol/RemoteObject.js:

(WebInspector.RemoteObject.prototype.callFunction.mycallback):
(WebInspector.RemoteObject.prototype.callFunction):
Add extra handling of arguments to allow nicer looking calls by other classes.

  • UserInterface/Views/CSSStyleDetailsSidebarPanel.css:

Changed next-sibling selector (+) to general-sibling selector (~).

(.sidebar > .panel.details.css-style > .content ~ :matches(.options-container, .class-list-container)):
(.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :matches(.options-container, .class-list-container)):
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle):
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected):
(.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container[hidden]):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > input[type="checkbox"]):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .add-class-icon):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class:not(.active) > .class-name-input):
(.sidebar > .panel.details.css-style > .content ~ .class-list-container > *:matches(.new-class, .class-toggle)):

  • UserInterface/Views/CSSStyleDetailsSidebarPanel.js:

(WebInspector.CSSStyleDetailsSidebarPanel):
Also changed the few instances of "var" to "let".

(WebInspector.CSSStyleDetailsSidebarPanel.prototype.refresh):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype.addEventListeners):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._handleNodeAttributeModified):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._handleNodeAttributeRemoved):
Adds listeners to the DOMNode specifically listening for changes to the
class attribute and repopulates the class toggle list if fired.

(WebInspector.CSSStyleDetailsSidebarPanel.prototype._classToggleButtonClicked):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassContainerClicked):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassInputKeyPressed):
If the Enter key is pressed, add a new class equal to the input value.

(WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassInputBlur):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._populateClassToggles):
Loops through all the classes, including previously removed ones, for the
selected node and creates a toggle for each.

(WebInspector.CSSStyleDetailsSidebarPanel.prototype._createToggleForClassName.classNameToggleChanged):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._createToggleForClassName):
Creates a toggle element for the given className and adds it to the container.

(WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass.resolvedNode.toggleClass):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass.resolvedNode):
(WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass):
Uses the Element.classList to toggle the given className on the selected node.

Location:
trunk/Source/WebInspectorUI
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebInspectorUI/ChangeLog

    r195376 r195432  
     12016-01-21  Devin Rousso  <dcrousso+webkit@gmail.com>
     2
     3        Web Inspector: Add toggle-able list of classes for each element
     4        https://bugs.webkit.org/show_bug.cgi?id=152678
     5
     6        Reviewed by Timothy Hatcher.
     7
     8        Adds a button to the CSS sidebar that, when toggled, displays a section
     9        directly above it containing all the classes for the selected node that,
     10        when toggled, adds or removes the class from the node.
     11
     12        * Localizations/en.lproj/localizedStrings.js:
     13
     14        * UserInterface/Protocol/RemoteObject.js:
     15        (WebInspector.RemoteObject.prototype.callFunction.mycallback):
     16        (WebInspector.RemoteObject.prototype.callFunction):
     17        Add extra handling of arguments to allow nicer looking calls by other classes.
     18
     19        * UserInterface/Views/CSSStyleDetailsSidebarPanel.css:
     20        Changed next-sibling selector (+) to general-sibling selector (~).
     21
     22        (.sidebar > .panel.details.css-style > .content ~ :matches(.options-container, .class-list-container)):
     23        (.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :matches(.options-container, .class-list-container)):
     24        (.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle):
     25        (.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected):
     26        (.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover):
     27        (.sidebar > .panel.details.css-style > .content ~ .class-list-container):
     28        (.sidebar > .panel.details.css-style > .content ~ .class-list-container[hidden]):
     29        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class):
     30        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > input[type="checkbox"]):
     31        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .add-class-icon):
     32        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input):
     33        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class:not(.active) > .class-name-input):
     34        (.sidebar > .panel.details.css-style > .content ~ .class-list-container > *:matches(.new-class, .class-toggle)):
     35
     36        * UserInterface/Views/CSSStyleDetailsSidebarPanel.js:
     37        (WebInspector.CSSStyleDetailsSidebarPanel):
     38        Also changed the few instances of "var" to "let".
     39
     40        (WebInspector.CSSStyleDetailsSidebarPanel.prototype.refresh):
     41        (WebInspector.CSSStyleDetailsSidebarPanel.prototype.addEventListeners):
     42        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._handleNodeAttributeModified):
     43        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._handleNodeAttributeRemoved):
     44        Adds listeners to the DOMNode specifically listening for changes to the
     45        class attribute and repopulates the class toggle list if fired.
     46
     47        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._classToggleButtonClicked):
     48        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassContainerClicked):
     49        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassInputKeyPressed):
     50        If the Enter key is pressed, add a new class equal to the input value.
     51
     52        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._addClassInputBlur):
     53        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._populateClassToggles):
     54        Loops through all the classes, including previously removed ones, for the
     55        selected node and creates a toggle for each.
     56
     57        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._createToggleForClassName.classNameToggleChanged):
     58        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._createToggleForClassName):
     59        Creates a toggle element for the given className and adds it to the container.
     60
     61        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass.resolvedNode.toggleClass):
     62        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass.resolvedNode):
     63        (WebInspector.CSSStyleDetailsSidebarPanel.prototype._toggleClass):
     64        Uses the Element.classList to toggle the given className on the selected node.
     65
    1662016-01-20  Saam barati  <sbarati@apple.com>
    267
  • trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js

    r195376 r195432  
    5454localizedStrings["Add New Probe Expression"] = "Add New Probe Expression";
    5555localizedStrings["Add New Watch Expression"] = "Add New Watch Expression";
     56localizedStrings["Add a Class"] = "Add a Class";
    5657localizedStrings["Add new breakpoint action after this action"] = "Add new breakpoint action after this action";
    5758localizedStrings["Add probe expression"] = "Add probe expression";
     
    117118localizedStrings["Child Layers"] = "Child Layers";
    118119localizedStrings["Children"] = "Children";
     120localizedStrings["Classes"] = "Classes";
    119121localizedStrings["Clear"] = "Clear";
    120122localizedStrings["Clear Log"] = "Clear Log";
     
    267269localizedStrings["Encoding"] = "Encoding";
    268270localizedStrings["End Capturing"] = "End Capturing";
     271localizedStrings["Enter Class Name"] = "Enter Class Name";
    269272localizedStrings["Enter a Gradient"] = "Enter a Gradient";
    270273localizedStrings["Enter a URL"] = "Enter a URL";
     
    648651localizedStrings["Timestamp \u2014 %s"] = "Timestamp \u2014 %s";
    649652localizedStrings["Timing"] = "Timing";
     653localizedStrings["Toggle Classes"] = "Toggle Classes";
    650654localizedStrings["Top"] = "Top";
    651655localizedStrings["Total Time"] = "Total Time";
  • trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js

    r194311 r195432  
    417417        {
    418418            result = result ? WebInspector.RemoteObject.fromPayload(result) : null;
    419             callback(error, result, wasThrown);
     419
     420            if (callback && typeof callback === "function")
     421                callback(error, result, wasThrown);
    420422        }
    421423
     
    423425            args = args.map(WebInspector.RemoteObject.createCallArgument);
    424426
    425         RuntimeAgent.callFunctionOn(this._objectId, appendWebInspectorSourceURL(functionDeclaration.toString()), args, true, undefined, generatePreview, mycallback);
     427        RuntimeAgent.callFunctionOn(this._objectId, appendWebInspectorSourceURL(functionDeclaration.toString()), args, true, undefined, !!generatePreview, mycallback);
    426428    }
    427429
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.css

    r189733 r195432  
    6666}
    6767
    68 .sidebar > .panel.details.css-style > .content + .options-container {
     68.sidebar > .panel.details.css-style > .content ~ :matches(.options-container, .class-list-container) {
    6969    display: flex;
    7070    align-items: center;
    7171    position: absolute;
    72     bottom: 0;
    7372    width: 100%;
    74     height: 29px;
    7573    background-color: white;
    7674    border-top: 1px solid hsl(0, 0%, 70%);
    7775}
    7876
    79 .sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) + .options-container {
     77.sidebar > .panel.details.css-style > .content ~ .options-container {
     78    bottom: 0;
     79    height: 30px;
     80}
     81
     82.sidebar > .panel.details.css-style > .content:not(.supports-new-rule, .has-filter-bar) ~ :matches(.options-container, .class-list-container) {
    8083    display: none;
    8184}
    8285
    83 .sidebar > .panel.details.css-style > .content + .options-container > .new-rule {
     86.sidebar > .panel.details.css-style > .content ~ .options-container > .new-rule {
    8487    width: 15px;
    8588    min-width: 15px;
     
    9093}
    9194
    92 .sidebar > .panel.details.css-style > .content + .options-container > .filter-bar {
     95.sidebar > .panel.details.css-style > .content ~ .options-container > .filter-bar {
    9396    width: -webkit-fill-available;
    9497    background-color: transparent;
    9598}
    9699
    97 .sidebar > .panel.details.css-style > .content:not(.supports-new-rule) + .options-container > .new-rule,
    98 .sidebar > .panel.details.css-style > .content:not(.has-filter-bar) + .options-container > .filter-bar {
     100.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle {
     101    margin: 0 5px 1px 0;
     102    padding: 2px 4px 3px;
     103    background: none;
     104    border: none;
     105    border-radius: 3px;
     106    -webkit-appearance: none;
     107}
     108
     109.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle.selected {
     110    color: white;
     111    background-color: hsl(212, 92%, 54%);
     112}
     113
     114.sidebar > .panel.details.css-style > .content ~ .options-container > .toggle-class-toggle:not(.selected):hover {
     115    color: white;
     116    background-color: hsla(212, 92%, 54%, 0.5);
     117}
     118
     119.sidebar > .panel.details.css-style > .content:not(.supports-new-rule) ~ .options-container > .new-rule,
     120.sidebar > .panel.details.css-style > .content:not(.has-filter-bar) ~ .options-container > .filter-bar {
    99121    display: none;
     122}
     123
     124.sidebar > .panel.details.css-style > .content ~ .class-list-container {
     125    flex-wrap: wrap;
     126    bottom: 30px;
     127    max-height: 65px;
     128    padding: 3px 2px;
     129    overflow-y: scroll;
     130}
     131
     132/* FIXME: <https://webkit.org/b/152674> Elements with the "hidden" attribute still show up if "display: flex;" */
     133.sidebar > .panel.details.css-style > .content ~ .class-list-container[hidden] {
     134    display: none;
     135}
     136
     137.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class {
     138    display: flex;
     139    align-items: center;
     140}
     141
     142.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > input[type="checkbox"] {
     143    pointer-events: none;
     144}
     145
     146.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .add-class-icon {
     147    width: 12px;
     148    height: 12px;
     149}
     150
     151.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class > .class-name-input {
     152    width: 100px;
     153    height: 18px;
     154    margin: 0 0 0 2px;
     155}
     156
     157.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class.active > .add-class-icon,
     158.sidebar > .panel.details.css-style > .content ~ .class-list-container > .new-class:not(.active) > .class-name-input {
     159    display: none;
     160}
     161
     162.sidebar > .panel.details.css-style > .content ~ .class-list-container > *:matches(.new-class, .class-toggle) {
     163    margin: 1px 3px;
    100164}
    101165
  • trunk/Source/WebInspectorUI/UserInterface/Views/CSSStyleDetailsSidebarPanel.js

    r194116 r195432  
    3838            this._forcedPseudoClassContainer.className = "pseudo-classes";
    3939
    40             var groupElement = null;
     40            let groupElement = null;
    4141
    4242            WebInspector.CSSStyleManager.ForceablePseudoClasses.forEach(function(pseudoClass) {
    4343                // We don't localize the label since it is a CSS pseudo-class from the CSS standard.
    44                 var label = pseudoClass.capitalize();
    45 
    46                 var labelElement = document.createElement("label");
    47 
    48                 var checkboxElement = document.createElement("input");
     44                let label = pseudoClass.capitalize();
     45
     46                let labelElement = document.createElement("label");
     47
     48                let checkboxElement = document.createElement("input");
    4949                checkboxElement.addEventListener("change", this._forcedPseudoClassCheckboxChanged.bind(this, pseudoClass));
    5050                checkboxElement.type = "checkbox";
     
    8888        this._navigationItem.addEventListener(WebInspector.ScopeRadioButtonNavigationItem.Event.SelectedItemChanged, this._handleSelectedItemChanged, this);
    8989
    90         var optionsContainer = document.createElement("div");
    91         optionsContainer.classList.add("options-container");
    92 
    93         var newRuleButton = document.createElement("img");
    94         newRuleButton.classList.add("new-rule");
     90        let optionsContainer = this.element.createChild("div", "options-container");
     91
     92        let newRuleButton = optionsContainer.createChild("img", "new-rule");
    9593        newRuleButton.title = WebInspector.UIString("New Rule");
    9694        newRuleButton.addEventListener("click", this._newRuleButtonClicked.bind(this));
    97         optionsContainer.appendChild(newRuleButton);
    9895
    9996        this._filterBar = new WebInspector.FilterBar;
     
    10299        optionsContainer.appendChild(this._filterBar.element);
    103100
     101        this._classToggleButton = optionsContainer.createChild("button", "toggle-class-toggle");
     102        this._classToggleButton.textContent = WebInspector.UIString("Classes");
     103        this._classToggleButton.title = WebInspector.UIString("Toggle Classes");
     104        this._classToggleButton.addEventListener("click", this._classToggleButtonClicked.bind(this));
     105
     106        this._classListContainer = this.element.createChild("div", "class-list-container");
     107        this._classListContainer.hidden = true;
     108
     109        this._addClassContainer = this._classListContainer.createChild("div", "new-class");
     110        this._addClassContainer.title = WebInspector.UIString("Add a Class");
     111        this._addClassContainer.addEventListener("click", this._addClassContainerClicked.bind(this));
     112
     113        let addClassCheckbox = this._addClassContainer.createChild("input");
     114        addClassCheckbox.type = "checkbox";
     115        addClassCheckbox.checked = true;
     116
     117        let addClassIcon = useSVGSymbol("Images/Plus13.svg", "add-class-icon");
     118        this._addClassContainer.appendChild(addClassIcon);
     119
     120        this._addClassInput = this._addClassContainer.createChild("input", "class-name-input");
     121        this._addClassInput.setAttribute("placeholder", WebInspector.UIString("Enter Class Name"));
     122        this._addClassInput.addEventListener("keypress", this._addClassInputKeyPressed.bind(this));
     123        this._addClassInput.addEventListener("blur", this._addClassInputBlur.bind(this));
     124
    104125        WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetAdded, this.refresh, this);
    105126        WebInspector.cssStyleManager.addEventListener(WebInspector.CSSStyleManager.Event.StyleSheetRemoved, this.refresh, this);
    106 
    107         this.element.appendChild(optionsContainer);
    108127    }
    109128
     
    117136    refresh()
    118137    {
    119         var domNode = this.domNode;
     138        let domNode = this.domNode;
    120139        if (!domNode)
    121140            return;
     
    123142        this.contentView.element.scrollTop = this._initialScrollOffset;
    124143
    125         for (var panel of this._panels) {
     144        for (let panel of this._panels) {
    126145            panel.element._savedScrollTop = undefined;
    127146            panel.markAsNeedsRefresh(domNode);
     
    129148
    130149        this._updatePseudoClassCheckboxes();
     150
     151        if (!this._classListContainer.hidden)
     152            this._populateClassToggles();
    131153    }
    132154
     
    169191    addEventListeners()
    170192    {
    171         var effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
     193        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
    172194        if (!effectiveDOMNode)
    173195            return;
    174196
    175197        effectiveDOMNode.addEventListener(WebInspector.DOMNode.Event.EnabledPseudoClassesChanged, this._updatePseudoClassCheckboxes, this);
     198        effectiveDOMNode.addEventListener(WebInspector.DOMNode.Event.AttributeModified, this._handleNodeAttributeModified, this);
     199        effectiveDOMNode.addEventListener(WebInspector.DOMNode.Event.AttributeRemoved, this._handleNodeAttributeRemoved, this);
    176200    }
    177201
    178202    removeEventListeners()
    179203    {
    180         var effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
     204        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
    181205        if (!effectiveDOMNode)
    182206            return;
     
    202226    _panelMatchingIdentifier(identifier)
    203227    {
    204         var selectedPanel
    205 
    206         for (var panel of this._panels) {
     228        let selectedPanel = null;
     229        for (let panel of this._panels) {
    207230            if (panel.navigationInfo.identifier !== identifier)
    208231                continue;
     
    217240    _handleSelectedItemChanged()
    218241    {
    219         var selectedIdentifier = this._navigationItem.selectedItemIdentifier;
    220         var selectedPanel = this._panelMatchingIdentifier(selectedIdentifier);
     242        let selectedIdentifier = this._navigationItem.selectedItemIdentifier;
     243        let selectedPanel = this._panelMatchingIdentifier(selectedIdentifier);
    221244        this._switchPanels(selectedPanel);
    222245    }
     
    259282            return;
    260283
    261         var effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
     284        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
    262285
    263286        effectiveDOMNode.setPseudoClassEnabled(pseudoClass, event.target.checked);
     
    269292            return;
    270293
    271         var effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
    272 
    273         var enabledPseudoClasses = effectiveDOMNode.enabledPseudoClasses;
    274 
    275         for (var pseudoClass in this._forcedPseudoClassCheckboxes) {
    276             var checkboxElement = this._forcedPseudoClassCheckboxes[pseudoClass];
     294        let effectiveDOMNode = this.domNode.isPseudoElement() ? this.domNode.parentNode : this.domNode;
     295
     296        let enabledPseudoClasses = effectiveDOMNode.enabledPseudoClasses;
     297
     298        for (let pseudoClass in this._forcedPseudoClassCheckboxes) {
     299            let checkboxElement = this._forcedPseudoClassCheckboxes[pseudoClass];
    277300            checkboxElement.checked = enabledPseudoClasses.includes(pseudoClass);
    278301        }
    279302    }
     303
     304    _handleNodeAttributeModified(event)
     305    {
     306        if (event && event.data && event.data.name === "class")
     307            this._populateClassToggles();
     308    }
     309
     310    _handleNodeAttributeRemoved(event)
     311    {
     312        if (event && event.data && event.data.name === "class")
     313            this._populateClassToggles();
     314    }
     315
    280316
    281317    _newRuleButtonClicked()
     
    283319        if (this._selectedPanel && typeof this._selectedPanel.newRuleButtonClicked === "function")
    284320            this._selectedPanel.newRuleButtonClicked();
     321    }
     322
     323    _classToggleButtonClicked(event)
     324    {
     325        this._classToggleButton.classList.toggle("selected");
     326        this._classListContainer.hidden = !this._classListContainer.hidden;
     327        if (this._classListContainer.hidden)
     328            return;
     329
     330        this._populateClassToggles();
     331    }
     332
     333    _addClassContainerClicked(event)
     334    {
     335        this._addClassContainer.classList.add("active");
     336        this._addClassInput.focus();
     337    }
     338
     339    _addClassInputKeyPressed(event)
     340    {
     341        if (event.keyCode !== WebInspector.KeyboardShortcut.Key.Enter.keyCode)
     342            return;
     343
     344        this._addClassInput.blur();
     345    }
     346
     347    _addClassInputBlur(event)
     348    {
     349        this._toggleClass.call(this, this._addClassInput.value, true);
     350        this._addClassContainer.classList.remove("active");
     351        this._addClassInput.value = null;
     352    }
     353
     354    _populateClassToggles()
     355    {
     356        this._classListContainer.removeChildren();
     357        this._classListContainer.appendChild(this._addClassContainer);
     358
     359        let classes = this.domNode.getAttribute("class");
     360        let classToggledMap = this.domNode[WebInspector.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol];
     361        if (!classToggledMap)
     362            classToggledMap = this.domNode[WebInspector.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol] = new Map;
     363
     364        if (classes && classes.length) {
     365            for (let className of classes.split(/\s+/))
     366                classToggledMap.set(className, true);
     367        }
     368
     369        for (let [className, toggled] of classToggledMap) {
     370            if ((toggled && !classes.includes(className)) || (!toggled && classes.includes(className))) {
     371                toggled = !toggled;
     372                classToggledMap.set(className, toggled);
     373            }
     374
     375            this._createToggleForClassName(className);
     376        }
     377    }
     378
     379    _createToggleForClassName(className)
     380    {
     381        if (!className || !className.length)
     382            return;
     383
     384        let classToggledMap = this.domNode[WebInspector.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol];
     385        if (!classToggledMap)
     386            return;
     387
     388        if (!classToggledMap.has(className))
     389            classToggledMap.set(className, true);
     390
     391        let toggled = classToggledMap.get(className);
     392
     393        let classNameContainer = document.createElement("div");
     394        classNameContainer.classList.add("class-toggle");
     395
     396        let classNameToggle = classNameContainer.createChild("input");
     397        classNameToggle.type = "checkbox";
     398        classNameToggle.checked = toggled;
     399
     400        let classNameTitle = classNameContainer.createChild("span");
     401        classNameTitle.textContent = className;
     402
     403        function classNameToggleChanged(event) {
     404            this._toggleClass.call(this, className, classNameToggle.checked);
     405            classToggledMap.set(className, classNameToggle.checked);
     406        }
     407
     408        classNameToggle.addEventListener("click", classNameToggleChanged.bind(this));
     409        classNameTitle.addEventListener("click", (event) => {
     410            classNameToggle.checked = !classNameToggle.checked;
     411            classNameToggleChanged.call(this);
     412        });
     413
     414        this._classListContainer.appendChild(classNameContainer);
     415    }
     416
     417    _toggleClass(className, flag)
     418    {
     419        if (!className || !className.length)
     420            return;
     421
     422        let effectiveNode = this.domNode;
     423        if (effectiveNode && effectiveNode.isPseudoElement())
     424            effectiveNode = effectiveNode.parentNode;
     425
     426        console.assert(effectiveNode);
     427        if (!effectiveNode)
     428            return;
     429
     430        if (effectiveNode.nodeType() !== Node.ELEMENT_NODE)
     431            return;
     432
     433        function resolvedNode(object)
     434        {
     435            if (!object)
     436                return;
     437
     438            function toggleClass(className, flag)
     439            {
     440                this.classList.toggle(className, flag);
     441            }
     442
     443            object.callFunction(toggleClass, [className, flag]);
     444            object.release();
     445        }
     446
     447        WebInspector.RemoteObject.resolveNode(effectiveNode, "", resolvedNode);
    285448    }
    286449
     
    300463WebInspector.CSSStyleDetailsSidebarPanel.NoFilterMatchInPropertyClassName = "filter-property-non-matching";
    301464
     465WebInspector.CSSStyleDetailsSidebarPanel.ToggledClassesSymbol = Symbol("css-style-details-sidebar-panel-toggled-classes-symbol");
Note: See TracChangeset for help on using the changeset viewer.