hexp 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 45fe82cfc464b888c41d8b632a929f6074d9b1cb
4
- data.tar.gz: 9a015de7db34bd56cadf8304a940d51fea9f6d9e
3
+ metadata.gz: c9c632d0e470fa5f4c296f3eea2ae8069eef7b54
4
+ data.tar.gz: 4d22a65fe1a865974c745846bf2e4f350b807a12
5
5
  SHA512:
6
- metadata.gz: ef380c391229dcb9716d9472882714ded77f5c3e0169f8ff98312a5e23bd1b61e3caed513f0e2c561e86b9e399b94ee88d0fbd7606f1ee83b353884199cff596
7
- data.tar.gz: 29570e22c84b840bd04429ca27f5dc9535e3e4b080007ffda9e80f9472b61ae476ca1a4a036600c8db6f6cd9921a2be0cd44dc8c394505b7a5642874b6148454
6
+ metadata.gz: fe5cdf5086cb3c3a44b4a3a5b06ffa8787084865af31d607a253b4ecb8373f5611f270c70f780d1ee1f991f20dab4770aec803b423fe78cf0a665121b3df641c
7
+ data.tar.gz: bd4927fdc7ab98569707f1ef9966b15ffcb2eed58524212511b9cf62976ada17bc94adda6c86f30fce5c7b2cc8f45d2e1544fdfc27b45970c94ac7e20e9eb5df
@@ -1,22 +1,46 @@
1
- # Currently fails on JRuby, partly due to Nokogiri behaving differently,
2
- # and partly for some other reason I'm not sure about regarding
3
- # Hexp::Node::Normalize
4
1
  language: ruby
5
- script: "bundle exec rspec"
2
+
3
+ script: bundle exec rake $TASK
4
+
5
+ sudo: false
6
+
6
7
  rvm:
7
8
  - 1.9.3
8
- - 2.0.0
9
- - 2.1.1
10
- - 2.1.2
11
- - 2.1.3
9
+ - 2.0
12
10
  - 2.1
13
- - rbx
11
+ - 2.2
14
12
  - jruby
15
13
  - jruby-head
14
+ - rbx
16
15
  - ruby-head
16
+
17
+ env:
18
+ - TASK=rspec
19
+ - TASK=mutant
20
+
17
21
  matrix:
22
+ # Jruby should be taken out of this list. It fails now because of a
23
+ # subtle Nokogiri incompatibility
18
24
  allow_failures:
19
25
  - rvm: jruby
20
26
  - rvm: ruby-head
21
27
  - rvm: jruby-head
22
28
  - rvm: rbx
29
+ - env: TASK=mutant
30
+
31
+ # Only run mutant on 2.2
32
+ exclude:
33
+ - rvm: 1.9.3
34
+ env: TASK=mutant
35
+ - rvm: 2.0
36
+ env: TASK=mutant
37
+ - rvm: 2.1
38
+ env: TASK=mutant
39
+ - rvm: jruby
40
+ env: TASK=mutant
41
+ - rvm: jruby-head
42
+ env: TASK=mutant
43
+ - rvm: rbx
44
+ env: TASK=mutant
45
+ - rvm: ruby-head
46
+ env: TASK=mutant
@@ -1,6 +1,12 @@
1
1
  ### Development
2
2
 
