зеркало из https://github.com/mozilla/gecko-dev.git
Bug 696180 - Add support for inherited properties to the rule view. r=robcee
This commit is contained in:
Родитель
34e156b413
Коммит
c4e2d0b48a
|
@ -125,19 +125,29 @@ ElementStyle.prototype = {
|
|||
{
|
||||
this.rules = [];
|
||||
|
||||
let element = this.element;
|
||||
do {
|
||||
this._addElementRules(element);
|
||||
} while ((element = element.parentNode) &&
|
||||
element.nodeType === Ci.nsIDOMNode.ELEMENT_NODE);
|
||||
|
||||
// Mark overridden computed styles.
|
||||
this.markOverridden();
|
||||
},
|
||||
|
||||
_addElementRules: function ElementStyle_addElementRules(aElement)
|
||||
{
|
||||
let inherited = aElement !== this.element ? aElement : null;
|
||||
|
||||
// Include the element's style first.
|
||||
this.rules.push(new Rule(this, {
|
||||
style: this.element.style,
|
||||
selectorText: CssLogic.l10n("rule.sourceElement")
|
||||
}));
|
||||
this._maybeAddRule({
|
||||
style: aElement.style,
|
||||
selectorText: CssLogic.l10n("rule.sourceElement"),
|
||||
inherited: inherited
|
||||
});
|
||||
|
||||
// Get the styles that apply to the element.
|
||||
try {
|
||||
var domRules = this.domUtils.getCSSStyleRules(this.element);
|
||||
} catch (ex) {
|
||||
Services.console.logStringMessage("ElementStyle_populate error: " + ex);
|
||||
return;
|
||||
}
|
||||
var domRules = this.domUtils.getCSSStyleRules(aElement);
|
||||
|
||||
// getCSStyleRules returns ordered from least-specific to
|
||||
// most-specific.
|
||||
|
@ -150,14 +160,43 @@ ElementStyle.prototype = {
|
|||
continue;
|
||||
}
|
||||
|
||||
// XXX: non-style rules.
|
||||
if (domRule.type === Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
this.rules.push(new Rule(this, { domRule: domRule }));
|
||||
if (domRule.type !== Ci.nsIDOMCSSRule.STYLE_RULE) {
|
||||
continue;
|
||||
}
|
||||
|
||||
this._maybeAddRule({
|
||||
domRule: domRule,
|
||||
inherited: inherited
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a rule if it's one we care about. Filters out duplicates and
|
||||
* inherited styles with no inherited properties.
|
||||
*
|
||||
* @param {object} aOptions
|
||||
* Options for creating the Rule, see the Rule constructor.
|
||||
*
|
||||
* @return true if we added the rule.
|
||||
*/
|
||||
_maybeAddRule: function ElementStyle_maybeAddRule(aOptions)
|
||||
{
|
||||
// If we've already included this domRule (for example, when a
|
||||
// common selector is inherited), ignore it.
|
||||
if (aOptions.domRule &&
|
||||
this.rules.some(function(rule) rule.domRule === aOptions.domRule)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Mark overridden computed styles.
|
||||
this.markOverridden();
|
||||
let rule = new Rule(this, aOptions);
|
||||
|
||||
// Ignore inherited rules with no properties.
|
||||
if (aOptions.inherited && rule.textProps.length == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.rules.push(rule);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -178,7 +217,7 @@ ElementStyle.prototype = {
|
|||
let computedProps = [];
|
||||
for each (let textProp in textProps) {
|
||||
computedProps = computedProps.concat(textProp.computed);
|
||||
};
|
||||
}
|
||||
|
||||
// Walk over the computed properties. As we see a property name
|
||||
// for the first time, mark that property's name as taken by this
|
||||
|
@ -273,6 +312,8 @@ ElementStyle.prototype = {
|
|||
* the domRule's style will be used.
|
||||
* selectorText: selector text to display. If omitted, the domRule's
|
||||
* selectorText will be used.
|
||||
* inherited: An element this rule was inherited from. If omitted,
|
||||
* the rule applies directly to the current element.
|
||||
* @constructor
|
||||
*/
|
||||
function Rule(aElementStyle, aOptions)
|
||||
|
@ -281,7 +322,7 @@ function Rule(aElementStyle, aOptions)
|
|||
this.domRule = aOptions.domRule || null;
|
||||
this.style = aOptions.style || this.domRule.style;
|
||||
this.selectorText = aOptions.selectorText || this.domRule.selectorText;
|
||||
|
||||
this.inherited = aOptions.inherited || null;
|
||||
this._getTextProperties();
|
||||
}
|
||||
|
||||
|
@ -297,6 +338,17 @@ Rule.prototype = {
|
|||
let line = this.elementStyle.domUtils.getRuleLine(this.domRule);
|
||||
this._title += ":" + line;
|
||||
}
|
||||
|
||||
if (this.inherited) {
|
||||
let eltText = this.inherited.tagName.toLowerCase();
|
||||
if (this.inherited.id) {
|
||||
eltText += "#" + this.inherited.id;
|
||||
}
|
||||
let args = [eltText, this._title];
|
||||
this._title = CssLogic._strings.formatStringFromName("rule.inheritedSource",
|
||||
args, args.length);
|
||||
}
|
||||
|
||||
return this._title;
|
||||
},
|
||||
|
||||
|
@ -416,7 +468,13 @@ Rule.prototype = {
|
|||
if(!matches || !matches[2])
|
||||
continue;
|
||||
|
||||
let prop = new TextProperty(this, matches[1], matches[2], matches[3] || "");
|
||||
let name = matches[1];
|
||||
if (this.inherited &&
|
||||
!this.elementStyle.domUtils.isInheritedProperty(name)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
let prop = new TextProperty(this, name, matches[2], matches[3] || "");
|
||||
this.textProps.push(prop);
|
||||
}
|
||||
},
|
||||
|
|
|
@ -53,6 +53,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_styleinspector_bug_672744_search_filter.js \
|
||||
browser_bug_692400_element_style.js \
|
||||
browser_ruleview_editor.js \
|
||||
browser_ruleview_inherit.js \
|
||||
browser_ruleview_manipulation.js \
|
||||
browser_ruleview_override.js \
|
||||
browser_ruleview_ui.js \
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Cu.import("resource:///modules/devtools/CssRuleView.jsm");
|
||||
|
||||
let doc;
|
||||
|
||||
function simpleInherit()
|
||||
{
|
||||
let style = '' +
|
||||
'#test2 {' +
|
||||
' background-color: green;' +
|
||||
' color: purple;' +
|
||||
'}';
|
||||
|
||||
let styleNode = addStyle(doc, style);
|
||||
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
let inheritRule = elementStyle.rules[1];
|
||||
is(inheritRule.selectorText, "#test2", "Inherited rule should be the one that includes inheritable properties.");
|
||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||
let inheritProp = inheritRule.textProps[0];
|
||||
is(inheritProp.name, "color", "color should have been inherited.");
|
||||
|
||||
styleNode.parentNode.removeChild(styleNode);
|
||||
|
||||
emptyInherit();
|
||||
}
|
||||
|
||||
function emptyInherit()
|
||||
{
|
||||
// No inheritable styles, this rule shouldn't show up.
|
||||
let style = '' +
|
||||
'#test2 {' +
|
||||
' background-color: green;' +
|
||||
'}';
|
||||
|
||||
let styleNode = addStyle(doc, style);
|
||||
doc.body.innerHTML = '<div id="test2"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 1, "Should have 1 rule.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
styleNode.parentNode.removeChild(styleNode);
|
||||
|
||||
elementStyleInherit();
|
||||
}
|
||||
|
||||
function elementStyleInherit()
|
||||
{
|
||||
doc.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>';
|
||||
|
||||
let elementStyle = new _ElementStyle(doc.getElementById("test1"));
|
||||
|
||||
is(elementStyle.rules.length, 2, "Should have 2 rules.");
|
||||
|
||||
let elementRule = elementStyle.rules[0];
|
||||
ok(!elementRule.inherited, "Element style attribute should not consider itself inherited.");
|
||||
|
||||
let inheritRule = elementStyle.rules[1];
|
||||
ok(!inheritRule.domRule, "Inherited rule should be an element style, not a rule.");
|
||||
ok(!!inheritRule.inherited, "Rule should consider itself inherited.");
|
||||
is(inheritRule.textProps.length, 1, "Should only display one inherited style");
|
||||
let inheritProp = inheritRule.textProps[0];
|
||||
is(inheritProp.name, "color", "color should have been inherited.");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function finishTest()
|
||||
{
|
||||
doc = 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(simpleInherit, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic style inspector tests";
|
||||
}
|
|
@ -19,6 +19,12 @@ rule.status.UNMATCHED=Unmatched
|
|||
rule.sourceInline=inline
|
||||
rule.sourceElement=element
|
||||
|
||||
# LOCALIZATION NOTE (rule.inheritedSource): Shown for CSS rules
|
||||
# that were inherited from a parent node. Will be passed a node
|
||||
# identifier and a source location.
|
||||
# e.g "Inherited from body#bodyID (styles.css:20)"
|
||||
rule.inheritedSource=Inherited from %S (%S)
|
||||
|
||||
# LOCALIZATION NOTE (group): Style properties are displayed in categories and
|
||||
# these are the category names.
|
||||
group.Text_Fonts_and_Color=Text, Fonts & Color
|
||||
|
@ -34,3 +40,4 @@ group.Effects_and_Other=Effects and Other
|
|||
style.highlighter.button.label1=Properties
|
||||
style.highlighter.accesskey1=P
|
||||
style.highlighter.button.tooltip=Inspect element styles
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче