Skip to content

Commit 3dba6e3

Browse files
committed
Prefer !important rules over non-!important rules in the same ruleset
Previously, the css rule "color: black !important; color: red;" would be collapsed to "color: red;" as the processor did not take whether the !important flag was set inside the same rule. This commit makes the Declaration Value initializer take notice of the !important flag and correctly handle it.
1 parent 54b8ea5 commit 3dba6e3

File tree

3 files changed

+19
-3
lines changed

3 files changed

+19
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
### Unreleased
44

5+
* Prefer `!important` rules over non-`!important` rules in the same ruleset
56
* Minor performance improvements
67

78
### Version v1.21.0

lib/css_parser/rule_set.rb

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,20 @@ def initialize(declarations = {})
8989
# puts declarations['margin']
9090
# => #<CssParser::RuleSet::Declarations::Value:0x00000000030c1838 @important=true, @order=2, @value="0px auto">
9191
#
92-
# If the property already exists its value will be over-written.
92+
# If the property already exists its value will be over-written unless it was !important and the new value
93+
# is not !important.
9394
# If the value is empty - property will be deleted
9495
def []=(property, value)
9596
property = normalize_property(property)
97+
currently_important = declarations[property]&.important
9698

97-
if value.is_a?(Value)
99+
if value.is_a?(Value) && (!currently_important || value.important)
98100
declarations[property] = value
99101
elsif value.to_s.strip.empty?
100102
delete property
101103
else
102-
declarations[property] = Value.new(value)
104+
value = Value.new(value)
105+
declarations[property] = value if !currently_important || value.important
103106
end
104107
rescue ArgumentError => e
105108
raise e.exception, "#{property} #{e.message}"

test/test_merging.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ def test_merging_important
109109
assert_equal 'black !important;', merged['color']
110110
end
111111

112+
def test_prioritising_important_over_non_important_in_the_same_block
113+
rs1 = RuleSet.new(block: 'color: black !important; color: red;')
114+
merged = CssParser.merge(rs1)
115+
assert_equal 'black !important;', merged['color']
116+
end
117+
118+
def test_prioritising_two_important_declarations_in_the_same_block
119+
rs1 = RuleSet.new(block: 'color: black !important; color: red !important;')
120+
merged = CssParser.merge(rs1)
121+
assert_equal 'red !important;', merged['color']
122+
end
123+
112124
def test_merging_multiple_important
113125
rs1 = RuleSet.new(block: 'color: black !important;', specificity: 1000)
114126
rs2 = RuleSet.new(block: 'color: red !important;', specificity: 1)

0 commit comments

Comments
 (0)