nokogiri 1.6.1 → 1.6.2.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nokogiri might be problematic. Click here for more details.

Files changed (93) hide show
  1. checksums.yaml +7 -7
  2. data/.editorconfig +17 -0
  3. data/.travis.yml +4 -6
  4. data/CHANGELOG.ja.rdoc +37 -8
  5. data/CHANGELOG.rdoc +48 -3
  6. data/Gemfile +3 -3
  7. data/Manifest.txt +57 -1
  8. data/README.ja.rdoc +22 -16
  9. data/README.rdoc +24 -19
  10. data/ROADMAP.md +1 -2
  11. data/Rakefile +161 -58
  12. data/build_all +56 -31
  13. data/dependencies.yml +3 -3
  14. data/ext/nokogiri/extconf.rb +379 -121
  15. data/ext/nokogiri/html_document.c +2 -2
  16. data/ext/nokogiri/nokogiri.c +6 -1
  17. data/ext/nokogiri/xml_document.c +5 -4
  18. data/ext/nokogiri/xml_node.c +11 -4
  19. data/ext/nokogiri/xml_reader.c +1 -1
  20. data/ext/nokogiri/xml_sax_parser_context.c +40 -0
  21. data/ext/nokogiri/xml_syntax_error.c +10 -5
  22. data/ext/nokogiri/xml_syntax_error.h +1 -1
  23. data/ext/nokogiri/xml_xpath_context.c +2 -14
  24. data/ext/nokogiri/xslt_stylesheet.c +1 -1
  25. data/lib/nokogiri.rb +31 -22
  26. data/lib/nokogiri/css/node.rb +0 -50
  27. data/lib/nokogiri/css/parser.rb +213 -218
  28. data/lib/nokogiri/css/parser.y +21 -30
  29. data/lib/nokogiri/css/xpath_visitor.rb +62 -14
  30. data/lib/nokogiri/html/document.rb +97 -18
  31. data/lib/nokogiri/html/sax/parser.rb +2 -2
  32. data/lib/nokogiri/version.rb +1 -1
  33. data/lib/nokogiri/xml/builder.rb +1 -1
  34. data/lib/nokogiri/xml/document.rb +2 -2
  35. data/lib/nokogiri/xml/dtd.rb +10 -0
  36. data/lib/nokogiri/xml/node.rb +26 -1
  37. data/lib/nokogiri/xml/sax/parser.rb +1 -1
  38. data/ports/archives/libxslt-1.1.28.tar.gz +0 -0
  39. data/ports/patches/libxml2/0001-Fix-parser-local-buffers-size-problems.patch +265 -0
  40. data/ports/patches/libxml2/0002-Fix-entities-local-buffers-size-problems.patch +102 -0
  41. data/ports/patches/libxml2/0003-Fix-an-error-in-previous-commit.patch +26 -0
  42. data/ports/patches/libxml2/0004-Fix-potential-out-of-bound-access.patch +26 -0
  43. data/ports/patches/libxml2/0005-Detect-excessive-entities-expansion-upon-replacement.patch +158 -0
  44. data/ports/patches/libxml2/0006-Do-not-fetch-external-parsed-entities.patch +78 -0
  45. data/ports/patches/libxml2/0007-Enforce-XML_PARSER_EOF-state-handling-through-the-pa.patch +480 -0
  46. data/ports/patches/libxml2/0008-Improve-handling-of-xmlStopParser.patch +315 -0
  47. data/ports/patches/libxml2/0009-Fix-a-couple-of-return-without-value.patch +37 -0
  48. data/ports/patches/libxslt/0001-Adding-doc-update-related-to-1.1.28.patch +222 -0
  49. data/ports/patches/libxslt/0002-Fix-a-couple-of-places-where-f-printf-parameters-wer.patch +53 -0
  50. data/ports/patches/libxslt/0003-Initialize-pseudo-random-number-generator-with-curre.patch +60 -0
  51. data/ports/patches/libxslt/0004-EXSLT-function-str-replace-is-broken-as-is.patch +42 -0
  52. data/ports/patches/libxslt/0006-Fix-str-padding-to-work-with-UTF-8-strings.patch +164 -0
  53. data/ports/patches/libxslt/0007-Separate-function-for-predicate-matching-in-patterns.patch +587 -0
  54. data/ports/patches/libxslt/0008-Fix-direct-pattern-matching.patch +80 -0
  55. data/ports/patches/libxslt/0009-Fix-certain-patterns-with-predicates.patch +185 -0
  56. data/ports/patches/libxslt/0010-Fix-handling-of-UTF-8-strings-in-EXSLT-crypto-module.patch +126 -0
  57. data/ports/patches/libxslt/0013-Memory-leak-in-xsltCompileIdKeyPattern-error-path.patch +25 -0
  58. data/ports/patches/libxslt/0014-Fix-for-bug-436589.patch +43 -0
  59. data/ports/patches/libxslt/0015-Fix-mkdir-for-mingw.patch +41 -0
  60. data/suppressions/README.txt +1 -0
  61. data/suppressions/nokogiri_ree-1.8.7.358.supp +61 -0
  62. data/suppressions/nokogiri_ruby-1.8.7.370.supp +0 -0
  63. data/suppressions/nokogiri_ruby-1.9.2.320.supp +28 -0
  64. data/suppressions/nokogiri_ruby-1.9.3.327.supp +28 -0
  65. data/test/css/test_nthiness.rb +65 -2
  66. data/test/css/test_parser.rb +27 -10
  67. data/test/css/test_tokenizer.rb +1 -1
  68. data/test/css/test_xpath_visitor.rb +6 -1
  69. data/test/files/atom.xml +344 -0
  70. data/test/files/shift_jis_no_charset.html +9 -0
  71. data/test/helper.rb +10 -0
  72. data/test/html/test_document.rb +74 -7
  73. data/test/html/test_document_encoding.rb +10 -0
  74. data/test/html/test_document_fragment.rb +3 -3
  75. data/test/namespaces/test_namespaces_in_cloned_doc.rb +31 -0
  76. data/test/test_nokogiri.rb +6 -0
  77. data/test/test_reader.rb +7 -4
  78. data/test/test_xslt_transforms.rb +25 -0
  79. data/test/xml/sax/test_parser.rb +16 -0
  80. data/test/xml/sax/test_parser_context.rb +9 -0
  81. data/test/xml/test_builder.rb +9 -0
  82. data/test/xml/test_c14n.rb +12 -2
  83. data/test/xml/test_document.rb +66 -0
  84. data/test/xml/test_document_fragment.rb +5 -0
  85. data/test/xml/test_dtd.rb +84 -0
  86. data/test/xml/test_entity_reference.rb +3 -3
  87. data/test/xml/test_node.rb +21 -3
  88. data/test/xml/test_node_attributes.rb +17 -0
  89. data/test/xml/test_schema.rb +26 -0
  90. data/test/xml/test_xpath.rb +81 -0
  91. metadata +254 -174
  92. data/ports/archives/libxslt-1.1.26.tar.gz +0 -0
  93. data/tasks/cross_compile.rb +0 -134
