lib/css_parser/parser.rb in css_parser-1.6.0 vs lib/css_parser/parser.rb in css_parser-1.7.0
- old
+ new
@@ -1,5 +1,6 @@
+# frozen_string_literal: true
module CssParser
# Exception class used for any errors encountered while downloading remote files.
class RemoteFileError < IOError; end
# Exception class used if a request is made to load a CSS file more than once.
@@ -182,11 +183,12 @@
#
# +media_types+ can be a symbol or an array of symbols.
def add_rule_set!(ruleset, media_types = :all)
raise ArgumentError unless ruleset.kind_of?(CssParser::RuleSet)
- media_types = [media_types].flatten.collect { |mt| CssParser.sanitize_media_query(mt)}
+ media_types = [media_types] unless Array === media_types
+ media_types = media_types.flat_map { |mt| CssParser.sanitize_media_query(mt)}
@rules << {:media_types => media_types, :rules => ruleset}
end
# Remove a CssParser RuleSet object.
@@ -240,41 +242,43 @@
# Iterate through CSS selectors.
#
# +media_types+ can be a symbol or an array of symbols.
# See RuleSet#each_selector for +options+.
def each_selector(all_media_types = :all, options = {}) # :yields: selectors, declarations, specificity, media_types
+ return to_enum(:each_selector) unless block_given?
+
each_rule_set(all_media_types) do |rule_set, media_types|
rule_set.each_selector(options) do |selectors, declarations, specificity|
yield selectors, declarations, specificity, media_types
end
end
end
# Output all CSS rules as a single stylesheet.
def to_s(which_media = :all)
- out = ''
+ out = String.new
styles_by_media_types = {}
each_selector(which_media) do |selectors, declarations, specificity, media_types|
media_types.each do |media_type|
styles_by_media_types[media_type] ||= []
styles_by_media_types[media_type] << [selectors, declarations]
end
end
styles_by_media_types.each_pair do |media_type, media_styles|
media_block = (media_type != :all)
- out += "@media #{media_type} {\n" if media_block
+ out << "@media #{media_type} {\n" if media_block
media_styles.each do |media_style|
if media_block
- out += " #{media_style[0]} {\n #{media_style[1]}\n }\n"
+ out << " #{media_style[0]} {\n #{media_style[1]}\n }\n"
else
- out += "#{media_style[0]} {\n#{media_style[1]}\n}\n"
+ out << "#{media_style[0]} {\n#{media_style[1]}\n}\n"
end
end
- out += "}\n" if media_block
+ out << "}\n" if media_block
end
out
end
@@ -312,99 +316,100 @@
in_charset = false # @charset is ignored for now
in_string = false
in_at_media_rule = false
in_media_block = false
- current_selectors = ''
- current_media_query = ''
- current_declarations = ''
+ current_selectors = String.new
+ current_media_query = String.new
+ current_declarations = String.new
# once we are in a rule, we will use this to store where we started if we are capturing offsets
rule_start = nil
offset = nil
- block.scan(/(([\\]{2,})|([\\]?[{}\s"])|(.[^\s"{}\\]*))/) do |matches|
- token = matches[0]
-
+ block.scan(/\s+|[\\]{2,}|[\\]?[{}\s"]|.[^\s"{}\\]*/) do |token|
# save the regex offset so that we know where in the file we are
offset = Regexp.last_match.offset(0) if options[:capture_offsets]
- if token =~ /\A"/ # found un-escaped double quote
+ if token.start_with?('"') # found un-escaped double quote
in_string = !in_string
end
if in_declarations > 0
# too deep, malformed declaration block
if in_declarations > 1
- in_declarations -= 1 if token =~ /\}/
+ in_declarations -= 1 if token.include?('}')
next
end
- if token =~ /\{/ and not in_string
+ if !in_string && token.include?('{')
in_declarations += 1
next
end
- current_declarations += token
+ current_declarations << token
- if token =~ /\}/ and not in_string
+ if !in_string && token.include?('}')
current_declarations.gsub!(/\}[\s]*$/, '')
in_declarations -= 1
+ current_declarations.strip!
- unless current_declarations.strip.empty?
+ unless current_declarations.empty?
if options[:capture_offsets]
add_rule_with_offsets!(current_selectors, current_declarations, options[:filename], (rule_start..offset.last), current_media_queries)
else
add_rule!(current_selectors, current_declarations, current_media_queries)
end
end
- current_selectors = ''
- current_declarations = ''
+ current_selectors = String.new
+ current_declarations = String.new
# restart our search for selectors and declarations
rule_start = nil if options[:capture_offsets]
end
elsif token =~ /@media/i
# found '@media', reset current media_types
in_at_media_rule = true
current_media_queries = []
elsif in_at_media_rule
- if token =~ /\{/
+ if token.include?('{')
block_depth = block_depth + 1
in_at_media_rule = false
in_media_block = true
current_media_queries << CssParser.sanitize_media_query(current_media_query)
- current_media_query = ''
- elsif token =~ /[,]/
+ current_media_query = String.new
+ elsif token.include?(',')
# new media query begins
- token.gsub!(/[,]/, ' ')
- current_media_query += token.strip + ' '
+ token.tr!(',', ' ')
+ token.strip!
+ current_media_query << token << ' '
current_media_queries << CssParser.sanitize_media_query(current_media_query)
- current_media_query = ''
+ current_media_query = String.new
else
- current_media_query += token.strip + ' '
+ token.strip!
+ current_media_query << token << ' '
end
elsif in_charset or token =~ /@charset/i
# iterate until we are out of the charset declaration
- in_charset = (token =~ /;/ ? false : true)
+ in_charset = !token.include?(';')
else
- if token =~ /\}/ and not in_string
+ if !in_string && token.include?('}')
block_depth = block_depth - 1
# reset the current media query scope
if in_media_block
current_media_queries = [:all]
in_media_block = false
end
else
- if token =~ /\{/ and not in_string
+ if !in_string && token.include?('{')
current_selectors.strip!
in_declarations += 1
else
# if we are in a selector, add the token to the current selectors
- current_selectors += token
+ current_selectors << token
# mark this as the beginning of the selector unless we have already marked it
rule_start = offset.first if options[:capture_offsets] && rule_start.nil? && token =~ /^[^\s]+$/
end
end