Skip to content

Commit 22a224b

Browse files
committed
refactor: !important handling
1 parent 7cafa22 commit 22a224b

File tree

6 files changed

+47
-21
lines changed

6 files changed

+47
-21
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66

77
- New `http` & `file` features which give a way to disable resolving external stylesheets and reduce the compiled artifacts size.
88

9+
### Fixed
10+
11+
- `!important` rules not overriding inlined styles. [#152](https://github.com/Stranger6667/css-inline/issues/152)
12+
913
## [0.8.1] - 2022-04-01
1014

1115
### Fixed

bindings/python/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## [Unreleased]
44

5+
### Fixed
6+
7+
- `!important` rules not overriding inlined styles. [#152](https://github.com/Stranger6667/css-inline/issues/152)
8+
59
## [0.8.2] - 2022-04-01
610

711
### Fixed

bindings/wasm/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Fixed
66

77
- Not respecting specificity in case of inlining overlapping rules like `padding` and `padding-top`. [#142](https://github.com/Stranger6667/css-inline/issues/142)
8+
- `!important` rules not overriding inlined styles. [#152](https://github.com/Stranger6667/css-inline/issues/152)
89

910
## [0.8.0] - 2022-01-10
1011

css-inline/src/lib.rs

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -470,28 +470,35 @@ fn merge_styles(
470470
let (name, value) = declaration?;
471471
let mut style = String::with_capacity(256);
472472
style.push_str(&name);
473-
style.push(':');
474-
replace_double_quotes!(style, name, value);
473+
style.push_str(": ");
474+
replace_double_quotes!(style, name, value.trim());
475475
final_styles.push(style);
476476
// This property won't be taken from new styles unless it's !important
477477
buffer.push(name.to_string());
478478
}
479479
for (property, (_, value)) in new_styles {
480-
let index = buffer.iter().position(|r| r == property);
481-
let is_important = value.ends_with("!important");
482-
if index == None || is_important {
483-
let mut style = String::with_capacity(256);
484-
style.push_str(&property);
485-
style.push(':');
486-
replace_double_quotes!(style, property, value);
487-
// Strip !important so additional styles with !important can override this
488-
style = style.replace("!important", "");
489-
style = style.trim().to_string();
490-
if index != None {
491-
final_styles[index.unwrap()] = style;
492-
} else {
493-
final_styles.push(style);
480+
match (
481+
value.strip_suffix("!important"),
482+
buffer.iter().position(|r| r == property),
483+
) {
484+
// The new rule is `!important` and there is already one in existing styles:
485+
// override with the new one.
486+
#[allow(clippy::integer_arithmetic)]
487+
(Some(value), Some(index)) => {
488+
// Reuse existing allocation
489+
let target = &mut final_styles[index];
490+
// Keep '<rule>: ` (with a space at the end)
491+
// NOTE: There will be no overflow as the new len is always smaller than the old one
492+
target.truncate(property.len() + 2);
493+
// And push the value
494+
target.push_str(value.trim())
494495
}
496+
// No such rules exist - push the version with `!important` trimmed
497+
(Some(value), None) => final_styles.push(format!("{}: {}", property, value.trim())),
498+
// Completely new rule - write it
499+
(None, None) => final_styles.push(format!("{}: {}", property, value.trim())),
500+
// Rule exists and the new one is not `!important` - keep the original one
501+
(None, Some(_)) => {}
495502
}
496503
}
497504
Ok(final_styles.join(";"))

css-inline/tests/test_inlining.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ fn simple_merge() {
6262
// Then new styles should be merged with the existing ones
6363
let option_1 = html!(
6464
style,
65-
r#"<h1 style="font-size: 1px;color:red;">Big Text</h1>"#
65+
r#"<h1 style="font-size: 1px;color: red">Big Text</h1>"#
6666
);
6767
let option_2 = html!(
6868
style,
69-
r#"<h1 style="color:red;font-size: 1px;">Big Text</h1>"#
69+
r#"<h1 style="color: red;font-size: 1px">Big Text</h1>"#
7070
);
7171
let valid = (inlined == option_1) || (inlined == option_2);
7272
assert!(valid, "{}", inlined);
@@ -83,6 +83,16 @@ fn overloaded_styles() {
8383
)
8484
}
8585

86+
#[test]
87+
fn important() {
88+
// `!important` rules should override existing inline styles
89+
assert_inlined!(
90+
style = "h1 { color: blue !important; }",
91+
body = r#"<h1 style="color: red;">Big Text</h1>"#,
92+
expected = r#"<h1 style="color: blue">Big Text</h1>"#
93+
)
94+
}
95+
8696
#[test]
8797
fn font_family_quoted() {
8898
// When property value contains double quotes
@@ -102,7 +112,7 @@ fn existing_styles() {
102112
style = "h1 { color: red; }",
103113
body = r#"<h1 style="color: blue">Hello world!</h1>"#,
104114
// Then the existing rule should be preferred
105-
expected = r#"<h1 style="color: blue;">Hello world!</h1>"#
115+
expected = r#"<h1 style="color: blue">Hello world!</h1>"#
106116
)
107117
}
108118

@@ -116,7 +126,7 @@ fn existing_styles_with_merge() {
116126
body = r#"<h1 style="color: blue">Hello world!</h1>"#,
117127
// Then the existing rule should be preferred
118128
// And the new style should be merged
119-
expected = r#"<h1 style="color: blue;font-size:14px;">Hello world!</h1>"#
129+
expected = r#"<h1 style="color: blue;font-size: 14px">Hello world!</h1>"#
120130
)
121131
}
122132

css-inline/tests/test_selectors.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,6 @@ fn overwrite_comma() {
356356
assert_inlined!(
357357
style = r#"h1,h2,h3 {color: #000;}"#,
358358
body = r#"<h1 style="color: #fff">Foo</h1><h3 style="color: #fff">Foo</h3>"#,
359-
expected = r#"<h1 style="color: #fff;">Foo</h1><h3 style="color: #fff;">Foo</h3>"#
359+
expected = r#"<h1 style="color: #fff">Foo</h1><h3 style="color: #fff">Foo</h3>"#
360360
)
361361
}

0 commit comments

Comments
 (0)