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.



69
70
71
72
# File 'lib/css_parser/rule_set.rb', line 69

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

Instance Method Details

#==(other) ⇒ Object



209
210
211
212
213
# File 'lib/css_parser/rule_set.rb', line 209

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



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

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



92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/css_parser/rule_set.rb', line 92

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



125
126
127
# File 'lib/css_parser/rule_set.rb', line 125

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

#key?(property) ⇒ Boolean

Returns:

  • (Boolean)


112
113
114
# File 'lib/css_parser/rule_set.rb', line 112

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)


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
191
192
193
194
195
196
# File 'lib/css_parser/rule_set.rb', line 143

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

#sizeObject



116
117
118
# File 'lib/css_parser/rule_set.rb', line 116

def size
  declarations.size
end

#to_s(options = {}) ⇒ Object



198
199
200
201
202
203
204
205
206
207
# File 'lib/css_parser/rule_set.rb', line 198

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