class CssParser::RuleSet::Declarations

def ==(other)

def ==(other)
  return false unless other.is_a?(self.class)
  declarations == other.declarations && declarations.keys == other.declarations.keys
end

def [](property)

def [](property)
  declarations[normalize_property(property)]
end

def []=(property, value)

Parameters:
  • value (Value, #to_s) -- of the property
  • property (#to_s) -- that should be added
def []=(property, value)
  property = normalize_property(property)
  currently_important = declarations[property]&.important
  if value.is_a?(Value) && (!currently_important || value.important)
    declarations[property] = value
  elsif value.to_s.strip.empty?
    delete property
  else
    value = Value.new(value)
    declarations[property] = value if !currently_important || value.important
  end
rescue ArgumentError => e
  raise e.exception, "#{property} #{e.message}"
end

def delete(property)

Parameters:
  • property (#to_s) -- property to be removed
def delete(property)
  declarations.delete(normalize_property(property))
end

def initialize(declarations = {})

def initialize(declarations = {})
  self.declarations = {}
  declarations.each { |property, value| add_declaration!(property, value) }
end

def key?(property)

def key?(property)
  declarations.key?(normalize_property(property))
end

def normalize_property(property)

def normalize_property(property)
  property = property.to_s.downcase
  property.strip!
  property
end

def replace_declaration!(property, replacements, preserve_importance: false)

Parameters:
  • replacements (Hash [String, Value]>) -- hash with properties to replace with
  • property (#to_s) -- property name to be replaces
def replace_declaration!(property, replacements, preserve_importance: false)
  property = normalize_property(property)
  raise ArgumentError, "property #{property} does not exist" unless key?(property)
  replacement_declarations = self.class.new(replacements)
  if preserve_importance
    importance = get_value(property).important
    replacement_declarations.each_value { |value| value.important = importance }
  end
  replacement_keys = declarations.keys
  replacement_values = declarations.values
  property_index = replacement_keys.index(property)
  # We should preserve subsequent declarations of the same properties
  # and prior important ones if replacement one is not important
  replacements = replacement_declarations.each.with_object({}) do |(key, replacement), result|
    existing = declarations[key]
    # No existing -> set
    unless existing
      result[key] = replacement
      next
    end
    # Replacement more important than existing -> replace
    if replacement.important && !existing.important
      result[key] = replacement
      replaced_index = replacement_keys.index(key)
      replacement_keys.delete_at(replaced_index)
      replacement_values.delete_at(replaced_index)
      property_index -= 1 if replaced_index < property_index
      next
    end
    # Existing is more important than replacement -> keep
    next if !replacement.important && existing.important
    # Existing and replacement importance are the same,
    # value which is declared later wins
    result[key] = replacement if property_index > replacement_keys.index(key)
  end
  return if replacements.empty?
  replacement_keys.delete_at(property_index)
  replacement_keys.insert(property_index, *replacements.keys)
  replacement_values.delete_at(property_index)
  replacement_values.insert(property_index, *replacements.values)
  self.declarations = replacement_keys.zip(replacement_values).to_h
end

def size

def size
  declarations.size
end

def to_s(options = {})

def to_s(options = {})
  str = declarations.reduce(+'') do |memo, (prop, value)|
    importance = options[:force_important] || value.important ? ' !important' : ''
    memo << "#{prop}: #{value.value}#{importance}; "
  end
  # TODO: Clean-up regexp doesn't seem to work
  str.gsub!(/^[\s^({)]+|[\n\r\f\t]*|\s+$/mx, '')
  str.strip!
  str
end