Class: CssParser::RuleSet::Declarations

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/css_parser/rule_set.rb

Defined Under Namespace

Classes: Value

Instance Method Summary collapse

Constructor Details

#initialize(declarations = {}) ⇒ Declarations

Returns a new instance of Declarations.



63
64
65
66
# File 'lib/css_parser/rule_set.rb', line 63

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

Instance Method Details

#==(other) ⇒ Object



203
204
205
206
207
# File 'lib/css_parser/rule_set.rb', line 203

def ==(other)
  return false unless other.is_a?(self.class)

  declarations == other.declarations && declarations.keys == other.declarations.keys
end

#[](property) ⇒ Object Also known as: get_value



101
102
103
# File 'lib/css_parser/rule_set.rb', line 101

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

#[]=(property, value) ⇒ Object Also known as: add_declaration!

Add a CSS declaration If the property already exists its value will be over-written. If the value is empty - property will be deleted

Examples:

declarations['color'] = 'blue'

puts declarations['color']
=> #<CssParser::RuleSet::Declarations::Value:0x000000000305c730 @important=false, @order=1, @value="blue">
declarations['margin'] = '0px auto !important'

puts declarations['margin']
=> #<CssParser::RuleSet::Declarations::Value:0x00000000030c1838 @important=true, @order=2, @value="0px auto">

Parameters:

  • property (#to_s)

    that should be added

  • value (Value, #to_s)

    of the property



86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/css_parser/rule_set.rb', line 86

def []=(property, value)
  property = normalize_property(property)

  if value.is_a?(Value)
    declarations[property] = value
  elsif value.to_s.strip.empty?
    delete property
  else
    declarations[property] = Value.new(value)
  end
rescue ArgumentError => e
  raise e.exception, "#{property} #{e.message}"
end

#delete(property) ⇒ Object Also known as: remove_declaration!

Remove CSS declaration

Examples:

declarations.delete('color')

Parameters:

  • property (#to_s)

    property to be removed



119
120
121
# File 'lib/css_parser/rule_set.rb', line 119

def delete(property)
  declarations.delete(normalize_property(property))
end

#key?(property) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
# File 'lib/css_parser/rule_set.rb', line 106

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

#replace_declaration!(property, replacements, preserve_importance: false) ⇒ Object

Replace CSS property with multiple declarations

Examples:

declarations = Declarations.new('line-height' => '0.25px', 'font' => 'small-caps', 'font-size' => '12em')
declarations.replace_declaration!('font', {'line-height' => '1px', 'font-variant' => 'small-caps', 'font-size' => '24px'})
declarations
=> #<CssParser::RuleSet::Declarations:0x00000000029c3018
@declarations=
{"line-height"=>#<CssParser::RuleSet::Declarations::Value:0x00000000038ac458 @important=false, @value="1px">,
 "font-variant"=>#<CssParser::RuleSet::Declarations::Value:0x00000000039b3ec8 @important=false, @value="small-caps">,
 "font-size"=>#<CssParser::RuleSet::Declarations::Value:0x00000000029c2c80 @important=false, @value="12em">}>

Parameters:

  • property (#to_s)

    property name to be replaces

  • replacements (Hash<String => [String, Value]>)

    hash with properties to replace with

Raises:

  • (ArgumentError)


137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/css_parser/rule_set.rb', line 137

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 { |_key, 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

#sizeObject



110
111
112
# File 'lib/css_parser/rule_set.rb', line 110

def size
  declarations.size
end

#to_s(options = {}) ⇒ Object



192
193
194
195
196
197
198
199
200
201
# File 'lib/css_parser/rule_set.rb', line 192

def to_s(options = {})
  str = declarations.reduce(String.new) 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