3
- [full diff](http://github.com/plexus/hexp/compare/v0.4.2...master)
3
+ [full diff](http://github.com/plexus/hexp/compare/v0.4.4...master)
4
+
5
+ ### v0.4.4
6
+
7
+ * Drop the dependency on SASS, use Nokogiri instead for parsing CSS
8
+ selectors
9
+
4
10
 
5
11
  ### v0.4.3
6
12
 
data/Rakefile CHANGED
@@ -46,9 +46,18 @@ end
46
46
  require 'mutant'
47
47
  task :default => :mutant
48
48
 
49
+ desc "run mutant"
49
50
  task :mutant do
50
51
  pattern = ENV.fetch('PATTERN', 'Hexp*')
51
52
  opts = ENV.fetch('MUTANT_OPTS', '').split(' ')
52
53
  result = Mutant::CLI.run(%w[-Ilib -rhexp --use rspec --score 100] + opts + [pattern])
53
54
  fail unless result == Mutant::CLI::EXIT_SUCCESS
54
55
  end
56
+
57
+ require 'rspec/core/rake_task'
58
+
59
+ desc "run rspec"
60
+ RSpec::Core::RakeTask.new(:rspec) do |t, task_args|
61
+ t.rspec_opts = "-Ispec"
62
+ t.pattern = "spec"
63
+ end
@@ -0,0 +1,32 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, we pledge to respect
4
+ all people who contribute through reporting issues, posting feature
5
+ requests, updating documentation, submitting pull requests or patches,
6
+ and other activities.
7
+
8
+ We are committed to making participation in this project a
9
+ harassment-free experience for everyone, regardless of level of
10
+ experience, gender, gender identity and expression, sexual
11
+ orientation, disability, personal appearance, body size, race, age, or
12
+ religion.
13
+
14
+ Examples of unacceptable behavior by participants include the use of
15
+ sexual language or imagery, derogatory comments or personal attacks,
16
+ trolling, public or private harassment, insults, or other
17
+ unprofessional conduct.
18
+
19
+ Project maintainers have the right and responsibility to remove, edit,
20
+ or reject comments, commits, code, wiki edits, issues, and other
21
+ contributions that are not aligned to this Code of Conduct. Project
22
+ maintainers who do not follow the Code of Conduct may be removed from
23
+ the project team.
24
+
25
+ Instances of abusive, harassing, or otherwise unacceptable behavior
26
+ may be reported by opening an issue or contacting one or more of the
27
+ project maintainers.
28
+
29
+ This Code of Conduct is adapted from the
30
+ [Contributor Covenant](http:contributor-covenant.org), version 1.0.0,
31
+ available at
32
+ [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
@@ -17,7 +17,6 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = `git ls-files -- spec`.split($/)
18
18
  gem.extra_rdoc_files = %w[README.md]
19
19
 
20
- gem.add_runtime_dependency 'sass', '~> 3.2.19'
21
20
  gem.add_runtime_dependency 'nokogiri', '~> 1.6'
22
21
  gem.add_runtime_dependency 'equalizer', '~> 0.0'
23
22
  gem.add_runtime_dependency 'concord', '~> 0.0'
@@ -3,7 +3,6 @@ require 'forwardable'
3
3
  require 'pathname'
4
4
 
5
5
  require 'nokogiri'
6
- require 'sass'
7
6
  require 'equalizer'
8
7
  require 'concord'
9
8
 
@@ -112,7 +111,6 @@ require 'hexp/list'
112
111
  require 'hexp/dom'
113
112
 
114
113
  require 'hexp/css_selector'
115
- require 'hexp/css_selector/sass_parser'
116
114
  require 'hexp/css_selector/parser'
117
115
 
118
116
  require 'hexp/errors'
@@ -100,9 +100,13 @@ module Hexp
100
100
  #
101
101
  # @api private
102
102
  def matches?(element)
103
- members.any? do |sequence|
104
- sequence.members.count == 1 &&
105
- sequence.head_matches?(element)
103
+ members.any? do |member|
104
+ case member
105
+ when Sequence
106
+ member.members.count == 1 && member.head_matches?(element)
107
+ else
108
+ member.matches?(element)
109
+ end
106
110
  end
107
111
  end
108
112
 
@@ -164,6 +168,10 @@ module Hexp
164
168
  class SimpleSequence
165
169
  include Members
166
170
 
171
+ def matches_path?(path)
172
+ matches?(path.last)
173
+ end
174
+
167
175
  # Does the element match all parts of this SimpleSequence
168
176
  #
169
177
  # @params [Hexp::Node] element
@@ -176,12 +184,17 @@ module Hexp
176
184
  simple.matches?(element)
177
185
  end
178
186
  end
187
+ alias head_matches? matches?
179
188
  end
180
189
 
181
190
  # A CSS element declaration, like 'div'
182
191
  class Element
183
192
  include Named
184
193
 
194
+ def matches_path?(path)
195
+ matches?(path.last)
196
+ end
197
+
185
198
  # Does the node match this element selector
186
199
  #
187
200
  # @param [Hexp::Node] element
@@ -196,6 +209,10 @@ module Hexp
196
209
 
197
210
  # Match any element, '*'
198
211
  class Universal
212
+ def self.new
213
+ @@instance ||= super
214
+ end
215
+
199
216
  def matches?(element)
200
217
  true
201
218
  end
@@ -250,9 +267,9 @@ module Hexp
250
267
  #
251
268
  # @api private
252
269
  class Attribute
253
- include Equalizer.new(:name, :namespace, :operator, :value, :flags)
270
+ include Equalizer.new(:name, :operator, :value)
254
271
 
255
- attr_reader :name, :namespace, :operator, :value, :flags
272
+ attr_reader :name, :operator, :value
256
273
 
257
274
  # Construct a new Attribute selector
258
275
  #
@@ -261,23 +278,17 @@ module Hexp
261
278
  #
262
279
  # @param [String] name
263
280
  # Name of the attribute, like 'href'
264
- # @param [String] namespace
265
- # unused
266
281
  # @param [nil, String] operator
267
282
  # Operator like '~=', '^=', ... Use blank to simply test attribute
268
283
  # presence.
269
284
  # @param [String] value
270
285
  # Value to test for, operator dependent
271
- # @param [Object] flags
272
- # unused
273
286
  #
274
287
  # @api private
275
- def initialize(name, namespace, operator, value, flags)
288
+ def initialize(name, operator, value)
276
289
  @name = name.freeze
277
- @namespace = namespace.freeze
278
290
  @operator = operator.freeze
279
291
  @value = value.freeze
280
- @flag = flags.freeze
281
292
  end
282
293
 
283
294
  # Debugging representation
@@ -286,7 +297,7 @@ module Hexp
286
297
  #
287
298
  # @api private
288
299
  def inspect
289
- "<#{self.class.name.split('::').last} name=#{name} namespace=#{namespace.inspect} operator=#{operator.inspect} value=#{value.inspect} flags=#{flags.inspect}>"
300
+ "<#{self.class.name.split('::').last} name=#{name} operator=#{operator.inspect} value=#{value.inspect}>"
290
301
  end
291
302
 
292
303
  # Does the node match this attribute selector
@@ -301,9 +312,6 @@ module Hexp
301
312
  return false unless element[name]
302
313
  attribute = element[name]
303
314
 
304
- # TODO: check the spec with regards to IDENTIFIERS vs STRINGS as value
305
- # see if we can lett SASS parse the string instead of unwrapping
306
- # it ourselves
307
315
  value = self.value
308
316
  value = $1.gsub('\"', '"') if value =~ /\A"?(.*?)"?\z/
309
317
 
@@ -311,19 +319,19 @@ module Hexp
311
319
  # CSS 2
312
320
  when nil
313
321
  true
314
- when '=' # exact match
322
+ when :equal # '=': exact match
315
323
  attribute == value
316
- when '~=' # space separated list contains
324
+ when :includes # '~=': space separated list contains
317
325
  attribute.split(' ').include?(value)
318
- when '|=' # equal to, or starts with followed by a dash
326
+ when :dash_match # '|=' equal to, or starts with followed by a dash
319
327
  attribute =~ /\A#{Regexp.escape(value)}(-|\z)/
320
328
 
321
329
  # CSS 3
322
- when '^=' # starts with
330
+ when :prefix_match #'^=': starts with
323
331
  attribute.index(value) == 0
324
- when '$=' # ends with
332
+ when :suffix_match # '$=': ends with
325
333
  attribute =~ /#{Regexp.escape(value)}\z/
326
- when '*=' # contains
334
+ when :substring_match # '*=': contains
327
335
  !!(attribute =~ /#{Regexp.escape(value)}/)
328
336
 
329
337
  else
@@ -28,7 +28,11 @@ module Hexp
28
28
  #
29
29
  # @api private
30
30
  def parse
31
- rewrite_comma_sequence(SassParser.call(@selector))
31
+ CommaSequence.new(
32
+ ::Nokogiri::CSS.parse(@selector).map do |node|
33
+ node.accept(self)
34
+ end
35
+ )
32
36
  end
33
37
 
34
38
  # Parse a CSS selector in one go
@@ -41,77 +45,59 @@ module Hexp
41
45
  new(selector).parse
42
46
  end
43
47
 
44
- private
45
-
46
- # Map CommaSequence from the SASS namespace to our own
47
- #
48
- # @param [Sass::Selector::CommaSequence] comma_sequence
49
- # @return [Hexp::CssSelector::CommaSequence]
50
- #
51
- # @api private
52
- def rewrite_comma_sequence(comma_sequence)
53
- CommaSequence.new(comma_sequence.members.map{|sequence| rewrite_sequence(sequence)})
48
+ def visit_descendant_selector(node)
49
+ Sequence.new(
50
+ node.value.map {|child| child.accept(self) }
51
+ )
54
52
  end
55
53
 
56
- # Map Sequence from the SASS namespace to our own
57
- #
58
- # @param [Sass::Selector::Sequence] comma_sequence
59
- # @return [Hexp::CssSelector::Sequence]
60
- #
61
- # @api private
62
- def rewrite_sequence(sequence)
63
- Sequence.new(sequence.members.map{|simple_sequence| rewrite_simple_sequence(simple_sequence)})
64
- end
54
+ def visit_conditional_selector(node)
55
+ head, tail = node.value
56
+ children = [head]
57
+ while tail.type == :COMBINATOR
58
+ head, tail = tail.value
59
+ children << head
60
+ end
61
+ children << tail
65
62
 
66
- # Map SimpleSequence from the SASS namespace to our own
67
- #
68
- # @param [Sass::Selector::SimpleSequence] comma_sequence
69
- # @return [Hexp::CssSelector::SimpleSequence]
70
- #
71
- # @api private
72
- def rewrite_simple_sequence(simple_sequence)
73
- SimpleSequence.new(simple_sequence.members.map{|simple| rewrite_simple(simple)})
63
+ SimpleSequence.new(
64
+ children.map {|child| child.accept(self) }
65
+ )
74
66
  end
75
67
 
76
- # Map Simple from the SASS namespace to our own
77
- #
78
- # @param [Sass::Selector::Simple] comma_sequence
79
- # @return [Hexp::CssSelector::Simple]
80
- #
81
- # @api private
82
- def rewrite_simple(simple)
83
- case simple
84
- when ::Sass::Selector::Element # span
85
- Element.new(simple.name.first)
86
- when ::Sass::Selector::Class # .foo
87
- Class.new(simple.name.first)
88
- when ::Sass::Selector::Id # #main
89
- Id.new(simple.name.first)
90
- when ::Sass::Selector::Attribute # [href^="http://"]
91
- raise "CSS attribute selector flags are curently ignored by Hexp (not implemented)" unless simple.flags.nil?
92
- raise "CSS attribute namespaces are curently ignored by Hexp (not implemented)" unless simple.namespace.nil?
93
- raise "CSS attribute operator #{simple.operator} not understood by Hexp" unless %w[= ~= ^= |= $= *=].include?(simple.operator) || simple.operator.nil?
94
- Attribute.new(
95
- simple.name.first,
96
- simple.namespace,
97
- simple.operator,
98
- simple.value ? simple.value.first : nil,
99
- simple.flags
100
- )
101
- when ::Sass::Selector::Universal # *
68
+ def visit_element_name(node)
69
+ if node.value == ["*"]
102
70
  Universal.new
103
71
  else
104
- raise "CSS selectors containing #{simple.class} are not implemented in Hexp"
72
+ Element.new(node.value.first)
105
73
  end
74
+ end
75
+
76
+ def visit_class_condition(node)
77
+ Class.new(node.value.first)
78
+ end
106
79
 
107
- # As of yet unimplemented
108
- # when ::Sass::Selector::Universal # *
109
- # when ::Sass::Selector::Parent # & in Sass
110
- # when ::Sass::Selector::Interpolation # #{} in Sass
111
- # when ::Sass::Selector::Pseudo # :visited, ::first-line, :nth-child(2n+1)
112
- # when ::Sass::Selector::SelectorPseudoClass # :not(.foo)
80
+ def visit_id(node)
81
+ Id.new(node.value.first.sub(/^#/, ''))
82
+ end
83
+
84
+ # ul > li
85
+ def visit_child_selector(node)
86
+ raise "not implemented"
87
+ end
113
88
 
89
+ # [href^="http://"]
90
+ def visit_attribute_condition(node)
91
+ element, operator, value = node.value
92
+ name = element.value.first
93
+ Attribute.new(name.sub(/^@/, ''), operator, value)
114
94
  end
95
+
96
+ # li:first / li:nth-child(3n)
97
+ def visit_pseudo_selector(node)
98
+ raise "not implemented"
99
+ end
100
+
115
101
  end
116
102
  end
117
103
  end
@@ -1,3 +1,3 @@
1
1
  module Hexp
2
- VERSION = '0.4.3'
2
+ VERSION = '0.4.4'
3
3
  end
@@ -7,8 +7,11 @@ RSpec::Matchers.define :dom_eq do |other_dom|
7
7
  end
8
8
  end
9
9
 
10
- RSpec.configure do |configuration|
11
- configuration.mock_with :rspec do |configuration|
10
+ RSpec.configure do |rspec|
11
+ rspec.mock_with :rspec do |configuration|
12
12
  configuration.syntax = :expect
13
13
  end
14
+ rspec.around(:each) do |example|
15
+ Timeout.timeout(1, &example)
16
+ end
14
17
  end
@@ -1,12 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Hexp::CssSelector::Attribute do
4
- subject(:selector) { described_class.new(name, namespace, operator, value, flags) }
4
+ subject(:selector) { described_class.new(name, operator, value) }
5
5
  let(:name) { nil }
6
- let(:namespace) { nil }
7
6
  let(:operator) { nil }
8
7
  let(:value) { nil }
9
- let(:flags) { nil }
10
8
 
11
9
  describe 'without an operator' do
12
10
  let(:name) { 'href' }
@@ -26,7 +24,7 @@ describe Hexp::CssSelector::Attribute do
26
24
 
27
25
  describe 'with the "=" operator' do
28
26
  let(:name) { 'class' }
29
- let(:operator) { '=' }
27
+ let(:operator) { :equal }
30
28
  let(:value) { 'foo' }
31
29
 
32
30
  it "should match if the attribute's value is exactly equal to the given value" do
@@ -44,7 +42,7 @@ describe Hexp::CssSelector::Attribute do
44
42
 
45
43
  describe 'the "~=" operator' do
46
44
  let(:name) { 'class' }
47
- let(:operator) { '~=' }
45
+ let(:operator) { :includes }
48
46
  let(:value) { 'foo' }
49
47
 
50
48
  it 'should match an entry in a space separated list' do
@@ -62,7 +60,7 @@ describe Hexp::CssSelector::Attribute do
62
60
 
63
61
  describe 'the "|=" operator' do
64
62
  let(:name) { 'id' }
65
- let(:operator) { '|=' }
63
+ let(:operator) { :dash_match }
66
64
  let(:value) { 'foo' }
67
65
 
68
66
  it 'should match if the attribute starts with the value, followed by a dash' do
@@ -80,7 +78,7 @@ describe Hexp::CssSelector::Attribute do
80
78
 
81
79
  describe 'the "^=" operator' do
82
80
  let(:name) { 'id' }
83
- let(:operator) { '^=' }
81
+ let(:operator) { :prefix_match }
84
82
  let(:value) { 'foo' }
85
83
 
86
84
  it 'should match if the attribute is just the value' do
@@ -98,7 +96,7 @@ describe Hexp::CssSelector::Attribute do
98
96
 
99
97
  describe 'the "$=" operator' do
100
98
  let(:name) { 'id' }
101
- let(:operator) { '$=' }
99
+ let(:operator) { :suffix_match }
102
100
  let(:value) { 'foo' }
103
101
 
104
102
  it 'should match if the attribute is just the value' do
@@ -116,7 +114,7 @@ describe Hexp::CssSelector::Attribute do
116
114
 
117
115
  describe 'the "*=" operator' do
118
116
  let(:name) { 'id' }
119
- let(:operator) { '*=' }
117
+ let(:operator) { :substring_match }
120
118
  let(:value) { 'foo' }
121
119
 
122
120
  it 'should match if the attribute is just the value' do
@@ -9,10 +9,7 @@ describe Hexp::CssSelector::Parser do
9
9
  context 'with a single tag' do
10
10
  let(:selector) { 'body' }
11
11
  it {
12
- should eq HC::CommaSequence[
13
- HC::Sequence[
14
- HC::SimpleSequence[
15
- HC::Element.new('body')]]]
12
+ should eq HC::CommaSequence[HC::Element.new('body')]
16
13
  }
17
14
  end
18
15
 
@@ -29,6 +26,7 @@ describe Hexp::CssSelector::Parser do
29
26
  should eq HC::CommaSequence[
30
27
  HC::Sequence[
31
28
  HC::SimpleSequence[
29
+ HC::Universal.new,
32
30
  HC::Id.new('main')],
33
31
  HC::SimpleSequence[
34
32
  HC::Element.new('a'),
@@ -40,11 +38,10 @@ describe Hexp::CssSelector::Parser do
40
38
  let(:selector) { 'div[link=href]' }
41
39
  it {
42
40
  should eq HC::CommaSequence[
43
- HC::Sequence[
44
41
  HC::SimpleSequence[
45
42
  HC::Element.new('div'),
46
- HC::Attribute.new('link', nil, '=', 'href', nil),
47
- ]]]
43
+ HC::Attribute.new('link', :equal, 'href'),
44
+ ]]
48
45
  }
49
46
  end
50
47
 
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hexp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.3
4
+ version: 0.4.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arne Brasseur
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-13 00:00:00.000000000 Z
11
+ date: 2015-02-15 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: sass
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: 3.2.19
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: 3.2.19
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: nokogiri
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -153,6 +139,7 @@ files:
153
139
  - README.md
154
140
  - Rakefile
155
141
  - bench/node/rewrite_bench.rb
142
+ - code_of_conduct.md
156
143
  - config/devtools.yml
157
144
  - config/flay.yml
158
145
  - config/flog.yml
@@ -173,7 +160,6 @@ files:
173
160
  - lib/hexp/core_ext/nil.rb
174
161
  - lib/hexp/css_selector.rb
175
162
  - lib/hexp/css_selector/parser.rb
176
- - lib/hexp/css_selector/sass_parser.rb
177
163
  - lib/hexp/dom.rb
178
164
  - lib/hexp/dsl.rb
179
165
  - lib/hexp/errors.rb
@@ -249,7 +235,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
249
235
  version: '0'
250
236
  requirements: []
251
237
  rubyforge_project:
252
- rubygems_version: 2.2.2
238
+ rubygems_version: 2.4.5
253
239
  signing_key:
254
240
  specification_version: 4
255
241
  summary: Generate and manipulate HTML documents and nodes.
@@ -1,40 +0,0 @@
1
- module Hexp
2
- module CssSelector
3
- # A CSS Parser that only knows how to parse CSS selectors
4
- #
5
- class SassParser < ::Sass::SCSS::CssParser
6
- # Initialize the parser with the selector to parse
7
- #
8
- # @param [String] selector
9
- #
10
- # @api private
11
- def initialize(selector)
12
- # TODO this is a private API and has before changed in minor versions,
13
- # see if there is a more robust call.
14
- super(selector, '', 0)
15
- end
16
-
17
- # Parse the selector
18
- #
19
- # @return [Sass::Selector::CommaSequence]
20
- #
21
- # @api private
22
- def parse
23
- init_scanner!
24
- result = selector_comma_sequence
25
- raise "Invalid CSS selector : unconsumed input #{@scanner.rest}" unless @scanner.eos?
26
- result
27
- end
28
-
29
- # Parse a CSS selector in one go
30
- #
31
- # @param [String] selector
32
- # @return [Sass::Selector::CommaSequence]
33
- #
34
- # @api private
35
- def self.call(selector)
36
- self.new(selector).parse
37
- end
38
- end
39
- end
40
- end