author | Simon Lindholm <simon.lindholm10@gmail.com> |
Fri, 07 Aug 2015 18:16:32 -0700 | |
changeset 256936 | 6e532fe19bb77bfa6965ffcd360d33bfc417ce41 |
parent 256935 | 380be310da45a5b810ab47035588dbb2345cee9d |
child 256937 | 7fe4321e40bc819001710904408dd7dac59ff7eb |
push id | 29195 |
push user | philringnalda@gmail.com |
push date | Sun, 09 Aug 2015 01:37:55 +0000 |
treeherder | mozilla-central@fd63d8ed9d2e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bgrins |
bugs | 1187777, 100644 |
milestone | 42.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/devtools/styleinspector/rule-view.js +++ b/browser/devtools/styleinspector/rule-view.js @@ -2207,16 +2207,17 @@ CssRuleView.prototype = { * The rule property TextPropertyEditor object. * @return {bool} true if the computed property was highlighted, false * otherwise. */ _highlightComputedProperty: function(editor) { let isComputedHighlighted = false; // Highlight search matches in the computed list of properties + editor._populateComputed(); for (let computed of editor.prop.computed) { if (computed.element) { // Get the actual property value displayed in the computed list let computedName = computed.name.toLowerCase(); let computedValue = computed.parsedValue.toLowerCase(); isComputedHighlighted = this._highlightMatches(computed.element, { searchName: this.searchPropertyName, @@ -2836,16 +2837,17 @@ RuleEditor.prototype = { function TextPropertyEditor(aRuleEditor, aProperty) { this.ruleEditor = aRuleEditor; this.ruleView = this.ruleEditor.ruleView; this.doc = this.ruleEditor.doc; this.popup = this.ruleView.popup; this.prop = aProperty; this.prop.editor = this; this.browserWindow = this.doc.defaultView.top; + this._populatedComputed = false; this._onEnableClicked = this._onEnableClicked.bind(this); this._onExpandClicked = this._onExpandClicked.bind(this); this._onStartEditing = this._onStartEditing.bind(this); this._onNameDone = this._onNameDone.bind(this); this._onValueDone = this._onValueDone.bind(this); this._onSwatchCommit = this._onSwatchCommit.bind(this); this._onSwatchPreview = this._onSwatchPreview.bind(this); @@ -3178,34 +3180,47 @@ TextPropertyEditor.prototype = { }, _onStartEditing: function() { this.element.classList.remove("ruleview-overridden"); this.enable.style.visibility = "hidden"; }, /** - * Populate the list of computed styles. + * Update the indicator for computed styles. The computed styles themselves + * are populated on demand, when they become visible. */ _updateComputed: function() { - // Clear out existing viewers. - while (this.computed.hasChildNodes()) { - this.computed.removeChild(this.computed.lastChild); + this.computed.innerHTML = ""; + + let showExpander = this.prop.computed.some(c => c.name !== this.prop.name); + this.expander.style.visibility = showExpander ? "visible" : "hidden"; + + this._populatedComputed = false; + if (this.expander.hasAttribute("open")) { + this._populateComputed(); } - - let showExpander = false; + }, + + /** + * Populate the list of computed styles. + */ + _populateComputed: function() { + if (this._populatedComputed) { + return; + } + this._populatedComputed = true; + for (let computed of this.prop.computed) { // Don't bother to duplicate information already // shown in the text property. if (computed.name === this.prop.name) { continue; } - showExpander = true; - let li = createChild(this.computed, "li", { class: "ruleview-computed" }); if (computed.overridden) { li.classList.add("ruleview-overridden"); } @@ -3233,23 +3248,16 @@ TextPropertyEditor.prototype = { }); appendText(li, ";"); // Store the computed style element for easy access when highlighting // styles computed.element = li; } - - // Show or hide the expander as needed. - if (showExpander) { - this.expander.style.visibility = "visible"; - } else { - this.expander.style.visibility = "hidden"; - } }, /** * Handles clicks on the disabled property. */ _onEnableClicked: function(aEvent) { let checked = this.enable.hasAttribute("checked"); if (checked) { @@ -3272,30 +3280,32 @@ TextPropertyEditor.prototype = { if (this.computed.hasAttribute("filter-open") || this.computed.hasAttribute("user-open")) { this.expander.removeAttribute("open"); this.computed.removeAttribute("filter-open"); this.computed.removeAttribute("user-open"); } else { this.expander.setAttribute("open", "true"); this.computed.setAttribute("user-open", ""); + this._populateComputed(); } aEvent.stopPropagation(); }, /** * Expands the computed list when a computed property is matched by the style * filtering. The filter-open attribute is used to track whether or not the * computed list was toggled opened by the filter. */ expandForFilter: function() { if (!this.computed.hasAttribute("user-open")) { this.expander.setAttribute("open", "true"); this.computed.setAttribute("filter-open", ""); + this._populateComputed(); } }, /** * Collapses the computed list that was expanded by style filtering. */ collapseForFilter: function() { this.computed.removeAttribute("filter-open");
--- a/browser/devtools/styleinspector/test/browser.ini +++ b/browser/devtools/styleinspector/test/browser.ini @@ -69,16 +69,18 @@ support-files = [browser_ruleview_colorpicker-multiple-changes.js] [browser_ruleview_colorpicker-release-outside-frame.js] [browser_ruleview_colorpicker-revert-on-ESC.js] [browser_ruleview_colorpicker-swatch-displayed.js] [browser_ruleview_completion-existing-property_01.js] [browser_ruleview_completion-existing-property_02.js] [browser_ruleview_completion-new-property_01.js] [browser_ruleview_completion-new-property_02.js] +[browser_ruleview_computed_01.js] +[browser_ruleview_computed_02.js] [browser_ruleview_completion-popup-hidden-after-navigation.js] [browser_ruleview_content_01.js] [browser_ruleview_content_02.js] skip-if = e10s # Bug 1039528: "inspect element" contextual-menu doesn't work with e10s [browser_ruleview_context-menu-show-mdn-docs-01.js] [browser_ruleview_context-menu-show-mdn-docs-02.js] [browser_ruleview_context-menu-show-mdn-docs-03.js] [browser_ruleview_copy_styles.js]
new file mode 100644 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_ruleview_computed_01.js @@ -0,0 +1,47 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests that the rule view shows expanders for properties with computed lists. + +let TEST_URI = ` + <style type="text/css"> + #testid { + margin: 4px; + top: 0px; + } + </style> + <h1 id="testid">Styled Node</h1> +`; + +add_task(function*() { + yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openRuleView(); + yield selectNode("#testid", inspector); + yield testExpandersShown(inspector, view); +}); + +function* testExpandersShown(inspector, view) { + let rule = getRuleViewRuleEditor(view, 1).rule; + + info("Check that the correct rules are visible"); + is(rule.selectorText, "#testid", "Second rule is #testid."); + is(rule.textProps[0].name, "margin", "First property is margin."); + is(rule.textProps[1].name, "top", "Second property is top."); + + info("Check that the expanders are shown correctly"); + is(rule.textProps[0].editor.expander.style.visibility, "visible", + "margin expander is visible."); + is(rule.textProps[1].editor.expander.style.visibility, "hidden", + "top expander is hidden."); + ok(!rule.textProps[0].editor.expander.hasAttribute("open"), + "margin computed list is closed."); + ok(!rule.textProps[1].editor.expander.hasAttribute("open"), + "top computed list is closed."); + ok(!rule.textProps[0].editor.computed.hasChildNodes(), + "margin computed list is empty before opening."); + ok(!rule.textProps[1].editor.computed.hasChildNodes(), + "top computed list is empty."); +}
new file mode 100644 --- /dev/null +++ b/browser/devtools/styleinspector/test/browser_ruleview_computed_02.js @@ -0,0 +1,68 @@ +/* vim: set ft=javascript ts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests that the rule view computed lists can be expanded/collapsed, +// and contain the right subproperties. + +let TEST_URI = ` + <style type="text/css"> + #testid { + margin: 0px 1px 2px 3px; + top: 0px; + } + </style> + <h1 id="testid">Styled Node</h1> +`; + +add_task(function*() { + yield addTab("data:text/html;charset=utf-8," + encodeURIComponent(TEST_URI)); + let {inspector, view} = yield openRuleView(); + yield selectNode("#testid", inspector); + yield testComputedList(inspector, view); +}); + +function* testComputedList(inspector, view) { + let rule = getRuleViewRuleEditor(view, 1).rule; + let propEditor = rule.textProps[0].editor; + let expander = propEditor.expander; + + ok(!expander.hasAttribute("open"), "margin computed list is closed"); + + info("Opening the computed list of margin property") + expander.click(); + ok(expander.hasAttribute("open"), "margin computed list is open"); + + let computed = propEditor.prop.computed; + let computedDom = propEditor.computed; + let propNames = [ + "margin-top", + "margin-right", + "margin-bottom", + "margin-left" + ]; + + is(computed.length, propNames.length, "There should be 4 computed values"); + is(computedDom.children.length, propNames.length, "There should be 4 nodes in the DOM"); + propNames.forEach((propName, i) => { + let propValue = i + "px"; + is(computed[i].name, propName, "Computed property #" + i + " has name " + propName); + is(computed[i].value, propValue, "Computed property #" + i + " has value " + propValue); + is(computedDom.getElementsByClassName("ruleview-propertyname")[i].textContent, propName, + "Computed property #" + i + " in DOM has correct name"); + is(computedDom.getElementsByClassName("ruleview-propertyvalue")[i].textContent, propValue, + "Computed property #" + i + " in DOM has correct value"); + }); + + info("Closing the computed list of margin property") + expander.click(); + ok(!expander.hasAttribute("open"), "margin computed list is closed"); + + info("Opening the computed list of margin property") + expander.click(); + ok(expander.hasAttribute("open"), "margin computed list is open"); + is(computed.length, propNames.length, "Still 4 computed values"); + is(computedDom.children.length, propNames.length, "Still 4 nodes in the DOM"); +}
--- a/browser/devtools/styleinspector/test/browser_ruleview_edit-property-computed.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_edit-property-computed.js @@ -59,9 +59,17 @@ function* editAndCheck(view) { "padding-left" ]; is(computed.length, propNames.length, "There should be 4 computed values"); propNames.forEach((propName, i) => { is(computed[i].name, propName, "Computed property #" + i + " has name " + propName); is(computed[i].value, newPaddingValue, "Computed value of " + propName + " is as expected"); }); + + propEditor.expander.click(); + let computedDom = propEditor.computed; + is(computedDom.children.length, propNames.length, "There should be 4 nodes in the DOM"); + propNames.forEach((propName, i) => { + is(computedDom.getElementsByClassName("ruleview-propertyvalue")[i].textContent, + newPaddingValue, "Computed value of " + propName + " in DOM is as expected"); + }); }