@@ -77,7 +77,7 @@ static VALUE read_io( VALUE klass,
77
77
 
78
78
  error = xmlGetLastError();
79
79
  if(error)
80
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
80
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
81
81
  else
82
82
  rb_raise(rb_eRuntimeError, "Could not parse document");
83
83
 
@@ -123,7 +123,7 @@ static VALUE read_memory( VALUE klass,
123
123
 
124
124
  error = xmlGetLastError();
125
125
  if(error)
126
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
126
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
127
127
  else
128
128
  rb_raise(rb_eRuntimeError, "Could not parse document");
129
129
 
@@ -14,7 +14,12 @@ VALUE mNokogiriHtmlSax ;
14
14
  */
15
15
  int vasprintf (char **strp, const char *fmt, va_list ap)
16
16
  {
17
- int len = vsnprintf (NULL, 0, fmt, ap) + 1;
17
+ /* Mingw32/64 have a broken vsnprintf implementation that fails when
18
+ * using a zero-byte limit in order to retrieve the required size for malloc.
19
+ * So we use a one byte buffer instead.
20
+ */
21
+ char tmp[1];
22
+ int len = vsnprintf (tmp, 1, fmt, ap) + 1;
18
23
  char *res = (char *)malloc((unsigned int)len);
19
24
  if (res == NULL)
20
25
  return -1;
@@ -231,7 +231,7 @@ static VALUE read_io( VALUE klass,
231
231
 
232
232
  error = xmlGetLastError();
233
233
  if(error)
234
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
234
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
235
235
  else
236
236
  rb_raise(rb_eRuntimeError, "Could not parse document");
237
237
 
@@ -275,7 +275,7 @@ static VALUE read_memory( VALUE klass,
275
275
 
276
276
  error = xmlGetLastError();
277
277
  if(error)
278
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
278
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
279
279
  else
280
280
  rb_raise(rb_eRuntimeError, "Could not parse document");
281
281
 
@@ -417,7 +417,7 @@ static VALUE create_entity(int argc, VALUE *argv, VALUE self)
417
417
  if(NULL == ptr) {
418
418
  xmlErrorPtr error = xmlGetLastError();
419
419
  if(error)
420
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
420
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
421
421
  else
422
422
  rb_raise(rb_eRuntimeError, "Could not create entity");
423
423
 
@@ -497,6 +497,7 @@ static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
497
497
  ns = NULL;
498
498
  }
499
499
  else{
500
+ Check_Type(incl_ns, T_ARRAY);
500
501
  ns_len = RARRAY_LEN(incl_ns);
501
502
  ns = calloc((size_t)ns_len+1, sizeof(xmlChar *));
502
503
  for (i = 0 ; i < ns_len ; i++) {
@@ -510,7 +511,7 @@ static VALUE canonicalize(int argc, VALUE* argv, VALUE self)
510
511
  xmlC14NExecute(doc, cb, ctx,
511
512
  (int) (NIL_P(mode) ? 0 : NUM2INT(mode)),
512
513
  ns,
513
- (int) (NIL_P(with_comments) ? 0 : 1),
514
+ (int) RTEST(with_comments),
514
515
  buf);
515
516
 
516
517
  xmlOutputBufferClose(buf);
@@ -14,7 +14,14 @@ static void debug_node_dealloc(xmlNodePtr x)
14
14
 
15
15
  static void mark(xmlNodePtr node)
16
16
  {
17
- rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
17
+ xmlNodePtr doc = node->doc;
18
+ if(doc->type == XML_DOCUMENT_NODE || doc->type == XML_HTML_DOCUMENT_NODE) {
19
+ if(DOC_RUBY_OBJECT_TEST(doc)) {
20
+ rb_gc_mark(DOC_RUBY_OBJECT(doc));
21
+ }
22
+ } else if(node->doc->_private) {
23
+ rb_gc_mark((VALUE)doc->_private);
24
+ }
18
25
  }
19
26
 
20
27
  /* :nodoc: */
@@ -850,8 +857,8 @@ static VALUE attribute_nodes(VALUE self)
850
857
  * call-seq:
851
858
  * namespace()
852
859
  *
853
- * returns the default namespace set on this node (as with an "xmlns="
854
- * attribute), as a Namespace object.
860
+ * returns the namespace of the element or attribute node as a Namespace
861
+ * object, or nil if there is no namespace for the element or attribute.
855
862
  */
856
863
  static VALUE namespace(VALUE self)
857
864
  {
@@ -1258,7 +1265,7 @@ static VALUE process_xincludes(VALUE self, VALUE options)
1258
1265
 
1259
1266
  error = xmlGetLastError();
1260
1267
  if(error)
1261
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
1268
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
1262
1269
  else
1263
1270
  rb_raise(rb_eRuntimeError, "Could not perform xinclude substitution");
1264
1271
  }
@@ -471,7 +471,7 @@ static VALUE read_more(VALUE self)
471
471
 
472
472
  error = xmlGetLastError();
473
473
  if(error)
474
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
474
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
475
475
  else
476
476
  rb_raise(rb_eRuntimeError, "Error pulling: %d", ret);
477
477
 
@@ -201,6 +201,44 @@ static VALUE column(VALUE self)
201
201
  return Qnil;
202
202
  }
203
203
 
204
+ /*
205
+ * call-seq:
206
+ * recovery=(boolean)
207
+ *
208
+ * Should this parser recover from structural errors? It will not stop processing
209
+ * file on structural errors if if set to true
210
+ */
211
+ static VALUE set_recovery(VALUE self, VALUE value)
212
+ {
213
+ xmlParserCtxtPtr ctxt;
214
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
215
+
216
+ if(value == Qfalse)
217
+ ctxt->recovery = 0;
218
+ else
219
+ ctxt->recovery = 1;
220
+
221
+ return value;
222
+ }
223
+
224
+ /*
225
+ * call-seq:
226
+ * recovery
227
+ *
228
+ * Should this parser recover from structural errors? It will not stop processing
229
+ * file on structural errors if if set to true
230
+ */
231
+ static VALUE get_recovery(VALUE self)
232
+ {
233
+ xmlParserCtxtPtr ctxt;
234
+ Data_Get_Struct(self, xmlParserCtxt, ctxt);
235
+
236
+ if(ctxt->recovery == 0)
237
+ return Qfalse;
238
+ else
239
+ return Qtrue;
240
+ }
241
+
204
242
  void init_xml_sax_parser_context()
205
243
  {
206
244
  VALUE nokogiri = rb_define_module("Nokogiri");
@@ -217,6 +255,8 @@ void init_xml_sax_parser_context()
217
255
  rb_define_method(klass, "parse_with", parse_with, 1);
218
256
  rb_define_method(klass, "replace_entities=", set_replace_entities, 1);
219
257
  rb_define_method(klass, "replace_entities", get_replace_entities, 0);
258
+ rb_define_method(klass, "recovery=", set_recovery, 1);
259
+ rb_define_method(klass, "recovery", get_recovery, 0);
220
260
  rb_define_method(klass, "line", line, 0);
221
261
  rb_define_method(klass, "column", column, 0);
222
262
  }
@@ -3,19 +3,24 @@
3
3
  void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error)
4
4
  {
5
5
  VALUE list = (VALUE)ctx;
6
- rb_ary_push(list, Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
6
+ rb_ary_push(list, Nokogiri_wrap_xml_syntax_error(error));
7
7
  }
8
8
 
9
9
  void Nokogiri_error_raise(void * ctx, xmlErrorPtr error)
10
10
  {
11
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error((VALUE)NULL, error));
11
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
12
12
  }
13
13
 
14
- VALUE Nokogiri_wrap_xml_syntax_error(VALUE klass, xmlErrorPtr error)
14
+ VALUE Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error)
15
15
  {
16
- VALUE msg, e;
16
+ VALUE msg, e, klass;
17
17
 
18
- if(!klass) klass = cNokogiriXmlSyntaxError;
18
+ klass = cNokogiriXmlSyntaxError;
19
+
20
+ if (error->domain == XML_FROM_XPATH) {
21
+ VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
22
+ klass = rb_const_get(xpath, rb_intern("SyntaxError"));
23
+ }
19
24
 
20
25
  msg = (error && error->message) ? NOKOGIRI_STR_NEW2(error->message) : Qnil;
21
26
 
@@ -4,7 +4,7 @@
4
4
  #include <nokogiri.h>
5
5
 
6
6
  void init_xml_syntax_error();
7
- VALUE Nokogiri_wrap_xml_syntax_error(VALUE klass, xmlErrorPtr error);
7
+ VALUE Nokogiri_wrap_xml_syntax_error(xmlErrorPtr error);
8
8
  void Nokogiri_error_array_pusher(void * ctx, xmlErrorPtr error);
9
9
  NORETURN(void Nokogiri_error_raise(void * ctx, xmlErrorPtr error));
10
10
 
@@ -171,15 +171,6 @@ static xmlXPathFunction lookup( void *ctx,
171
171
  return NULL;
172
172
  }
173
173
 
174
- NORETURN(static void xpath_exception_handler(void * ctx, xmlErrorPtr error));
175
- static void xpath_exception_handler(void * ctx, xmlErrorPtr error)
176
- {
177
- VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
178
- VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
179
-
180
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
181
- }
182
-
183
174
  NORETURN(static void xpath_generic_exception_handler(void * ctx, const char *msg, ...));
184
175
  static void xpath_generic_exception_handler(void * ctx, const char *msg, ...)
185
176
  {
@@ -221,7 +212,7 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
221
212
  }
222
213
 
223
214
  xmlResetLastError();
224
- xmlSetStructuredErrorFunc(NULL, xpath_exception_handler);
215
+ xmlSetStructuredErrorFunc(NULL, Nokogiri_error_raise);
225
216
 
226
217
  /* For some reason, xmlXPathEvalExpression will blow up with a generic error */
227
218
  /* when there is a non existent function. */
@@ -232,11 +223,8 @@ static VALUE evaluate(int argc, VALUE *argv, VALUE self)
232
223
  xmlSetGenericErrorFunc(NULL, NULL);
233
224
 
234
225
  if(xpath == NULL) {
235
- VALUE xpath = rb_const_get(mNokogiriXml, rb_intern("XPath"));
236
- VALUE klass = rb_const_get(xpath, rb_intern("SyntaxError"));
237
-
238
226
  xmlErrorPtr error = xmlGetLastError();
239
- rb_exc_raise(Nokogiri_wrap_xml_syntax_error(klass, error));
227
+ rb_exc_raise(Nokogiri_wrap_xml_syntax_error(error));
240
228
  }
241
229
 
242
230
  assert(ctx->doc);
@@ -237,7 +237,7 @@ static void shutdownFunc(xsltTransformContextPtr ctxt,
237
237
  * call-seq:
238
238
  * register(uri, custom_handler_class)
239
239
  *
240
- * Register a class that implements custom XLST transformation functions.
240
+ * Register a class that implements custom XSLT transformation functions.
241
241
  */
242
242
  static VALUE registr(VALUE self, VALUE uri, VALUE obj)
243
243
  {
@@ -2,9 +2,6 @@
2
2
  # Modify the PATH on windows so that the external DLLs will get loaded.
3
3
 
4
4
  require 'rbconfig'
5
- ENV['PATH'] = [File.expand_path(
6
- File.join(File.dirname(__FILE__), "..", "ext", "nokogiri")
7
- ), ENV['PATH']].compact.join(';') if RbConfig::CONFIG['host_os'] =~ /(mswin|mingw)/i
8
5
 
9
6
  if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
10
7
  # The line below caused a problem on non-GAE rack environment.
@@ -13,7 +10,7 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
13
10
  # However, simply cutting defined?(JRuby::Rack::VERSION) off resulted in
14
11
  # an unable-to-load-nokogiri problem. Thus, now, Nokogiri checks the presense
15
12
  # of appengine-rack.jar in $LOAD_PATH. If Nokogiri is on GAE, Nokogiri
16
- # should skip loading xml jars. This is because those are in WEB-INF/lib and
13
+ # should skip loading xml jars. This is because those are in WEB-INF/lib and
17
14
  # already set in the classpath.
18
15
  unless $LOAD_PATH.to_s.include?("appengine-rack")
19
16
  require 'stringio'
@@ -25,7 +22,12 @@ if defined?(RUBY_ENGINE) && RUBY_ENGINE == "jruby"
25
22
  end
26
23
  end
27
24
 
28
- require 'nokogiri/nokogiri'
25
+ begin
26
+ RUBY_VERSION =~ /(\d+.\d+)/
27
+ require "nokogiri/#{$1}/nokogiri"
28
+ rescue LoadError
29
+ require 'nokogiri/nokogiri'
30
+ end
29
31
  require 'nokogiri/version'
30
32
  require 'nokogiri/syntax_error'
31
33
  require 'nokogiri/xml'
@@ -36,7 +38,8 @@ require 'nokogiri/css'
36
38
  require 'nokogiri/html/builder'
37
39
 
38
40
  # Nokogiri parses and searches XML/HTML very quickly, and also has
39
- # correctly implemented CSS3 selector support as well as XPath support.
41
+ # correctly implemented CSS3 selector support as well as XPath 1.0
42
+ # support.
40
43
  #
41
44
  # Parsing a document returns either a Nokogiri::XML::Document, or a
42
45
  # Nokogiri::HTML::Document depending on the kind of document you parse.
@@ -65,20 +68,19 @@ module Nokogiri
65
68
  ###
66
69
  # Parse an HTML or XML document. +string+ contains the document.
67
70
  def parse string, url = nil, encoding = nil, options = nil
68
- doc =
69
- if string.respond_to?(:read) ||
70
- string =~ /^\s*<[^Hh>]*html/i # Probably html
71
- Nokogiri.HTML(
72
- string,
73
- url,
74
- encoding, options || XML::ParseOptions::DEFAULT_HTML
75
- )
76
- else
77
- Nokogiri.XML(string, url, encoding,
78
- options || XML::ParseOptions::DEFAULT_XML)
79
- end
80
- yield doc if block_given?
81
- doc
71
+ if string.respond_to?(:read) ||
72
+ /^\s*<(?:!DOCTYPE\s+)?html[\s>]/i === string[0, 512]
73
+ # Expect an HTML indicator to appear within the first 512
74
+ # characters of a document. (<?xml ?> + <?xml-stylesheet ?>
75
+ # shouldn't be that long)
76
+ Nokogiri.HTML(string, url, encoding,
77
+ options || XML::ParseOptions::DEFAULT_HTML)
78
+ else
79
+ Nokogiri.XML(string, url, encoding,
80
+ options || XML::ParseOptions::DEFAULT_XML)
81
+ end.tap { |doc|
82
+ yield doc if block_given?
83
+ }
82
84
  end
83
85
 
84
86
  ###
@@ -110,6 +112,14 @@ module Nokogiri
110
112
  Nokogiri(*args, &block).slop!
111
113
  end
112
114
  end
115
+
116
+ # Make sure to support some popular encoding aliases not known by
117
+ # all iconv implementations.
118
+ {
119
+ 'Windows-31J' => 'CP932', # Windows-31J is the IANA registered name of CP932.
120
+ }.each { |alias_name, name|
121
+ EncodingHandler.alias(name, alias_name) if EncodingHandler[alias_name].nil?
122
+ }
113
123
  end
114
124
 
115
125
  ###
@@ -120,8 +130,7 @@ end
120
130
  # To specify the type of document, use Nokogiri.XML or Nokogiri.HTML.
121
131
  def Nokogiri(*args, &block)
122
132
  if block_given?
123
- builder = Nokogiri::HTML::Builder.new(&block)
124
- return builder.doc.root
133
+ Nokogiri::HTML::Builder.new(&block).doc.root
125
134
  else
126
135
  Nokogiri.parse(*args)
127
136
  end
@@ -22,60 +22,10 @@ module Nokogiri
22
22
  ###
23
23
  # Convert this CSS node to xpath with +prefix+ using +visitor+
24
24
  def to_xpath prefix = '//', visitor = XPathVisitor.new
25
- self.preprocess!
26
25
  prefix = '.' if ALLOW_COMBINATOR_ON_SELF.include?(type) && value.first.nil?
27
26
  prefix + visitor.accept(self)
28
27
  end
29
28
 
30
- # Preprocess this node tree
31
- def preprocess!
32
- ### Deal with nth-child
33
- matches = find_by_type(
34
- [:CONDITIONAL_SELECTOR,
35
- [:ELEMENT_NAME],
36
- [:PSEUDO_CLASS,
37
- [:FUNCTION]
38
- ]
39
- ]
40
- )
41
- matches.each do |match|
42
- if match.value[1].value[0].value[0] =~ /^nth-(last-)?child/
43
- tag_name = match.value[0].value.first
44
- match.value[0].value = ['*']
45
- match.value[1] = Node.new(:COMBINATOR, [
46
- match.value[1].value[0],
47
- Node.new(:FUNCTION, ['self(', tag_name])
48
- ])
49
- end
50
- end
51
-
52
- ### Deal with first-child, last-child
53
- matches = find_by_type(
54
- [:CONDITIONAL_SELECTOR,
55
- [:ELEMENT_NAME], [:PSEUDO_CLASS]
56
- ])
57
- matches.each do |match|
58
- if ['first-child', 'last-child'].include?(match.value[1].value.first)
59
- which = match.value[1].value.first.gsub(/-\w*$/, '')
60
- tag_name = match.value[0].value.first
61
- match.value[0].value = ['*']
62
- match.value[1] = Node.new(:COMBINATOR, [
63
- Node.new(:FUNCTION, ["#{which}("]),
64
- Node.new(:FUNCTION, ['self(', tag_name])
65
- ])
66
- elsif 'only-child' == match.value[1].value.first
67
- tag_name = match.value[0].value.first
68
- match.value[0].value = ['*']
69
- match.value[1] = Node.new(:COMBINATOR, [
70
- Node.new(:FUNCTION, ["#{match.value[1].value.first}("]),
71
- Node.new(:FUNCTION, ['self(', tag_name])
72
- ])
73
- end
74
- end
75
-
76
- self
77
- end
78
-
79
29
  # Find a node by type using +types+
80
30
  def find_by_type types
81
31
  matches = []
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.8
3
+ # This file is automatically generated by Racc 1.4.9
4
4
  # from Racc grammer file "".
5
5
  #
6
6
 
@@ -14,96 +14,104 @@ module Nokogiri
14
14
  ##### State transition tables begin ###
15
15
 
16
16
  racc_action_table = [
17
- 21, 4, 5, 7, 29, 4, 5, 7, 30, 19,
18
- -26, 6, 21, 9, 8, 6, 29, 9, 8, 22,
19
- 31, 19, 20, 21, 23, 15, 17, 29, 24, 83,
20
- 31, 22, 19, 84, 20, 21, 23, 15, 17, 29,
21
- 24, 92, 22, 85, 19, 20, 21, 23, 15, 17,
22
- 20, 24, 82, 90, 22, 59, 24, 20, 89, 23,
23
- 15, 17, 21, 24, 88, 22, 29, 4, 5, 7,
24
- 23, 19, 71, 29, 91, 29, 86, 6, 19, 9,
25
- 8, 22, 29, 29, 20, 89, 23, 15, 17, 35,
26
- 24, 20, 29, 20, 15, 17, 15, 24, 35, 24,
27
- 20, 20, 29, 15, 15, 93, 24, 24, 21, 64,
28
- 20, 95, 29, 15, 97, 96, 24, 43, -26, 46,
29
- 20, 52, 53, 15, 51, 98, 24, 22, 79, 80,
30
- 20, 99, 23, 15, 48, 42, 24, 79, 80, 75,
31
- 76, 77, 101, 78, 87, 86, 41, 74, 75, 76,
32
- 77, 35, 78, 104, 52, 56, 74, 55, 52, 56,
33
- 105, 55, 52, 56, nil, 55, 52, 56, nil, 55 ]
17
+ 21, 31, 20, 32, 30, 4, 5, 7, 24, 19,
18
+ 92, 21, 90, 32, 95, 6, 91, 9, 8, 22,
19
+ 62, 90, 20, 85, 23, 15, 17, 21, 24, -23,
20
+ 47, 30, 4, 5, 7, 23, 19, 52, 84, 21,
21
+ 56, 89, 6, 30, 9, 8, 22, 83, 19, 20,
22
+ 21, 23, 15, 17, 30, 24, 98, 97, 22, 19,
23
+ 68, 20, 21, 23, 15, 17, 30, 24, 86, 22,
24
+ 87, 19, 20, 93, 23, 15, 17, 30, 24, 30,
25
+ 82, 22, 52, 84, 20, 56, 23, 15, 17, -23,
26
+ 24, 30, 35, 30, 35, 20, 19, 20, 15, 96,
27
+ 15, 24, -23, 24, 30, 99, 35, 21, 35, 20,
28
+ 100, 20, 15, 17, 15, 24, 42, 24, 45, 35,
29
+ 30, 30, 20, 88, 87, 15, 47, 90, 24, 71,
30
+ 102, 23, 30, 40, 41, 35, 35, 105, 20, 20,
31
+ 106, 15, 15, nil, 24, 24, nil, 35, nil, nil,
32
+ 20, 79, 80, 15, 30, nil, 24, nil, 52, 54,
33
+ nil, 56, 75, 76, 77, nil, 78, nil, nil, 35,
34
+ 74, nil, 20, 79, 80, 15, 17, nil, 24, nil,
35
+ 52, 53, nil, 51, 75, 76, 77, nil, 78, 4,
36
+ 5, 7, 74, 48, 52, 84, nil, 56, nil, 6,
37
+ nil, 9, 8, 52, 84, nil, 56 ]
34
38
 
35
39
  racc_action_check = [
36
- 0, 14, 14, 14, 0, 0, 0, 0, 1, 0,
37
- 43, 14, 40, 14, 14, 0, 40, 0, 0, 0,
38
- 1, 40, 0, 31, 0, 0, 0, 31, 0, 47,
39
- 57, 40, 31, 49, 40, 13, 40, 40, 40, 13,
40
- 40, 57, 31, 50, 13, 31, 24, 31, 31, 31,
41
- 11, 31, 46, 53, 13, 24, 11, 13, 53, 13,
42
- 13, 13, 23, 13, 52, 24, 23, 23, 23, 23,
43
- 24, 23, 42, 35, 54, 28, 55, 23, 35, 23,
44
- 23, 23, 27, 10, 23, 56, 23, 23, 23, 33,
45
- 23, 35, 26, 28, 35, 35, 28, 35, 10, 28,
46
- 27, 10, 25, 27, 10, 67, 27, 10, 20, 30,
47
- 26, 72, 68, 26, 73, 73, 26, 20, 19, 20,
48
- 25, 21, 21, 25, 21, 81, 25, 20, 45, 45,
49
- 68, 83, 20, 68, 21, 18, 68, 44, 44, 45,
50
- 45, 45, 87, 45, 51, 51, 15, 45, 44, 44,
51
- 44, 12, 44, 90, 89, 89, 44, 89, 86, 86,
52
- 101, 86, 88, 88, nil, 88, 22, 22, nil, 22 ]
40
+ 0, 1, 11, 60, 0, 0, 0, 0, 11, 0,
41
+ 55, 24, 54, 1, 60, 0, 53, 0, 0, 0,
42
+ 24, 53, 0, 49, 0, 0, 0, 23, 0, 54,
43
+ 24, 23, 23, 23, 23, 24, 23, 89, 89, 13,
44
+ 89, 52, 23, 13, 23, 23, 23, 46, 13, 23,
45
+ 39, 23, 23, 23, 39, 23, 73, 73, 13, 39,
46
+ 31, 13, 32, 13, 13, 13, 32, 13, 50, 39,
47
+ 56, 32, 39, 57, 39, 39, 39, 27, 39, 28,
48
+ 45, 32, 47, 47, 32, 47, 32, 32, 32, 19,
49
+ 32, 35, 27, 10, 28, 27, 35, 28, 27, 72,
50
+ 28, 27, 42, 28, 29, 81, 35, 20, 10, 35,
51
+ 83, 10, 35, 35, 10, 35, 20, 10, 20, 29,
52
+ 26, 58, 29, 51, 51, 29, 20, 84, 29, 41,
53
+ 88, 20, 25, 15, 18, 26, 58, 91, 26, 58,
54
+ 102, 26, 58, nil, 26, 58, nil, 25, nil, nil,
55
+ 25, 43, 43, 25, 22, nil, 25, nil, 22, 22,
56
+ nil, 22, 43, 43, 43, nil, 43, nil, nil, 22,
57
+ 43, nil, 22, 44, 44, 22, 22, nil, 22, nil,
58
+ 21, 21, nil, 21, 44, 44, 44, nil, 44, 14,
59
+ 14, 14, 44, 21, 87, 87, nil, 87, nil, 14,
60
+ nil, 14, 14, 90, 90, nil, 90 ]
53
61
 
54
62
  racc_action_pointer = [
55
- -2, 8, nil, nil, nil, nil, nil, nil, nil, nil,
56
- 77, 26, 130, 33, -6, 135, nil, nil, 106, 89,
57
- 106, 111, 156, 60, 44, 96, 86, 76, 69, nil,
58
- 109, 21, nil, 68, nil, 67, nil, nil, nil, nil,
59
- 10, nil, 61, -19, 134, 125, 27, 0, nil, 10,
60
- 20, 133, 52, 46, 51, 64, 73, 18, nil, nil,
61
- nil, nil, nil, nil, nil, nil, nil, 82, 106, nil,
62
- nil, nil, 86, 104, nil, nil, nil, nil, nil, nil,
63
- nil, 100, nil, 120, nil, nil, 148, 135, 152, 144,
64
- 140, nil, nil, nil, nil, nil, nil, nil, nil, nil,
65
- nil, 147, nil, nil, nil, nil ]
63
+ -2, 1, nil, nil, nil, nil, nil, nil, nil, nil,
64
+ 87, -22, nil, 37, 182, 122, nil, nil, 105, 60,
65
+ 105, 170, 148, 25, 9, 126, 114, 71, 73, 98,
66
+ nil, 60, 60, nil, nil, 85, nil, nil, nil, 48,
67
+ nil, 118, 73, 148, 170, 55, 18, 72, nil, 0,
68
+ 45, 112, 29, 9, 0, -13, 58, 50, 115, nil,
69
+ -9, nil, nil, nil, nil, nil, nil, nil, nil, nil,
70
+ nil, nil, 74, 46, nil, nil, nil, nil, nil, nil,
71
+ nil, 80, nil, 99, 115, nil, nil, 184, 123, 27,
72
+ 193, 124, nil, nil, nil, nil, nil, nil, nil, nil,
73
+ nil, nil, 127, nil, nil, nil, nil ]
66
74
 
67
75
  racc_action_default = [
68
- -27, -74, -2, -3, -4, -5, -6, -7, -8, -9,
69
- -50, -13, -17, -27, -20, -74, -22, -23, -74, -25,
70
- -27, -74, -74, -27, -74, -55, -56, -57, -58, -59,
71
- -74, -27, -10, -49, -12, -27, -14, -15, -16, -18,
72
- -27, -21, -74, -32, -62, -62, -74, -74, -33, -74,
73
- -74, -41, -42, -43, -74, -41, -43, -74, -47, -48,
74
- -51, -52, -53, -54, 106, -1, -11, -74, -71, -73,
75
- -19, -24, -74, -74, -63, -64, -65, -66, -67, -68,
76
- -69, -74, -30, -74, -34, -35, -74, -46, -74, -74,
77
- -74, -36, -37, -70, -72, -28, -60, -61, -29, -31,
78
- -38, -74, -39, -40, -45, -44 ]
76
+ -24, -73, -2, -3, -4, -5, -6, -7, -8, -9,
77
+ -47, -11, -14, -24, -17, -73, -19, -20, -73, -22,
78
+ -24, -73, -24, -24, -73, -53, -54, -55, -56, -57,
79
+ -58, -73, -24, -10, -46, -24, -12, -13, -15, -24,
80
+ -18, -73, -29, -61, -61, -73, -73, -73, -30, -73,
81
+ -73, -38, -39, -40, -22, -73, -38, -73, -70, -72,
82
+ -73, -44, -45, -48, -49, -50, -51, -52, 107, -1,
83
+ -16, -21, -73, -73, -62, -63, -64, -65, -66, -67,
84
+ -68, -73, -27, -73, -40, -31, -32, -73, -43, -73,
85
+ -73, -73, -33, -69, -71, -34, -25, -59, -60, -26,
86
+ -28, -35, -73, -36, -37, -42, -41 ]
79
87
 
80
88
  racc_goto_table = [
81
- 49, 54, 33, 39, 36, 1, 34, 45, 38, 72,
82
- 81, 58, 32, 37, 47, 44, 68, 60, 61, 62,
83
- 63, 65, 40, 50, 67, nil, nil, 69, 57, 66,
84
- 70, nil, nil, nil, nil, nil, nil, nil, nil, nil,
89
+ 49, 34, 38, 44, 1, 72, 81, 61, 37, 58,
90
+ 36, 46, 43, 59, 33, 39, 63, 64, 65, 66,
91
+ 67, 69, 58, 50, nil, nil, 59, 60, 70, nil,
85
92
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
93
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 94,
86
94
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
87
- 94, nil, nil, nil, nil, 100, nil, 102, 103 ]
95
+ nil, nil, nil, nil, nil, nil, 101, nil, 103, 104 ]
88
96
 
89
97
  racc_goto_check = [
90
- 18, 18, 8, 2, 11, 1, 9, 10, 9, 17,
91
- 17, 10, 7, 12, 15, 16, 6, 8, 8, 8,
92
- 8, 2, 4, 19, 22, nil, nil, 8, 1, 9,
93
- 2, nil, nil, nil, nil, nil, nil, nil, nil, nil,
98
+ 17, 11, 2, 8, 1, 16, 16, 8, 10, 6,
99
+ 9, 14, 15, 11, 7, 4, 11, 11, 11, 11,
100
+ 11, 2, 6, 18, nil, nil, 11, 1, 2, nil,
94
101
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
102
+ nil, nil, nil, nil, nil, nil, nil, nil, nil, 11,
95
103
  nil, nil, nil, nil, nil, nil, nil, nil, nil, nil,
96
- 8, nil, nil, nil, nil, 18, nil, 18, 18 ]
104
+ nil, nil, nil, nil, nil, nil, 17, nil, 17, 17 ]
97
105
 
98
106
  racc_goto_pointer = [
99
- nil, 5, -10, nil, 8, nil, -19, 2, -8, -4,
100
- -13, -7, 2, nil, nil, -6, -5, -35, -21, 2,
101
- nil, nil, -11 ]
107
+ nil, 4, -11, nil, 1, nil, -13, 4, -17, -1,
108
+ -3, -9, nil, nil, -9, -8, -38, -21, 2, nil,
109
+ nil, nil, nil ]
102
110
 
