diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c2a87..23470e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### Unreleased +* Prefer `!important` rules over non-`!important` rules in the same ruleset * Minor performance improvements ### Version v1.21.0 diff --git a/lib/css_parser/rule_set.rb b/lib/css_parser/rule_set.rb index 5c06a92..467f2b5 100644 --- a/lib/css_parser/rule_set.rb +++ b/lib/css_parser/rule_set.rb @@ -89,17 +89,20 @@ def initialize(declarations = {}) # puts declarations['margin'] # => # # - # If the property already exists its value will be over-written. + # If the property already exists its value will be over-written unless it was !important and the new value + # is not !important. # If the value is empty - property will be deleted def []=(property, value) property = normalize_property(property) + currently_important = declarations[property]&.important - if value.is_a?(Value) + if value.is_a?(Value) && (!currently_important || value.important) declarations[property] = value elsif value.to_s.strip.empty? delete property else - declarations[property] = Value.new(value) + value = Value.new(value) + declarations[property] = value if !currently_important || value.important end rescue ArgumentError => e raise e.exception, "#{property} #{e.message}" diff --git a/test/test_merging.rb b/test/test_merging.rb index 360f2ae..83f8e41 100644 --- a/test/test_merging.rb +++ b/test/test_merging.rb @@ -109,6 +109,18 @@ def test_merging_important assert_equal 'black !important;', merged['color'] end + def test_prioritising_important_over_non_important_in_the_same_block + rs1 = RuleSet.new(block: 'color: black !important; color: red;') + merged = CssParser.merge(rs1) + assert_equal 'black !important;', merged['color'] + end + + def test_prioritising_two_important_declarations_in_the_same_block + rs1 = RuleSet.new(block: 'color: black !important; color: red !important;') + merged = CssParser.merge(rs1) + assert_equal 'red !important;', merged['color'] + end + def test_merging_multiple_important rs1 = RuleSet.new(block: 'color: black !important;', specificity: 1000) rs2 = RuleSet.new(block: 'color: red !important;', specificity: 1)