css_parser 1.17.1 → 1.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/css_parser/parser.rb +74 -22
- data/lib/css_parser/regexps.rb +1 -1
- data/lib/css_parser/rule_set.rb +67 -29
- data/lib/css_parser/version.rb +1 -1
- data/lib/css_parser.rb +1 -1
- metadata +4 -116
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5597d8abc3bd6dac3e4f4c7bb241cc4e1110ee0bdae226870ec35ab7ba85ee4f
|
4
|
+
data.tar.gz: 7191e6f6768060de7ddedc0420b0650046ca329bfbf5ef42444b342970eab752
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d8a71809154ea8535a22709a8877a6d8c7a93ada53a42e1a497ef8893292a261580fc1f2aa65c723d217498124278e2c226dafc69f2549cdbff0b6b4a7eb8895
|
7
|
+
data.tar.gz: 8c644bed6fe56143c4ccc5fe02a29e98de9cc728efdc7881f1816a10e562faf0a4e67210ff329068d4b5a2bb377239cfcd25b5594527b893522fbd6ec7cfa994
|
data/lib/css_parser/parser.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'strscan'
|
4
|
+
|
3
5
|
module CssParser
|
4
6
|
# Exception class used for any errors encountered while downloading remote files.
|
5
7
|
class RemoteFileError < IOError; end
|
@@ -16,7 +18,8 @@ module CssParser
|
|
16
18
|
# [<tt>import</tt>] Follow <tt>@import</tt> rules. Boolean, default is <tt>true</tt>.
|
17
19
|
# [<tt>io_exceptions</tt>] Throw an exception if a link can not be found. Boolean, default is <tt>true</tt>.
|
18
20
|
class Parser
|
19
|
-
USER_AGENT = "Ruby CSS Parser/#{CssParser::VERSION} (https://github.com/premailer/css_parser)"
|
21
|
+
USER_AGENT = "Ruby CSS Parser/#{CssParser::VERSION} (https://github.com/premailer/css_parser)".freeze
|
22
|
+
RULESET_TOKENIZER_RX = /\s+|\\{2,}|\\?[{}\s"]|[()]|.[^\s"{}()\\]*/.freeze
|
20
23
|
STRIP_CSS_COMMENTS_RX = %r{/\*.*?\*/}m.freeze
|
21
24
|
STRIP_HTML_COMMENTS_RX = /<!--|-->/m.freeze
|
22
25
|
|
@@ -133,7 +136,7 @@ module CssParser
|
|
133
136
|
block.scan(RE_AT_IMPORT_RULE).each do |import_rule|
|
134
137
|
media_types = []
|
135
138
|
if (media_string = import_rule[-1])
|
136
|
-
media_string.split(
|
139
|
+
media_string.split(',').each do |t|
|
137
140
|
media_types << CssParser.sanitize_media_query(t) unless t.empty?
|
138
141
|
end
|
139
142
|
else
|
@@ -164,14 +167,44 @@ module CssParser
|
|
164
167
|
parse_block_into_rule_sets!(block, options)
|
165
168
|
end
|
166
169
|
|
167
|
-
# Add a CSS rule by setting the +selectors+, +declarations+
|
170
|
+
# Add a CSS rule by setting the +selectors+, +declarations+
|
171
|
+
# and +media_types+. Optional pass +filename+ , +offset+ for source
|
172
|
+
# reference too.
|
168
173
|
#
|
169
|
-
# +media_types+ can be a symbol or an array of symbols.
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
174
|
+
# +media_types+ can be a symbol or an array of symbols. default to :all
|
175
|
+
# optional fields for source location for source location
|
176
|
+
# +filename+ can be a string or uri pointing to the file or url location.
|
177
|
+
# +offset+ should be Range object representing the start and end byte locations where the rule was found in the file.
|
178
|
+
def add_rule!(*args, selectors: nil, block: nil, filename: nil, offset: nil, media_types: :all) # rubocop:disable Metrics/ParameterLists
|
179
|
+
if args.any?
|
180
|
+
media_types = nil
|
181
|
+
if selectors || block || filename || offset || media_types
|
182
|
+
raise ArgumentError, "don't mix positional and keyword arguments arguments"
|
183
|
+
end
|
184
|
+
|
185
|
+
warn '[DEPRECATION] `add_rule!` with positional arguments is deprecated. ' \
|
186
|
+
'Please use keyword arguments instead.', uplevel: 1
|
187
|
+
|
188
|
+
case args.length
|
189
|
+
when 2
|
190
|
+
selectors, block = args
|
191
|
+
when 3
|
192
|
+
selectors, block, media_types = args
|
193
|
+
else
|
194
|
+
raise ArgumentError
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
begin
|
199
|
+
rule_set = RuleSet.new(
|
200
|
+
selectors: selectors, block: block,
|
201
|
+
offset: offset, filename: filename
|
202
|
+
)
|
203
|
+
|
204
|
+
add_rule_set!(rule_set, media_types)
|
205
|
+
rescue ArgumentError => e
|
206
|
+
raise e if @options[:rule_set_exceptions]
|
207
|
+
end
|
175
208
|
end
|
176
209
|
|
177
210
|
# Add a CSS rule by setting the +selectors+, +declarations+, +filename+, +offset+ and +media_types+.
|
@@ -180,8 +213,11 @@ module CssParser
|
|
180
213
|
# +offset+ should be Range object representing the start and end byte locations where the rule was found in the file.
|
181
214
|
# +media_types+ can be a symbol or an array of symbols.
|
182
215
|
def add_rule_with_offsets!(selectors, declarations, filename, offset, media_types = :all)
|
183
|
-
|
184
|
-
|
216
|
+
warn '[DEPRECATION] `add_rule_with_offsets!` is deprecated. Please use `add_rule!` instead.', uplevel: 1
|
217
|
+
add_rule!(
|
218
|
+
selectors: selectors, block: declarations, media_types: media_types,
|
219
|
+
filename: filename, offset: offset
|
220
|
+
)
|
185
221
|
end
|
186
222
|
|
187
223
|
# Add a CssParser RuleSet object.
|
@@ -329,11 +365,15 @@ module CssParser
|
|
329
365
|
|
330
366
|
# once we are in a rule, we will use this to store where we started if we are capturing offsets
|
331
367
|
rule_start = nil
|
332
|
-
|
368
|
+
start_offset = nil
|
369
|
+
end_offset = nil
|
333
370
|
|
334
|
-
|
371
|
+
scanner = StringScanner.new(block)
|
372
|
+
until scanner.eos?
|
335
373
|
# save the regex offset so that we know where in the file we are
|
336
|
-
|
374
|
+
start_offset = scanner.pos
|
375
|
+
token = scanner.scan(RULESET_TOKENIZER_RX)
|
376
|
+
end_offset = scanner.pos
|
337
377
|
|
338
378
|
if token.start_with?('"') # found un-escaped double quote
|
339
379
|
in_string = !in_string
|
@@ -360,11 +400,14 @@ module CssParser
|
|
360
400
|
current_declarations.strip!
|
361
401
|
|
362
402
|
unless current_declarations.empty?
|
403
|
+
add_rule_options = {
|
404
|
+
selectors: current_selectors, block: current_declarations,
|
405
|
+
media_types: current_media_queries
|
406
|
+
}
|
363
407
|
if options[:capture_offsets]
|
364
|
-
|
365
|
-
else
|
366
|
-
add_rule!(current_selectors, current_declarations, current_media_queries)
|
408
|
+
add_rule_options.merge!(filename: options[:filename], offset: rule_start..end_offset)
|
367
409
|
end
|
410
|
+
add_rule!(**add_rule_options)
|
368
411
|
end
|
369
412
|
|
370
413
|
current_selectors = String.new
|
@@ -423,18 +466,21 @@ module CssParser
|
|
423
466
|
current_selectors << token
|
424
467
|
|
425
468
|
# mark this as the beginning of the selector unless we have already marked it
|
426
|
-
rule_start =
|
469
|
+
rule_start = start_offset if options[:capture_offsets] && rule_start.nil? && token =~ /^[^\s]+$/
|
427
470
|
end
|
428
471
|
end
|
429
472
|
|
430
473
|
# check for unclosed braces
|
431
474
|
return unless in_declarations > 0
|
432
475
|
|
433
|
-
|
434
|
-
|
476
|
+
add_rule_options = {
|
477
|
+
selectors: current_selectors, block: current_declarations,
|
478
|
+
media_types: current_media_queries
|
479
|
+
}
|
480
|
+
if options[:capture_offsets]
|
481
|
+
add_rule_options.merge!(filename: options[:filename], offset: rule_start..end_offset)
|
435
482
|
end
|
436
|
-
|
437
|
-
add_rule_with_offsets!(current_selectors, current_declarations, options[:filename], (rule_start..offset.last), current_media_queries)
|
483
|
+
add_rule!(**add_rule_options)
|
438
484
|
end
|
439
485
|
|
440
486
|
# Load a remote CSS file.
|
@@ -452,6 +498,8 @@ module CssParser
|
|
452
498
|
if options.is_a? Hash
|
453
499
|
opts.merge!(options)
|
454
500
|
else
|
501
|
+
warn '[DEPRECATION] `load_uri!` with positional arguments is deprecated. ' \
|
502
|
+
'Please use keyword arguments instead.', uplevel: 1
|
455
503
|
opts[:base_uri] = options if options.is_a? String
|
456
504
|
opts[:media_types] = deprecated if deprecated
|
457
505
|
end
|
@@ -478,6 +526,8 @@ module CssParser
|
|
478
526
|
if options.is_a? Hash
|
479
527
|
opts.merge!(options)
|
480
528
|
else
|
529
|
+
warn '[DEPRECATION] `load_file!` with positional arguments is deprecated. ' \
|
530
|
+
'Please use keyword arguments instead.', uplevel: 1
|
481
531
|
opts[:base_dir] = options if options.is_a? String
|
482
532
|
opts[:media_types] = deprecated if deprecated
|
483
533
|
end
|
@@ -501,6 +551,8 @@ module CssParser
|
|
501
551
|
if options.is_a? Hash
|
502
552
|
opts.merge!(options)
|
503
553
|
else
|
554
|
+
warn '[DEPRECATION] `load_file!` with positional arguments is deprecated. ' \
|
555
|
+
'Please use keyword arguments instead.', uplevel: 1
|
504
556
|
opts[:base_dir] = options if options.is_a? String
|
505
557
|
opts[:media_types] = deprecated if deprecated
|
506
558
|
end
|
data/lib/css_parser/regexps.rb
CHANGED
@@ -11,7 +11,7 @@ module CssParser
|
|
11
11
|
RE_NON_ASCII = Regexp.new('([\x00-\xFF])', Regexp::IGNORECASE | Regexp::NOENCODING) # [^\0-\177]
|
12
12
|
RE_UNICODE = Regexp.new('(\\\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])*)', Regexp::IGNORECASE | Regexp::EXTENDED | Regexp::MULTILINE | Regexp::NOENCODING)
|
13
13
|
RE_ESCAPE = Regexp.union(RE_UNICODE, '|(\\\\[^\n\r\f0-9a-f])')
|
14
|
-
RE_IDENT = Regexp.new("[
|
14
|
+
RE_IDENT = Regexp.new("[-]?([_a-z]|#{RE_NON_ASCII}|#{RE_ESCAPE})([_a-z0-9-]|#{RE_NON_ASCII}|#{RE_ESCAPE})*", Regexp::IGNORECASE | Regexp::NOENCODING)
|
15
15
|
|
16
16
|
# General strings
|
17
17
|
RE_STRING1 = /("(.[^\n\r\f"]*|\\#{RE_NL}|#{RE_ESCAPE})*")/.freeze
|
data/lib/css_parser/rule_set.rb
CHANGED
@@ -26,6 +26,11 @@ module CssParser
|
|
26
26
|
|
27
27
|
WHITESPACE_REPLACEMENT = '___SPACE___'
|
28
28
|
|
29
|
+
# Tokens for parse_declarations!
|
30
|
+
COLON = ':'.freeze
|
31
|
+
SEMICOLON = ';'.freeze
|
32
|
+
LPAREN = '('.freeze
|
33
|
+
RPAREN = ')'.freeze
|
29
34
|
class Declarations
|
30
35
|
class Value
|
31
36
|
attr_reader :value
|
@@ -58,7 +63,7 @@ module CssParser
|
|
58
63
|
|
59
64
|
extend Forwardable
|
60
65
|
|
61
|
-
def_delegators :declarations, :each
|
66
|
+
def_delegators :declarations, :each, :each_value
|
62
67
|
|
63
68
|
def initialize(declarations = {})
|
64
69
|
self.declarations = {}
|
@@ -142,7 +147,7 @@ module CssParser
|
|
142
147
|
|
143
148
|
if preserve_importance
|
144
149
|
importance = get_value(property).important
|
145
|
-
replacement_declarations.
|
150
|
+
replacement_declarations.each_value { |value| value.important = importance }
|
146
151
|
end
|
147
152
|
|
148
153
|
replacement_keys = declarations.keys
|
@@ -223,6 +228,12 @@ module CssParser
|
|
223
228
|
|
224
229
|
extend Forwardable
|
225
230
|
|
231
|
+
# optional field for storing source reference
|
232
|
+
# File offset range
|
233
|
+
attr_reader :offset
|
234
|
+
# the local or remote location
|
235
|
+
attr_accessor :filename
|
236
|
+
|
226
237
|
# Array of selector strings.
|
227
238
|
attr_reader :selectors
|
228
239
|
|
@@ -237,9 +248,38 @@ module CssParser
|
|
237
248
|
alias []= add_declaration!
|
238
249
|
alias remove_declaration! delete
|
239
250
|
|
240
|
-
def initialize(selectors, block,
|
251
|
+
def initialize(*args, selectors: nil, block: nil, offset: nil, filename: nil, specificity: nil) # rubocop:disable Metrics/ParameterLists
|
252
|
+
if args.any?
|
253
|
+
if selectors || block || offset || filename || specificity
|
254
|
+
raise ArgumentError, "don't mix positional and keyword arguments"
|
255
|
+
end
|
256
|
+
|
257
|
+
warn '[DEPRECATION] positional arguments are deprecated use keyword instead.', uplevel: 1
|
258
|
+
|
259
|
+
case args.length
|
260
|
+
when 2
|
261
|
+
selectors, block = args
|
262
|
+
when 3
|
263
|
+
selectors, block, specificity = args
|
264
|
+
when 4
|
265
|
+
filename, offset, selectors, block = args
|
266
|
+
when 5
|
267
|
+
filename, offset, selectors, block, specificity = args
|
268
|
+
else
|
269
|
+
raise ArgumentError
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
241
273
|
@selectors = []
|
242
274
|
@specificity = specificity
|
275
|
+
|
276
|
+
unless offset.nil? == filename.nil?
|
277
|
+
raise ArgumentError, 'require both offset and filename or no offset and no filename'
|
278
|
+
end
|
279
|
+
|
280
|
+
@offset = offset
|
281
|
+
@filename = filename
|
282
|
+
|
243
283
|
parse_selectors!(selectors) if selectors
|
244
284
|
parse_declarations!(block)
|
245
285
|
end
|
@@ -308,7 +348,7 @@ module CssParser
|
|
308
348
|
|
309
349
|
replacement =
|
310
350
|
if value.match(CssParser::RE_INHERIT)
|
311
|
-
BACKGROUND_PROPERTIES.
|
351
|
+
BACKGROUND_PROPERTIES.to_h { |key| [key, 'inherit'] }
|
312
352
|
else
|
313
353
|
{
|
314
354
|
'background-image' => value.slice!(CssParser::RE_IMAGE),
|
@@ -448,7 +488,7 @@ module CssParser
|
|
448
488
|
|
449
489
|
replacement =
|
450
490
|
if value =~ CssParser::RE_INHERIT
|
451
|
-
LIST_STYLE_PROPERTIES.
|
491
|
+
LIST_STYLE_PROPERTIES.to_h { |key| [key, 'inherit'] }
|
452
492
|
else
|
453
493
|
{
|
454
494
|
'list-style-type' => value.slice!(CssParser::RE_LIST_STYLE_TYPE),
|
@@ -612,20 +652,32 @@ module CssParser
|
|
612
652
|
return unless block
|
613
653
|
|
614
654
|
continuation = nil
|
615
|
-
block.split(
|
616
|
-
decs = (continuation ? continuation
|
617
|
-
if decs
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
value = matches[2]
|
623
|
-
add_declaration!(property, value)
|
624
|
-
continuation = nil
|
655
|
+
block.split(SEMICOLON) do |decs|
|
656
|
+
decs = (continuation ? "#{continuation};#{decs}" : decs)
|
657
|
+
if unmatched_open_parenthesis?(decs)
|
658
|
+
# Semicolon happened within parenthesis, so it is a part of the value
|
659
|
+
# the rest of the value is in the next segment
|
660
|
+
continuation = decs
|
661
|
+
next
|
625
662
|
end
|
663
|
+
|
664
|
+
next unless (colon = decs.index(COLON))
|
665
|
+
|
666
|
+
property = decs[0, colon]
|
667
|
+
value = decs[(colon + 1)..]
|
668
|
+
property.strip!
|
669
|
+
value.strip!
|
670
|
+
next if property.empty? || value.empty?
|
671
|
+
|
672
|
+
add_declaration!(property, value)
|
673
|
+
continuation = nil
|
626
674
|
end
|
627
675
|
end
|
628
676
|
|
677
|
+
def unmatched_open_parenthesis?(declarations)
|
678
|
+
(lparen_index = declarations.index(LPAREN)) && !declarations.index(RPAREN, lparen_index)
|
679
|
+
end
|
680
|
+
|
629
681
|
#--
|
630
682
|
# TODO: way too simplistic
|
631
683
|
#++
|
@@ -650,18 +702,4 @@ module CssParser
|
|
650
702
|
end
|
651
703
|
end
|
652
704
|
end
|
653
|
-
|
654
|
-
class OffsetAwareRuleSet < RuleSet
|
655
|
-
# File offset range
|
656
|
-
attr_reader :offset
|
657
|
-
|
658
|
-
# the local or remote location
|
659
|
-
attr_accessor :filename
|
660
|
-
|
661
|
-
def initialize(filename, offset, selectors, block, specificity = nil)
|
662
|
-
super(selectors, block, specificity)
|
663
|
-
@offset = offset
|
664
|
-
@filename = filename
|
665
|
-
end
|
666
|
-
end
|
667
705
|
end
|
data/lib/css_parser/version.rb
CHANGED
data/lib/css_parser.rb
CHANGED
@@ -111,7 +111,7 @@ module CssParser
|
|
111
111
|
#++
|
112
112
|
def self.calculate_specificity(selector)
|
113
113
|
a = 0
|
114
|
-
b = selector.scan(
|
114
|
+
b = selector.scan('#').length
|
115
115
|
c = selector.scan(NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX_NC).length
|
116
116
|
d = selector.scan(ELEMENTS_AND_PSEUDO_ELEMENTS_RX_NC).length
|
117
117
|
|
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.19.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: 2024-
|
11
|
+
date: 2024-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: addressable
|
@@ -24,118 +24,6 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: benchmark-ips
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: bump
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :development
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: maxitest
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: memory_profiler
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :development
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
- !ruby/object:Gem::Dependency
|
84
|
-
name: rake
|
85
|
-
requirement: !ruby/object:Gem::Requirement
|
86
|
-
requirements:
|
87
|
-
- - ">="
|
88
|
-
- !ruby/object:Gem::Version
|
89
|
-
version: '0'
|
90
|
-
type: :development
|
91
|
-
prerelease: false
|
92
|
-
version_requirements: !ruby/object:Gem::Requirement
|
93
|
-
requirements:
|
94
|
-
- - ">="
|
95
|
-
- !ruby/object:Gem::Version
|
96
|
-
version: '0'
|
97
|
-
- !ruby/object:Gem::Dependency
|
98
|
-
name: rubocop
|
99
|
-
requirement: !ruby/object:Gem::Requirement
|
100
|
-
requirements:
|
101
|
-
- - "~>"
|
102
|
-
- !ruby/object:Gem::Version
|
103
|
-
version: '1.8'
|
104
|
-
type: :development
|
105
|
-
prerelease: false
|
106
|
-
version_requirements: !ruby/object:Gem::Requirement
|
107
|
-
requirements:
|
108
|
-
- - "~>"
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
version: '1.8'
|
111
|
-
- !ruby/object:Gem::Dependency
|
112
|
-
name: rubocop-rake
|
113
|
-
requirement: !ruby/object:Gem::Requirement
|
114
|
-
requirements:
|
115
|
-
- - ">="
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
118
|
-
type: :development
|
119
|
-
prerelease: false
|
120
|
-
version_requirements: !ruby/object:Gem::Requirement
|
121
|
-
requirements:
|
122
|
-
- - ">="
|
123
|
-
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
125
|
-
- !ruby/object:Gem::Dependency
|
126
|
-
name: webrick
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
128
|
-
requirements:
|
129
|
-
- - ">="
|
130
|
-
- !ruby/object:Gem::Version
|
131
|
-
version: '0'
|
132
|
-
type: :development
|
133
|
-
prerelease: false
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
135
|
-
requirements:
|
136
|
-
- - ">="
|
137
|
-
- !ruby/object:Gem::Version
|
138
|
-
version: '0'
|
139
27
|
description: A set of classes for parsing CSS in Ruby.
|
140
28
|
email: code@dunae.ca
|
141
29
|
executables: []
|
@@ -164,14 +52,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
164
52
|
requirements:
|
165
53
|
- - ">="
|
166
54
|
- !ruby/object:Gem::Version
|
167
|
-
version: '
|
55
|
+
version: '3.0'
|
168
56
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
169
57
|
requirements:
|
170
58
|
- - ">="
|
171
59
|
- !ruby/object:Gem::Version
|
172
60
|
version: '0'
|
173
61
|
requirements: []
|
174
|
-
rubygems_version: 3.
|
62
|
+
rubygems_version: 3.4.19
|
175
63
|
signing_key:
|
176
64
|
specification_version: 4
|
177
65
|
summary: Ruby CSS parser.
|