librsvg/0002-Compute-the-specificity-of-CSS-selectors.patch
Dominique Leuenberger 1ccad9b44d Accepting request 746179 from home:favogt:branches:GNOME:Factory
- 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
2019-11-07 10:54:08 +00:00

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