Skip to content

Commit 69fcf94

Browse files
committed
fix: Fixed style applying rules to use specificity
1 parent e2f3a22 commit 69fcf94

1 file changed

Lines changed: 25 additions & 11 deletions

File tree

harbor/engine/src/html5/dom.rs

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use crate::css::cssom::{
99
CSSDeclaration, CSSRuleNode, CSSRuleType, CSSStyleRuleData, CSSStyleSheet, CSSStyleSheetExt,
1010
ComputedStyle, DocumentOrShadowRootStyle, StyleSheetList,
1111
};
12-
use crate::css::selectors::MatchesElement;
12+
use crate::css::selectors::{ComplexSelector, MatchesElement, Specificity};
1313
use crate::html5::elements::link::LinkElement;
1414
use crate::http::url::URL;
1515
use crate::infra::Serializable;
@@ -1028,7 +1028,8 @@ impl Element {
10281028
let document = node_doc.borrow();
10291029
let style_sheets = document.style_sheets();
10301030

1031-
let mut declarations_to_use: HashMap<String, Vec<CSSDeclaration>> = HashMap::new();
1031+
let mut declarations_to_use: HashMap<String, Vec<(ComplexSelector, CSSDeclaration)>> =
1032+
HashMap::new();
10321033

10331034
for stylesheet in style_sheets.style_sheets.iter() {
10341035
for rule in stylesheet.borrow().css_rules().iter() {
@@ -1046,7 +1047,7 @@ impl Element {
10461047
declarations_to_use
10471048
.entry(declaration.property_name.clone())
10481049
.or_insert_with(Vec::new)
1049-
.push(declaration.clone());
1050+
.push((selector.clone(), declaration.clone()));
10501051

10511052
// handle_declaration(
10521053
// declaration,
@@ -1065,16 +1066,29 @@ impl Element {
10651066
}
10661067
}
10671068

1068-
for (_, declaration) in declarations_to_use.iter() {
1069-
let mut declaration_to_use = declaration.last().unwrap();
1069+
for (_, declarations) in declarations_to_use.iter() {
1070+
let (_, declaration) = declarations
1071+
.iter()
1072+
.max_by(|(selector_a, decl_a), (selector_b, decl_b)| {
1073+
// Compare specificity
1074+
let spec_a = selector_a.specificity();
1075+
let spec_b = selector_b.specificity();
10701076

1071-
for decl in declaration.iter().rev() {
1072-
if decl.important && !declaration_to_use.important {
1073-
declaration_to_use = decl;
1074-
}
1075-
}
1077+
if spec_a != spec_b {
1078+
return spec_a.cmp(&spec_b);
1079+
}
1080+
1081+
if decl_a.important && !decl_b.important {
1082+
return std::cmp::Ordering::Greater;
1083+
} else if !decl_a.important && decl_b.important {
1084+
return std::cmp::Ordering::Less;
1085+
}
1086+
1087+
std::cmp::Ordering::Equal
1088+
})
1089+
.unwrap();
10761090

1077-
handle_declaration(declaration_to_use, self.style_mut(), parents, viewport_size);
1091+
handle_declaration(declaration, self.style_mut(), parents, viewport_size);
10781092
}
10791093

10801094
let mut new_parents = match parents {

0 commit comments

Comments
 (0)