Class: Cataract::Declarations
- Inherits:
-
Object
- Object
- Cataract::Declarations
- Includes:
- Enumerable
- Defined in:
- lib/cataract/declarations.rb,
lib/cataract/pure.rb,
ext/cataract/cataract.c
Overview
Container for CSS property declarations with merge and cascade support.
The Declarations class provides a convenient Ruby interface for working with CSS property-value pairs. It wraps an array of Declaration structs (defined in C) and provides hash-like access, iteration, and merging capabilities.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Compare this Declarations with another object.
-
#delete(property) ⇒ Array<Declaration>
Delete a property from the declaration block.
-
#each {|property, value, important| ... } ⇒ Enumerator?
Iterate through each property-value pair.
-
#empty? ⇒ Boolean
Check if the declaration block is empty.
-
#get_property(property) ⇒ String?
(also: #[])
Get the value of a CSS property.
-
#important?(property) ⇒ Boolean
Check if a property has the !important flag.
-
#initialize(properties = {}) ⇒ Declarations
constructor
Create a new Declarations container.
-
#initialize_copy(source) ⇒ Object
Ensure dup/clone create a proper independent copy, duplicating the internal declarations array so mutations (via []=, delete, merge!, etc.) on the copy don't affect the source.
-
#key?(property) ⇒ Boolean
(also: #has_property?)
Check if a property is defined in this declaration block.
-
#merge(other) ⇒ Declarations
Merge another set of declarations (non-mutating).
-
#merge!(other) ⇒ self
Merge another set of declarations into this one (mutating).
-
#set_property(property, value) ⇒ void
(also: #[]=)
Set the value of a CSS property.
-
#size ⇒ Integer
(also: #length)
Get the number of declarations.
-
#to_a ⇒ Array<Declaration>
Convert to an array of Declaration structs.
-
#to_h ⇒ Hash<String, String>
Convert to a hash of property => value pairs.
-
#to_s ⇒ String
(also: #to_str)
Instance method: Declarations#to_s Converts declarations to CSS string.
Constructor Details
#initialize(properties = {}) ⇒ Declarations
Create a new Declarations container.
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/cataract/declarations.rb', line 37 def initialize(properties = {}) case properties when Array # Array of Declaration structs from C parser - store directly @values = properties when Hash # Hash from user - convert to internal storage @values = [] properties.each { |prop, value| self[prop] = value } when String # String "color: red; background: blue" - parse it @values = parse_declaration_string(properties) else @values = [] end end |
Instance Method Details
#==(other) ⇒ Boolean
Compare this Declarations with another object.
306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'lib/cataract/declarations.rb', line 306 def ==(other) case other when Declarations # Compare arrays of Declaration structs to_a == other.to_a when String # Allow string comparison for convenience to_s == other else false end end |
#delete(property) ⇒ Array<Declaration>
Delete a property from the declaration block.
160 161 162 163 |
# File 'lib/cataract/declarations.rb', line 160 def delete(property) prop = normalize_property(property) @values.delete_if { |v| v.property == prop } end |
#each {|property, value, important| ... } ⇒ Enumerator?
Iterate through each property-value pair.
176 177 178 179 180 181 182 |
# File 'lib/cataract/declarations.rb', line 176 def each return enum_for(:each) unless block_given? @values.each do |val| yield val.property, val.value, val.important end end |
#empty? ⇒ Boolean
Check if the declaration block is empty.
195 196 197 |
# File 'lib/cataract/declarations.rb', line 195 def empty? @values.empty? end |
#get_property(property) ⇒ String? Also known as: []
Get the value of a CSS property.
Returns the property value with !important suffix if present. Property names are case-insensitive.
66 67 68 69 70 71 72 73 |
# File 'lib/cataract/declarations.rb', line 66 def get_property(property) prop = normalize_property(property) val = find_value(prop) return nil if val.nil? suffix = val.important ? ' !important' : '' "#{val.value}#{suffix}" end |
#important?(property) ⇒ Boolean
Check if a property has the !important flag.
147 148 149 150 |
# File 'lib/cataract/declarations.rb', line 147 def important?(property) val = find_value(normalize_property(property)) val ? val.important : false end |
#initialize_copy(source) ⇒ Object
Ensure dup/clone create a proper independent copy, duplicating the internal declarations array so mutations (via []=, delete, merge!, etc.) on the copy don't affect the source. Declaration structs themselves are treated as immutable value objects throughout this class (always replaced wholesale, never mutated in place), so a shallow copy of the array is sufficient - defining this via initialize_copy (rather than overriding #dup directly) ensures #clone gets the same fix, since both go through initialize_copy.
291 292 293 294 |
# File 'lib/cataract/declarations.rb', line 291 def initialize_copy(source) super @values = source.instance_variable_get(:@values).dup end |
#key?(property) ⇒ Boolean Also known as: has_property?
Check if a property is defined in this declaration block.
132 133 134 |
# File 'lib/cataract/declarations.rb', line 132 def key?(property) !find_value(normalize_property(property)).nil? end |
#merge(other) ⇒ Declarations
Merge another set of declarations (non-mutating).
Creates a copy of this Declarations object and merges the other into it.
277 278 279 |
# File 'lib/cataract/declarations.rb', line 277 def merge(other) dup.merge!(other) end |
#merge!(other) ⇒ self
Merge another set of declarations into this one (mutating).
Properties from the other declarations will overwrite properties in this one. The !important flag is preserved during merge.
252 253 254 255 256 257 258 259 260 261 262 |
# File 'lib/cataract/declarations.rb', line 252 def merge!(other) case other when Declarations other.each { |prop, value, important| self[prop] = important ? "#{value} !important" : value } when Hash other.each { |prop, value| self[prop] = value } else raise ArgumentError, 'Can only merge Declarations or Hash objects' end self end |
#set_property(property, value) ⇒ void Also known as: []=
This method returns an undefined value.
Set the value of a CSS property.
Property names are normalized to lowercase. Trailing semicolons are stripped. The !important flag can be included in the value string.
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/cataract/declarations.rb', line 89 def set_property(property, value) prop = normalize_property(property) # Parse !important and strip trailing semicolons (css_parser compatibility) clean_value = value.to_s.strip # Remove trailing semicolons (guard to avoid allocation when no semicolon present) # value_str = value_str.sub(/;+$/, '') if value_str.end_with?(';') clean_value.sub!(/;+$/, '') if clean_value.end_with?(';') is_important = clean_value.end_with?('!important') if is_important clean_value.sub!(/\s*!important\s*$/, '').strip! else clean_value.strip! end # Reject malformed declarations with no value (e.g., "color: !important") # css_parser silently ignores these return if clean_value.empty? # Find existing value or create new one # Properties from C parser are already normalized, so direct comparison existing_index = @values.find_index { |v| v.property == prop } # Create a new Declaration struct new_val = Cataract::Declaration.new(prop, clean_value, is_important) if existing_index @values[existing_index] = new_val else @values << new_val end end |
#size ⇒ Integer Also known as: length
Get the number of declarations.
187 188 189 |
# File 'lib/cataract/declarations.rb', line 187 def size @values.size end |
#to_a ⇒ Array<Declaration>
Convert to an array of Declaration structs.
Returns the internal array of Declaration structs, which is useful for creating Rule objects or passing to C functions.
234 235 236 |
# File 'lib/cataract/declarations.rb', line 234 def to_a @values end |
#to_h ⇒ Hash<String, String>
Convert to a hash of property => value pairs.
Values include !important suffix if present.
219 220 221 222 223 224 225 226 |
# File 'lib/cataract/declarations.rb', line 219 def to_h result = {} each do |property, value, is_important| suffix = is_important ? ' !important' : '' result[property] = "#{value}#{suffix}" end result end |
#to_s ⇒ String Also known as: to_str
Instance method: Declarations#to_s Converts declarations to CSS string
42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'lib/cataract/pure.rb', line 42 def to_s result = String.new @values.each_with_index do |decl, i| result << decl.property result << ': ' result << decl.value result << ' !important' if decl.important result << ';' result << ' ' if i < @values.length - 1 # Add space after semicolon except for last end result end |