aboutsummaryrefslogtreecommitdiff
path: root/src/css.cc
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2010-04-23 14:53:33 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2010-04-23 14:53:33 +0200
commit0b045d5fe5e9540ba22b2d441d4346fbd3646dd9 (patch)
treefdd30ece6f5c57c6c0fc380065db83ae2d2acd7d /src/css.cc
parent1b40d6342a64924426642cc742849a8172e25fb2 (diff)
use CSS rule position when specificity is equal
When two CSS rules have the same specificity make sure they are applied in the order as they appear in the stylesheets (see [1]). Testcase: <html><head><style> A:link {color: red} A.foo {color: green} </style></head><body> <a class="foo" href=http://www.dillo.org>should be green</a> </body></html> Reported by: corvid [1] http://www.w3.org/TR/CSS2/cascade.html#cascading-order
Diffstat (limited to 'src/css.cc')
-rw-r--r--src/css.cc19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/css.cc b/src/css.cc
index 1b81ea7c..988d0dc6 100644
--- a/src/css.cc
+++ b/src/css.cc
@@ -287,13 +287,14 @@ void CssSimpleSelector::print () {
}
}
-CssRule::CssRule (CssSelector *selector, CssPropertyList *props) {
+CssRule::CssRule (CssSelector *selector, CssPropertyList *props, int pos) {
assert (selector->size () > 0);
this->selector = selector;
this->selector->ref ();
this->props = props;
this->props->ref ();
+ this->pos = pos;
spec = selector->specificity ();
};
@@ -435,17 +436,23 @@ void CssStyleSheet::apply (CssPropertyList *props,
if (ruleList[numLists])
numLists++;
- // Apply potentially matching rules from ruleList[0-3] with
- // ascending specificity. Each ruleList is sorted already.
+ // Apply potentially matching rules from ruleList[0-numLists] with
+ // ascending specificity.
+ // If specificity is equal, rules are applied in order of appearance.
+ // Each ruleList is sorted already.
while (true) {
int minSpec = 1 << 30;
+ int minPos = 1 << 30;
int minSpecIndex = -1;
for (int i = 0; i < numLists; i++) {
if (ruleList[i] && ruleList[i]->size () > index[i] &&
- ruleList[i]->get(index[i])->specificity () < minSpec) {
+ (ruleList[i]->get(index[i])->specificity () < minSpec ||
+ (ruleList[i]->get(index[i])->specificity () == minSpec &&
+ ruleList[i]->get(index[i])->position () < minPos))) {
minSpec = ruleList[i]->get(index[i])->specificity ();
+ minPos = ruleList[i]->get(index[i])->position ();
minSpecIndex = i;
}
}
@@ -465,6 +472,8 @@ CssStyleSheet *CssContext::userStyle;
CssStyleSheet *CssContext::userImportantStyle;
CssContext::CssContext () {
+ pos = 0;
+
for (int o = CSS_PRIMARY_USER_AGENT; o < CSS_PRIMARY_LAST; o++)
sheet[o] = NULL;
@@ -532,7 +541,7 @@ void CssContext::addRule (CssSelector *sel, CssPropertyList *props,
CssPrimaryOrder order) {
if (props->size () > 0) {
- CssRule *rule = new CssRule (sel, props);
+ CssRule *rule = new CssRule (sel, props, pos++);
if (sheet[order] == NULL)
sheet[order] = new CssStyleSheet ();