Class: Hexp::CssSelector::Parser
- Inherits:
-
Object
- Object
- Hexp::CssSelector::Parser
- Defined in:
- lib/hexp/css_selector/parser.rb
Overview
A parser of CSS selectors
This is a wrapper around the SASS parser. This way we are isolated from changes in SASS. It also makes things easier should we decide to switch to a different parsing library or roll our own parser. We only use a fraction of the functionality of SASS so this might be worth it, although at this point I want to avoid reinventing that wheel.
The classes that make up the parse tree largely mimic the ones from SASS, like CommaSequence, SimpleSequence, Class, Id, etc. By having them in our own namespace however we can easily add Hexp-specific functionality to them.
Class Method Summary collapse
-
.call(selector) ⇒ Hexp::CssSelector::CommaSequence
private
Parse a CSS selector in one go.
Instance Method Summary collapse
-
#initialize(selector) ⇒ Parser
constructor
private
Initialize the parser with the selector to parse.
-
#parse ⇒ Hexp::CssSelector::CommaSequence
private
Parse the selector.
-
#visit_attribute_condition(node) ⇒ Object
[href^=“http://”].
-
#visit_child_selector(node) ⇒ Object
ul > li.
- #visit_class_condition(node) ⇒ Object
- #visit_conditional_selector(node) ⇒ Object
- #visit_descendant_selector(node) ⇒ Object
- #visit_element_name(node) ⇒ Object
- #visit_id(node) ⇒ Object
-
#visit_pseudo_selector(node) ⇒ Object
li:first / li:nth-child(3n).
Constructor Details
#initialize(selector) ⇒ Parser
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.
Initialize the parser with the selector to parse
21 22 23 |
# File 'lib/hexp/css_selector/parser.rb', line 21 def initialize(selector) @selector = selector.freeze end |
Class Method Details
.call(selector) ⇒ Hexp::CssSelector::CommaSequence
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.
Parse a CSS selector in one go
44 45 46 |
# File 'lib/hexp/css_selector/parser.rb', line 44 def self.call(selector) new(selector).parse end |
Instance Method Details
#parse ⇒ Hexp::CssSelector::CommaSequence
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.
Parse the selector
30 31 32 33 34 35 36 |
# File 'lib/hexp/css_selector/parser.rb', line 30 def parse CommaSequence.new( ::Nokogiri::CSS.parse(@selector).map do |node| node.accept(self) end ) end |
#visit_attribute_condition(node) ⇒ Object
- href^=“http://”
90 91 92 93 94 |
# File 'lib/hexp/css_selector/parser.rb', line 90 def visit_attribute_condition(node) element, operator, value = node.value name = element.value.first Attribute.new(name.sub(/^@/, ''), operator, value) end |
#visit_child_selector(node) ⇒ Object
ul > li
85 86 87 |
# File 'lib/hexp/css_selector/parser.rb', line 85 def visit_child_selector(node) raise "not implemented" end |
#visit_class_condition(node) ⇒ Object
76 77 78 |
# File 'lib/hexp/css_selector/parser.rb', line 76 def visit_class_condition(node) Class.new(node.value.first) end |
#visit_conditional_selector(node) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/hexp/css_selector/parser.rb', line 54 def visit_conditional_selector(node) head, tail = node.value children = [head] while tail.type == :COMBINATOR head, tail = tail.value children << head end children << tail SimpleSequence.new( children.map {|child| child.accept(self) } ) end |
#visit_descendant_selector(node) ⇒ Object
48 49 50 51 52 |
# File 'lib/hexp/css_selector/parser.rb', line 48 def visit_descendant_selector(node) Sequence.new( node.value.map {|child| child.accept(self) } ) end |
#visit_element_name(node) ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/hexp/css_selector/parser.rb', line 68 def visit_element_name(node) if node.value == ["*"] Universal.new else Element.new(node.value.first) end end |
#visit_id(node) ⇒ Object
80 81 82 |
# File 'lib/hexp/css_selector/parser.rb', line 80 def visit_id(node) Id.new(node.value.first.sub(/^#/, '')) end |
#visit_pseudo_selector(node) ⇒ Object
li:first / li:nth-child(3n)
97 98 99 |
# File 'lib/hexp/css_selector/parser.rb', line 97 def visit_pseudo_selector(node) raise "not implemented" end |