103
111
  racc_goto_default = [
104
- nil, nil, 3, 2, 13, 14, 10, nil, 12, nil,
105
- 11, 28, 27, 26, 16, 18, nil, nil, nil, nil,
106
- 25, 73, nil ]
112
+ nil, nil, 3, 2, 13, 14, 10, nil, 11, 28,
113
+ 27, 12, 26, 16, 18, nil, nil, 55, nil, 25,
114
+ 29, 73, 57 ]
107
115
 
108
116
  racc_reduce_table = [
109
117
  0, 0, :racc_error,
@@ -117,73 +125,72 @@ racc_reduce_table = [
117
125
  1, 35, :_reduce_8,
118
126
  1, 35, :_reduce_9,
119
127
  2, 36, :_reduce_10,
120
- 3, 36, :_reduce_11,
121
- 2, 36, :_reduce_12,
122
128
  1, 36, :_reduce_none,
123
- 2, 36, :_reduce_14,
124
- 2, 36, :_reduce_15,
125
- 2, 36, :_reduce_16,
126
- 1, 36, :_reduce_17,
127
- 2, 34, :_reduce_18,
128
- 3, 33, :_reduce_19,
129
+ 2, 36, :_reduce_12,
130
+ 2, 36, :_reduce_13,
131
+ 1, 36, :_reduce_14,
132
+ 2, 34, :_reduce_15,
133
+ 3, 33, :_reduce_16,
129
134
  1, 33, :_reduce_none,
130
- 2, 44, :_reduce_21,
135
+ 2, 43, :_reduce_18,
131
136
  1, 37, :_reduce_none,
132
- 1, 37, :_reduce_23,
133
- 3, 45, :_reduce_24,
134
- 1, 45, :_reduce_25,
135
- 1, 46, :_reduce_26,
136
- 0, 46, :_reduce_none,
137
- 4, 43, :_reduce_28,
138
- 4, 43, :_reduce_29,
139
- 3, 43, :_reduce_30,
140
- 3, 47, :_reduce_31,
141
- 1, 47, :_reduce_32,
142
- 2, 41, :_reduce_33,
143
- 3, 41, :_reduce_34,
144
- 3, 41, :_reduce_35,
145
- 3, 41, :_reduce_36,
146
- 3, 41, :_reduce_37,
147
- 3, 49, :_reduce_38,
148
- 3, 49, :_reduce_39,
149
- 3, 49, :_reduce_40,
150
- 1, 49, :_reduce_none,
151
- 1, 49, :_reduce_none,
152
- 1, 49, :_reduce_43,
153
- 4, 50, :_reduce_44,
154
- 3, 50, :_reduce_45,
155
- 2, 50, :_reduce_46,
156
- 2, 42, :_reduce_47,
157
- 2, 42, :_reduce_48,
137
+ 1, 37, :_reduce_20,
138
+ 3, 44, :_reduce_21,
139
+ 1, 44, :_reduce_22,
140
+ 1, 45, :_reduce_23,
141
+ 0, 45, :_reduce_none,
142
+ 4, 41, :_reduce_25,
143
+ 4, 41, :_reduce_26,
144
+ 3, 41, :_reduce_27,
145
+ 3, 46, :_reduce_28,
146
+ 1, 46, :_reduce_29,
147
+ 2, 39, :_reduce_30,
148
+ 3, 39, :_reduce_31,
149
+ 3, 39, :_reduce_32,
150
+ 3, 39, :_reduce_33,
151
+ 3, 39, :_reduce_34,
152
+ 3, 48, :_reduce_35,
153
+ 3, 48, :_reduce_36,
154
+ 3, 48, :_reduce_37,
155
+ 1, 48, :_reduce_none,
156
+ 1, 48, :_reduce_none,
157
+ 1, 48, :_reduce_40,
158
+ 4, 49, :_reduce_41,
159
+ 3, 49, :_reduce_42,
160
+ 2, 49, :_reduce_43,
161
+ 2, 40, :_reduce_44,
162
+ 2, 40, :_reduce_45,
158
163
  1, 38, :_reduce_none,
159
164
  0, 38, :_reduce_none,
160
- 2, 39, :_reduce_51,
161
- 2, 39, :_reduce_52,
162
- 2, 39, :_reduce_53,
163
- 2, 39, :_reduce_54,
164
- 1, 39, :_reduce_none,
165
- 1, 39, :_reduce_none,
166
- 1, 39, :_reduce_none,
167
- 1, 39, :_reduce_none,
168
- 1, 51, :_reduce_59,
169
- 2, 48, :_reduce_60,
170
- 2, 48, :_reduce_61,
171
- 0, 48, :_reduce_none,
165
+ 2, 42, :_reduce_48,
166
+ 2, 42, :_reduce_49,
167
+ 2, 42, :_reduce_50,
168
+ 2, 42, :_reduce_51,
169
+ 2, 42, :_reduce_52,
170
+ 1, 42, :_reduce_none,
171
+ 1, 42, :_reduce_none,
172
+ 1, 42, :_reduce_none,
173
+ 1, 42, :_reduce_none,
174
+ 1, 42, :_reduce_none,
175
+ 1, 50, :_reduce_58,
176
+ 2, 47, :_reduce_59,
177
+ 2, 47, :_reduce_60,
178
+ 0, 47, :_reduce_none,
179
+ 1, 52, :_reduce_62,
172
180
  1, 52, :_reduce_63,
173
181
  1, 52, :_reduce_64,
174
182
  1, 52, :_reduce_65,
175
183
  1, 52, :_reduce_66,
176
184
  1, 52, :_reduce_67,
177
185
  1, 52, :_reduce_68,
178
- 1, 52, :_reduce_69,
179
- 3, 40, :_reduce_70,
186
+ 3, 51, :_reduce_69,
180
187
  1, 53, :_reduce_none,
181
188
  2, 53, :_reduce_none,
182
189
  1, 53, :_reduce_none ]
183
190
 
184
- racc_reduce_n = 74
191
+ racc_reduce_n = 73
185
192
 
186
- racc_shift_n = 106
193
+ racc_shift_n = 107
187
194
 
188
195
  racc_token_table = {
189
196
  false => 0,
@@ -278,19 +285,19 @@ Racc_token_to_s_table = [
278
285
  "simple_selector",
279
286
  "element_name",
280
287
  "hcap_0toN",
281
- "hcap_1toN",
282
- "negation",
283
288
  "function",
284
289
  "pseudo",
285
290
  "attrib",
291
+ "hcap_1toN",
286
292
  "class",
287
293
  "namespaced_ident",
288
294
  "namespace",
289
295
  "attrib_name",
290
296
  "attrib_val_0or1",
291
297
  "expr",
292
- "an_plus_b",
298
+ "nth",
293
299
  "attribute_id",
300
+ "negation",
294
301
  "eql_incl_dash",
295
302
  "negation_arg" ]
296
303
 
@@ -356,16 +363,7 @@ def _reduce_10(val, _values, result)
356
363
  result
357
364
  end
358
365
 
359
- def _reduce_11(val, _values, result)
360
- result = Node.new(:CONDITIONAL_SELECTOR,
361
- [
362
- val.first,
363
- Node.new(:COMBINATOR, [val[1], val.last])
364
- ]
365
- )
366
-
367
- result
368
- end
366
+ # reduce 11 omitted
369
367
 
370
368
  def _reduce_12(val, _values, result)
371
369
  result = Node.new(:CONDITIONAL_SELECTOR, val)
@@ -373,32 +371,13 @@ def _reduce_12(val, _values, result)
373
371
  result
374
372
  end
375
373
 
376
- # reduce 13 omitted
377
-
378
- def _reduce_14(val, _values, result)
374
+ def _reduce_13(val, _values, result)
379
375
  result = Node.new(:CONDITIONAL_SELECTOR, val)
380
376
 
381
377
  result
382
378
  end
383
379
 
384
- def _reduce_15(val, _values, result)
385
- result = Node.new(:CONDITIONAL_SELECTOR, val)
386
-
387
- result
388
- end
389
-
390
- def _reduce_16(val, _values, result)
391
- result = Node.new(:CONDITIONAL_SELECTOR,
392
- [
393
- Node.new(:ELEMENT_NAME, ['*']),
394
- Node.new(:COMBINATOR, val)
395
- ]
396
- )
397
-
398
- result
399
- end
400
-
401
- def _reduce_17(val, _values, result)
380
+ def _reduce_14(val, _values, result)
402
381
  result = Node.new(:CONDITIONAL_SELECTOR,
403
382
  [Node.new(:ELEMENT_NAME, ['*']), val.first]
404
383
  )
@@ -406,33 +385,33 @@ def _reduce_17(val, _values, result)
406
385
  result
407
386
  end
408
387
 
409
- def _reduce_18(val, _values, result)
388
+ def _reduce_15(val, _values, result)
410
389
  result = Node.new(val.first, [nil, val.last])
411
390
 
412
391
  result
413
392
  end
414
393
 
415
- def _reduce_19(val, _values, result)
394
+ def _reduce_16(val, _values, result)
416
395
  result = Node.new(val[1], [val.first, val.last])
417
396
 
418
397
  result
419
398
  end
420
399
 
421
- # reduce 20 omitted
400
+ # reduce 17 omitted
422
401
 
423
- def _reduce_21(val, _values, result)
402
+ def _reduce_18(val, _values, result)
424
403
  result = Node.new(:CLASS_CONDITION, [val[1]])
425
404
  result
426
405
  end
427
406
 
428
- # reduce 22 omitted
407
+ # reduce 19 omitted
429
408
 
430
- def _reduce_23(val, _values, result)
409
+ def _reduce_20(val, _values, result)
431
410
  result = Node.new(:ELEMENT_NAME, val)
432
411
  result
433
412
  end
434
413
 
435
- def _reduce_24(val, _values, result)
414
+ def _reduce_21(val, _values, result)
436
415
  result = Node.new(:ELEMENT_NAME,
437
416
  [[val.first, val.last].compact.join(':')]
438
417
  )
@@ -440,21 +419,21 @@ def _reduce_24(val, _values, result)
440
419
  result
441
420
  end
442
421
 
443
- def _reduce_25(val, _values, result)
422
+ def _reduce_22(val, _values, result)
444
423
  name = @namespaces.key?('xmlns') ? "xmlns:#{val.first}" : val.first
445
424
  result = Node.new(:ELEMENT_NAME, [name])
446
425
 
447
426
  result
448
427
  end
449
428
 
450
- def _reduce_26(val, _values, result)
429
+ def _reduce_23(val, _values, result)
451
430
  result = val[0]
452
431
  result
453
432
  end
454
433
 
455
- # reduce 27 omitted
434
+ # reduce 24 omitted
456
435
 
457
- def _reduce_28(val, _values, result)
436
+ def _reduce_25(val, _values, result)
458
437
  result = Node.new(:ATTRIBUTE_CONDITION,
459
438
  [val[1]] + (val[2] || [])
460
439
  )
@@ -462,7 +441,7 @@ def _reduce_28(val, _values, result)
462
441
  result
463
442
  end
464
443
 
465
- def _reduce_29(val, _values, result)
444
+ def _reduce_26(val, _values, result)
466
445
  result = Node.new(:ATTRIBUTE_CONDITION,
467
446
  [val[1]] + (val[2] || [])
468
447
  )
@@ -470,7 +449,7 @@ def _reduce_29(val, _values, result)
470
449
  result
471
450
  end
472
451
 
473
- def _reduce_30(val, _values, result)
452
+ def _reduce_27(val, _values, result)
474
453
  # Non standard, but hpricot supports it.
475
454
  result = Node.new(:PSEUDO_CLASS,
476
455
  [Node.new(:FUNCTION, ['nth-child(', val[1]])]
@@ -479,7 +458,7 @@ def _reduce_30(val, _values, result)
479
458
  result
480
459
  end
481
460
 
482
- def _reduce_31(val, _values, result)
461
+ def _reduce_28(val, _values, result)
483
462
  result = Node.new(:ELEMENT_NAME,
484
463
  [[val.first, val.last].compact.join(':')]
485
464
  )
@@ -487,7 +466,7 @@ def _reduce_31(val, _values, result)
487
466
  result
488
467
  end
489
468
 
490
- def _reduce_32(val, _values, result)
469
+ def _reduce_29(val, _values, result)
491
470
  # Default namespace is not applied to attributes.
492
471
  # So we don't add prefix "xmlns:" as in namespaced_ident.
493
472
  result = Node.new(:ELEMENT_NAME, [val.first])
@@ -495,62 +474,62 @@ def _reduce_32(val, _values, result)
495
474
  result
496
475
  end
497
476
 
498
- def _reduce_33(val, _values, result)
477
+ def _reduce_30(val, _values, result)
499
478
  result = Node.new(:FUNCTION, [val.first.strip])
500
479
 
501
480
  result
502
481
  end
503
482
 
504
- def _reduce_34(val, _values, result)
483
+ def _reduce_31(val, _values, result)
505
484
  result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
506
485
 
507
486
  result
508
487
  end
509
488
 
510
- def _reduce_35(val, _values, result)
489
+ def _reduce_32(val, _values, result)
511
490
  result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
512
491
 
513
492
  result
514
493
  end
515
494
 
516
- def _reduce_36(val, _values, result)
495
+ def _reduce_33(val, _values, result)
517
496
  result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
518
497
 
519
498
  result
520
499
  end
521
500
 
522
- def _reduce_37(val, _values, result)
501
+ def _reduce_34(val, _values, result)
523
502
  result = Node.new(:FUNCTION, [val.first.strip, val[1]].flatten)
524
503
 
525
504
  result
526
505
  end
527
506
 
528
- def _reduce_38(val, _values, result)
507
+ def _reduce_35(val, _values, result)
529
508
  result = [val.first, val.last]
530
509
  result
531
510
  end
532
511
 
533
- def _reduce_39(val, _values, result)
512
+ def _reduce_36(val, _values, result)
534
513
  result = [val.first, val.last]
535
514
  result
536
515
  end
537
516
 
538
- def _reduce_40(val, _values, result)
517
+ def _reduce_37(val, _values, result)
539
518
  result = [val.first, val.last]
540
519
  result
541
520
  end
542
521
 
543
- # reduce 41 omitted
522
+ # reduce 38 omitted
544
523
 
545
- # reduce 42 omitted
524
+ # reduce 39 omitted
546
525
 
547
- def _reduce_43(val, _values, result)
526
+ def _reduce_40(val, _values, result)
548
527
  if val[0] == 'even'
549
528
  val = ["2","n","+","0"]
550
- result = Node.new(:AN_PLUS_B, val)
529
+ result = Node.new(:NTH, val)
551
530
  elsif val[0] == 'odd'
552
531
  val = ["2","n","+","1"]
553
- result = Node.new(:AN_PLUS_B, val)
532
+ result = Node.new(:NTH, val)
554
533
  else
555
534
  # This is not CSS standard. It allows us to support this:
556
535
  # assert_xpath("//a[foo(., @href)]", @parser.parse('a:foo(@href)'))
@@ -562,9 +541,9 @@ def _reduce_43(val, _values, result)
562
541
  result
563
542
  end
564
543
 
565
- def _reduce_44(val, _values, result)
544
+ def _reduce_41(val, _values, result)
566
545
  if val[1] == 'n'
567
- result = Node.new(:AN_PLUS_B, val)
546
+ result = Node.new(:NTH, val)
568
547
  else
569
548
  raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
570
549
  end
@@ -572,15 +551,15 @@ def _reduce_44(val, _values, result)
572
551
  result
573
552
  end
574
553
 
575
- def _reduce_45(val, _values, result)
554
+ def _reduce_42(val, _values, result)
576
555
  # n+3, -n+3
577
556
  if val[0] == 'n'
578
557
  val.unshift("1")
579
- result = Node.new(:AN_PLUS_B, val)
558
+ result = Node.new(:NTH, val)
580
559
  elsif val[0] == '-n'
581
560
  val[0] = 'n'
582
561
  val.unshift("-1")
583
- result = Node.new(:AN_PLUS_B, val)
562
+ result = Node.new(:NTH, val)
584
563
  else
585
564
  raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
586
565
  end
@@ -588,11 +567,19 @@ def _reduce_45(val, _values, result)
588
567
  result
589
568
  end
590
569
 
591
- def _reduce_46(val, _values, result)
592
- if val[1] == 'n'
570
+ def _reduce_43(val, _values, result)
571
+ # 5n, -5n, 10n-1
572
+ n = val[1]
573
+ if n[0, 2] == 'n-'
574
+ val[1] = 'n'
575
+ val << "-"
576
+ # b is contained in n as n is the string "n-b"
577
+ val << n[2, n.size]
578
+ result = Node.new(:NTH, val)
579
+ elsif n == 'n'
593
580
  val << "+"
594
581
  val << "0"
595
- result = Node.new(:AN_PLUS_B, val)
582
+ result = Node.new(:NTH, val)
596
583
  else
597
584
  raise Racc::ParseError, "parse error on IDENT '#{val[1]}'"
598
585
  end
@@ -600,117 +587,125 @@ def _reduce_46(val, _values, result)
600
587
  result
601
588
  end
602
589
 
603
- def _reduce_47(val, _values, result)
590
+ def _reduce_44(val, _values, result)
604
591
  result = Node.new(:PSEUDO_CLASS, [val[1]])
605
592
 
606
593
  result
607
594
  end
608
595
 
609
- def _reduce_48(val, _values, result)
596
+ def _reduce_45(val, _values, result)
610
597
  result = Node.new(:PSEUDO_CLASS, [val[1]])
611
598
  result
612
599
  end
613
600
 
614
- # reduce 49 omitted
601
+ # reduce 46 omitted
615
602
 
616
- # reduce 50 omitted
603
+ # reduce 47 omitted
617
604
 
618
- def _reduce_51(val, _values, result)
605
+ def _reduce_48(val, _values, result)
619
606
  result = Node.new(:COMBINATOR, val)
620
607
 
621
608
  result
622
609
  end
623
610
 
624
- def _reduce_52(val, _values, result)
611
+ def _reduce_49(val, _values, result)
612
+ result = Node.new(:COMBINATOR, val)
613
+
614
+ result
615
+ end
616
+
617
+ def _reduce_50(val, _values, result)
625
618
  result = Node.new(:COMBINATOR, val)
626
619
 
627
620
  result
628
621
  end
629
622
 
630
- def _reduce_53(val, _values, result)
623
+ def _reduce_51(val, _values, result)
631
624
  result = Node.new(:COMBINATOR, val)
632
625
 
633
626
  result
634
627
  end
635
628
 
636
- def _reduce_54(val, _values, result)
629
+ def _reduce_52(val, _values, result)
637
630
  result = Node.new(:COMBINATOR, val)
638
631
 
639
632
  result
640
633
  end
641
634
 
635
+ # reduce 53 omitted
636
+
637
+ # reduce 54 omitted
638
+
642
639
  # reduce 55 omitted
643
640
 
644
641
  # reduce 56 omitted
645
642
 
646
643
  # reduce 57 omitted
647
644
 
648
- # reduce 58 omitted
649
-
650
- def _reduce_59(val, _values, result)
645
+ def _reduce_58(val, _values, result)
651
646
  result = Node.new(:ID, val)
652
647
  result
653
648
  end
654
649
 
655
- def _reduce_60(val, _values, result)
650
+ def _reduce_59(val, _values, result)
656
651
  result = [val.first, val[1]]
657
652
  result
658
653
  end
659
654
 
660
- def _reduce_61(val, _values, result)
655
+ def _reduce_60(val, _values, result)
661
656
  result = [val.first, val[1]]
662
657
  result
663
658
  end
664
659
 
665
- # reduce 62 omitted
660
+ # reduce 61 omitted
666
661
 
667
- def _reduce_63(val, _values, result)
662
+ def _reduce_62(val, _values, result)
668
663
  result = :equal
669
664
  result
670
665
  end
671
666
 
672
- def _reduce_64(val, _values, result)
667
+ def _reduce_63(val, _values, result)
673
668
  result = :prefix_match
674
669
  result
675
670
  end
676
671
 
677
- def _reduce_65(val, _values, result)
672
+ def _reduce_64(val, _values, result)
678
673
  result = :suffix_match
679
674
  result
680
675
  end
681
676
 
682
- def _reduce_66(val, _values, result)
677
+ def _reduce_65(val, _values, result)
683
678
  result = :substring_match
684
679
  result
685
680
  end
686
681
 
687
- def _reduce_67(val, _values, result)
682
+ def _reduce_66(val, _values, result)
688
683
  result = :not_equal
689
684
  result
690
685
  end
691
686
 
692
- def _reduce_68(val, _values, result)
687
+ def _reduce_67(val, _values, result)
693
688
  result = :includes
694
689
  result
695
690
  end
696
691
 
697
- def _reduce_69(val, _values, result)
692
+ def _reduce_68(val, _values, result)
698
693
  result = :dash_match
699
694
  result
700
695
  end
701
696
 
702
- def _reduce_70(val, _values, result)
697
+ def _reduce_69(val, _values, result)
703
698
  result = Node.new(:NOT, [val[1]])
704
699
 
705
700
  result
706
701
  end
707
702
 
703
+ # reduce 70 omitted
704
+
708
705
  # reduce 71 omitted
709
706
 
710
707
  # reduce 72 omitted
711
708
 
712
- # reduce 73 omitted
713
-
714
709
  def _reduce_none(val, _values, result)
715
710
  val[0]
716
711
  end