[librsvg: 3/5] Compute the specificity of CSS selectors
- From: Federico Mena Quintero <federico src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [librsvg: 3/5] Compute the specificity of CSS selectors
- Date: Thu, 7 Nov 2019 00:56:02 +0000 (UTC)
commit 3d3aacb4f3b96fa3bc210ca91c79d4afcc593690
Author: Federico Mena Quintero <federico gnome org>
Date: Wed Nov 6 17:59:53 2019 -0600
Compute the specificity of CSS selectors
And remove the unused function CssRules::lookup()
rsvg_internals/src/croco.rs | 2 ++
rsvg_internals/src/css.rs | 44 ++++++++++++++++++++++++++------------------
2 files changed, 28 insertions(+), 18 deletions(-)
---
diff --git a/rsvg_internals/src/croco.rs b/rsvg_internals/src/croco.rs
index 21ac8051..7bee041d 100644
--- a/rsvg_internals/src/croco.rs
+++ b/rsvg_internals/src/croco.rs
@@ -11,6 +11,7 @@ pub type CRTerm = gpointer;
pub type CRAdditionalSel = gpointer;
pub type CRStatus = u32;
+pub const CR_OK: u32 = 0;
pub type CREncoding = u32;
pub const CR_UTF_8: CREncoding = 5;
@@ -105,6 +106,7 @@ extern "C" {
pub fn cr_selector_unref(a_this: *mut CRSelector) -> gboolean;
pub fn cr_simple_sel_to_string(a_this: *mut CRSimpleSel) -> *mut libc::c_char;
+ pub fn cr_simple_sel_compute_specificity(a_this: *mut CRSimpleSel) -> CRStatus;
pub fn cr_string_peek_raw_str(a_this: CRString) -> *const libc::c_char;
diff --git a/rsvg_internals/src/css.rs b/rsvg_internals/src/css.rs
index 258668ad..bfadeb6c 100644
--- a/rsvg_internals/src/css.rs
+++ b/rsvg_internals/src/css.rs
@@ -73,11 +73,17 @@ impl<'i> AtRuleParser<'i> for DeclParser {
}
#[derive(Clone, Hash, PartialEq, Eq)]
-pub struct Selector(String);
+pub struct Selector {
+ name: String,
+ specificity: u64,
+}
impl Selector {
- fn new(s: &str) -> Selector {
- Selector(s.to_string())
+ fn new(s: &str, specificity: u64) -> Selector {
+ Selector {
+ name: s.to_string(),
+ specificity,
+ }
}
}
@@ -196,10 +202,6 @@ impl CssRules {
decl_list.add_declaration(declaration);
}
- pub fn lookup(&self, selector: &str) -> Option<&DeclarationList> {
- self.get_declarations(&Selector::new(selector))
- }
-
pub fn get_declarations(&self, selector: &Selector) -> Option<&DeclarationList> {
self.selectors_to_declarations.get(selector)
}
@@ -219,12 +221,12 @@ impl CssRules {
let id = node_data.get_id();
// *
- if *selector == Selector::new("*") {
+ if selector.name == "*" {
return true;
}
// tag
- if *selector == Selector::new(element_name) {
+ if selector.name == element_name {
return true;
}
@@ -234,7 +236,7 @@ impl CssRules {
// tag.class#id
if let Some(id) = id {
let target = format!("{}.{}#{}", element_name, cls, id);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
}
@@ -242,20 +244,20 @@ impl CssRules {
// .class#id
if let Some(id) = id {
let target = format!(".{}#{}", cls, id);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
}
// tag.class
let target = format!("{}.{}", element_name, cls);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
// didn't find anything more specific, just apply the class style
let target = format!(".{}", cls);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
}
@@ -265,13 +267,13 @@ impl CssRules {
if let Some(id) = id {
// id
let target = format!("#{}", id);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
// tag#id
let target = format!("{}#{}", element_name, id);
- if *selector == Selector::new(&target) {
+ if selector.name == target {
return true;
}
}
@@ -375,7 +377,15 @@ unsafe extern "C" fn css_property(
while !cur_sel.is_null() {
let simple_sel = (*cur_sel).simple_sel;
+ cur_sel = (*cur_sel).next;
+
if !simple_sel.is_null() {
+ if cr_simple_sel_compute_specificity(simple_sel) != CR_OK {
+ continue;
+ }
+
+ let specificity = u64::from((*simple_sel).specificity);
+
let raw_selector_name = cr_simple_sel_to_string(simple_sel) as *mut libc::c_char;
if !raw_selector_name.is_null() {
@@ -405,14 +415,12 @@ unsafe extern "C" fn css_property(
handler_data
.css_rules
- .add_declaration(Selector::new(&selector_name), declaration);
+ .add_declaration(Selector::new(&selector_name, specificity), declaration);
}
Err(_) => (), // invalid property name or invalid value; ignore
}
}
}
-
- cur_sel = (*cur_sel).next;
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]