Skip to content

Commit

Permalink
Merge pull request #126 from dark-panda/fix-functions
Browse files Browse the repository at this point in the history
Allow CSS functions to be used when expanding dimensions shorthand
  • Loading branch information
grosser committed Jul 27, 2021
2 parents 8cba68f + 2b65639 commit 23a8f8a
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 4 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Expand Up @@ -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

Expand Down
16 changes: 16 additions & 0 deletions lib/css_parser/regexps.rb
Expand Up @@ -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
Expand Down
20 changes: 17 additions & 3 deletions lib/css_parser/rule_set.rb
Expand Up @@ -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
Expand Down Expand Up @@ -358,7 +360,7 @@ def expand_dimensions_shorthand! # :nodoc:
# TODO: rgba, hsl, hsla
value.gsub!(RE_COLOUR) { |c| c.gsub(/(\s*,\s*)/, ',') }

matches = value.strip.split(/\s+/)
matches = split_value_preserving_function_whitespace(value)

case matches.length
when 1
Expand All @@ -374,8 +376,7 @@ def expand_dimensions_shorthand! # :nodoc:
raise ArgumentError, "Cannot parse #{value}"
end

t, r, b, l = values
replacement = {top => t, right => r, bottom => b, left => l}
replacement = [top, right, bottom, left].zip(values).to_h

declarations.replace_declaration!(property, replacement, preserve_importance: true)
end
Expand Down Expand Up @@ -634,6 +635,19 @@ def parse_selectors!(selectors) # :nodoc:
s
end
end

def split_value_preserving_function_whitespace(value)
split_value = value.gsub(RE_FUNCTIONS) do |c|
c.gsub!(/\s+/, WHITESPACE_REPLACEMENT)
c
end

matches = split_value.strip.split(/\s+/)

matches.each do |c|
c.gsub!(WHITESPACE_REPLACEMENT, ' ')
end
end
end

class OffsetAwareRuleSet < RuleSet
Expand Down
48 changes: 48 additions & 0 deletions test/test_rule_set_expanding_shorthand.rb
Expand Up @@ -296,6 +296,54 @@ def test_expanding_important_shorthand_with_replaced_properties
assert_equal expected_declarations, declarations
end

def test_functions_with_many_spaces
shorthand = 'margin: calc(1em / 4 * var(--foo));'
declarations = expand_declarations(shorthand)
expected_declarations = {
'margin-top' => 'calc(1em / 4 * var(--foo))',
'margin-bottom' => 'calc(1em / 4 * var(--foo))',
'margin-left' => 'calc(1em / 4 * var(--foo))',
'margin-right' => 'calc(1em / 4 * var(--foo))'
}
assert_equal expected_declarations, declarations
end

def test_functions_with_no_spaces
shorthand = 'margin: calc(1em/4*4);'
declarations = expand_declarations(shorthand)
expected_declarations = {
'margin-top' => 'calc(1em/4*4)',
'margin-bottom' => 'calc(1em/4*4)',
'margin-left' => 'calc(1em/4*4)',
'margin-right' => 'calc(1em/4*4)'
}
assert_equal expected_declarations, declarations
end

def test_functions_with_one_space
shorthand = 'margin: calc(1em /4);'
declarations = expand_declarations(shorthand)
expected_declarations = {
'margin-top' => 'calc(1em /4)',
'margin-bottom' => 'calc(1em /4)',
'margin-left' => 'calc(1em /4)',
'margin-right' => 'calc(1em /4)'
}
assert_equal expected_declarations, declarations
end

def test_functions_with_commas
shorthand = 'margin: clamp(1rem, 2.5vw, 2rem)'
declarations = expand_declarations(shorthand)
expected_declarations = {
'margin-top' => 'clamp(1rem, 2.5vw, 2rem)',
'margin-bottom' => 'clamp(1rem, 2.5vw, 2rem)',
'margin-left' => 'clamp(1rem, 2.5vw, 2rem)',
'margin-right' => 'clamp(1rem, 2.5vw, 2rem)'
}
assert_equal expected_declarations, declarations
end

protected

def expand_declarations(declarations)
Expand Down

0 comments on commit 23a8f8a

Please sign in to comment.