css_parser 1.6.0 → 1.7.0
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 +5 -5
- data/lib/css_parser.rb +6 -4
- data/lib/css_parser/parser.rb +36 -31
- data/lib/css_parser/regexps.rb +7 -7
- data/lib/css_parser/rule_set.rb +77 -77
- data/lib/css_parser/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 66714382244cadbf112104868d94ff8b131ac4cf007deacac52d726bee1a9f9a
|
4
|
+
data.tar.gz: 8ac559b1fb982da00dfbef4188b3773d2a78637f4db26393aba7cf62287b7883
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ba75d2e879d80cb7c854889990fd190f5c1fb664ed96b3a47ad78614a257d2ed7acfc3ba453ea34e87612636512305089c1a73d081c8a1c729a854217b17613e
|
7
|
+
data.tar.gz: ff49b36b1007ae8ce0ecbfd6a2e92536d16c46062898c0a3bae402bacdb731785d6e4b80b0d08e557fcf372f2b0da2d75629c471c8ed2ce59addd13629eda9b9
|
data/lib/css_parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'addressable/uri'
|
2
3
|
require 'uri'
|
3
4
|
require 'net/https'
|
@@ -122,10 +123,10 @@ module CssParser
|
|
122
123
|
def self.calculate_specificity(selector)
|
123
124
|
a = 0
|
124
125
|
b = selector.scan(/\#/).length
|
125
|
-
c = selector.scan(
|
126
|
-
d = selector.scan(
|
126
|
+
c = selector.scan(NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX_NC).length
|
127
|
+
d = selector.scan(ELEMENTS_AND_PSEUDO_ELEMENTS_RX_NC).length
|
127
128
|
|
128
|
-
|
129
|
+
"#{a}#{b}#{c}#{d}".to_i
|
129
130
|
rescue
|
130
131
|
return 0
|
131
132
|
end
|
@@ -160,7 +161,8 @@ module CssParser
|
|
160
161
|
end
|
161
162
|
|
162
163
|
def self.sanitize_media_query(raw)
|
163
|
-
mq = raw.to_s.gsub(/[\s]+/, ' ')
|
164
|
+
mq = raw.to_s.gsub(/[\s]+/, ' ')
|
165
|
+
mq.strip!
|
164
166
|
mq = 'all' if mq.empty?
|
165
167
|
mq.to_sym
|
166
168
|
end
|
data/lib/css_parser/parser.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module CssParser
|
2
3
|
# Exception class used for any errors encountered while downloading remote files.
|
3
4
|
class RemoteFileError < IOError; end
|
@@ -184,7 +185,8 @@ module CssParser
|
|
184
185
|
def add_rule_set!(ruleset, media_types = :all)
|
185
186
|
raise ArgumentError unless ruleset.kind_of?(CssParser::RuleSet)
|
186
187
|
|
187
|
-
media_types = [media_types]
|
188
|
+
media_types = [media_types] unless Array === media_types
|
189
|
+
media_types = media_types.flat_map { |mt| CssParser.sanitize_media_query(mt)}
|
188
190
|
|
189
191
|
@rules << {:media_types => media_types, :rules => ruleset}
|
190
192
|
end
|
@@ -242,6 +244,8 @@ module CssParser
|
|
242
244
|
# +media_types+ can be a symbol or an array of symbols.
|
243
245
|
# See RuleSet#each_selector for +options+.
|
244
246
|
def each_selector(all_media_types = :all, options = {}) # :yields: selectors, declarations, specificity, media_types
|
247
|
+
return to_enum(:each_selector) unless block_given?
|
248
|
+
|
245
249
|
each_rule_set(all_media_types) do |rule_set, media_types|
|
246
250
|
rule_set.each_selector(options) do |selectors, declarations, specificity|
|
247
251
|
yield selectors, declarations, specificity, media_types
|
@@ -251,7 +255,7 @@ module CssParser
|
|
251
255
|
|
252
256
|
# Output all CSS rules as a single stylesheet.
|
253
257
|
def to_s(which_media = :all)
|
254
|
-
out =
|
258
|
+
out = String.new
|
255
259
|
styles_by_media_types = {}
|
256
260
|
each_selector(which_media) do |selectors, declarations, specificity, media_types|
|
257
261
|
media_types.each do |media_type|
|
@@ -262,17 +266,17 @@ module CssParser
|
|
262
266
|
|
263
267
|
styles_by_media_types.each_pair do |media_type, media_styles|
|
264
268
|
media_block = (media_type != :all)
|
265
|
-
out
|
269
|
+
out << "@media #{media_type} {\n" if media_block
|
266
270
|
|
267
271
|
media_styles.each do |media_style|
|
268
272
|
if media_block
|
269
|
-
out
|
273
|
+
out << " #{media_style[0]} {\n #{media_style[1]}\n }\n"
|
270
274
|
else
|
271
|
-
out
|
275
|
+
out << "#{media_style[0]} {\n#{media_style[1]}\n}\n"
|
272
276
|
end
|
273
277
|
end
|
274
278
|
|
275
|
-
out
|
279
|
+
out << "}\n" if media_block
|
276
280
|
end
|
277
281
|
|
278
282
|
out
|
@@ -314,44 +318,43 @@ module CssParser
|
|
314
318
|
in_at_media_rule = false
|
315
319
|
in_media_block = false
|
316
320
|
|
317
|
-
current_selectors =
|
318
|
-
current_media_query =
|
319
|
-
current_declarations =
|
321
|
+
current_selectors = String.new
|
322
|
+
current_media_query = String.new
|
323
|
+
current_declarations = String.new
|
320
324
|
|
321
325
|
# once we are in a rule, we will use this to store where we started if we are capturing offsets
|
322
326
|
rule_start = nil
|
323
327
|
offset = nil
|
324
328
|
|
325
|
-
block.scan(
|
326
|
-
token = matches[0]
|
327
|
-
|
329
|
+
block.scan(/\s+|[\\]{2,}|[\\]?[{}\s"]|.[^\s"{}\\]*/) do |token|
|
328
330
|
# save the regex offset so that we know where in the file we are
|
329
331
|
offset = Regexp.last_match.offset(0) if options[:capture_offsets]
|
330
332
|
|
331
|
-
if token
|
333
|
+
if token.start_with?('"') # found un-escaped double quote
|
332
334
|
in_string = !in_string
|
333
335
|
end
|
334
336
|
|
335
337
|
if in_declarations > 0
|
336
338
|
# too deep, malformed declaration block
|
337
339
|
if in_declarations > 1
|
338
|
-
in_declarations -= 1 if token
|
340
|
+
in_declarations -= 1 if token.include?('}')
|
339
341
|
next
|
340
342
|
end
|
341
343
|
|
342
|
-
if
|
344
|
+
if !in_string && token.include?('{')
|
343
345
|
in_declarations += 1
|
344
346
|
next
|
345
347
|
end
|
346
348
|
|
347
|
-
current_declarations
|
349
|
+
current_declarations << token
|
348
350
|
|
349
|
-
if
|
351
|
+
if !in_string && token.include?('}')
|
350
352
|
current_declarations.gsub!(/\}[\s]*$/, '')
|
351
353
|
|
352
354
|
in_declarations -= 1
|
355
|
+
current_declarations.strip!
|
353
356
|
|
354
|
-
unless current_declarations.
|
357
|
+
unless current_declarations.empty?
|
355
358
|
if options[:capture_offsets]
|
356
359
|
add_rule_with_offsets!(current_selectors, current_declarations, options[:filename], (rule_start..offset.last), current_media_queries)
|
357
360
|
else
|
@@ -359,8 +362,8 @@ module CssParser
|
|
359
362
|
end
|
360
363
|
end
|
361
364
|
|
362
|
-
current_selectors =
|
363
|
-
current_declarations =
|
365
|
+
current_selectors = String.new
|
366
|
+
current_declarations = String.new
|
364
367
|
|
365
368
|
# restart our search for selectors and declarations
|
366
369
|
rule_start = nil if options[:capture_offsets]
|
@@ -370,26 +373,28 @@ module CssParser
|
|
370
373
|
in_at_media_rule = true
|
371
374
|
current_media_queries = []
|
372
375
|
elsif in_at_media_rule
|
373
|
-
if token
|
376
|
+
if token.include?('{')
|
374
377
|
block_depth = block_depth + 1
|
375
378
|
in_at_media_rule = false
|
376
379
|
in_media_block = true
|
377
380
|
current_media_queries << CssParser.sanitize_media_query(current_media_query)
|
378
|
-
current_media_query =
|
379
|
-
elsif token
|
381
|
+
current_media_query = String.new
|
382
|
+
elsif token.include?(',')
|
380
383
|
# new media query begins
|
381
|
-
token.
|
382
|
-
|
384
|
+
token.tr!(',', ' ')
|
385
|
+
token.strip!
|
386
|
+
current_media_query << token << ' '
|
383
387
|
current_media_queries << CssParser.sanitize_media_query(current_media_query)
|
384
|
-
current_media_query =
|
388
|
+
current_media_query = String.new
|
385
389
|
else
|
386
|
-
|
390
|
+
token.strip!
|
391
|
+
current_media_query << token << ' '
|
387
392
|
end
|
388
393
|
elsif in_charset or token =~ /@charset/i
|
389
394
|
# iterate until we are out of the charset declaration
|
390
|
-
in_charset =
|
395
|
+
in_charset = !token.include?(';')
|
391
396
|
else
|
392
|
-
if
|
397
|
+
if !in_string && token.include?('}')
|
393
398
|
block_depth = block_depth - 1
|
394
399
|
|
395
400
|
# reset the current media query scope
|
@@ -398,12 +403,12 @@ module CssParser
|
|
398
403
|
in_media_block = false
|
399
404
|
end
|
400
405
|
else
|
401
|
-
if
|
406
|
+
if !in_string && token.include?('{')
|
402
407
|
current_selectors.strip!
|
403
408
|
in_declarations += 1
|
404
409
|
else
|
405
410
|
# if we are in a selector, add the token to the current selectors
|
406
|
-
current_selectors
|
411
|
+
current_selectors << token
|
407
412
|
|
408
413
|
# mark this as the beginning of the selector unless we have already marked it
|
409
414
|
rule_start = offset.first if options[:capture_offsets] && rule_start.nil? && token =~ /^[^\s]+$/
|
data/lib/css_parser/regexps.rb
CHANGED
@@ -54,12 +54,12 @@ module CssParser
|
|
54
54
|
|
55
55
|
|
56
56
|
# Patterns for specificity calculations
|
57
|
-
|
58
|
-
(
|
57
|
+
NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX_NC= /
|
58
|
+
(?:\.[\w]+) # classes
|
59
59
|
|
|
60
|
-
\[(
|
60
|
+
\[(?:\w+) # attributes
|
61
61
|
|
|
62
|
-
(
|
62
|
+
(?:\:(?: # pseudo classes
|
63
63
|
link|visited|active
|
64
64
|
|hover|focus
|
65
65
|
|lang
|
@@ -72,10 +72,10 @@ module CssParser
|
|
72
72
|
|empty|contains
|
73
73
|
))
|
74
74
|
/ix
|
75
|
-
|
76
|
-
((
|
75
|
+
ELEMENTS_AND_PSEUDO_ELEMENTS_RX_NC = /
|
76
|
+
(?:(?:^|[\s\+\>\~]+)[\w]+ # elements
|
77
77
|
|
|
78
|
-
\:{1,2}( # pseudo-elements
|
78
|
+
\:{1,2}(?: # pseudo-elements
|
79
79
|
after|before
|
80
80
|
|first-letter|first-line
|
81
81
|
|selection
|
data/lib/css_parser/rule_set.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
module CssParser
|
2
3
|
class RuleSet
|
3
4
|
# Patterns for specificity calculations
|
@@ -6,6 +7,19 @@ module CssParser
|
|
6
7
|
|
7
8
|
BACKGROUND_PROPERTIES = ['background-color', 'background-image', 'background-repeat', 'background-position', 'background-size', 'background-attachment']
|
8
9
|
LIST_STYLE_PROPERTIES = ['list-style-type', 'list-style-position', 'list-style-image']
|
10
|
+
FONT_STYLE_PROPERTIES = ['font-style', 'font-variant', 'font-weight', 'font-size', 'line-height', 'font-family']
|
11
|
+
BORDER_STYLE_PROPERTIES = ['border-width', 'border-style', 'border-color']
|
12
|
+
BORDER_PROPERTIES = ['border', 'border-left', 'border-right', 'border-top', 'border-bottom']
|
13
|
+
|
14
|
+
NUMBER_OF_DIMENSIONS = 4
|
15
|
+
|
16
|
+
DIMENSIONS = [
|
17
|
+
['margin', %w(margin-top margin-right margin-bottom margin-left)],
|
18
|
+
['padding', %w(padding-top padding-right padding-bottom padding-left)],
|
19
|
+
['border-color', %w(border-top-color border-right-color border-bottom-color border-left-color)],
|
20
|
+
['border-style', %w(border-top-style border-right-style border-bottom-style border-left-style)],
|
21
|
+
['border-width', %w(border-top-width border-right-width border-bottom-width border-left-width)],
|
22
|
+
]
|
9
23
|
|
10
24
|
# Array of selector strings.
|
11
25
|
attr_reader :selectors
|
@@ -27,7 +41,7 @@ module CssParser
|
|
27
41
|
return '' unless property and not property.empty?
|
28
42
|
|
29
43
|
property = property.downcase.strip
|
30
|
-
properties = @declarations.inject(
|
44
|
+
properties = @declarations.inject(String.new) do |val, (key, data)|
|
31
45
|
#puts "COMPARING #{key} #{key.inspect} against #{property} #{property.inspect}"
|
32
46
|
importance = data[:is_important] ? ' !important' : ''
|
33
47
|
val << "#{data[:value]}#{importance}; " if key.downcase.strip == property
|
@@ -58,7 +72,8 @@ module CssParser
|
|
58
72
|
|
59
73
|
value.gsub!(/;\Z/, '')
|
60
74
|
is_important = !value.gsub!(CssParser::IMPORTANT_IN_PROPERTY_RX, '').nil?
|
61
|
-
property = property.downcase
|
75
|
+
property = property.downcase
|
76
|
+
property.strip!
|
62
77
|
#puts "SAVING #{property} #{value} #{is_important.inspect}"
|
63
78
|
@declarations[property] = {
|
64
79
|
:value => value, :is_important => is_important, :order => @order += 1
|
@@ -105,13 +120,14 @@ module CssParser
|
|
105
120
|
# TODO: Clean-up regexp doesn't seem to work
|
106
121
|
#++
|
107
122
|
def declarations_to_s(options = {})
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
123
|
+
str = String.new
|
124
|
+
each_declaration do |prop, val, is_important|
|
125
|
+
importance = (options[:force_important] || is_important) ? ' !important' : ''
|
126
|
+
str << "#{prop}: #{val}#{importance}; "
|
127
|
+
end
|
128
|
+
str.gsub!(/^[\s^(\{)]+|[\n\r\f\t]*|[\s]+$/mx, '')
|
129
|
+
str.strip!
|
130
|
+
str
|
115
131
|
end
|
116
132
|
|
117
133
|
# Return the CSS rule set as a string.
|
@@ -164,7 +180,7 @@ module CssParser
|
|
164
180
|
# Split shorthand border declarations (e.g. <tt>border: 1px red;</tt>)
|
165
181
|
# Additional splitting happens in expand_dimensions_shorthand!
|
166
182
|
def expand_border_shorthand! # :nodoc:
|
167
|
-
|
183
|
+
BORDER_PROPERTIES.each do |k|
|
168
184
|
next unless @declarations.has_key?(k)
|
169
185
|
|
170
186
|
value = @declarations[k][:value]
|
@@ -180,14 +196,8 @@ module CssParser
|
|
180
196
|
# Split shorthand dimensional declarations (e.g. <tt>margin: 0px auto;</tt>)
|
181
197
|
# into their constituent parts. Handles margin, padding, border-color, border-style and border-width.
|
182
198
|
def expand_dimensions_shorthand! # :nodoc:
|
183
|
-
|
184
|
-
'padding' => 'padding-%s',
|
185
|
-
'border-color' => 'border-%s-color',
|
186
|
-
'border-style' => 'border-%s-style',
|
187
|
-
'border-width' => 'border-%s-width'}.each do |property, expanded|
|
188
|
-
|
199
|
+
DIMENSIONS.each do |property, (top, right, bottom, left)|
|
189
200
|
next unless @declarations.has_key?(property)
|
190
|
-
|
191
201
|
value = @declarations[property][:value]
|
192
202
|
|
193
203
|
# RGB and HSL values in borders are the only units that can have spaces (within params).
|
@@ -199,29 +209,24 @@ module CssParser
|
|
199
209
|
|
200
210
|
matches = value.strip.split(/\s+/)
|
201
211
|
|
202
|
-
t, r, b, l = nil
|
203
|
-
|
204
212
|
case matches.length
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
when 4
|
215
|
-
t = matches[0]
|
216
|
-
r = matches[1]
|
217
|
-
b = matches[2]
|
218
|
-
l = matches[3]
|
213
|
+
when 1
|
214
|
+
values = matches.to_a * 4
|
215
|
+
when 2
|
216
|
+
values = matches.to_a * 2
|
217
|
+
when 3
|
218
|
+
values = matches.to_a
|
219
|
+
values << matches[1] # left = right
|
220
|
+
when 4
|
221
|
+
values = matches.to_a
|
219
222
|
end
|
220
223
|
|
221
|
-
|
222
|
-
|
223
|
-
split_declaration(property,
|
224
|
-
split_declaration(property,
|
224
|
+
t, r, b, l = values
|
225
|
+
|
226
|
+
split_declaration(property, top, t)
|
227
|
+
split_declaration(property, right, r)
|
228
|
+
split_declaration(property, bottom, b)
|
229
|
+
split_declaration(property, left, l)
|
225
230
|
|
226
231
|
@declarations.delete(property)
|
227
232
|
end
|
@@ -362,7 +367,7 @@ module CssParser
|
|
362
367
|
def create_border_shorthand! # :nodoc:
|
363
368
|
values = []
|
364
369
|
|
365
|
-
|
370
|
+
BORDER_STYLE_PROPERTIES.each do |property|
|
366
371
|
if @declarations.has_key?(property) and not @declarations[property][:is_important]
|
367
372
|
# can't merge if any value contains a space (i.e. has multiple values)
|
368
373
|
# we temporarily remove any spaces after commas for the check (inside rgba, etc...)
|
@@ -371,9 +376,7 @@ module CssParser
|
|
371
376
|
end
|
372
377
|
end
|
373
378
|
|
374
|
-
@declarations.delete(
|
375
|
-
@declarations.delete('border-style')
|
376
|
-
@declarations.delete('border-color')
|
379
|
+
BORDER_STYLE_PROPERTIES.each { |prop| @declarations.delete(prop)}
|
377
380
|
|
378
381
|
unless values.empty?
|
379
382
|
@declarations['border'] = {:value => values.join(' ')}
|
@@ -383,23 +386,20 @@ module CssParser
|
|
383
386
|
# Looks for long format CSS dimensional properties (margin, padding, border-color, border-style and border-width)
|
384
387
|
# and converts them into shorthand CSS properties.
|
385
388
|
def create_dimensions_shorthand! # :nodoc:
|
386
|
-
|
387
|
-
|
388
|
-
{'margin' => 'margin-%s',
|
389
|
-
'padding' => 'padding-%s',
|
390
|
-
'border-color' => 'border-%s-color',
|
391
|
-
'border-style' => 'border-%s-style',
|
392
|
-
'border-width' => 'border-%s-width'}.each do |property, expanded|
|
389
|
+
return if @declarations.size < NUMBER_OF_DIMENSIONS
|
393
390
|
|
394
|
-
|
395
|
-
|
396
|
-
dim == top or dim == right or dim == bottom or dim == left
|
397
|
-
end
|
391
|
+
DIMENSIONS.each do |property, dimensions|
|
392
|
+
(top, right, bottom, left) = dimensions
|
398
393
|
# All four dimensions must be present
|
399
|
-
if
|
394
|
+
if dimensions.count { |d| @declarations[d] } == NUMBER_OF_DIMENSIONS
|
400
395
|
values = {}
|
401
396
|
|
402
|
-
|
397
|
+
[
|
398
|
+
[:top, top],
|
399
|
+
[:right, right],
|
400
|
+
[:bottom, bottom],
|
401
|
+
[:left, left],
|
402
|
+
].each { |d, key| values[d] = @declarations[key][:value].downcase.strip }
|
403
403
|
|
404
404
|
if values[:left] == values[:right]
|
405
405
|
if values[:top] == values[:bottom]
|
@@ -419,7 +419,7 @@ module CssParser
|
|
419
419
|
@declarations[property] = {:value => new_value.strip} unless new_value.empty?
|
420
420
|
|
421
421
|
# Delete the longhand values
|
422
|
-
|
422
|
+
[top, right, bottom, left].each { |d| @declarations.delete(d) }
|
423
423
|
end
|
424
424
|
end
|
425
425
|
end
|
@@ -429,33 +429,28 @@ module CssParser
|
|
429
429
|
# tries to convert them into a shorthand CSS <tt>font</tt> property. All
|
430
430
|
# font properties must be present in order to create a shorthand declaration.
|
431
431
|
def create_font_shorthand! # :nodoc:
|
432
|
-
|
433
|
-
'line-height', 'font-family'].each do |prop|
|
432
|
+
FONT_STYLE_PROPERTIES.each do |prop|
|
434
433
|
return unless @declarations.has_key?(prop)
|
435
434
|
end
|
436
435
|
|
437
|
-
new_value =
|
436
|
+
new_value = String.new
|
438
437
|
['font-style', 'font-variant', 'font-weight'].each do |property|
|
439
438
|
unless @declarations[property][:value] == 'normal'
|
440
|
-
new_value
|
439
|
+
new_value << @declarations[property][:value] << ' '
|
441
440
|
end
|
442
441
|
end
|
443
442
|
|
444
|
-
new_value
|
443
|
+
new_value << @declarations['font-size'][:value]
|
445
444
|
|
446
445
|
unless @declarations['line-height'][:value] == 'normal'
|
447
|
-
new_value
|
446
|
+
new_value << '/' << @declarations['line-height'][:value]
|
448
447
|
end
|
449
448
|
|
450
|
-
new_value
|
449
|
+
new_value << ' ' << @declarations['font-family'][:value]
|
451
450
|
|
452
451
|
@declarations['font'] = {:value => new_value.gsub(/[\s]+/, ' ').strip}
|
453
452
|
|
454
|
-
|
455
|
-
'line-height', 'font-family'].each do |prop|
|
456
|
-
@declarations.delete(prop)
|
457
|
-
end
|
458
|
-
|
453
|
+
FONT_STYLE_PROPERTIES.each { |prop| @declarations.delete(prop) }
|
459
454
|
end
|
460
455
|
|
461
456
|
# Looks for long format CSS list-style properties (e.g. <tt>list-style-type</tt>) and
|
@@ -482,7 +477,9 @@ module CssParser
|
|
482
477
|
@declarations[dest] = {}
|
483
478
|
end
|
484
479
|
end
|
485
|
-
|
480
|
+
|
481
|
+
@declarations[dest] = @declarations[src].dup
|
482
|
+
@declarations[dest][:value] = v.to_s.strip
|
486
483
|
end
|
487
484
|
|
488
485
|
def parse_declarations!(block) # :nodoc:
|
@@ -490,19 +487,18 @@ module CssParser
|
|
490
487
|
|
491
488
|
return unless block
|
492
489
|
|
493
|
-
|
494
|
-
|
495
|
-
continuation = ''
|
490
|
+
continuation = nil
|
496
491
|
block.split(/[\;$]+/m).each do |decs|
|
497
|
-
decs = continuation + decs
|
492
|
+
decs = continuation ? continuation + decs : decs
|
498
493
|
if decs =~ /\([^)]*\Z/ # if it has an unmatched parenthesis
|
499
494
|
continuation = decs + ';'
|
500
495
|
|
501
|
-
elsif matches = decs.match(
|
502
|
-
|
503
|
-
|
496
|
+
elsif matches = decs.match(/\s*(.[^:]*)\s*:\s*(.+?)(;?\s*\Z)/i)
|
497
|
+
# skip end_of_declaration
|
498
|
+
property = matches[1]
|
499
|
+
value = matches[2]
|
504
500
|
add_declaration!(property, value)
|
505
|
-
continuation =
|
501
|
+
continuation = nil
|
506
502
|
end
|
507
503
|
end
|
508
504
|
end
|
@@ -511,7 +507,11 @@ module CssParser
|
|
511
507
|
# TODO: way too simplistic
|
512
508
|
#++
|
513
509
|
def parse_selectors!(selectors) # :nodoc:
|
514
|
-
@selectors = selectors.split(',').map
|
510
|
+
@selectors = selectors.split(',').map do |s|
|
511
|
+
s.gsub!(/\s+/, ' ')
|
512
|
+
s.strip!
|
513
|
+
s
|
514
|
+
end
|
515
515
|
end
|
516
516
|
end
|
517
517
|
|
data/lib/css_parser/version.rb
CHANGED
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.7.0
|
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: 2019-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -56,7 +56,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
56
56
|
version: '0'
|
57
57
|
requirements: []
|
58
58
|
rubyforge_project:
|
59
|
-
rubygems_version: 2.
|
59
|
+
rubygems_version: 2.7.6
|
60
60
|
signing_key:
|
61
61
|
specification_version: 4
|
62
62
|
summary: Ruby CSS parser.
|