зеркало из https://github.com/mozilla/gecko-dev.git
Bug 680111 - style inspector is not showing the correct selected rule, r=msucan
This commit is contained in:
Родитель
f3b4cf2717
Коммит
61c9d976da
|
@ -1087,6 +1087,7 @@ function CssSelector(aCssRule, aSelector)
|
|||
this._cssRule = aCssRule;
|
||||
this.text = aSelector;
|
||||
this.elementStyle = this.text == "@element.style";
|
||||
this._specificity = null;
|
||||
}
|
||||
|
||||
CssSelector.prototype = {
|
||||
|
@ -1168,6 +1169,57 @@ CssSelector.prototype = {
|
|||
return this._cssRule.line;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve specificity information for the current selector.
|
||||
*
|
||||
* @see http://www.w3.org/TR/css3-selectors/#specificity
|
||||
* @see http://www.w3.org/TR/CSS2/selector.html
|
||||
*
|
||||
* @return {object} an object holding specificity information for the current
|
||||
* selector.
|
||||
*/
|
||||
get specificity()
|
||||
{
|
||||
if (this._specificity) {
|
||||
return this._specificity;
|
||||
}
|
||||
|
||||
let specificity = {};
|
||||
|
||||
specificity.ids = 0;
|
||||
specificity.classes = 0;
|
||||
specificity.tags = 0;
|
||||
|
||||
// Split on CSS combinators (section 5.2).
|
||||
// TODO: We need to properly parse the selector. See bug 592743.
|
||||
if (!this.elementStyle) {
|
||||
this.text.split(/[ >+]/).forEach(function(aSimple) {
|
||||
// The regex leaves empty nodes combinators like ' > '
|
||||
if (!aSimple) {
|
||||
return;
|
||||
}
|
||||
// See http://www.w3.org/TR/css3-selectors/#specificity
|
||||
// We can count the IDs by counting the '#' marks.
|
||||
specificity.ids += (aSimple.match(/#/g) || []).length;
|
||||
// Similar with class names and attribute matchers
|
||||
specificity.classes += (aSimple.match(/\./g) || []).length;
|
||||
specificity.classes += (aSimple.match(/\[/g) || []).length;
|
||||
// Pseudo elements count as elements.
|
||||
specificity.tags += (aSimple.match(/:/g) || []).length;
|
||||
// If we have anything of substance before we get into ids/classes/etc
|
||||
// then it must be a tag if it isn't '*'.
|
||||
let tag = aSimple.split(/[#.[:]/)[0];
|
||||
if (tag && tag != "*") {
|
||||
specificity.tags++;
|
||||
}
|
||||
}, this);
|
||||
}
|
||||
|
||||
this._specificity = specificity;
|
||||
|
||||
return this._specificity;
|
||||
},
|
||||
|
||||
toString: function CssSelector_toString()
|
||||
{
|
||||
return this.text;
|
||||
|
@ -1470,6 +1522,25 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
|
|||
|
||||
let priority = this.selector._cssRule.getPropertyPriority(this.property);
|
||||
this.important = (priority === "important");
|
||||
|
||||
/* Score prefix:
|
||||
0 UA normal property
|
||||
1 UA important property
|
||||
2 normal property
|
||||
3 inline (element.style)
|
||||
4 important
|
||||
5 inline important
|
||||
*/
|
||||
let scorePrefix = this.systemRule ? 0 : 2;
|
||||
if (this.elementStyle) {
|
||||
scorePrefix++;
|
||||
}
|
||||
if (this.important) {
|
||||
scorePrefix += this.systemRule ? 1 : 2;
|
||||
}
|
||||
|
||||
this.specificityScore = "" + scorePrefix + this.specificity.ids +
|
||||
this.specificity.classes + this.specificity.tags;
|
||||
}
|
||||
|
||||
CssSelectorInfo.prototype = {
|
||||
|
@ -1518,6 +1589,17 @@ CssSelectorInfo.prototype = {
|
|||
return this.selector.elementStyle;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve specificity information for the current selector.
|
||||
*
|
||||
* @return {object} an object holding specificity information for the current
|
||||
* selector.
|
||||
*/
|
||||
get specificity()
|
||||
{
|
||||
return this.selector.specificity;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve the parent stylesheet index/position in the viewed document.
|
||||
*
|
||||
|
@ -1587,6 +1669,15 @@ CssSelectorInfo.prototype = {
|
|||
if (this.important && !aThat.important) return -1;
|
||||
if (aThat.important && !this.important) return 1;
|
||||
|
||||
if (this.specificity.ids > aThat.specificity.ids) return -1;
|
||||
if (aThat.specificity.ids > this.specificity.ids) return 1;
|
||||
|
||||
if (this.specificity.classes > aThat.specificity.classes) return -1;
|
||||
if (aThat.specificity.classes > this.specificity.classes) return 1;
|
||||
|
||||
if (this.specificity.tags > aThat.specificity.tags) return -1;
|
||||
if (aThat.specificity.tags > this.specificity.tags) return 1;
|
||||
|
||||
if (this.sheetIndex > aThat.sheetIndex) return -1;
|
||||
if (aThat.sheetIndex > this.sheetIndex) return 1;
|
||||
|
||||
|
|
|
@ -104,6 +104,13 @@ function teststylePanels() {
|
|||
doc.getElementById("container")
|
||||
];
|
||||
|
||||
// We have 3 style inspector instances, each with an element selected:
|
||||
// 1. #text
|
||||
// 2. #text2
|
||||
// 3. #container
|
||||
//
|
||||
// We will loop through each instance and check that the correct node is
|
||||
// selected and that the correct css selector has been selected as active
|
||||
info("looping through array to check initialization");
|
||||
for (let i = 0, max = stylePanels.length; i < max; i++) {
|
||||
ok(stylePanels[i], "style inspector instance " + i +
|
||||
|
@ -111,15 +118,40 @@ function teststylePanels() {
|
|||
ok(stylePanels[i].isOpen(), "style inspector " + i + " is open");
|
||||
|
||||
let htmlTree = stylePanels[i].cssHtmlTree;
|
||||
let cssLogic = htmlTree.cssLogic;
|
||||
let elt = eltArray[i];
|
||||
let eltId = elt.id;
|
||||
|
||||
is(eltArray[i], htmlTree.viewedElement,
|
||||
"style inspector node matches the selected node (id=" +
|
||||
eltArray[i].id + ")");
|
||||
// Check that the correct node is selected
|
||||
is(elt, htmlTree.viewedElement,
|
||||
"style inspector node matches the selected node (id=" + eltId + ")");
|
||||
is(htmlTree.viewedElement, stylePanels[i].cssLogic.viewedElement,
|
||||
"cssLogic node matches the cssHtmlTree node (id=" + eltArray[i].id + ")");
|
||||
"cssLogic node matches the cssHtmlTree node (id=" + eltId + ")");
|
||||
|
||||
ok(groupRuleCount(0, stylePanels[i]) > 0,
|
||||
"we have rules for the current node (id=" + eltArray[i].id + ")");
|
||||
|
||||
// Check that the correct css selector has been selected as active
|
||||
let matchedSelectors = cssLogic.getPropertyInfo("font-family").matchedSelectors;
|
||||
let sel = matchedSelectors[0];
|
||||
let selector = sel.selector.text;
|
||||
let value = sel.value;
|
||||
|
||||
// Because we know which selectors should be the best match and what their
|
||||
// values should be we can check them
|
||||
switch(eltId) {
|
||||
case "text":
|
||||
is(selector, "#container > .text", "correct best match for #text");
|
||||
is(value, "cursive", "correct css property value for #" + eltId);
|
||||
break;
|
||||
case "text2":
|
||||
is(selector, "#container > span", "correct best match for #text2");
|
||||
is(value, "cursive", "correct css property value for #" + eltId);
|
||||
break;
|
||||
case "container":
|
||||
is(selector, "#container", "correct best match for #container");
|
||||
is(value, "fantasy", "correct css property value for #" + eltId);
|
||||
}
|
||||
}
|
||||
|
||||
info("hiding stylePanels[1]");
|
||||
|
|
Загрузка…
Ссылка в новой задаче