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