Class: CSSNative::Rule

Inherits:
Object
  • Object
show all
Defined in:
lib/css-native/rule.rb,
lib/css-native/rule/stylesheet.rb

Defined Under Namespace

Classes: Stylesheet

Constant Summary collapse

COMBINATORS =

Combinators

{
  descendant: " ",
  child: " > ",
  sibling: " + ",
  adjacent: " + ",
  column: " || "
}
PSEUDO_CLASSES =

pseudo-classes name of value is pseudo-class, array values are acceptad options

Equality is compared by <option> === <value>, allowing 
classes to test for instances or regex matching

If array is empty, there’s no limitations (in the code, foraml CSS may differ) If array is nil, it takes no options

{
  # Linguistic
  dir: ["ltr", "rtl"],
  lang: [],
  # Location
  "any_link": nil,
  link: nil,
  visited: nil,
  "local_link": nil,
  target: nil,
  "target_within": nil,
  scope: nil,
  # User action
  hover: nil,
  active: nil,
  focus: nil,
  "focus_visible": nil,
  "focus_within": nil,
  # Time_dimensional _ ill_defined
  current: nil,
  past: nil,
  future: nil,
  # Resource state
  playing: nil,
  paused: nil,
  # Input
  enabled: nil,
  disabled: nil,
  "read_only": nil,
  "read_write": nil,
  "placeholder_shown": nil,
  default: nil,
  checked: nil,
  indeterminate: nil,
  blank: nil,
  valid: nil,
  invalid: nil,
  "in_range": nil,
  "out_of_range": nil,
  required: nil,
  optional: nil,
  "user_invalid": nil,
  root: nil,
  empty: nil,
  "nth_child": ["odd", "even", /^\d+(n(\s*\+\s*\d+)?)?$/],
  "nth_last_child": ["odd", "even", /^\d+(n(\s*\+\s*\d+)?)?$/],
  "first_child": nil,
  "last_child": nil,
  "only_child": nil,
  "nth_of_type": ["odd", "even", /^\d+(n(\s*\+\s*\d+)?)?$/],
  "nth_last_of_type": ["odd", "even", /^\d+(n(\s*\+\s*\d+)?)?$/],
  "first_of_type": nil,
  "last_of_type": nil,
  "only_of_type": nil,
}
PSEUDO_ELEMENTS =

pseudo-elements definition semantics same as pseudo-classes

{
  after: nil,
  before: nil,
  backdrop: nil,
  cue: nil,
  "cue_region": nil,
  "first_letter": nil,
  "first_line": nil,
  "file_selector_button": nil,
  "grammar_error": nil,
  marker: nil,
  part: [/[-a-zA-Z]+( [-a-zA-Z]+)?/],
  placeholder: nil,
  selection: nil,
  slotted: [],
  "spelling_error": nil,
  "target_text": nil,
}

Instance Method Summary collapse

Constructor Details

#initialize(parent, name = "", previous: nil) ⇒ Rule

Returns a new instance of Rule.



4
5
6
7
8
9
# File 'lib/css-native/rule.rb', line 4

def initialize(parent, name = "", previous: nil)
  @previous = previous
  @parent = parent
  @selector = name.to_s
  @stylesheet = Stylesheet.new(self)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(m, *args, &block) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
# File 'lib/css-native/rule.rb', line 211

def method_missing(m, *args, &block)
  if COMBINATORS.key?(m)
    combinator(m)
  elsif PSEUDO_CLASSES.key?(m)
    pseudo_class(m, *args, &block)
  elsif PSEUDO_ELEMENTS.key?(m)
    pseudo_element(m, *args, &block)
  else
    super(m, *args, &block)
  end
end

Instance Method Details

#all(&block) ⇒ Object

Raises:



57
58
59
60
61
62
# File 'lib/css-native/rule.rb', line 57

def all(&block)
  raise GrammarError.new("*") if previous_selector?
  @previous = :all
  @selector += "*"
  chain(&block)
end

#combinator(c) ⇒ Object

Raises:



86
87
88
89
90
91
92
# File 'lib/css-native/rule.rb', line 86

def combinator(c)
  m = c.to_sym
  raise GrammarError.new(COMBINATORS[m]) if previous_combinator?
  @previous = :combinator
  @selector += COMBINATORS[m]
  self
