Bug 680111 - style inspector is not showing the correct selected rule, r=msucan

This commit is contained in:
Mike Ratcliffe 2011-08-30 13:38:30 -03:00
Родитель f3b4cf2717
Коммит 61c9d976da
2 изменённых файлов: 127 добавлений и 4 удалений

Просмотреть файл

@ -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]");