From 133d2e18277e32b21fb0a3c20588e546e68f5001 Mon Sep 17 00:00:00 2001 From: J Smith Date: Fri, 16 Apr 2021 14:36:29 -0300 Subject: [PATCH] Allow CSS functions to be used when expanding dimensions shorthand --- CHANGELOG.md | 2 +- lib/css_parser/regexps.rb | 16 ++++++++++++++++ lib/css_parser/rule_set.rb | 8 +++++++- test/test_rule_set_expanding_shorthand.rb | 12 ++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index de60100..be37493 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ### Unreleased - * Put diff here + * Allow CSS functions to be used in CssParser::RuleSet#expand_dimensions_shorthand! [#126](https://github.com/premailer/css_parser/pull/126) ### Version 1.9.0 diff --git a/lib/css_parser/regexps.rb b/lib/css_parser/regexps.rb index 9b3bcf6..a76ffda 100644 --- a/lib/css_parser/regexps.rb +++ b/lib/css_parser/regexps.rb @@ -58,6 +58,22 @@ def self.regex_possible_values(*values) RE_BORDER_STYLE = /(\s*^)?(none|hidden|dotted|dashed|solid|double|dot-dash|dot-dot-dash|wave|groove|ridge|inset|outset)(\s*$)?/imx.freeze RE_BORDER_UNITS = Regexp.union(BOX_MODEL_UNITS_RX, /(thin|medium|thick)/i) + # Functions like calc, var, clamp, etc. + RE_FUNCTIONS = / + ( + [a-z0-9-]+ # function name + ) + (?> + \( # opening parenthesis + (?: + ([^()]+) + | # recursion via subexpression + \g<0> + )* + \) # closing parenthesis + ) + /imx.freeze + # Patterns for specificity calculations NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX_NC = / (?:\.\w+) # classes diff --git a/lib/css_parser/rule_set.rb b/lib/css_parser/rule_set.rb index 793e80f..dcd6126 100644 --- a/lib/css_parser/rule_set.rb +++ b/lib/css_parser/rule_set.rb @@ -24,6 +24,8 @@ class RuleSet ['border-width', %w[border-top-width border-right-width border-bottom-width border-left-width]] ].freeze + WHITESPACE_REPLACEMENT = '___SPACE___' + class Declarations class Value attr_reader :value @@ -357,6 +359,7 @@ def expand_dimensions_shorthand! # :nodoc: # # TODO: rgba, hsl, hsla value.gsub!(RE_COLOUR) { |c| c.gsub(/(\s*,\s*)/, ',') } + value.gsub!(RE_FUNCTIONS) { |c| c.gsub(/\s+/, WHITESPACE_REPLACEMENT) } matches = value.strip.split(/\s+/) @@ -375,7 +378,10 @@ def expand_dimensions_shorthand! # :nodoc: end t, r, b, l = values - replacement = {top => t, right => r, bottom => b, left => l} + + replacement = {top => t, right => r, bottom => b, left => l}.each_with_object({}) do |(key, replacement_value), memo| + memo[key] = replacement_value.gsub(WHITESPACE_REPLACEMENT, ' ') + end declarations.replace_declaration!(property, replacement, preserve_importance: true) end diff --git a/test/test_rule_set_expanding_shorthand.rb b/test/test_rule_set_expanding_shorthand.rb index 2d41018..7caee4b 100644 --- a/test/test_rule_set_expanding_shorthand.rb +++ b/test/test_rule_set_expanding_shorthand.rb @@ -296,6 +296,18 @@ def test_expanding_important_shorthand_with_replaced_properties assert_equal expected_declarations, declarations end + def test_functions + shorthand = 'margin: calc(1em / 4 * var(--foo)); margin-left: auto; margin-right: auto;' + declarations = expand_declarations(shorthand) + expected_declarations = { + 'margin-top' => 'calc(1em / 4 * var(--foo))', + 'margin-bottom' => 'calc(1em / 4 * var(--foo))', + 'margin-left' => 'auto', + 'margin-right' => 'auto' + } + assert_equal expected_declarations, declarations + end + protected def expand_declarations(declarations)