- Add patches to fix coloring of symbolic icons (glgo#GNOME/librsvg#525): * 0001-croco.rs-Add-struct-definition-for-CRSimpleSel.patch * 0002-Compute-the-specificity-of-CSS-selectors.patch * 0003-525-Consider-specificity-when-applying-CSS-selector-.patch OBS-URL: https://build.opensuse.org/request/show/746179 OBS-URL: https://build.opensuse.org/package/show/GNOME:Factory/librsvg?expand=0&rev=164
167 lines
5.4 KiB
Diff
167 lines
5.4 KiB
Diff
From 5796011ea5232783ee89e8467a76656873a3f7b4 Mon Sep 17 00:00:00 2001
|
|
From: Federico Mena Quintero <federico@gnome.org>
|
|
Date: Wed, 6 Nov 2019 17:59:53 -0600
|
|
Subject: [PATCH 2/3] 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 2bb4a3b9..c8ae072c 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;
|
|
}
|
|
}
|
|
|
|
--
|
|
2.23.0
|
|
|