css_parser 1.5.0.pre2 → 1.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: bcad7a186fec9e364d7b615e821fad091db568cc
4
- data.tar.gz: 4b0c9be7d82bf15144bda6bf09e1a0b328d7a5d0
2
+ SHA256:
3
+ metadata.gz: c049fe40a4b774b56e00c790cf18b78c8a94298185435471893cedff65a79c17
4
+ data.tar.gz: fd0600e1859e8bd188a12df4ccd252a1f75f4ae2f98707249c7750e622d5e2b4
5
5
  SHA512:
6
- metadata.gz: d5a2a1d8f77eb1dc9ed16d03bf6141385238d3c3fb774b9352df83d49a6c64881ba26226d8d5ff88af68130c503fef4164a44f0a0a0aa0662911659b1f1ae877
7
- data.tar.gz: 451dd77df3050fe539cc7098da6ba7f07b25fe977eae29d579f3ce55f85c7e72cfe9b45f25bf93d588f97e291ad2c0b6c553782980a9032ad22566f712a7bc9c
6
+ metadata.gz: 53b2f435c485d393778679d3202943a99b83607af4ce5edac9a15aac4461fb252371b43d98b7bf1886254b143da9bff5a61492d7a36e74e44e77b44f8ba38318
7
+ data.tar.gz: ab5fb0504811ebd05eb09e830447f832b67aad5e5559dd4be9e562c20d5bb4cc786165eb961b39867e8316c72ce90015de16e1857154784b4bf0fc700b92a34b
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'addressable/uri'
2
4
  require 'uri'
3
5
  require 'net/https'
@@ -12,7 +14,6 @@ require 'css_parser/regexps'
12
14
  require 'css_parser/parser'
13
15
 
14
16
  module CssParser
15
-
16
17
  # Merge multiple CSS RuleSets by cascading according to the CSS 2.1 cascading rules
17
18
  # (http://www.w3.org/TR/REC-CSS2/cascade.html#cascading-order).
18
19
  #
@@ -55,10 +56,10 @@ module CssParser
55
56
  @folded_declaration_cache = {}
56
57
 
57
58
  # in case called like CssParser.merge([rule_set, rule_set])
58
- rule_sets.flatten! if rule_sets[0].kind_of?(Array)
59
+ rule_sets.flatten! if rule_sets[0].is_a?(Array)
59
60
 
60
- unless rule_sets.all? {|rs| rs.kind_of?(CssParser::RuleSet)}
61
- raise ArgumentError, "all parameters must be CssParser::RuleSets."
61
+ unless rule_sets.all? { |rs| rs.is_a?(CssParser::RuleSet) }
62
+ raise ArgumentError, 'all parameters must be CssParser::RuleSets.'
62
63
  end
63
64
 
64
65
  return rule_sets[0] if rule_sets.length == 1
@@ -70,38 +71,27 @@ module CssParser
70
71
  rule_set.expand_shorthand!
71
72
 
72
73
  specificity = rule_set.specificity
73
- unless specificity
74
- if rule_set.selectors.length == 0
75
- specificity = 0
76
- else
77
- specificity = rule_set.selectors.map { |s| calculate_specificity(s) }.compact.max || 0
78
- end
79
- end
74
+ specificity ||= rule_set.selectors.map { |s| calculate_specificity(s) }.compact.max || 0
80
75
 
81
76
  rule_set.each_declaration do |property, value, is_important|
82
77
  # Add the property to the list to be folded per http://www.w3.org/TR/CSS21/cascade.html#cascading-order
83
- if not properties.has_key?(property)
84
- properties[property] = {:value => value, :specificity => specificity, :is_important => is_important}
78
+ if not properties.key?(property)
79
+ properties[property] = {value: value, specificity: specificity, is_important: is_important}
85
80
  elsif is_important
86
81
  if not properties[property][:is_important] or properties[property][:specificity] <= specificity
87
- properties[property] = {:value => value, :specificity => specificity, :is_important => is_important}
82
+ properties[property] = {value: value, specificity: specificity, is_important: is_important}
88
83
  end
