Class: Habaki::SubSelector
Overview
part of selector (eg in p.t, p is a tag subselector and .t a class subselector)
Instance Attribute Summary collapse
- #argument ⇒ String
- #attribute ⇒ QualifiedName
- #match ⇒ Symbol
- #position ⇒ SourcePosition
- #pseudo ⇒ Symbol
- #selectors ⇒ Selectors
- #tag ⇒ QualifiedName
- #value ⇒ String
Instance Method Summary collapse
-
#attribute_selector? ⇒ Boolean
is this selector on attribute ?.
-
#attribute_value_match?(val, specificity = nil) ⇒ Boolean
does selector match attribute value ?.
-
#class_match?(name, specificity = nil) ⇒ Boolean
does selector match class ?.
-
#element_match?(element, specificity = nil) ⇒ Boolean
does sub selector match Visitor::Element ?.
-
#id_match?(name, specificity = nil) ⇒ Boolean
does selector match id ?.
-
#pseudo_class_match?(element, specificity = nil) ⇒ Boolean
does selector pseudo class match Visitor::Element ?.
- #read_from_katana(sel) ⇒ Object private
- #string(format = Formatter::Base.new) ⇒ String
-
#tag_match?(name, specificity = nil) ⇒ Boolean
does selector match tag ?.
Methods inherited from Node
Instance Attribute Details
#attribute ⇒ QualifiedName
21 22 23 |
# File 'lib/habaki/sub_selector.rb', line 21 def attribute @attribute end |
#match ⇒ Symbol
14 15 16 |
# File 'lib/habaki/sub_selector.rb', line 14 def match @match end |
#position ⇒ SourcePosition
30 31 32 |
# File 'lib/habaki/sub_selector.rb', line 30 def position @position end |
#pseudo ⇒ Symbol
18 19 20 |
# File 'lib/habaki/sub_selector.rb', line 18 def pseudo @pseudo end |
#selectors ⇒ Selectors
27 28 29 |
# File 'lib/habaki/sub_selector.rb', line 27 def selectors @selectors end |
Instance Method Details
#attribute_selector? ⇒ Boolean
is this selector on attribute ?
34 35 36 |
# File 'lib/habaki/sub_selector.rb', line 34 def attribute_selector? @match.to_s.start_with?("attribute_") end |
#attribute_value_match?(val, specificity = nil) ⇒ Boolean
does selector match attribute value ?
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/habaki/sub_selector.rb', line 93 def attribute_value_match?(val, specificity = nil) match_with_specificity( case @match when :attribute_exact val == @value when :attribute_begin val.start_with?(@value) when :attribute_end val.end_with?(@value) when :attribute_contain val.include?(@value) when :attribute_hyphen val.start_with?("#{@value}-") else false end, specificity, 10) end |
#class_match?(name, specificity = nil) ⇒ Boolean
does selector match class ?
77 78 79 |
# File 'lib/habaki/sub_selector.rb', line 77 def class_match?(name, specificity = nil) match_with_specificity(@value == name, specificity, 10) end |
#element_match?(element, specificity = nil) ⇒ Boolean
does sub selector match Visitor::Element ?
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/habaki/sub_selector.rb', line 42 def element_match?(element, specificity = nil) case @match when :tag tag_match?(element.tag_name, specificity) when :class element.class_names.any?{|p_class_name| class_match?(p_class_name, specificity)} when :id id_match?(element.id_name, specificity) when :pseudo_class pseudo_class_match?(element, specificity) when :pseudo_element # TODO false else if attribute_selector? element_attr = element.attr(@attribute.local) (element_attr ? attribute_value_match?(element_attr, specificity) : false) else false end end end |
#id_match?(name, specificity = nil) ⇒ Boolean
does selector match id ?
85 86 87 |
# File 'lib/habaki/sub_selector.rb', line 85 def id_match?(name, specificity = nil) match_with_specificity(@value == name, specificity, 100) end |
#pseudo_class_match?(element, specificity = nil) ⇒ Boolean
does selector pseudo class match Visitor::Element ?
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 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 |
# File 'lib/habaki/sub_selector.rb', line 115 def pseudo_class_match?(element, specificity = nil) match_with_specificity( case @pseudo when :root element.tag_name == "html" when :empty element.children.empty? when :first_child parent_element = element.parent parent_element&.children.first == element when :last_child parent_element = element.parent parent_element&.children.last == element when :only_child parent_element = element.parent parent_element&.children.length == 1 && parent_element&.children.first == element when :nth_child parent_element = element.parent arg = @argument.split("+") case arg[0] when "odd" ((parent_element&.children.index(element) + 1) % 2 == 1) when "even" ((parent_element&.children.index(element) + 1) % 2 == 0) when /^\d+$/ parent_element&.children[@argument.to_i - 1] == element when "n" ((parent_element&.children.index(element) + 1) % 1) == (arg[1]&.to_i || 0) when /n$/ ((parent_element&.children.index(element) + 1) % arg[0].sub("n", "").to_i) == (arg[1]&.to_i || 0) else # TODO "of type" false end when :not !@selectors.element_match?(element) when :not_parsed, :unknown true when :link # All a elements that have an href attribute must match one of :link and :visited. # for now, always match :link true else # TODO # STDERR.puts "Habaki: unsupported pseudo #{@pseudo}" false end, specificity, 10) end |
#read_from_katana(sel) ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/habaki/sub_selector.rb', line 213 def read_from_katana(sel) @match = sel.match @tag = QualifiedName.read_from_katana(sel.tag) if sel.tag @pseudo = sel.pseudo @attribute = QualifiedName.read_from_katana(sel.data.attribute) if sel.data.attribute @value = sel.data.value @argument = sel.data.argument @selectors = Selectors.read_from_katana(sel.data.selectors) if sel.data.selectors @position = SourcePosition.new(sel.position.line, sel.position.column) end |
#string(format = Formatter::Base.new) ⇒ String
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 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/habaki/sub_selector.rb', line 166 def string(format = Formatter::Base.new) str = "" if attribute_selector? str += "[#{@attribute.string(format)}" case @match when :attribute_exact str += "=" when :attribute_set str += "]" when :attribute_list str += "~=" when :attribute_hyphen str += "|=" when :attribute_begin str += "^=" when :attribute_end str += "$=" when :attribute_contain str += "*=" end str += "\"#{@value}\"]" if @match != :attribute_set else case @match when :tag str += @tag.string(format) when :class str += ".#{@value}" when :id str += "##{@value}" when :pseudo_class, :pseudo_page_class str += ":#{@value}" case @pseudo when :any, :not, :host, :host_context str += @selectors.string(format) str += ")" when :lang, :nth_child, :nth_last_child, :nth_of_type, :nth_last_of_type str += "#{@argument})" end when :pseudo_element str += "::#{@value}" end end str end |
#tag_match?(name, specificity = nil) ⇒ Boolean
does selector match tag ?
69 70 71 |
# File 'lib/habaki/sub_selector.rb', line 69 def tag_match?(name, specificity = nil) match_with_specificity(@tag.local == name, specificity, 1) || @tag.local == "*" end |