end

#join(rule = nil) ⇒ Object

Grouping selectors

Raises:



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/css-native/rule.rb', line 65

def join(rule = nil)
  raise GrammarError.new(",") if previous_combinator?
  @previous = :join
  @selector += ","
  if rule.kind_of? Rule
    @selector += rule.instance_variable_get(:@selector)
  else
    @selector += rule.to_s
  end
  self
end

#pseudo_class(name, *args, &block) ⇒ Object

Raises:



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
# File 'lib/css-native/rule.rb', line 156

def pseudo_class(name, *args, &block)
  pc = name.to_s.gsub("_", "-")
  m = name.to_s.gsub("-", "_").to_sym
  raise PseudoClassError.new(method: pc) unless PSEUDO_CLASSES.key?(m)

  args.each? do |arg|
    unless matches_arg_defs?(PSEUDO_CLASSES[m], arg.to_s)
      raise PseudoClassError.new(argument: arg, method: pc)
    end
  end
  
  @previous = :pseudo_class
  @selector += ":#{pc}"
  @selector += "(#{args.join(" ")})" unless args.empty?
  chain(&block)
end

#pseudo_element(name, *args, &block) ⇒ Object

Raises:



194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/css-native/rule.rb', line 194

def pseudo_element(name, *args, &block)
  pe = name.to_s.gsub("_", "-")
  m = name.to_s.gsub("-", "_").to_sym
  raise PseudoElementError.new(method: pe) unless PSEUDO_ELEMENTS.key?(m)
 
  args.each? do |arg|
    unless matches_arg_defs?(PSEUDO_ELEMENTS[m], arg.to_s)
      raise PseudoElementError.new(argument: arg, method: pe)
    end
  end
  
  @previous = :pseudo_element
  @selector += "::#{pe}"
  @selector += "(#{args.join(" ")})" unless args.empty?
  chain(&block)
end

#respond_to_missing?(m, include_all = false) ⇒ Boolean

Returns:

  • (Boolean)


223
224
225
226
227
228
# File 'lib/css-native/rule.rb', line 223

def respond_to_missing?(m, include_all = false)
  COMBINATORS.key?(m) ||
  PSEUDO_CLASSES.key?(m) ||
  PSEUDO_ELEMENTS.key?(m) ||
  super(m, include_all)
end

#to_sObject



230
231
232
# File 'lib/css-native/rule.rb', line 230

def to_s
  "#{@selector} #{@stylesheet}"
end

#with(name, *args, type: :element, &block) ⇒ Object Also known as: select



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/css-native/rule.rb', line 37

def with(name, *args, type: :element, &block)
  case type
  when :element
    if name == :all
      all(&block)
    else
      with_element(name, &block)
    end
  when :class
    with_class(name, &block)
  when :id
    with_id(name, &block)
  when :attribute
    with_attribute(name, *args, &block)
  else
    raise CSSNative::RuleError.new("undefined rule type '#{type}' for css selector")
  end
end

#with_attribute(name, operation = :none, value = nil, case_sensitive: true, &block) ⇒ Object



31
32
33
34
35
# File 'lib/css-native/rule.rb', line 31

def with_attribute(name, operation = :none, value = nil, case_sensitive: true, &block)
  @previous = :attribute
  @selector += CSSNative::format_attribute(name, operation, value, case_sensitive: case_sensitive)
  chain(&block)
end

#with_class(name, &block) ⇒ Object



19
20
21
22
23
# File 'lib/css-native/rule.rb', line 19

def with_class(name, &block)
  @previous = :class
  @selector += CSSNative::format_class(name)
  chain(&block)
end

#with_element(name, &block) ⇒ Object

basic selectors

Raises:



12
13
14
15
16
17
# File 'lib/css-native/rule.rb', line 12

def with_element(name, &block)
  raise GrammarError.new(name) if previous_selector?
  @previous = :element
  @selector += CSSNative::format_element(name)
  chain(&block)
end

#with_id(name, &block) ⇒ Object



25
26
27
28
29
# File 'lib/css-native/rule.rb', line 25

def with_id(name, &block)
  @previous = :id
  @selector += CSSNative::format_id(name)
  chain(&block)
end