Bug 886039 - Port the computed view to the styles actor. r=mratcliffe

This commit is contained in:
Dave Camp 2013-08-08 08:44:57 -07:00
parent 2c5985bd8f
commit a92f1e8c67
17 changed files with 363 additions and 432 deletions

View File

@ -40,7 +40,7 @@ function test() {
testDiv.style.fontSize = "10px"; testDiv.style.fontSize = "10px";
// Start up the style inspector panel... // Start up the style inspector panel...
Services.obs.addObserver(stylePanelTests, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", stylePanelTests);
inspector.selection.setNode(testDiv); inspector.selection.setNode(testDiv);
}); });
@ -48,15 +48,13 @@ function test() {
function stylePanelTests() function stylePanelTests()
{ {
Services.obs.removeObserver(stylePanelTests, "StyleInspector-populated");
let computedview = inspector.sidebar.getWindowForTab("computedview").computedview; let computedview = inspector.sidebar.getWindowForTab("computedview").computedview;
ok(computedview, "Style Panel has a cssHtmlTree"); ok(computedview, "Style Panel has a cssHtmlTree");
let propView = getInspectorProp("font-size"); let propView = getInspectorProp("font-size");
is(propView.value, "10px", "Style inspector should be showing the correct font size."); is(propView.value, "10px", "Style inspector should be showing the correct font size.");
Services.obs.addObserver(stylePanelAfterChange, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", stylePanelAfterChange);
testDiv.style.fontSize = "15px"; testDiv.style.fontSize = "15px";
inspector.emit("layout-change"); inspector.emit("layout-change");
@ -64,8 +62,6 @@ function test() {
function stylePanelAfterChange() function stylePanelAfterChange()
{ {
Services.obs.removeObserver(stylePanelAfterChange, "StyleInspector-populated");
let propView = getInspectorProp("font-size"); let propView = getInspectorProp("font-size");
is(propView.value, "15px", "Style inspector should be showing the new font size."); is(propView.value, "15px", "Style inspector should be showing the new font size.");
@ -78,7 +74,7 @@ function test() {
inspector.sidebar.select("ruleview"); inspector.sidebar.select("ruleview");
executeSoon(function() { executeSoon(function() {
Services.obs.addObserver(stylePanelAfterSwitch, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", stylePanelAfterSwitch);
testDiv.style.fontSize = "20px"; testDiv.style.fontSize = "20px";
inspector.sidebar.select("computedview"); inspector.sidebar.select("computedview");
}); });
@ -86,8 +82,6 @@ function test() {
function stylePanelAfterSwitch() function stylePanelAfterSwitch()
{ {
Services.obs.removeObserver(stylePanelAfterSwitch, "StyleInspector-populated");
let propView = getInspectorProp("font-size"); let propView = getInspectorProp("font-size");
is(propView.value, "20px", "Style inspector should be showing the newest font size."); is(propView.value, "20px", "Style inspector should be showing the newest font size.");

View File

@ -53,45 +53,39 @@ function test() {
instance.setSize(500, 500); instance.setSize(500, 500);
openInspector(onInspectorUIOpen); openComputedView(onInspectorUIOpen);
} }
function onInspectorUIOpen(aInspector) { function onInspectorUIOpen(aInspector, aComputedView) {
inspector = aInspector; inspector = aInspector;
ok(inspector, "Got inspector instance"); ok(inspector, "Got inspector instance");
inspector.sidebar.select("computedview");
let div = content.document.getElementsByTagName("div")[0]; let div = content.document.getElementsByTagName("div")[0];
inspector.sidebar.once("computedview-ready", function() { inspector.selection.setNode(div);
Services.obs.addObserver(testShrink, "StyleInspector-populated", false); inspector.once("inspector-updated", testShrink);
inspector.selection.setNode(div);
});
} }
function testShrink() { function testShrink() {
Services.obs.removeObserver(testShrink, "StyleInspector-populated");
computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view; computedView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
ok(computedView, "We have access to the Computed View object"); ok(computedView, "We have access to the Computed View object");
is(computedWidth(), "500px", "Should show 500px initially."); is(computedWidth(), "500px", "Should show 500px initially.");
Services.obs.addObserver(function onShrink() { inspector.once("computed-view-refreshed", function onShrink() {
Services.obs.removeObserver(onShrink, "StyleInspector-populated");
is(computedWidth(), "100px", "div should be 100px after shrinking."); is(computedWidth(), "100px", "div should be 100px after shrinking.");
testGrow(); testGrow();
}, "StyleInspector-populated", false); });
instance.setSize(100, 100); instance.setSize(100, 100);
} }
function testGrow() { function testGrow() {
Services.obs.addObserver(function onGrow() { inspector.once("computed-view-refreshed", function onGrow() {
Services.obs.removeObserver(onGrow, "StyleInspector-populated");
is(computedWidth(), "500px", "Should be 500px after growing."); is(computedWidth(), "500px", "Should be 500px after growing.");
finishUp(); finishUp();
}, "StyleInspector-populated", false); });
instance.setSize(500, 500); instance.setSize(500, 500);
} }

View File

@ -18,6 +18,16 @@ function openInspector(callback)
}); });
} }
function openComputedView(callback)
{
openInspector(inspector => {
inspector.sidebar.once("computedview-ready", () => {
inspector.sidebar.select("computedview");
let ruleView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
callback(inspector, ruleView);
})
});
}
function openRuleView(callback) function openRuleView(callback)
{ {
openInspector(inspector => { openInspector(inspector => {

View File

@ -8,6 +8,9 @@ const {Cc, Ci, Cu} = require("chrome");
let ToolDefinitions = require("main").Tools; let ToolDefinitions = require("main").Tools;
let {CssLogic} = require("devtools/styleinspector/css-logic"); let {CssLogic} = require("devtools/styleinspector/css-logic");
let {ELEMENT_STYLE} = require("devtools/server/actors/styles");
let promise = require("sdk/core/promise");
let {EventEmitter} = require("devtools/shared/event-emitter");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/PluralForm.jsm"); Cu.import("resource://gre/modules/PluralForm.jsm");
@ -90,6 +93,7 @@ UpdateProcess.prototype = {
this.onDone(); this.onDone();
return; return;
} }
console.error(e);
throw e; throw e;
} }
}, },
@ -115,14 +119,18 @@ UpdateProcess.prototype = {
* will generally only be one). * will generally only be one).
* *
* @params {StyleInspector} aStyleInspector The owner of this CssHtmlTree * @params {StyleInspector} aStyleInspector The owner of this CssHtmlTree
* @param {PageStyleFront} aPageStyle
* Front for the page style actor that will be providing
* the style information.
*
* @constructor * @constructor
*/ */
function CssHtmlTree(aStyleInspector) function CssHtmlTree(aStyleInspector, aPageStyle)
{ {
this.styleWindow = aStyleInspector.window; this.styleWindow = aStyleInspector.window;
this.styleDocument = aStyleInspector.window.document; this.styleDocument = aStyleInspector.window.document;
this.styleInspector = aStyleInspector; this.styleInspector = aStyleInspector;
this.cssLogic = aStyleInspector.cssLogic; this.pageStyle = aPageStyle;
this.propertyViews = []; this.propertyViews = [];
let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]. let chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"].
@ -144,6 +152,8 @@ function CssHtmlTree(aStyleInspector)
// No results text. // No results text.
this.noResults = this.styleDocument.getElementById("noResults"); this.noResults = this.styleDocument.getElementById("noResults");
CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
// The element that we're inspecting, and the document that it comes from. // The element that we're inspecting, and the document that it comes from.
this.viewedElement = null; this.viewedElement = null;
this.createStyleViews(); this.createStyleViews();
@ -207,8 +217,6 @@ CssHtmlTree.prototype = {
// Cache the list of properties that match the selected element. // Cache the list of properties that match the selected element.
_matchedProperties: null, _matchedProperties: null,
htmlComplete: false,
// Used for cancelling timeouts in the style filter. // Used for cancelling timeouts in the style filter.
_filterChangedTimeout: null, _filterChangedTimeout: null,
@ -227,6 +235,10 @@ CssHtmlTree.prototype = {
// Number of visible properties // Number of visible properties
numVisibleProperties: 0, numVisibleProperties: 0,
setPageStyle: function(pageStyle) {
this.pageStyle = pageStyle;
},
get includeBrowserStyles() get includeBrowserStyles()
{ {
return this.includeBrowserStylesCheckbox.checked; return this.includeBrowserStylesCheckbox.checked;
@ -236,65 +248,65 @@ CssHtmlTree.prototype = {
* Update the highlighted element. The CssHtmlTree panel will show the style * Update the highlighted element. The CssHtmlTree panel will show the style
* information for the given element. * information for the given element.
* @param {nsIDOMElement} aElement The highlighted node to get styles for. * @param {nsIDOMElement} aElement The highlighted node to get styles for.
*
* @returns a promise that will be resolved when highlighting is complete.
*/ */
highlight: function CssHtmlTree_highlight(aElement) highlight: function(aElement) {
{
this.viewedElement = aElement;
this._matchedProperties = null;
if (!aElement) { if (!aElement) {
if (this._refreshProcess) { if (this._refreshProcess) {
this._refreshProcess.cancel(); this._refreshProcess.cancel();
} }
return; return promise.resolve(undefined)
} }
if (this.htmlComplete) { if (aElement === this.viewedElement) {
this.refreshSourceFilter(); return promise.resolve(undefined);
this.refreshPanel(); }
} else {
if (this._refreshProcess) { this.viewedElement = aElement;
this._refreshProcess.cancel();
this.refreshSourceFilter();
return this.refreshPanel();
},
_createPropertyViews: function()
{
if (this._createViewsPromise) {
return this._createViewsPromise;
}
let deferred = promise.defer();
this._createViewsPromise = deferred.promise;
this.refreshSourceFilter();
this.numVisibleProperties = 0;
let fragment = this.styleDocument.createDocumentFragment();
this._createViewsProcess = new UpdateProcess(this.styleWindow, CssHtmlTree.propertyNames, {
onItem: (aPropertyName) => {
// Per-item callback.
let propView = new PropertyView(this, aPropertyName);
fragment.appendChild(propView.buildMain());
fragment.appendChild(propView.buildSelectorContainer());
if (propView.visible) {
this.numVisibleProperties++;
}
this.propertyViews.push(propView);
},
onCancel: () => {
deferred.reject("_createPropertyViews cancelled");
},
onDone: () => {
// Completed callback.
this.propertyContainer.appendChild(fragment);
this.noResults.hidden = this.numVisibleProperties > 0;
deferred.resolve(undefined);
} }
});
CssHtmlTree.processTemplate(this.templateRoot, this.root, this); this._createViewsProcess.schedule();
return deferred.promise;
// Refresh source filter ... this must be done after templateRoot has been
// processed.
this.refreshSourceFilter();
this.numVisibleProperties = 0;
let fragment = this.styleDocument.createDocumentFragment();
this._refreshProcess = new UpdateProcess(this.styleWindow, CssHtmlTree.propertyNames, {
onItem: function(aPropertyName) {
// Per-item callback.
let propView = new PropertyView(this, aPropertyName);
fragment.appendChild(propView.buildMain());
fragment.appendChild(propView.buildSelectorContainer());
if (propView.visible) {
this.numVisibleProperties++;
}
propView.refreshMatchedSelectors();
this.propertyViews.push(propView);
}.bind(this),
onDone: function() {
// Completed callback.
this.htmlComplete = true;
this.propertyContainer.appendChild(fragment);
this.noResults.hidden = this.numVisibleProperties > 0;
this._refreshProcess = null;
// If a refresh was scheduled during the building, complete it.
if (this._needsRefresh) {
delete this._needsRefresh;
this.refreshPanel();
} else {
Services.obs.notifyObservers(null, "StyleInspector-populated", null);
}
}.bind(this)});
this._refreshProcess.schedule();
}
}, },
/** /**
@ -302,39 +314,54 @@ CssHtmlTree.prototype = {
*/ */
refreshPanel: function CssHtmlTree_refreshPanel() refreshPanel: function CssHtmlTree_refreshPanel()
{ {
// If we're still in the process of creating the initial layout, return promise.all([
// leave it alone. this._createPropertyViews(),
if (!this.htmlComplete) { this.pageStyle.getComputed(this.viewedElement, {
if (this._refreshProcess) { filter: this._sourceFilter,
this._needsRefresh = true; onlyMatched: !this.includeBrowserStyles,
markMatched: true
})
]).then(([createViews, computed]) => {
this._matchedProperties = new Set;
for (let name in computed) {
if (computed[name].matched) {
this._matchedProperties.add(name);
}
} }
return; this._computed = computed;
}
if (this._refreshProcess) { if (this._refreshProcess) {
this._refreshProcess.cancel(); this._refreshProcess.cancel();
} }
this.noResults.hidden = true; this.noResults.hidden = true;
// Reset visible property count // Reset visible property count
this.numVisibleProperties = 0; this.numVisibleProperties = 0;
// Reset zebra striping. // Reset zebra striping.
this._darkStripe = true; this._darkStripe = true;
let display = this.propertyContainer.style.display; let display = this.propertyContainer.style.display;
this._refreshProcess = new UpdateProcess(this.styleWindow, this.propertyViews, {
onItem: function(aPropView) { let deferred = promise.defer();
aPropView.refresh(); this._refreshProcess = new UpdateProcess(this.styleWindow, this.propertyViews, {
}.bind(this), onItem: (aPropView) => {
onDone: function() { aPropView.refresh();
this._refreshProcess = null; },
this.noResults.hidden = this.numVisibleProperties > 0; onCancel: () => {
Services.obs.notifyObservers(null, "StyleInspector-populated", null); deferred.reject("refresh cancelled");
}.bind(this) },
}); onDone: () => {
this._refreshProcess.schedule(); this._refreshProcess = null;
this.noResults.hidden = this.numVisibleProperties > 0;
this.styleInspector.inspector.emit("computed-view-refreshed");
deferred.resolve(undefined);
}
});
this._refreshProcess.schedule();
return deferred.promise;
}).then(null, (err) => console.error(err));
}, },
/** /**
@ -377,7 +404,7 @@ CssHtmlTree.prototype = {
refreshSourceFilter: function CssHtmlTree_setSourceFilter() refreshSourceFilter: function CssHtmlTree_setSourceFilter()
{ {
this._matchedProperties = null; this._matchedProperties = null;
this.cssLogic.sourceFilter = this.includeBrowserStyles ? this._sourceFilter = this.includeBrowserStyles ?
CssLogic.FILTER.UA : CssLogic.FILTER.UA :
CssLogic.FILTER.USER; CssLogic.FILTER.USER;
}, },
@ -409,21 +436,18 @@ CssHtmlTree.prototype = {
CssHtmlTree.propertyNames.sort(); CssHtmlTree.propertyNames.sort();
CssHtmlTree.propertyNames.push.apply(CssHtmlTree.propertyNames, CssHtmlTree.propertyNames.push.apply(CssHtmlTree.propertyNames,
mozProps.sort()); mozProps.sort());
this._createPropertyViews();
}, },
/** /**
* Get a list of properties that have matched selectors. * Get a set of properties that have matched selectors.
* *
* @return {object} the object maps property names (keys) to booleans (values) * @return {Set} If a property name is in the set, it has matching selectors.
* that tell if the given property has matched selectors or not.
*/ */
get matchedProperties() get matchedProperties()
{ {
if (!this._matchedProperties) { return this._matchedProperties || new Set;
this._matchedProperties =
this.cssLogic.hasMatchedSelectors(CssHtmlTree.propertyNames);
}
return this._matchedProperties;
}, },
/** /**
@ -473,6 +497,9 @@ CssHtmlTree.prototype = {
this.searchField.removeEventListener("command", this.filterChanged); this.searchField.removeEventListener("command", this.filterChanged);
// Cancel tree construction // Cancel tree construction
if (this._createViewsProcess) {
this._createViewsProcess.cancel();
}
if (this._refreshProcess) { if (this._refreshProcess) {
this._refreshProcess.cancel(); this._refreshProcess.cancel();
} }
@ -517,11 +544,18 @@ CssHtmlTree.prototype = {
delete this.propertyViews; delete this.propertyViews;
delete this.styleWindow; delete this.styleWindow;
delete this.styleDocument; delete this.styleDocument;
delete this.cssLogic;
delete this.styleInspector; delete this.styleInspector;
}, },
}; };
function PropertyInfo(aTree, aName) {
this.tree = aTree;
this.name = aName;
}
PropertyInfo.prototype = {
get value() this.tree._computed ? this.tree._computed[this.name].value : ""
}
/** /**
* A container to give easy access to property data from the template engine. * A container to give easy access to property data from the template engine.
* *
@ -539,6 +573,7 @@ function PropertyView(aTree, aName)
this.link = "https://developer.mozilla.org/CSS/" + aName; this.link = "https://developer.mozilla.org/CSS/" + aName;
this.templateMatchedSelectors = aTree.styleDocument.getElementById("templateMatchedSelectors"); this.templateMatchedSelectors = aTree.styleDocument.getElementById("templateMatchedSelectors");
this._propertyInfo = new PropertyInfo(aTree, aName);
} }
PropertyView.prototype = { PropertyView.prototype = {
@ -585,7 +620,7 @@ PropertyView.prototype = {
*/ */
get propertyInfo() get propertyInfo()
{ {
return this.tree.cssLogic.getPropertyInfo(this.name); return this._propertyInfo;
}, },
/** /**
@ -593,7 +628,7 @@ PropertyView.prototype = {
*/ */
get hasMatchedSelectors() get hasMatchedSelectors()
{ {
return this.name in this.tree.matchedProperties; return this.tree.matchedProperties.has(this.name);
}, },
/** /**
@ -738,15 +773,29 @@ PropertyView.prototype = {
} }
if (this.matchedExpanded && hasMatchedSelectors) { if (this.matchedExpanded && hasMatchedSelectors) {
CssHtmlTree.processTemplate(this.templateMatchedSelectors, return this.tree.pageStyle.getMatchedSelectors(this.tree.viewedElement, this.name).then(matched => {
this.matchedSelectorsContainer, this); if (!this.matchedExpanded) {
this.matchedExpander.setAttribute("open", ""); return;
}
this._matchedSelectorResponse = matched;
CssHtmlTree.processTemplate(this.templateMatchedSelectors,
this.matchedSelectorsContainer, this);
this.matchedExpander.setAttribute("open", "");
this.tree.styleInspector.inspector.emit("computed-view-property-expanded");
}).then(null, console.error);
} else { } else {
this.matchedSelectorsContainer.innerHTML = ""; this.matchedSelectorsContainer.innerHTML = "";
this.matchedExpander.removeAttribute("open"); this.matchedExpander.removeAttribute("open");
return promise.resolve(undefined);
} }
}, },
get matchedSelectors()
{
return this._matchedSelectorResponse;
},
/** /**
* Provide access to the matched SelectorViews that we are currently * Provide access to the matched SelectorViews that we are currently
* displaying. * displaying.
@ -755,7 +804,7 @@ PropertyView.prototype = {
{ {
if (!this._matchedSelectorViews) { if (!this._matchedSelectorViews) {
this._matchedSelectorViews = []; this._matchedSelectorViews = [];
this.propertyInfo.matchedSelectors.forEach( this._matchedSelectorResponse.forEach(
function matchedSelectorViews_convert(aSelectorInfo) { function matchedSelectorViews_convert(aSelectorInfo) {
this._matchedSelectorViews.push(new SelectorView(this.tree, aSelectorInfo)); this._matchedSelectorViews.push(new SelectorView(this.tree, aSelectorInfo));
}, this); }, this);
@ -802,6 +851,15 @@ function SelectorView(aTree, aSelectorInfo)
this.tree = aTree; this.tree = aTree;
this.selectorInfo = aSelectorInfo; this.selectorInfo = aSelectorInfo;
this._cacheStatusNames(); this._cacheStatusNames();
let rule = this.selectorInfo.rule;
if (rule && rule.parentStyleSheet) {
this.sheet = rule.parentStyleSheet;
this.source = CssLogic.shortSource(this.sheet) + ":" + rule.line;
} else {
this.source = CssLogic.l10n("rule.sourceElement");
this.href = "#";
}
} }
/** /**
@ -859,24 +917,25 @@ SelectorView.prototype = {
return SelectorView.CLASS_NAMES[this.selectorInfo.status - 1]; return SelectorView.CLASS_NAMES[this.selectorInfo.status - 1];
}, },
/** get href()
* A localized Get localized human readable info {
*/ if (this._href) {
text: function SelectorView_text(aElement) { return this._href;
let result = this.selectorInfo.selector.text;
if (this.selectorInfo.elementStyle) {
let source = this.selectorInfo.sourceElement;
let inspector = this.tree.styleInspector.inspector;
if (inspector.selection.node == source) {
result = "this";
} else {
result = CssLogic.getShortName(source);
}
result += ".style";
} }
let sheet = this.selectorInfo.rule.parentStyleSheet;
this._href = sheet ? sheet.href : "#";
return this._href;
},
return result; get sourceText()
{
return this.selectorInfo.sourceText;
},
get value()
{
return this.selectorInfo.value;
}, },
maybeOpenStyleEditor: function(aEvent) maybeOpenStyleEditor: function(aEvent)
@ -900,12 +959,8 @@ SelectorView.prototype = {
openStyleEditor: function(aEvent) openStyleEditor: function(aEvent)
{ {
let inspector = this.tree.styleInspector.inspector; let inspector = this.tree.styleInspector.inspector;
let contentDoc = inspector.selection.document; let rule = this.selectorInfo.rule;
let cssSheet = this.selectorInfo.selector.cssRule._cssSheet; let line = rule.line || 0;
let line = this.selectorInfo.ruleLine || 0;
let contentSheet = false;
let styleSheet;
let styleSheets;
// The style editor can only display stylesheets coming from content because // The style editor can only display stylesheets coming from content because
// chrome stylesheets are not listed in the editor's stylesheet selector. // chrome stylesheets are not listed in the editor's stylesheet selector.
@ -913,40 +968,28 @@ SelectorView.prototype = {
// If the stylesheet is a content stylesheet we send it to the style // If the stylesheet is a content stylesheet we send it to the style
// editor else we display it in the view source window. // editor else we display it in the view source window.
// //
// We check if cssSheet exists in case of inline styles (which contain no
// sheet)
if (cssSheet) {
styleSheet = cssSheet.domSheet;
styleSheets = contentDoc.styleSheets;
// Array.prototype.indexOf always returns -1 here so we loop through let href = rule.href;
// the styleSheets array instead. let sheet = rule.parentStyleSheet;
for each (let sheet in styleSheets) { if (sheet && href && !sheet.isSystem) {
if (sheet == styleSheet) {
contentSheet = true;
break;
}
}
}
if (contentSheet) {
let target = inspector.target; let target = inspector.target;
if (ToolDefinitions.styleEditor.isTargetSupported(target)) { if (ToolDefinitions.styleEditor.isTargetSupported(target)) {
gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) { gDevTools.showToolbox(target, "styleeditor").then(function(toolbox) {
toolbox.getCurrentPanel().selectStyleSheet(styleSheet.href, line); toolbox.getCurrentPanel().selectStyleSheet(href, line);
}); });
} }
} else { return;
let href = styleSheet ? styleSheet.href : "";
let viewSourceUtils = inspector.viewSourceUtils;
if (this.selectorInfo.sourceElement) {
href = this.selectorInfo.sourceElement.ownerDocument.location.href;
}
viewSourceUtils.viewSource(href, null, contentDoc, line);
} }
},
let contentDoc = null;
let rawNode = this.tree.viewedElement.rawNode();
if (rawNode) {
contentDoc = rawNode.ownerDocument;
}
let viewSourceUtils = inspector.viewSourceUtils;
viewSourceUtils.viewSource(href, null, contentDoc, line);
}
}; };
exports.CssHtmlTree = CssHtmlTree; exports.CssHtmlTree = CssHtmlTree;

View File

@ -98,12 +98,12 @@
<a target="_blank" class="link theme-link" <a target="_blank" class="link theme-link"
onclick="${selector.openStyleEditor}" onclick="${selector.openStyleEditor}"
onkeydown="${selector.maybeOpenStyleEditor}" onkeydown="${selector.maybeOpenStyleEditor}"
title="${selector.selectorInfo.href}" title="${selector.href}"
tabindex="0">${selector.selectorInfo.source}</a> tabindex="0">${selector.source}</a>
</span> </span>
<span dir="ltr" class="rule-text ${selector.statusClass} theme-fg-color3" title="${selector.statusText}"> <span dir="ltr" class="rule-text ${selector.statusClass} theme-fg-color3" title="${selector.statusText}">
${selector.text(__element)} ${selector.sourceText}
<span class="other-property-value theme-fg-color1">${selector.selectorInfo.value}</span> <span class="other-property-value theme-fg-color1">${selector.value}</span>
</span> </span>
</p> </p>
</loop> </loop>

View File

@ -15,7 +15,6 @@ loader.lazyGetter(this, "RuleView", () => require("devtools/styleinspector/rule-
loader.lazyGetter(this, "ComputedView", () => require("devtools/styleinspector/computed-view")); loader.lazyGetter(this, "ComputedView", () => require("devtools/styleinspector/computed-view"));
loader.lazyGetter(this, "_strings", () => Services.strings loader.lazyGetter(this, "_strings", () => Services.strings
.createBundle("chrome://browser/locale/devtools/styleinspector.properties")); .createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
loader.lazyGetter(this, "CssLogic", () => require("devtools/styleinspector/css-logic").CssLogic);
// This module doesn't currently export any symbols directly, it only // This module doesn't currently export any symbols directly, it only
// registers inspector tools. // registers inspector tools.
@ -171,21 +170,20 @@ function ComputedViewTool(aInspector, aWindow, aIFrame)
this.window = aWindow; this.window = aWindow;
this.document = aWindow.document; this.document = aWindow.document;
this.outerIFrame = aIFrame; this.outerIFrame = aIFrame;
this.cssLogic = new CssLogic(); this.view = new ComputedView.CssHtmlTree(this, aInspector.pageStyle);
this.view = new ComputedView.CssHtmlTree(this);
this._onSelect = this.onSelect.bind(this); this._onSelect = this.onSelect.bind(this);
this.inspector.selection.on("detached", this._onSelect); this.inspector.selection.on("detached", this._onSelect);
this.inspector.selection.on("new-node", this._onSelect); this.inspector.selection.on("new-node-front", this._onSelect);
if (this.inspector.highlighter) { if (this.inspector.highlighter) {
this.inspector.highlighter.on("locked", this._onSelect); this.inspector.highlighter.on("locked", this._onSelect);
} }
this.refresh = this.refresh.bind(this); this.refresh = this.refresh.bind(this);
this.inspector.on("layout-change", this.refresh); this.inspector.on("layout-change", this.refresh);
this.inspector.sidebar.on("computedview-selected", this.refresh);
this.inspector.selection.on("pseudoclass", this.refresh); this.inspector.selection.on("pseudoclass", this.refresh);
this.panelSelected = this.panelSelected.bind(this);
this.inspector.sidebar.on("computedview-selected", this.panelSelected);
this.cssLogic.highlight(null);
this.view.highlight(null); this.view.highlight(null);
this.onSelect(); this.onSelect();
@ -196,24 +194,35 @@ exports.ComputedViewTool = ComputedViewTool;
ComputedViewTool.prototype = { ComputedViewTool.prototype = {
onSelect: function CVT_onSelect(aEvent) onSelect: function CVT_onSelect(aEvent)
{ {
if (!this.isActive()) {
// We'll try again when we're selected.
return;
}
this.view.setPageStyle(this.inspector.pageStyle);
if (!this.inspector.selection.isConnected() || if (!this.inspector.selection.isConnected() ||
!this.inspector.selection.isElementNode()) { !this.inspector.selection.isElementNode()) {
this.view.highlight(null); this.view.highlight(null);
return; return;
} }
if (!aEvent || aEvent == "new-node") { if (!aEvent || aEvent == "new-node-front") {
if (this.inspector.selection.reason == "highlighter") { if (this.inspector.selection.reason == "highlighter") {
// FIXME: We should hide view's content // FIXME: We should hide view's content
} else { } else {
this.cssLogic.highlight(this.inspector.selection.node); let done = this.inspector.updating("computed-view");
this.view.highlight(this.inspector.selection.node); this.view.highlight(this.inspector.selection.nodeFront).then(() => {
done();
});
} }
} }
if (aEvent == "locked") { if (aEvent == "locked" && this.inspector.selection.nodeFront != this.view.viewedElement) {
this.cssLogic.highlight(this.inspector.selection.node); let done = this.inspector.updating("computed-view");
this.view.highlight(this.inspector.selection.node); this.view.highlight(this.inspector.selection.nodeFront).then(() => {
done();
});
} }
}, },
@ -223,17 +232,24 @@ ComputedViewTool.prototype = {
refresh: function CVT_refresh() { refresh: function CVT_refresh() {
if (this.isActive()) { if (this.isActive()) {
this.cssLogic.highlight(this.inspector.selection.node);
this.view.refreshPanel(); this.view.refreshPanel();
} }
}, },
panelSelected: function() {
if (this.inspector.selection.nodeFront === this.view.viewedElement) {
this.view.refreshPanel();
} else {
this.onSelect();
}
},
destroy: function CVT_destroy(aContext) destroy: function CVT_destroy(aContext)
{ {
this.inspector.off("layout-change", this.refresh); this.inspector.off("layout-change", this.refresh);
this.inspector.sidebar.off("computedview-selected", this.refresh); this.inspector.sidebar.off("computedview-selected", this.refresh);
this.inspector.selection.off("pseudoclass", this.refresh); this.inspector.selection.off("pseudoclass", this.refresh);
this.inspector.selection.off("new-node", this._onSelect); this.inspector.selection.off("new-node-front", this._onSelect);
if (this.inspector.highlighter) { if (this.inspector.highlighter) {
this.inspector.highlighter.off("locked", this._onSelect); this.inspector.highlighter.off("locked", this._onSelect);
} }

View File

@ -12,7 +12,6 @@ relativesrcdir = @relativesrcdir@
include $(DEPTH)/config/autoconf.mk include $(DEPTH)/config/autoconf.mk
MOCHITEST_BROWSER_FILES = \ MOCHITEST_BROWSER_FILES = \
browser_styleinspector.js \
browser_bug683672.js \ browser_bug683672.js \
browser_styleinspector_bug_672746_default_styles.js \ browser_styleinspector_bug_672746_default_styles.js \
browser_styleinspector_bug_672744_search_filter.js \ browser_styleinspector_bug_672744_search_filter.js \

View File

@ -13,6 +13,7 @@ const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/tes
let tempScope = {}; let tempScope = {};
let {CssHtmlTree, PropertyView} = devtools.require("devtools/styleinspector/computed-view"); let {CssHtmlTree, PropertyView} = devtools.require("devtools/styleinspector/computed-view");
let {console} = Cu.import("resource://gre/modules/devtools/Console.jsm", {});
function test() function test()
{ {
@ -25,49 +26,49 @@ function tabLoaded()
{ {
browser.removeEventListener("load", tabLoaded, true); browser.removeEventListener("load", tabLoaded, true);
doc = content.document; doc = content.document;
openInspector(selectNode); openComputedView(selectNode);
} }
function selectNode(aInspector) function selectNode(aInspector, aComputedView)
{ {
inspector = aInspector; inspector = aInspector;
computedView = aComputedView;
div = content.document.getElementById("test"); div = content.document.getElementById("test");
ok(div, "captain, we have the div"); ok(div, "captain, we have the div");
inspector.selection.setNode(div); inspector.selection.setNode(div);
inspector.once("inspector-updated", runTests);
inspector.sidebar.once("computedview-ready", function() {
computedView = getComputedView(inspector);
inspector.sidebar.select("computedview");
runTests();
});
} }
function runTests() function runTests()
{ {
testMatchedSelectors(); testMatchedSelectors().then(() => {
info("finishing up");
info("finishing up"); finishUp();
finishUp(); });
} }
function testMatchedSelectors() function testMatchedSelectors()
{ {
info("checking selector counts, matched rules and titles"); info("checking selector counts, matched rules and titles");
is(div, computedView.viewedElement, is(div, computedView.viewedElement.rawNode(),
"style inspector node matches the selected node"); "style inspector node matches the selected node");
let propertyView = new PropertyView(computedView, "color"); let propertyView = new PropertyView(computedView, "color");
let numMatchedSelectors = propertyView.propertyInfo.matchedSelectors.length; propertyView.buildMain();
propertyView.buildSelectorContainer();
propertyView.matchedExpanded = true;
return propertyView.refreshMatchedSelectors().then(() => {
let numMatchedSelectors = propertyView.matchedSelectors.length;
is(numMatchedSelectors, 6, is(numMatchedSelectors, 6,
"CssLogic returns the correct number of matched selectors for div"); "CssLogic returns the correct number of matched selectors for div");
is(propertyView.hasMatchedSelectors, true, is(propertyView.hasMatchedSelectors, true,
"hasMatchedSelectors returns true"); "hasMatchedSelectors returns true");
}).then(null, (err) => console.error(err));
} }
function finishUp() function finishUp()

View File

@ -11,6 +11,9 @@ let computedView;
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" + const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
"test/browser_bug722196_identify_media_queries.html"; "test/browser_bug722196_identify_media_queries.html";
let {PropertyView} = devtools.require("devtools/styleinspector/computed-view");
let {CssLogic} = devtools.require("devtools/styleinspector/css-logic");
function test() function test()
{ {
waitForExplicitFinish(); waitForExplicitFinish();
@ -23,26 +26,24 @@ function docLoaded()
browser.removeEventListener("load", docLoaded, true); browser.removeEventListener("load", docLoaded, true);
doc = content.document; doc = content.document;
openInspector(selectNode); openComputedView(selectNode);
} }
function selectNode(aInspector) function selectNode(aInspector, aComputedView)
{ {
computedView = aComputedView;
var div = doc.querySelector("div"); var div = doc.querySelector("div");
ok(div, "captain, we have the div"); ok(div, "captain, we have the div");
aInspector.selection.setNode(div); aInspector.selection.setNode(div);
aInspector.once("inspector-updated", checkCssLogic);
aInspector.sidebar.once("computedview-ready", function() {
aInspector.sidebar.select("computedview");
computedView = getComputedView(aInspector);
checkSheets();
});
} }
function checkSheets() function checkCssLogic()
{ {
let cssLogic = computedView.cssLogic; let cssLogic = new CssLogic();
cssLogic.highlight(doc.querySelector("div"));
cssLogic.processMatchedSelectors(); cssLogic.processMatchedSelectors();
let _strings = Services.strings let _strings = Services.strings
@ -57,7 +58,26 @@ function checkSheets()
is(cssLogic._matchedRules[1][0].source, source2, is(cssLogic._matchedRules[1][0].source, source2,
"rule.source gives correct output for rule 2"); "rule.source gives correct output for rule 2");
finishUp(); checkPropertyView();
}
function checkPropertyView()
{
let propertyView = new PropertyView(computedView, "width");
propertyView.buildMain();
propertyView.buildSelectorContainer();
propertyView.matchedExpanded = true;
return propertyView.refreshMatchedSelectors().then(() => {
let numMatchedSelectors = propertyView.matchedSelectors.length;
is(numMatchedSelectors, 2,
"Property view has the correct number of matched selectors for div");
is(propertyView.hasMatchedSelectors, true,
"hasMatchedSelectors returns true");
finishUp();
}).then(null, (err) => console.error(err));
} }
function finishUp() function finishUp()

View File

@ -13,29 +13,23 @@ function createDocument()
doc.title = "Style Inspector Selector Text Test"; doc.title = "Style Inspector Selector Text Test";
openInspector(openComputedView); openComputedView(startTests);
} }
function openComputedView(aInspector) function startTests(aInspector, aComputedView)
{ {
computedView = aComputedView;
let div = doc.querySelector("div"); let div = doc.querySelector("div");
ok(div, "captain, we have the test div"); ok(div, "captain, we have the test div");
aInspector.selection.setNode(div); aInspector.selection.setNode(div);
aInspector.once("inspector-updated", SI_checkText);
aInspector.sidebar.once("computedview-ready", function() {
aInspector.sidebar.select("computedview");
computedView = getComputedView(aInspector);
Services.obs.addObserver(SI_checkText, "StyleInspector-populated", false);
});
} }
function SI_checkText() function SI_checkText()
{ {
Services.obs.removeObserver(SI_checkText, "StyleInspector-populated");
let propertyView = null; let propertyView = null;
computedView.propertyViews.some(function(aView) { computedView.propertyViews.some(function(aView) {
if (aView.name == "color") { if (aView.name == "color") {
@ -50,15 +44,16 @@ function SI_checkText()
is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true"); is(propertyView.hasMatchedSelectors, true, "hasMatchedSelectors is true");
propertyView.matchedExpanded = true; propertyView.matchedExpanded = true;
propertyView.refreshMatchedSelectors(); propertyView.refreshMatchedSelectors().then(() => {
let span = propertyView.matchedSelectorsContainer.querySelector("span.rule-text"); let span = propertyView.matchedSelectorsContainer.querySelector("span.rule-text");
ok(span, "found the first table row"); ok(span, "found the first table row");
let selector = propertyView.matchedSelectorViews[0]; let selector = propertyView.matchedSelectorViews[0];
ok(selector, "found the first matched selector view"); ok(selector, "found the first matched selector view");
finishUp(); finishUp();
});
} }
function finishUp() function finishUp()

View File

@ -42,29 +42,20 @@ const DOCUMENT_URL = "data:text/html,"+encodeURIComponent(
function selectNode(aInspector) function selectNode(aInspector, aComputedView)
{ {
inspector = aInspector; inspector = aInspector;
computedView = aComputedView;
let span = doc.querySelector("span"); let span = doc.querySelector("span");
ok(span, "captain, we have the span"); ok(span, "captain, we have the span");
aInspector.selection.setNode(span); inspector.selection.setNode(span);
inspector.once("inspector-updated", testInlineStyle);
aInspector.sidebar.once("computedview-ready", function() {
aInspector.sidebar.select("computedview");
computedView = getComputedView(aInspector);
Services.obs.addObserver(testInlineStyle, "StyleInspector-populated", false);
});
} }
function testInlineStyle() function testInlineStyle()
{ {
Services.obs.removeObserver(testInlineStyle, "StyleInspector-populated");
info("expanding property");
expandProperty(0, function propertyExpanded() { expandProperty(0, function propertyExpanded() {
Services.ww.registerNotification(function onWindow(aSubject, aTopic) { Services.ww.registerNotification(function onWindow(aSubject, aTopic) {
if (aTopic != "domwindowopened") { if (aTopic != "domwindowopened") {
@ -137,12 +128,13 @@ function validateStyleEditorSheet(aEditor, aExpectedSheetIndex)
function expandProperty(aIndex, aCallback) function expandProperty(aIndex, aCallback)
{ {
info("expanding property " + aIndex);
let contentDoc = computedView.styleDocument; let contentDoc = computedView.styleDocument;
let expando = contentDoc.querySelectorAll(".expandable")[aIndex]; let expando = contentDoc.querySelectorAll(".expandable")[aIndex];
expando.click(); expando.click();
// We use executeSoon to give the property time to expand. inspector.once("computed-view-property-expanded", aCallback);
executeSoon(aCallback);
} }
function getLinkByIndex(aIndex) function getLinkByIndex(aIndex)
@ -168,7 +160,7 @@ function test()
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee,
true); true);
doc = content.document; doc = content.document;
waitForFocus(function () { openInspector(selectNode); }, content); waitForFocus(function () { openComputedView(selectNode); }, content);
}, true); }, true);
content.location = DOCUMENT_URL; content.location = DOCUMENT_URL;

View File

@ -32,33 +32,24 @@ function createDocument()
'</div>'; '</div>';
doc.title = "Computed view context menu test"; doc.title = "Computed view context menu test";
openInspector(selectNode) openComputedView(selectNode)
} }
function selectNode(aInspector) function selectNode(aInspector, aComputedView)
{ {
computedView = aComputedView;
win = aInspector.sidebar.getWindowForTab("computedview");
let span = doc.querySelector("span"); let span = doc.querySelector("span");
ok(span, "captain, we have the span"); ok(span, "captain, we have the span");
aInspector.selection.setNode(span); aInspector.selection.setNode(span);
aInspector.once("inspector-updated", runStyleInspectorTests);
aInspector.sidebar.once("computedview-ready", function() {
aInspector.sidebar.select("computedview");
computedView = getComputedView(aInspector);
win = aInspector.sidebar.getWindowForTab("computedview");
Services.obs.addObserver(runStyleInspectorTests,
"StyleInspector-populated", false);
});
} }
function runStyleInspectorTests() function runStyleInspectorTests()
{ {
Services.obs.removeObserver(runStyleInspectorTests,
"StyleInspector-populated", false);
let contentDocument = computedView.styleDocument; let contentDocument = computedView.styleDocument;
let prop = contentDocument.querySelector(".property-view"); let prop = contentDocument.querySelector(".property-view");
ok(prop, "captain, we have the property-view node"); ok(prop, "captain, we have the property-view node");

View File

@ -1,89 +0,0 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the style inspector works properly
let doc;
let inspector;
let computedView;
function createDocument()
{
doc.body.innerHTML = '<style type="text/css"> ' +
'span { font-variant: small-caps; color: #000000; } ' +
'.nomatches {color: #ff0000;}</style> <div id="first" style="margin: 10em; ' +
'font-size: 14pt; font-family: helvetica, sans-serif; color: #AAA">\n' +
'<h1>Some header text</h1>\n' +
'<p id="salutation" style="font-size: 12pt">hi.</p>\n' +
'<p id="body" style="font-size: 12pt">I am a test-case. This text exists ' +
'solely to provide some things to <span style="color: yellow">' +
'highlight</span> and <span style="font-weight: bold">count</span> ' +
'style list-items in the box at right. If you are reading this, ' +
'you should go do something else instead. Maybe read a book. Or better ' +
'yet, write some test-cases for another bit of code. ' +
'<span style="font-style: italic">Maybe more inspector test-cases!</span></p>\n' +
'<p id="closing">end transmission</p>\n' +
'<p>Inspect using inspectstyle(document.querySelectorAll("span")[0])</p>' +
'</div>';
doc.title = "Style Inspector Test";
openInspector(openComputedView);
}
function openComputedView(aInspector)
{
inspector = aInspector;
inspector.sidebar.once("computedview-ready", function() {
computedView = getComputedView(inspector);
inspector.sidebar.select("computedview");
runStyleInspectorTests();
});
}
function runStyleInspectorTests()
{
var spans = doc.querySelectorAll("span");
ok(spans, "captain, we have the spans");
for (var i = 0, numSpans = spans.length; i < numSpans; i++) {
inspector.selection.setNode(spans[i]);
is(spans[i], computedView.viewedElement,
"style inspector node matches the selected node");
is(computedView.viewedElement, computedView.cssLogic.viewedElement,
"cssLogic node matches the cssHtmlTree node");
}
SI_CheckProperty();
finishUp();
}
function SI_CheckProperty()
{
let cssLogic = computedView.cssLogic;
let propertyInfo = cssLogic.getPropertyInfo("color");
ok(propertyInfo.matchedRuleCount > 0, "color property has matching rules");
}
function finishUp()
{
doc = computedView = null;
gBrowser.removeCurrentTab();
finish();
}
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
doc = content.document;
waitForFocus(createDocument, content);
}, true);
content.location = "data:text/html,basic style inspector tests";
}

View File

@ -16,24 +16,14 @@ function createDocument()
'</div>'; '</div>';
doc.title = "Style Inspector Search Filter Test"; doc.title = "Style Inspector Search Filter Test";
openInspector(openComputedView); openComputedView(runStyleInspectorTests);
} }
function openComputedView(aInspector) function runStyleInspectorTests(aInspector, aComputedView)
{ {
inspector = aInspector; inspector = aInspector;
computedView = aComputedView;
inspector.sidebar.once("computedview-ready", function() {
inspector.sidebar.select("computedview");
computedView = getComputedView(inspector);
runStyleInspectorTests();
});
}
function runStyleInspectorTests()
{
Services.obs.addObserver(SI_toggleDefaultStyles, "StyleInspector-populated", false);
SI_inspectNode(); SI_inspectNode();
} }
@ -43,32 +33,28 @@ function SI_inspectNode()
ok(span, "captain, we have the matches span"); ok(span, "captain, we have the matches span");
inspector.selection.setNode(span); inspector.selection.setNode(span);
inspector.once("inspector-updated", () => {
is(span, computedView.viewedElement, is(span, computedView.viewedElement.rawNode(),
"style inspector node matches the selected node"); "style inspector node matches the selected node");
is(computedView.viewedElement, computedView.cssLogic.viewedElement, SI_toggleDefaultStyles();
"cssLogic node matches the cssHtmlTree node"); }).then(null, (err) => console.error(err));
} }
function SI_toggleDefaultStyles() function SI_toggleDefaultStyles()
{ {
Services.obs.removeObserver(SI_toggleDefaultStyles, "StyleInspector-populated");
info("checking \"Browser styles\" checkbox"); info("checking \"Browser styles\" checkbox");
let doc = computedView.styleDocument; let doc = computedView.styleDocument;
let checkbox = doc.querySelector(".includebrowserstyles"); let checkbox = doc.querySelector(".includebrowserstyles");
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", SI_AddFilterText);
checkbox.click(); checkbox.click();
} }
function SI_AddFilterText() function SI_AddFilterText()
{ {
Services.obs.removeObserver(SI_AddFilterText, "StyleInspector-populated");
let doc = computedView.styleDocument; let doc = computedView.styleDocument;
let searchbar = doc.querySelector(".devtools-searchinput"); let searchbar = doc.querySelector(".devtools-searchinput");
Services.obs.addObserver(SI_checkFilter, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", SI_checkFilter);
info("setting filter text to \"color\""); info("setting filter text to \"color\"");
searchbar.focus(); searchbar.focus();
@ -82,7 +68,6 @@ function SI_AddFilterText()
function SI_checkFilter() function SI_checkFilter()
{ {
Services.obs.removeObserver(SI_checkFilter, "StyleInspector-populated");
let propertyViews = computedView.propertyViews; let propertyViews = computedView.propertyViews;
info("check that the correct properties are visible"); info("check that the correct properties are visible");

View File

@ -16,43 +16,27 @@ function createDocument()
'</div>'; '</div>';
doc.title = "Style Inspector Default Styles Test"; doc.title = "Style Inspector Default Styles Test";
openInspector(openComputedView); openComputedView(SI_inspectNode);
} }
function openComputedView(aInspector) function SI_inspectNode(aInspector, aComputedView)
{ {
inspector = aInspector; inspector = aInspector;
computedView = aComputedView;
inspector.sidebar.once("computedview-ready", function() {
inspector.sidebar.select("computedview");
computedView = getComputedView(inspector);
runStyleInspectorTests();
});
}
function runStyleInspectorTests()
{
Services.obs.addObserver(SI_check, "StyleInspector-populated", false);
SI_inspectNode();
}
function SI_inspectNode()
{
let span = doc.querySelector("#matches"); let span = doc.querySelector("#matches");
ok(span, "captain, we have the matches span"); ok(span, "captain, we have the matches span");
inspector.selection.setNode(span); inspector.selection.setNode(span);
inspector.once("inspector-updated", () => {
is(span, computedView.viewedElement, is(span, computedView.viewedElement.rawNode(),
"style inspector node matches the selected node"); "style inspector node matches the selected node");
is(computedView.viewedElement, computedView.cssLogic.viewedElement, SI_check();
"cssLogic node matches the cssHtmlTree node"); });
} }
function SI_check() function SI_check()
{ {
Services.obs.removeObserver(SI_check, "StyleInspector-populated");
is(propertyVisible("color"), true, is(propertyVisible("color"), true,
"span #matches color property is visible"); "span #matches color property is visible");
is(propertyVisible("background-color"), false, is(propertyVisible("background-color"), false,
@ -66,14 +50,13 @@ function SI_toggleDefaultStyles()
// Click on the checkbox. // Click on the checkbox.
let doc = computedView.styleDocument; let doc = computedView.styleDocument;
let checkbox = doc.querySelector(".includebrowserstyles"); let checkbox = doc.querySelector(".includebrowserstyles");
Services.obs.addObserver(SI_checkDefaultStyles, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", SI_checkDefaultStyles);
checkbox.click(); checkbox.click();
} }
function SI_checkDefaultStyles() function SI_checkDefaultStyles()
{ {
Services.obs.removeObserver(SI_checkDefaultStyles, "StyleInspector-populated");
// Check that the default styles are now applied. // Check that the default styles are now applied.
is(propertyVisible("color"), true, is(propertyVisible("color"), true,
"span color property is visible"); "span color property is visible");

View File

@ -15,45 +15,33 @@ function createDocument()
'<span id="matches" class="matches">Some styled text</span>'; '<span id="matches" class="matches">Some styled text</span>';
doc.title = "Tests that the no results placeholder works properly"; doc.title = "Tests that the no results placeholder works properly";
openInspector(openComputedView); openComputedView(runStyleInspectorTests);
} }
function openComputedView(aInspector) function runStyleInspectorTests(aInspector, aComputedView)
{ {
inspector = aInspector; inspector = aInspector;
computedView = aComputedView;
inspector.sidebar.once("computedview-ready", function() {
inspector.sidebar.select("computedview");
computedView = getComputedView(inspector);
runStyleInspectorTests();
});
}
function runStyleInspectorTests()
{
Services.obs.addObserver(SI_AddFilterText, "StyleInspector-populated", false);
let span = doc.querySelector("#matches"); let span = doc.querySelector("#matches");
ok(span, "captain, we have the matches span"); ok(span, "captain, we have the matches span");
inspector.selection.setNode(span); inspector.selection.setNode(span);
inspector.once("inspector-updated", () => {
is(span, computedView.viewedElement.rawNode(),
"style inspector node matches the selected node");
SI_AddFilterText();
});
is(span, computedView.viewedElement,
"style inspector node matches the selected node");
is(computedView.viewedElement, computedView.cssLogic.viewedElement,
"cssLogic node matches the cssHtmlTree node");
} }
function SI_AddFilterText() function SI_AddFilterText()
{ {
Services.obs.removeObserver(SI_AddFilterText, "StyleInspector-populated");
let searchbar = computedView.searchField; let searchbar = computedView.searchField;
let searchTerm = "xxxxx"; let searchTerm = "xxxxx";
Services.obs.addObserver(SI_checkPlaceholderVisible, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", SI_checkPlaceholderVisible);
info("setting filter text to \"" + searchTerm + "\""); info("setting filter text to \"" + searchTerm + "\"");
searchbar.focus(); searchbar.focus();
for each (let c in searchTerm) { for each (let c in searchTerm) {
@ -63,7 +51,6 @@ function SI_AddFilterText()
function SI_checkPlaceholderVisible() function SI_checkPlaceholderVisible()
{ {
Services.obs.removeObserver(SI_checkPlaceholderVisible, "StyleInspector-populated");
info("SI_checkPlaceholderVisible called"); info("SI_checkPlaceholderVisible called");
let placeholder = computedView.noResults; let placeholder = computedView.noResults;
let win = computedView.styleWindow; let win = computedView.styleWindow;
@ -78,7 +65,7 @@ function SI_ClearFilterText()
{ {
let searchbar = computedView.searchField; let searchbar = computedView.searchField;
Services.obs.addObserver(SI_checkPlaceholderHidden, "StyleInspector-populated", false); inspector.once("computed-view-refreshed", SI_checkPlaceholderHidden);
info("clearing filter text"); info("clearing filter text");
searchbar.focus(); searchbar.focus();
searchbar.value = ""; searchbar.value = "";
@ -87,7 +74,6 @@ function SI_ClearFilterText()
function SI_checkPlaceholderHidden() function SI_checkPlaceholderHidden()
{ {
Services.obs.removeObserver(SI_checkPlaceholderHidden, "StyleInspector-populated");
let placeholder = computedView.noResults; let placeholder = computedView.noResults;
let win = computedView.styleWindow; let win = computedView.styleWindow;
let display = win.getComputedStyle(placeholder).display; let display = win.getComputedStyle(placeholder).display;

View File

@ -59,6 +59,17 @@ function openRuleView(callback)
}); });
} }
function openComputedView(callback)
{
openInspector(inspector => {
inspector.sidebar.once("computedview-ready", () => {
inspector.sidebar.select("computedview");
let ruleView = inspector.sidebar.getWindowForTab("computedview").computedview.view;
callback(inspector, ruleView);
})
});
}
function addStyle(aDocument, aString) function addStyle(aDocument, aString)
{ {
let node = aDocument.createElement('style'); let node = aDocument.createElement('style');