89
84
  elsif properties[property][:specificity] < specificity or properties[property][:specificity] == specificity
90
85
  unless properties[property][:is_important]
91
- properties[property] = {:value => value, :specificity => specificity, :is_important => is_important}
86
+ properties[property] = {value: value, specificity: specificity, is_important: is_important}
92
87
  end
93
88
  end
94
- end
89
+ end
95
90
  end
96
91
 
97
- merged = RuleSet.new(nil, nil)
98
-
99
- properties.each do |property, details|
100
- if details[:is_important]
101
- merged[property.strip] = details[:value].strip.gsub(/\;\Z/, '') + '!important'
102
- else
103
- merged[property.strip] = details[:value].strip
104
- end
92
+ merged = properties.each_with_object(RuleSet.new(nil, nil)) do |(property, details), rule_set|
93
+ value = details[:value].strip
94
+ rule_set[property.strip] = details[:is_important] ? "#{value.gsub(/;\Z/, '')}!important" : value
105
95
  end
106
96
 
107
97
  merged.create_shorthand!
@@ -122,12 +112,12 @@ module CssParser
122
112
  def self.calculate_specificity(selector)
123
113
  a = 0
124
114
  b = selector.scan(/\#/).length
125
- c = selector.scan(NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX).length
126
- d = selector.scan(ELEMENTS_AND_PSEUDO_ELEMENTS_RX).length
115
+ c = selector.scan(NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX_NC).length
116
+ d = selector.scan(ELEMENTS_AND_PSEUDO_ELEMENTS_RX_NC).length
127
117
 
128
- (a.to_s + b.to_s + c.to_s + d.to_s).to_i
118
+ "#{a}#{b}#{c}#{d}".to_i
129
119
  rescue
130
- return 0
120
+ 0
131
121
  end
132
122
 
133
123
  # Make <tt>url()</tt> links absolute.
@@ -144,23 +134,25 @@ module CssParser
144
134
  # "http://example.org/style/basic.css").inspect
145
135
  # => "body { background: url('http://example.org/style/yellow.png?abc=123') };"
146
136
  def self.convert_uris(css, base_uri)
147
- base_uri = Addressable::URI.parse(base_uri) unless base_uri.kind_of?(Addressable::URI)
137
+ base_uri = Addressable::URI.parse(base_uri) unless base_uri.is_a?(Addressable::URI)
148
138
 
149
139
  css.gsub(URI_RX) do
150
- uri = $1.to_s
151
- uri.gsub!(/["']+/, '')
140
+ uri = Regexp.last_match(1).to_s.gsub(/["']+/, '')
152
141
  # Don't process URLs that are already absolute
153
- unless uri =~ /^[a-z]+\:\/\//i
142
+ unless uri.match(%r{^[a-z]+://}i)
154
143
  begin
155
- uri = base_uri + uri
156
- rescue; end
144
+ uri = base_uri.join(uri)
145
+ rescue
146
+ nil
147
+ end
157
148
  end
158
- "url('#{uri.to_s}')"
149
+ "url('#{uri}')"
159
150
  end
160
151
  end
161
152
 
162
153
  def self.sanitize_media_query(raw)
163
- mq = raw.to_s.gsub(/[\s]+/, ' ').strip
154
+ mq = raw.to_s.gsub(/\s+/, ' ')
155
+ mq.strip!
164
156
  mq = 'all' if mq.empty?
165
157
  mq.to_sym
166
158
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module CssParser
2
4
  # Exception class used for any errors encountered while downloading remote files.
3
5
  class RemoteFileError < IOError; end
@@ -14,13 +16,13 @@ module CssParser
14
16
  # [<tt>import</tt>] Follow <tt>@import</tt> rules. Boolean, default is <tt>true</tt>.
15
17
  # [<tt>io_exceptions</tt>] Throw an exception if a link can not be found. Boolean, default is <tt>true</tt>.
16
18
  class Parser
17
- USER_AGENT = "Ruby CSS Parser/#{CssParser::VERSION} (https://github.com/premailer/css_parser)"
19
+ USER_AGENT = "Ruby CSS Parser/#{CssParser::VERSION} (https://github.com/premailer/css_parser)"
18
20
 
19
- STRIP_CSS_COMMENTS_RX = /\/\*.*?\*\//m
20
- STRIP_HTML_COMMENTS_RX = /\<\!\-\-|\-\-\>/m
21
+ STRIP_CSS_COMMENTS_RX = %r{/\*.*?\*/}m.freeze
22
+ STRIP_HTML_COMMENTS_RX = /<!--|-->/m.freeze
21
23
 
22
24
  # Initial parsing
23
- RE_AT_IMPORT_RULE = /\@import\s*(?:url\s*)?(?:\()?(?:\s*)["']?([^'"\s\)]*)["']?\)?([\w\s\,^\]\(\)]*)\)?[;\n]?/
25
+ RE_AT_IMPORT_RULE = /@import\s*(?:url\s*)?(?:\()?(?:\s*)["']?([^'"\s)]*)["']?\)?([\w\s,^\]()]*)\)?[;\n]?/.freeze
24
26
 
25
27
  MAX_REDIRECTS = 3
26
28
 
@@ -34,10 +36,10 @@ module CssParser
34
36
  class << self; attr_reader :folded_declaration_cache; end
35
37
 
36
38
  def initialize(options = {})
37
- @options = {:absolute_paths => false,
38
- :import => true,
39
- :io_exceptions => true,
40
- :capture_offsets => false}.merge(options)
39
+ @options = {absolute_paths: false,
40
+ import: true,
41
+ io_exceptions: true,
42
+ capture_offsets: false}.merge(options)
41
43
 
42
44
  # array of RuleSets
43
45
  @rules = []
@@ -69,21 +71,20 @@ module CssParser
69
71
  # Returns an array of declarations.
70
72
  def find_by_selector(selector, media_types = :all)
71
73
  out = []
72
- each_selector(media_types) do |sel, dec, spec|
74
+ each_selector(media_types) do |sel, dec, _spec|
73
75
  out << dec if sel.strip == selector.strip
74
76
  end
75
77
  out
76
78
  end
77
- alias_method :[], :find_by_selector
79
+ alias [] find_by_selector
78
80
 
79
81
  # Finds the rule sets that match the given selectors
80
82
  def find_rule_sets(selectors, media_types = :all)
81
83
  rule_sets = []
82
84
 
83
85
  selectors.each do |selector|
84
- selector.gsub!(/\s+/, ' ')
85
- selector.strip!
86
- each_rule_set(media_types) do |rule_set, media_type|
86
+ selector = selector.gsub(/\s+/, ' ').strip
87
+ each_rule_set(media_types) do |rule_set, _media_type|
87
88
  if !rule_sets.member?(rule_set) && rule_set.selectors.member?(selector)
88
89
  rule_sets << rule_set
89
90
  end
@@ -114,9 +115,9 @@ module CssParser
114
115
  # parser = CssParser::Parser.new
115
116
  # parser.add_block!(css)
116
117
  def add_block!(block, options = {})
117
- options = {:base_uri => nil, :base_dir => nil, :charset => nil, :media_types => :all, :only_media_types => :all}.merge(options)
118
- options[:media_types] = [options[:media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
119
- options[:only_media_types] = [options[:only_media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
118
+ options = {base_uri: nil, base_dir: nil, charset: nil, media_types: :all, only_media_types: :all}.merge(options)
119
+ options[:media_types] = [options[:media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt) }
120
+ options[:only_media_types] = [options[:only_media_types]].flatten.collect { |mt| CssParser.sanitize_media_query(mt) }
120
121
 
121
122
  block = cleanup_block(block, options)
122
123
 
@@ -128,19 +129,19 @@ module CssParser
128
129
  if @options[:import]
129
130
  block.scan(RE_AT_IMPORT_RULE).each do |import_rule|
130
131
  media_types = []
131
- if media_string = import_rule[-1]
132
- media_string.split(/[,]/).each do |t|
132
+ if (media_string = import_rule[-1])
133
+ media_string.split(/,/).each do |t|
133
134
  media_types << CssParser.sanitize_media_query(t) unless t.empty?
134
135
  end
135
136
  else
136
137
  media_types = [:all]
137
138
  end
138
139
 
139
- next unless options[:only_media_types].include?(:all) or media_types.length < 1 or (media_types & options[:only_media_types]).length > 0
140
+ next unless options[:only_media_types].include?(:all) or media_types.empty? or !(media_types & options[:only_media_types]).empty?
140
141
 
141
142
  import_path = import_rule[0].to_s.gsub(/['"]*/, '').strip
142
143
 
143
- import_options = { :media_types => media_types }
144
+ import_options = {media_types: media_types}
144
145
  import_options[:capture_offsets] = true if options[:capture_offsets]
145
146
 
146
147
  if options[:base_uri]
@@ -182,20 +183,21 @@ module CssParser
182
183
  #
183
184
  # +media_types+ can be a symbol or an array of symbols.
184
185
  def add_rule_set!(ruleset, media_types = :all)
185
- raise ArgumentError unless ruleset.kind_of?(CssParser::RuleSet)
186
+ raise ArgumentError unless ruleset.is_a?(CssParser::RuleSet)
186
187
 
187
- media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
188
+ media_types = [media_types] unless media_types.is_a?(Array)
189
+ media_types = media_types.flat_map { |mt| CssParser.sanitize_media_query(mt) }
188
190
 
189
- @rules << {:media_types => media_types, :rules => ruleset}
191
+ @rules << {media_types: media_types, rules: ruleset}
190
192
  end
191
193
 
192
194
  # Remove a CssParser RuleSet object.
193
195
  #
194
196
  # +media_types+ can be a symbol or an array of symbols.
195
197
  def remove_rule_set!(ruleset, media_types = :all)
196
- raise ArgumentError unless ruleset.kind_of?(CssParser::RuleSet)
198
+ raise ArgumentError unless ruleset.is_a?(CssParser::RuleSet)
197
199
 
198
- media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
200
+ media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt) }
199
201
 
200
202
  @rules.reject! do |rule|
201
203
  rule[:media_types] == media_types && rule[:rules].to_s == ruleset.to_s
@@ -207,7 +209,7 @@ module CssParser
207
209
  # +media_types+ can be a symbol or an array of symbols.
208
210
  def each_rule_set(media_types = :all) # :yields: rule_set, media_types
209
211
  media_types = [:all] if media_types.nil?
210
- media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
212
+ media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt) }
211
213
 
212
214
  @rules.each do |block|
213
215
  if media_types.include?(:all) or block[:media_types].any? { |mt| media_types.include?(mt) }
@@ -220,7 +222,7 @@ module CssParser
220
222
  def to_h(which_media = :all)
221
223
  out = {}
222
224
  styles_by_media_types = {}
223
- each_selector(which_media) do |selectors, declarations, specificity, media_types|
225
+ each_selector(which_media) do |selectors, declarations, _specificity, media_types|
224
226
  media_types.each do |media_type|
225
227
  styles_by_media_types[media_type] ||= []
226
228
  styles_by_media_types[media_type] << [selectors, declarations]
@@ -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(__method__, all_media_types, options) 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,9 +255,10 @@ 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 = []
255
259
  styles_by_media_types = {}
256
- each_selector(which_media) do |selectors, declarations, specificity, media_types|
260
+
261
+ each_selector(which_media) do |selectors, declarations, _specificity, media_types|
257
262
  media_types.each do |media_type|
258
263
  styles_by_media_types[media_type] ||= []
259
264
  styles_by_media_types[media_type] << [selectors, declarations]
@@ -262,20 +267,21 @@ module CssParser
262
267
 
263
268
  styles_by_media_types.each_pair do |media_type, media_styles|
264
269
  media_block = (media_type != :all)
265
- out += "@media #{media_type} {\n" if media_block
270
+ out << "@media #{media_type} {" if media_block
266
271
 
267
272
  media_styles.each do |media_style|
268
273
  if media_block
269
- out += " #{media_style[0]} {\n #{media_style[1]}\n }\n"
274
+ out.push(" #{media_style[0]} {\n #{media_style[1]}\n }")
270
275
  else
271
- out += "#{media_style[0]} {\n#{media_style[1]}\n}\n"
276
+ out.push("#{media_style[0]} {\n#{media_style[1]}\n}")
272
277
  end
273
278
  end
274
279
 
275
- out += "}\n" if media_block
280
+ out << '}' if media_block
276
281
  end
277
282
 
278
- out
283
+ out << ''
284
+ out.join("\n")
279
285
  end
280
286
 
281
287
  # A hash of { :media_query => rule_sets }
@@ -283,7 +289,7 @@ module CssParser
283
289
  rules_by_media = {}
284
290
  @rules.each do |block|
285
291
  block[:media_types].each do |mt|
286
- unless rules_by_media.has_key?(mt)
292
+ unless rules_by_media.key?(mt)
287
293
  rules_by_media[mt] = []
288
294
  end
289
295
  rules_by_media[mt] << block[:rules]
@@ -295,15 +301,13 @@ module CssParser
295
301
 
296
302
  # Merge declarations with the same selector.
297
303
  def compact! # :nodoc:
298
- compacted = []
299
-
300
- compacted
304
+ []
301
305
  end
302
306
 
303
307
  def parse_block_into_rule_sets!(block, options = {}) # :nodoc:
304
308
  current_media_queries = [:all]
305
309
  if options[:media_types]
306
- current_media_queries = options[:media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
310
+ current_media_queries = options[:media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt) }
307
311
  end
308
312
 
309
313
  in_declarations = 0
@@ -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(/(([\\]{2,})|([\\]?[{}\s"])|(.[^\s"{}\\]*))/) do |matches|
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 =~ /\A"/ # found un-escaped double quote
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 token =~ /\{/ and not in_string
344
+ if !in_string && token.include?('{')
343
345
  in_declarations += 1
344
346
  next
345
347
  end
346
348
 
347
- current_declarations += token
349
+ current_declarations << token
348
350
 
349
- if token =~ /\}/ and not in_string
350
- current_declarations.gsub!(/\}[\s]*$/, '')
351
+ if !in_string && token.include?('}')
352
+ current_declarations.gsub!(/\}\s*$/, '')
351
353
 
352
354
  in_declarations -= 1
355
+ current_declarations.strip!
353
356
 
354
- unless current_declarations.strip.empty?
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,56 +373,54 @@ module CssParser
370
373
  in_at_media_rule = true
371
374
  current_media_queries = []
372
375
  elsif in_at_media_rule
373
- if token =~ /\{/
374
- block_depth = block_depth + 1
376
+ if token.include?('{')
377
+ 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.gsub!(/[,]/, ' ')
382
- current_media_query += token.strip + ' '
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
- current_media_query += token.strip + ' '
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 = (token =~ /;/ ? false : true)
395
+ in_charset = !token.include?(';')
396
+ elsif !in_string && token.include?('}')
397
+ block_depth -= 1
398
+
399
+ # reset the current media query scope
400
+ if in_media_block
401
+ current_media_queries = [:all]
402
+ in_media_block = false
403
+ end
404
+ elsif !in_string && token.include?('{')
405
+ current_selectors.strip!
406
+ in_declarations += 1
391
407
  else
392
- if token =~ /\}/ and not in_string
393
- block_depth = block_depth - 1
408
+ # if we are in a selector, add the token to the current selectors
409
+ current_selectors << token
394
410
 
395
- # reset the current media query scope
396
- if in_media_block
397
- current_media_queries = [:all]
398
- in_media_block = false
399
- end
400
- else
401
- if token =~ /\{/ and not in_string
402
- current_selectors.strip!
403
- in_declarations += 1
404
- else
405
- # if we are in a selector, add the token to the current selectors
406
- current_selectors += token
407
-
408
- # mark this as the beginning of the selector unless we have already marked it
409
- rule_start = offset.first if options[:capture_offsets] && rule_start.nil? && token =~ /^[^\s]+$/
410
- end
411
- end
411
+ # mark this as the beginning of the selector unless we have already marked it
412
+ rule_start = offset.first if options[:capture_offsets] && rule_start.nil? && token =~ /^[^\s]+$/
412
413
  end
413
414
  end
414
415
 
415
416
  # check for unclosed braces
416
- if in_declarations > 0
417
- if options[:capture_offsets]
418
- add_rule_with_offsets!(current_selectors, current_declarations, options[:filename], (rule_start..offset.last), current_media_queries)
419
- else
420
- add_rule!(current_selectors, current_declarations, current_media_queries)
421
- end
417
+ return unless in_declarations > 0
418
+
419
+ unless options[:capture_offsets]
420
+ return add_rule!(current_selectors, current_declarations, current_media_queries)
422
421
  end
422
+
423
+ add_rule_with_offsets!(current_selectors, current_declarations, options[:filename], (rule_start..offset.last), current_media_queries)
423
424
  end
424
425
 
425
426
  # Load a remote CSS file.
@@ -432,7 +433,7 @@ module CssParser
432
433
  def load_uri!(uri, options = {}, deprecated = nil)
433
434
  uri = Addressable::URI.parse(uri) unless uri.respond_to? :scheme
434
435
 
435
- opts = {:base_uri => nil, :media_types => :all}
436
+ opts = {base_uri: nil, media_types: :all}
436
437
 
437
438
  if options.is_a? Hash
438
439
  opts.merge!(options)
@@ -452,14 +453,13 @@ module CssParser
452
453
  opts[:filename] = uri.to_s if opts[:capture_offsets]
453
454
 
454
455
  src, = read_remote_file(uri) # skip charset
455
- if src
456
- add_block!(src, opts)
457
- end
456
+
457
+ add_block!(src, opts) if src
458
458
  end
459
459
 
460
460
  # Load a local CSS file.
461
461
  def load_file!(file_name, options = {}, deprecated = nil)
462
- opts = {:base_dir => nil, :media_types => :all}
462
+ opts = {base_dir: nil, media_types: :all}
463
463
 
464
464
  if options.is_a? Hash
465
465
  opts.merge!(options)
@@ -482,7 +482,7 @@ module CssParser
482
482
 
483
483
  # Load a local CSS string.
484
484
  def load_string!(src, options = {}, deprecated = nil)
485
- opts = {:base_dir => nil, :media_types => :all}
485
+ opts = {base_dir: nil, media_types: :all}
486
486
 
487
487
  if options.is_a? Hash
488
488
  opts.merge!(options)
@@ -494,9 +494,8 @@ module CssParser
494
494
  add_block!(src, opts)
495
495
  end
496
496
 
497
-
498
-
499
497
  protected
498
+
500
499
  # Check that a path hasn't been loaded already
501
500
  #
502
501
  # Raises a CircularReferenceError exception if io_exceptions are on,
@@ -505,10 +504,11 @@ module CssParser
505
504
  path = path.to_s
506
505
  if @loaded_uris.include?(path)
507
506
  raise CircularReferenceError, "can't load #{path} more than once" if @options[:io_exceptions]
508
- return false
507
+
508
+ false
509
509
  else
510
510
  @loaded_uris << path
511
- return true
511
+ true
512
512
  end
513
513
  end
514
514
 
@@ -528,7 +528,7 @@ module CssParser
528
528
  # Returns a string.
529
529
  def cleanup_block(block, options = {}) # :nodoc:
530
530
  # Strip CSS comments
531
- utf8_block = block.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: ' ')
531
+ utf8_block = block.encode('UTF-8', 'UTF-8', invalid: :replace, undef: :replace, replace: ' ')
532
532
  utf8_block = ignore_pattern(utf8_block, STRIP_CSS_COMMENTS_RX, options)
533
533
 
534
534
  # Strip HTML comments - they shouldn't really be in here but
@@ -536,7 +536,7 @@ module CssParser
536
536
  utf8_block = ignore_pattern(utf8_block, STRIP_HTML_COMMENTS_RX, options)
537
537
 
538
538
  # Strip lines containing just whitespace
539
- utf8_block.gsub!(/^\s+$/, "") unless options[:capture_offsets]
539
+ utf8_block.gsub!(/^\s+$/, '') unless options[:capture_offsets]
540
540
 
541
541
  utf8_block
542
542
  end
@@ -572,11 +572,8 @@ module CssParser
572
572
  if uri.scheme == 'file'
573
573
  # local file
574
574
  path = uri.path
575
- path.gsub!(/^\//, '') if Gem.win_platform?
576
- fh = open(path, 'rb')
577
- src = fh.read
578
- charset = fh.respond_to?(:charset) ? fh.charset : 'utf-8'
579
- fh.close
575
+ path.gsub!(%r{^/}, '') if Gem.win_platform?
576
+ src = File.read(path, mode: 'rb')
580
577
  else
581
578
  # remote file
582
579
  if uri.scheme == 'https'
@@ -594,21 +591,22 @@ module CssParser
594
591
 
595
592
  if res.code.to_i >= 400
596
593
  @redirect_count = nil
597
- raise RemoteFileError.new(uri.to_s) if @options[:io_exceptions]
594
+ raise RemoteFileError, uri.to_s if @options[:io_exceptions]
595
+
598
596
  return '', nil
599
597
  elsif res.code.to_i >= 300 and res.code.to_i < 400
600
- if res['Location'] != nil
598
+ unless res['Location'].nil?
601
599
  return read_remote_file Addressable::URI.parse(Addressable::URI.escape(res['Location']))
602
600
  end
603
601
  end
604
602
 
605
603
  case res['content-encoding']
606
- when 'gzip'
607
- io = Zlib::GzipReader.new(StringIO.new(res.body))
608
- src = io.read
609
- when 'deflate'
610
- io = Zlib::Inflate.new
611
- src = io.inflate(res.body)
604
+ when 'gzip'
605
+ io = Zlib::GzipReader.new(StringIO.new(res.body))
606
+ src = io.read
607
+ when 'deflate'
608
+ io = Zlib::Inflate.new
609
+ src = io.inflate(res.body)
612
610
  end
613
611
  end
614
612
 
@@ -622,15 +620,17 @@ module CssParser
622
620
  end
623
621
  rescue
624
622
  @redirect_count = nil
625
- raise RemoteFileError.new(uri.to_s)if @options[:io_exceptions]
623
+ raise RemoteFileError, uri.to_s if @options[:io_exceptions]
624
+
626
625
  return nil, nil
627
626
  end
628
627
 
629
628
  @redirect_count = nil
630
- return src, charset
629
+ [src, charset]
631
630
  end
632
631
 
633
632
  private
633
+
634
634
  # Save a folded declaration block to the internal cache.
635
635
  def save_folded_declaration(block_hash, folded_declaration) # :nodoc:
636
636
  @folded_declaration_cache[block_hash] = folded_declaration
@@ -638,7 +638,7 @@ module CssParser
638
638
 
639
639
  # Retrieve a folded declaration block from the internal cache.
640
640
  def get_folded_declaration(block_hash) # :nodoc:
641
- return @folded_declaration_cache[block_hash] ||= nil
641
+ @folded_declaration_cache[block_hash] ||= nil
642
642
  end
643
643
 
644
644
  def reset! # :nodoc:
@@ -652,14 +652,15 @@ module CssParser
652
652
  # passed hash
653
653
  def css_node_to_h(hash, key, val)
654
654
  hash[key.strip] = '' and return hash if val.nil?
655
+
655
656
  lines = val.split(';')
656
657
  nodes = {}
657
658
  lines.each do |line|
658
659
  parts = line.split(':', 2)
659
- if (parts[1] =~ /:/)
660
+ if parts[1] =~ /:/
660
661
  nodes[parts[0]] = css_node_to_h(hash, parts[0], parts[1])
661
662
  else
662
- nodes[parts[0].to_s.strip] =parts[1].to_s.strip
663
+ nodes[parts[0].to_s.strip] = parts[1].to_s.strip
663
664
  end
664
665
  end
665
666
  hash[key.strip] = nodes