css_parser 1.20.0 → 1.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/css_parser/parser.rb +15 -13
- data/lib/css_parser/rule_set.rb +22 -17
- data/lib/css_parser/version.rb +1 -1
- data/lib/css_parser.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebc43b9f09241b83ffe9a2878e0a2e5295c79f6d2e02bb20dcaf54d376f91e58
|
4
|
+
data.tar.gz: 5b29858923af894f1b84251c59de6a4638ae0929b63ac0b432a7607d9dd32111
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fd7a00f2be5a2ddbf730eb115dbc0e15f9ac7a71ac92e1a056161a2b418e01d7abeb757c6f8d5fabafd9e4f7dba034b209ca571012ee44ee6b377b2e4bd8100f
|
7
|
+
data.tar.gz: ac8aeba706f1ae35126c6d5c4a150a52862af8654f1342e6c5b36ebce8c0b71c26e0d0931d09081b3b01a70685c3d2b173031a3e1ff32a8477799c3e39e013e4
|
data/lib/css_parser/parser.rb
CHANGED
@@ -359,9 +359,9 @@ module CssParser
|
|
359
359
|
in_at_media_rule = false
|
360
360
|
in_media_block = false
|
361
361
|
|
362
|
-
current_selectors =
|
363
|
-
current_media_query =
|
364
|
-
current_declarations =
|
362
|
+
current_selectors = +''
|
363
|
+
current_media_query = +''
|
364
|
+
current_declarations = +''
|
365
365
|
|
366
366
|
# once we are in a rule, we will use this to store where we started if we are capturing offsets
|
367
367
|
rule_start = nil
|
@@ -405,18 +405,19 @@ module CssParser
|
|
405
405
|
media_types: current_media_queries
|
406
406
|
}
|
407
407
|
if options[:capture_offsets]
|
408
|
-
add_rule_options
|
408
|
+
add_rule_options[:filename] = options[:filename]
|
409
|
+
add_rule_options[:offset] = rule_start..end_offset
|
409
410
|
end
|
410
411
|
add_rule!(**add_rule_options)
|
411
412
|
end
|
412
413
|
|
413
|
-
current_selectors =
|
414
|
-
current_declarations =
|
414
|
+
current_selectors = +''
|
415
|
+
current_declarations = +''
|
415
416
|
|
416
417
|
# restart our search for selectors and declarations
|
417
418
|
rule_start = nil if options[:capture_offsets]
|
418
419
|
end
|
419
|
-
elsif
|
420
|
+
elsif /@media/i.match?(token)
|
420
421
|
# found '@media', reset current media_types
|
421
422
|
in_at_media_rule = true
|
422
423
|
current_media_queries = []
|
@@ -426,14 +427,14 @@ module CssParser
|
|
426
427
|
in_at_media_rule = false
|
427
428
|
in_media_block = true
|
428
429
|
current_media_queries << CssParser.sanitize_media_query(current_media_query)
|
429
|
-
current_media_query =
|
430
|
+
current_media_query = +''
|
430
431
|
elsif token.include?(',')
|
431
432
|
# new media query begins
|
432
433
|
token.tr!(',', ' ')
|
433
434
|
token.strip!
|
434
435
|
current_media_query << token << ' '
|
435
436
|
current_media_queries << CssParser.sanitize_media_query(current_media_query)
|
436
|
-
current_media_query =
|
437
|
+
current_media_query = +''
|
437
438
|
else
|
438
439
|
token.strip!
|
439
440
|
# special-case the ( and ) tokens to remove inner-whitespace
|
@@ -447,7 +448,7 @@ module CssParser
|
|
447
448
|
current_media_query << token << ' '
|
448
449
|
end
|
449
450
|
end
|
450
|
-
elsif in_charset or
|
451
|
+
elsif in_charset or /@charset/i.match?(token)
|
451
452
|
# iterate until we are out of the charset declaration
|
452
453
|
in_charset = !token.include?(';')
|
453
454
|
elsif !in_string && token.include?('}')
|
@@ -466,7 +467,7 @@ module CssParser
|
|
466
467
|
current_selectors << token
|
467
468
|
|
468
469
|
# mark this as the beginning of the selector unless we have already marked it
|
469
|
-
rule_start = start_offset if options[:capture_offsets] && rule_start.nil? &&
|
470
|
+
rule_start = start_offset if options[:capture_offsets] && rule_start.nil? && /^[^\s]+$/.match?(token)
|
470
471
|
end
|
471
472
|
end
|
472
473
|
|
@@ -478,7 +479,8 @@ module CssParser
|
|
478
479
|
media_types: current_media_queries
|
479
480
|
}
|
480
481
|
if options[:capture_offsets]
|
481
|
-
add_rule_options
|
482
|
+
add_rule_options[:filename] = options[:filename]
|
483
|
+
add_rule_options[:offset] = rule_start..end_offset
|
482
484
|
end
|
483
485
|
add_rule!(**add_rule_options)
|
484
486
|
end
|
@@ -718,7 +720,7 @@ module CssParser
|
|
718
720
|
nodes = {}
|
719
721
|
lines.each do |line|
|
720
722
|
parts = line.split(':', 2)
|
721
|
-
if parts[1]
|
723
|
+
if parts[1].include?(':')
|
722
724
|
nodes[parts[0]] = css_node_to_h(hash, parts[0], parts[1])
|
723
725
|
else
|
724
726
|
nodes[parts[0].to_s.strip] = parts[1].to_s.strip
|
data/lib/css_parser/rule_set.rb
CHANGED
@@ -11,8 +11,10 @@ module CssParser
|
|
11
11
|
BACKGROUND_PROPERTIES = ['background-color', 'background-image', 'background-repeat', 'background-position', 'background-size', 'background-attachment'].freeze
|
12
12
|
LIST_STYLE_PROPERTIES = ['list-style-type', 'list-style-position', 'list-style-image'].freeze
|
13
13
|
FONT_STYLE_PROPERTIES = ['font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family'].freeze
|
14
|
+
FONT_WEIGHT_PROPERTIES = ['font-style', 'font-weight', 'font-variant'].freeze
|
14
15
|
BORDER_STYLE_PROPERTIES = ['border-width', 'border-style', 'border-color'].freeze
|
15
16
|
BORDER_PROPERTIES = ['border', 'border-left', 'border-right', 'border-top', 'border-bottom'].freeze
|
17
|
+
DIMENSION_DIRECTIONS = [:top, :right, :bottom, :left].freeze
|
16
18
|
|
17
19
|
NUMBER_OF_DIMENSIONS = 4
|
18
20
|
|
@@ -87,17 +89,20 @@ module CssParser
|
|
87
89
|
# puts declarations['margin']
|
88
90
|
# => #<CssParser::RuleSet::Declarations::Value:0x00000000030c1838 @important=true, @order=2, @value="0px auto">
|
89
91
|
#
|
90
|
-
# 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.
|
91
94
|
# If the value is empty - property will be deleted
|
92
95
|
def []=(property, value)
|
93
96
|
property = normalize_property(property)
|
97
|
+
currently_important = declarations[property]&.important
|
94
98
|
|
95
|
-
if value.is_a?(Value)
|
99
|
+
if value.is_a?(Value) && (!currently_important || value.important)
|
96
100
|
declarations[property] = value
|
97
101
|
elsif value.to_s.strip.empty?
|
98
102
|
delete property
|
99
103
|
else
|
100
|
-
|
104
|
+
value = Value.new(value)
|
105
|
+
declarations[property] = value if !currently_important || value.important
|
101
106
|
end
|
102
107
|
rescue ArgumentError => e
|
103
108
|
raise e.exception, "#{property} #{e.message}"
|
@@ -196,7 +201,7 @@ module CssParser
|
|
196
201
|
end
|
197
202
|
|
198
203
|
def to_s(options = {})
|
199
|
-
str = declarations.reduce(
|
204
|
+
str = declarations.reduce(+'') do |memo, (prop, value)|
|
200
205
|
importance = options[:force_important] || value.important ? ' !important' : ''
|
201
206
|
memo << "#{prop}: #{value.value}#{importance}; "
|
202
207
|
end
|
@@ -455,17 +460,17 @@ module CssParser
|
|
455
460
|
else
|
456
461
|
font_props['font-family'] = m
|
457
462
|
end
|
458
|
-
elsif
|
459
|
-
|
463
|
+
elsif /normal|inherit/i.match?(m)
|
464
|
+
FONT_WEIGHT_PROPERTIES.each do |font_prop|
|
460
465
|
font_props[font_prop] ||= m
|
461
466
|
end
|
462
|
-
elsif
|
467
|
+
elsif /italic|oblique/i.match?(m)
|
463
468
|
font_props['font-style'] = m
|
464
|
-
elsif
|
469
|
+
elsif /small-caps/i.match?(m)
|
465
470
|
font_props['font-variant'] = m
|
466
|
-
elsif
|
471
|
+
elsif /[1-9]00$|bold|bolder|lighter/i.match?(m)
|
467
472
|
font_props['font-weight'] = m
|
468
|
-
elsif
|
473
|
+
elsif CssParser::FONT_UNITS_RX.match?(m)
|
469
474
|
if m.include?('/')
|
470
475
|
font_props['font-size'], font_props['line-height'] = m.split('/', 2)
|
471
476
|
else
|
@@ -488,7 +493,7 @@ module CssParser
|
|
488
493
|
value = declaration.value.dup
|
489
494
|
|
490
495
|
replacement =
|
491
|
-
if
|
496
|
+
if CssParser::RE_INHERIT.match?(value)
|
492
497
|
LIST_STYLE_PROPERTIES.to_h { |key| [key, 'inherit'] }
|
493
498
|
else
|
494
499
|
{
|
@@ -554,15 +559,15 @@ module CssParser
|
|
554
559
|
#
|
555
560
|
# TODO: this is extremely similar to create_background_shorthand! and should be combined
|
556
561
|
def create_border_shorthand! # :nodoc:
|
557
|
-
values = BORDER_STYLE_PROPERTIES.
|
562
|
+
values = BORDER_STYLE_PROPERTIES.filter_map do |property|
|
558
563
|
next unless (declaration = declarations[property])
|
559
564
|
next if declaration.important
|
560
565
|
# can't merge if any value contains a space (i.e. has multiple values)
|
561
566
|
# we temporarily remove any spaces after commas for the check (inside rgba, etc...)
|
562
|
-
next if declaration.value.gsub(/,\s/, ',').strip
|
567
|
+
next if /\s/.match?(declaration.value.gsub(/,\s/, ',').strip)
|
563
568
|
|
564
569
|
declaration.value
|
565
|
-
end
|
570
|
+
end
|
566
571
|
|
567
572
|
return if values.size != BORDER_STYLE_PROPERTIES.size
|
568
573
|
|
@@ -579,7 +584,7 @@ module CssParser
|
|
579
584
|
return if declarations.size < NUMBER_OF_DIMENSIONS
|
580
585
|
|
581
586
|
DIMENSIONS.each do |property, dimensions|
|
582
|
-
values =
|
587
|
+
values = DIMENSION_DIRECTIONS.each_with_index.with_object({}) do |(side, index), result|
|
583
588
|
next unless (declaration = declarations[dimensions[index]])
|
584
589
|
|
585
590
|
result[side] = declaration.value
|
@@ -602,7 +607,7 @@ module CssParser
|
|
602
607
|
def create_font_shorthand! # :nodoc:
|
603
608
|
return unless FONT_STYLE_PROPERTIES.all? { |prop| declarations.key?(prop) }
|
604
609
|
|
605
|
-
new_value =
|
610
|
+
new_value = +''
|
606
611
|
['font-style', 'font-variant', 'font-weight'].each do |property|
|
607
612
|
unless declarations[property].value == 'normal'
|
608
613
|
new_value << declarations[property].value << ' '
|
@@ -639,7 +644,7 @@ module CssParser
|
|
639
644
|
return [:top] if values.values.uniq.count == 1
|
640
645
|
|
641
646
|
# `/* top | right | bottom | left */`
|
642
|
-
return
|
647
|
+
return DIMENSION_DIRECTIONS if values[:left] != values[:right]
|
643
648
|
|
644
649
|
# Vertical are the same & horizontal are the same, `/* vertical | horizontal */`
|
645
650
|
return [:top, :left] if values[:top] == values[:bottom]
|
data/lib/css_parser/version.rb
CHANGED
data/lib/css_parser.rb
CHANGED
@@ -57,7 +57,7 @@ module CssParser
|
|
57
57
|
# in case called like CssParser.merge([rule_set, rule_set])
|
58
58
|
rule_sets.flatten! if rule_sets[0].is_a?(Array)
|
59
59
|
|
60
|
-
unless rule_sets.all?
|
60
|
+
unless rule_sets.all?(CssParser::RuleSet)
|
61
61
|
raise ArgumentError, 'all parameters must be CssParser::RuleSets.'
|
62
62
|
end
|
63
63
|
|
@@ -70,7 +70,7 @@ module CssParser
|
|
70
70
|
rule_set.expand_shorthand!
|
71
71
|
|
72
72
|
specificity = rule_set.specificity
|
73
|
-
specificity ||= rule_set.selectors.
|
73
|
+
specificity ||= rule_set.selectors.filter_map { |s| calculate_specificity(s) }.max || 0
|
74
74
|
|
75
75
|
rule_set.each_declaration do |property, value, is_important|
|
76
76
|
# Add the property to the list to be folded per http://www.w3.org/TR/CSS21/cascade.html#cascading-order
|
@@ -138,7 +138,7 @@ module CssParser
|
|
138
138
|
css.gsub(URI_RX) do
|
139
139
|
uri = Regexp.last_match(1).to_s.gsub(/["']+/, '')
|
140
140
|
# Don't process URLs that are already absolute
|
141
|
-
unless uri.match(%r{^[a-z]+://}i)
|
141
|
+
unless uri.match?(%r{^[a-z]+://}i)
|
142
142
|
begin
|
143
143
|
uri = base_uri.join(uri)
|
144
144
|
rescue
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: css_parser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.21.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Dunae
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|