nokogiri 1.5.10 → 1.13.0

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 (334) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +5 -0
  3. data/LICENSE-DEPENDENCIES.md +1903 -0
  4. data/LICENSE.md +9 -0
  5. data/README.md +280 -0
  6. data/bin/nokogiri +84 -31
  7. data/dependencies.yml +73 -0
  8. data/ext/nokogiri/depend +38 -358
  9. data/ext/nokogiri/extconf.rb +956 -100
  10. data/ext/nokogiri/gumbo.c +584 -0
  11. data/ext/nokogiri/html4_document.c +166 -0
  12. data/ext/nokogiri/html4_element_description.c +294 -0
  13. data/ext/nokogiri/html4_entity_lookup.c +37 -0
  14. data/ext/nokogiri/html4_sax_parser_context.c +120 -0
  15. data/ext/nokogiri/html4_sax_push_parser.c +95 -0
  16. data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
  17. data/ext/nokogiri/nokogiri.c +232 -87
  18. data/ext/nokogiri/nokogiri.h +188 -129
  19. data/ext/nokogiri/test_global_handlers.c +40 -0
  20. data/ext/nokogiri/xml_attr.c +49 -40
  21. data/ext/nokogiri/xml_attribute_decl.c +18 -18
  22. data/ext/nokogiri/xml_cdata.c +24 -23
  23. data/ext/nokogiri/xml_comment.c +29 -21
  24. data/ext/nokogiri/xml_document.c +327 -223
  25. data/ext/nokogiri/xml_document_fragment.c +12 -16
  26. data/ext/nokogiri/xml_dtd.c +56 -50
  27. data/ext/nokogiri/xml_element_content.c +31 -26
  28. data/ext/nokogiri/xml_element_decl.c +22 -22
  29. data/ext/nokogiri/xml_encoding_handler.c +45 -20
  30. data/ext/nokogiri/xml_entity_decl.c +32 -30
  31. data/ext/nokogiri/xml_entity_reference.c +16 -18
  32. data/ext/nokogiri/xml_namespace.c +74 -32
  33. data/ext/nokogiri/xml_node.c +1290 -680
  34. data/ext/nokogiri/xml_node_set.c +239 -208
  35. data/ext/nokogiri/xml_processing_instruction.c +17 -19
  36. data/ext/nokogiri/xml_reader.c +227 -189
  37. data/ext/nokogiri/xml_relax_ng.c +52 -28
  38. data/ext/nokogiri/xml_sax_parser.c +123 -125
  39. data/ext/nokogiri/xml_sax_parser_context.c +138 -79
  40. data/ext/nokogiri/xml_sax_push_parser.c +88 -35
  41. data/ext/nokogiri/xml_schema.c +112 -33
  42. data/ext/nokogiri/xml_syntax_error.c +50 -23
  43. data/ext/nokogiri/xml_text.c +14 -18
  44. data/ext/nokogiri/xml_xpath_context.c +227 -140
  45. data/ext/nokogiri/xslt_stylesheet.c +162 -168
  46. data/gumbo-parser/CHANGES.md +63 -0
  47. data/gumbo-parser/Makefile +101 -0
  48. data/gumbo-parser/THANKS +27 -0
  49. data/gumbo-parser/src/Makefile +34 -0
  50. data/gumbo-parser/src/README.md +41 -0
  51. data/gumbo-parser/src/ascii.c +75 -0
  52. data/gumbo-parser/src/ascii.h +115 -0
  53. data/gumbo-parser/src/attribute.c +42 -0
  54. data/gumbo-parser/src/attribute.h +17 -0
  55. data/gumbo-parser/src/char_ref.c +22225 -0
  56. data/gumbo-parser/src/char_ref.h +29 -0
  57. data/gumbo-parser/src/char_ref.rl +2154 -0
  58. data/gumbo-parser/src/error.c +626 -0
  59. data/gumbo-parser/src/error.h +148 -0
  60. data/gumbo-parser/src/foreign_attrs.c +104 -0
  61. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  62. data/gumbo-parser/src/gumbo.h +943 -0
  63. data/gumbo-parser/src/insertion_mode.h +33 -0
  64. data/gumbo-parser/src/macros.h +91 -0
  65. data/gumbo-parser/src/parser.c +4875 -0
  66. data/gumbo-parser/src/parser.h +41 -0
  67. data/gumbo-parser/src/replacement.h +33 -0
  68. data/gumbo-parser/src/string_buffer.c +103 -0
  69. data/gumbo-parser/src/string_buffer.h +68 -0
  70. data/gumbo-parser/src/string_piece.c +48 -0
  71. data/gumbo-parser/src/svg_attrs.c +174 -0
  72. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  73. data/gumbo-parser/src/svg_tags.c +137 -0
  74. data/gumbo-parser/src/svg_tags.gperf +55 -0
  75. data/gumbo-parser/src/tag.c +222 -0
  76. data/gumbo-parser/src/tag_lookup.c +382 -0
  77. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  78. data/gumbo-parser/src/tag_lookup.h +13 -0
  79. data/gumbo-parser/src/token_buffer.c +79 -0
  80. data/gumbo-parser/src/token_buffer.h +71 -0
  81. data/gumbo-parser/src/token_type.h +17 -0
  82. data/gumbo-parser/src/tokenizer.c +3463 -0
  83. data/gumbo-parser/src/tokenizer.h +112 -0
  84. data/gumbo-parser/src/tokenizer_states.h +339 -0
  85. data/gumbo-parser/src/utf8.c +245 -0
  86. data/gumbo-parser/src/utf8.h +164 -0
  87. data/gumbo-parser/src/util.c +68 -0
  88. data/gumbo-parser/src/util.h +30 -0
  89. data/gumbo-parser/src/vector.c +111 -0
  90. data/gumbo-parser/src/vector.h +45 -0
  91. data/lib/nokogiri/class_resolver.rb +67 -0
  92. data/lib/nokogiri/css/node.rb +10 -58
  93. data/lib/nokogiri/css/parser.rb +327 -288
  94. data/lib/nokogiri/css/parser.y +67 -45
  95. data/lib/nokogiri/css/parser_extras.rb +52 -49
  96. data/lib/nokogiri/css/syntax_error.rb +3 -1
  97. data/lib/nokogiri/css/tokenizer.rb +107 -104
  98. data/lib/nokogiri/css/tokenizer.rex +7 -6
  99. data/lib/nokogiri/css/xpath_visitor.rb +263 -75
  100. data/lib/nokogiri/css.rb +50 -17
  101. data/lib/nokogiri/decorators/slop.rb +17 -8
  102. data/lib/nokogiri/extension.rb +31 -0
  103. data/lib/nokogiri/gumbo.rb +15 -0
  104. data/lib/nokogiri/html.rb +38 -27
  105. data/lib/nokogiri/{html → html4}/builder.rb +4 -2
  106. data/lib/nokogiri/html4/document.rb +331 -0
  107. data/lib/nokogiri/html4/document_fragment.rb +54 -0
  108. data/lib/nokogiri/{html → html4}/element_description.rb +3 -1
  109. data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
  110. data/lib/nokogiri/{html → html4}/entity_lookup.rb +4 -2
  111. data/lib/nokogiri/{html → html4}/sax/parser.rb +24 -15
  112. data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
  113. data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
  114. data/lib/nokogiri/html4.rb +46 -0
  115. data/lib/nokogiri/html5/document.rb +88 -0
  116. data/lib/nokogiri/html5/document_fragment.rb +83 -0
  117. data/lib/nokogiri/html5/node.rb +96 -0
  118. data/lib/nokogiri/html5.rb +477 -0
  119. data/lib/nokogiri/jruby/dependencies.rb +21 -0
  120. data/lib/nokogiri/syntax_error.rb +2 -0
  121. data/lib/nokogiri/version/constant.rb +6 -0
  122. data/lib/nokogiri/version/info.rb +221 -0
  123. data/lib/nokogiri/version.rb +3 -90
  124. data/lib/nokogiri/xml/attr.rb +6 -3
  125. data/lib/nokogiri/xml/attribute_decl.rb +3 -1
  126. data/lib/nokogiri/xml/builder.rb +96 -54
  127. data/lib/nokogiri/xml/cdata.rb +3 -1
  128. data/lib/nokogiri/xml/character_data.rb +2 -0
  129. data/lib/nokogiri/xml/document.rb +234 -95
  130. data/lib/nokogiri/xml/document_fragment.rb +86 -36
  131. data/lib/nokogiri/xml/dtd.rb +16 -4
  132. data/lib/nokogiri/xml/element_content.rb +2 -0
  133. data/lib/nokogiri/xml/element_decl.rb +3 -1
  134. data/lib/nokogiri/xml/entity_decl.rb +4 -2
  135. data/lib/nokogiri/xml/entity_reference.rb +20 -0
  136. data/lib/nokogiri/xml/namespace.rb +3 -0
  137. data/lib/nokogiri/xml/node/save_options.rb +8 -4
  138. data/lib/nokogiri/xml/node.rb +947 -502
  139. data/lib/nokogiri/xml/node_set.rb +168 -159
  140. data/lib/nokogiri/xml/notation.rb +13 -0
  141. data/lib/nokogiri/xml/parse_options.rb +40 -5
  142. data/lib/nokogiri/xml/pp/character_data.rb +9 -6
  143. data/lib/nokogiri/xml/pp/node.rb +25 -26
  144. data/lib/nokogiri/xml/pp.rb +4 -2
  145. data/lib/nokogiri/xml/processing_instruction.rb +3 -1
  146. data/lib/nokogiri/xml/reader.rb +23 -28
  147. data/lib/nokogiri/xml/relax_ng.rb +8 -2
  148. data/lib/nokogiri/xml/sax/document.rb +45 -49
  149. data/lib/nokogiri/xml/sax/parser.rb +43 -41
  150. data/lib/nokogiri/xml/sax/parser_context.rb +8 -3
  151. data/lib/nokogiri/xml/sax/push_parser.rb +6 -5
  152. data/lib/nokogiri/xml/sax.rb +6 -4
  153. data/lib/nokogiri/xml/schema.rb +19 -9
  154. data/lib/nokogiri/xml/searchable.rb +259 -0
  155. data/lib/nokogiri/xml/syntax_error.rb +25 -1
  156. data/lib/nokogiri/xml/text.rb +2 -0
  157. data/lib/nokogiri/xml/xpath/syntax_error.rb +4 -2
  158. data/lib/nokogiri/xml/xpath.rb +15 -4
  159. data/lib/nokogiri/xml/xpath_context.rb +3 -3
  160. data/lib/nokogiri/xml.rb +38 -36
  161. data/lib/nokogiri/xslt/stylesheet.rb +3 -1
  162. data/lib/nokogiri/xslt.rb +18 -16
  163. data/lib/nokogiri.rb +69 -69
  164. data/lib/xsd/xmlparser/nokogiri.rb +26 -24
  165. data/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
  166. data/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
  167. data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +25 -0
  168. data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
  169. data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
  170. data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
  171. data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
  172. data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
  173. data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  174. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
  175. data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
  176. data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
  177. data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
  178. metadata +382 -460
  179. data/.autotest +0 -26
  180. data/.gemtest +0 -0
  181. data/CHANGELOG.ja.rdoc +0 -785
  182. data/CHANGELOG.rdoc +0 -783
  183. data/C_CODING_STYLE.rdoc +0 -33
  184. data/Manifest.txt +0 -303
  185. data/README.ja.rdoc +0 -106
  186. data/README.rdoc +0 -175
  187. data/ROADMAP.md +0 -90
  188. data/Rakefile +0 -228
  189. data/STANDARD_RESPONSES.md +0 -47
  190. data/Y_U_NO_GEMSPEC.md +0 -155
  191. data/build_all +0 -105
  192. data/ext/nokogiri/html_document.c +0 -170
  193. data/ext/nokogiri/html_document.h +0 -10
  194. data/ext/nokogiri/html_element_description.c +0 -279
  195. data/ext/nokogiri/html_element_description.h +0 -10
  196. data/ext/nokogiri/html_entity_lookup.c +0 -32
  197. data/ext/nokogiri/html_entity_lookup.h +0 -8
  198. data/ext/nokogiri/html_sax_parser_context.c +0 -116
  199. data/ext/nokogiri/html_sax_parser_context.h +0 -11
  200. data/ext/nokogiri/html_sax_push_parser.c +0 -87
  201. data/ext/nokogiri/html_sax_push_parser.h +0 -9
  202. data/ext/nokogiri/xml_attr.h +0 -9
  203. data/ext/nokogiri/xml_attribute_decl.h +0 -9
  204. data/ext/nokogiri/xml_cdata.h +0 -9
  205. data/ext/nokogiri/xml_comment.h +0 -9
  206. data/ext/nokogiri/xml_document.h +0 -23
  207. data/ext/nokogiri/xml_document_fragment.h +0 -10
  208. data/ext/nokogiri/xml_dtd.h +0 -10
  209. data/ext/nokogiri/xml_element_content.h +0 -10
  210. data/ext/nokogiri/xml_element_decl.h +0 -9
  211. data/ext/nokogiri/xml_encoding_handler.h +0 -8
  212. data/ext/nokogiri/xml_entity_decl.h +0 -10
  213. data/ext/nokogiri/xml_entity_reference.h +0 -9
  214. data/ext/nokogiri/xml_io.c +0 -56
  215. data/ext/nokogiri/xml_io.h +0 -11
  216. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  217. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  218. data/ext/nokogiri/xml_namespace.h +0 -13
  219. data/ext/nokogiri/xml_node.h +0 -13
  220. data/ext/nokogiri/xml_node_set.h +0 -14
  221. data/ext/nokogiri/xml_processing_instruction.h +0 -9
  222. data/ext/nokogiri/xml_reader.h +0 -10
  223. data/ext/nokogiri/xml_relax_ng.h +0 -9
  224. data/ext/nokogiri/xml_sax_parser.h +0 -39
  225. data/ext/nokogiri/xml_sax_parser_context.h +0 -10
  226. data/ext/nokogiri/xml_sax_push_parser.h +0 -9
  227. data/ext/nokogiri/xml_schema.h +0 -9
  228. data/ext/nokogiri/xml_syntax_error.h +0 -13
  229. data/ext/nokogiri/xml_text.h +0 -9
  230. data/ext/nokogiri/xml_xpath_context.h +0 -10
  231. data/ext/nokogiri/xslt_stylesheet.h +0 -14
  232. data/lib/nokogiri/html/document.rb +0 -254
  233. data/lib/nokogiri/html/document_fragment.rb +0 -41
  234. data/lib/nokogiri/html/element_description_defaults.rb +0 -671
  235. data/lib/nokogiri/html/sax/parser_context.rb +0 -16
  236. data/lib/nokogiri/html/sax/push_parser.rb +0 -16
  237. data/tasks/cross_compile.rb +0 -150
  238. data/tasks/nokogiri.org.rb +0 -24
  239. data/tasks/test.rb +0 -95
  240. data/test/css/test_nthiness.rb +0 -159
  241. data/test/css/test_parser.rb +0 -341
  242. data/test/css/test_tokenizer.rb +0 -198
  243. data/test/css/test_xpath_visitor.rb +0 -91
  244. data/test/decorators/test_slop.rb +0 -16
  245. data/test/files/2ch.html +0 -108
  246. data/test/files/address_book.rlx +0 -12
  247. data/test/files/address_book.xml +0 -10
  248. data/test/files/bar/bar.xsd +0 -4
  249. data/test/files/dont_hurt_em_why.xml +0 -422
  250. data/test/files/encoding.html +0 -82
  251. data/test/files/encoding.xhtml +0 -84
  252. data/test/files/exslt.xml +0 -8
  253. data/test/files/exslt.xslt +0 -35
  254. data/test/files/foo/foo.xsd +0 -4
  255. data/test/files/metacharset.html +0 -10
  256. data/test/files/noencoding.html +0 -47
  257. data/test/files/po.xml +0 -32
  258. data/test/files/po.xsd +0 -66
  259. data/test/files/shift_jis.html +0 -10
  260. data/test/files/shift_jis.xml +0 -5
  261. data/test/files/snuggles.xml +0 -3
  262. data/test/files/staff.dtd +0 -10
  263. data/test/files/staff.xml +0 -59
  264. data/test/files/staff.xslt +0 -32
  265. data/test/files/test_document_url/bar.xml +0 -2
  266. data/test/files/test_document_url/document.dtd +0 -4
  267. data/test/files/test_document_url/document.xml +0 -6
  268. data/test/files/tlm.html +0 -850
  269. data/test/files/to_be_xincluded.xml +0 -2
  270. data/test/files/valid_bar.xml +0 -2
  271. data/test/files/xinclude.xml +0 -4
  272. data/test/helper.rb +0 -154
  273. data/test/html/sax/test_parser.rb +0 -141
  274. data/test/html/sax/test_parser_context.rb +0 -46
  275. data/test/html/test_builder.rb +0 -164
  276. data/test/html/test_document.rb +0 -552
  277. data/test/html/test_document_encoding.rb +0 -138
  278. data/test/html/test_document_fragment.rb +0 -261
  279. data/test/html/test_element_description.rb +0 -105
  280. data/test/html/test_named_characters.rb +0 -14
  281. data/test/html/test_node.rb +0 -196
  282. data/test/html/test_node_encoding.rb +0 -27
  283. data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
  284. data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
  285. data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
  286. data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
  287. data/test/test_convert_xpath.rb +0 -135
  288. data/test/test_css_cache.rb +0 -45
  289. data/test/test_encoding_handler.rb +0 -46
  290. data/test/test_memory_leak.rb +0 -156
  291. data/test/test_nokogiri.rb +0 -132
  292. data/test/test_reader.rb +0 -555
  293. data/test/test_soap4r_sax.rb +0 -52
  294. data/test/test_xslt_transforms.rb +0 -254
  295. data/test/xml/node/test_save_options.rb +0 -28
  296. data/test/xml/node/test_subclass.rb +0 -44
  297. data/test/xml/sax/test_parser.rb +0 -366
  298. data/test/xml/sax/test_parser_context.rb +0 -106
  299. data/test/xml/sax/test_push_parser.rb +0 -157
  300. data/test/xml/test_attr.rb +0 -64
  301. data/test/xml/test_attribute_decl.rb +0 -86
  302. data/test/xml/test_builder.rb +0 -306
  303. data/test/xml/test_c14n.rb +0 -151
  304. data/test/xml/test_cdata.rb +0 -48
  305. data/test/xml/test_comment.rb +0 -29
  306. data/test/xml/test_document.rb +0 -828
  307. data/test/xml/test_document_encoding.rb +0 -28
  308. data/test/xml/test_document_fragment.rb +0 -223
  309. data/test/xml/test_dtd.rb +0 -103
  310. data/test/xml/test_dtd_encoding.rb +0 -33
  311. data/test/xml/test_element_content.rb +0 -56
  312. data/test/xml/test_element_decl.rb +0 -73
  313. data/test/xml/test_entity_decl.rb +0 -122
  314. data/test/xml/test_entity_reference.rb +0 -245
  315. data/test/xml/test_namespace.rb +0 -95
  316. data/test/xml/test_node.rb +0 -1137
  317. data/test/xml/test_node_attributes.rb +0 -96
  318. data/test/xml/test_node_encoding.rb +0 -107
  319. data/test/xml/test_node_inheritance.rb +0 -32
  320. data/test/xml/test_node_reparenting.rb +0 -374
  321. data/test/xml/test_node_set.rb +0 -755
  322. data/test/xml/test_parse_options.rb +0 -64
  323. data/test/xml/test_processing_instruction.rb +0 -30
  324. data/test/xml/test_reader_encoding.rb +0 -142
  325. data/test/xml/test_relax_ng.rb +0 -60
  326. data/test/xml/test_schema.rb +0 -103
  327. data/test/xml/test_syntax_error.rb +0 -12
  328. data/test/xml/test_text.rb +0 -45
  329. data/test/xml/test_unparented_node.rb +0 -422
  330. data/test/xml/test_xinclude.rb +0 -83
  331. data/test/xml/test_xpath.rb +0 -295
  332. data/test/xslt/test_custom_functions.rb +0 -133
  333. data/test/xslt/test_exception_handling.rb +0 -37
  334. data/test_all +0 -81
@@ -1,6 +1,7 @@
1
1
  module Nokogiri
2
2
  module CSS
3
- class Tokenizer # :nodoc:
3
+ # :nodoc: all
4
+ class Tokenizer
4
5
 
5
6
  macro
6
7
  nl \n|\r\n|\r|\f
@@ -14,8 +15,8 @@ macro
14
15
  nmstart [_A-Za-z]|{nonascii}|{escape}
15
16
  ident [-@]?({nmstart})({nmchar})*
16
17
  name ({nmchar})+
17
- string1 "([^\n\r\f"]|{nl}|{nonascii}|{escape})*"
18
- string2 '([^\n\r\f']|{nl}|{nonascii}|{escape})*'
18
+ string1 "([^\n\r\f"]|{nl}|{nonascii}|{escape})*(?<!\\)(?:\\{2})*"
19
+ string2 '([^\n\r\f']|{nl}|{nonascii}|{escape})*(?<!\\)(?:\\{2})*'
19
20
  string {string1}|{string2}
20
21
 
21
22
  rule
@@ -34,7 +35,7 @@ rule
34
35
  {w}!={w} { [:NOT_EQUAL, text] }
35
36
  {w}={w} { [:EQUAL, text] }
36
37
  {w}\) { [:RPAREN, text] }
37
- {w}\[{w} { [:LSQUARE, text] }
38
+ \[{w} { [:LSQUARE, text] }
38
39
  {w}\] { [:RSQUARE, text] }
39
40
  {w}\+{w} { [:PLUS, text] }
40
41
  {w}>{w} { [:GREATER, text] }
@@ -44,9 +45,9 @@ rule
44
45
  {num} { [:NUMBER, text] }
45
46
  {w}\/\/{w} { [:DOUBLESLASH, text] }
46
47
  {w}\/{w} { [:SLASH, text] }
47
-
48
+
48
49
  U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})? {[:UNICODE_RANGE, text] }
49
-
50
+
50
51
  [\s]+ { [:S, text] }
51
52
  {string} { [:STRING, text] }
52
53
  . { [text, text] }
@@ -1,52 +1,140 @@
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
3
+
1
4
  module Nokogiri
2
5
  module CSS
3
- class XPathVisitor # :nodoc:
4
- def visit_function node
5
- # note that nth-child and nth-last-child are preprocessed in css/node.rb.
6
- msg = :"visit_function_#{node.value.first.gsub(/[(]/, '')}"
7
- return self.send(msg, node) if self.respond_to?(msg)
6
+ # When translating CSS selectors to XPath queries with Nokogiri::CSS.xpath_for, the XPathVisitor
7
+ # class allows for changing some of the behaviors related to builtin xpath functions and quirks
8
+ # of HTML5.
9
+ class XPathVisitor
10
+ WILDCARD_NAMESPACES = Nokogiri.libxml2_patches.include?("0009-allow-wildcard-namespaces.patch") # :nodoc:
11
+
12
+ # Enum to direct XPathVisitor when to use Nokogiri builtin XPath functions.
13
+ module BuiltinsConfig
14
+ # Never use Nokogiri builtin functions, always generate vanilla XPath 1.0 queries. This is
15
+ # the default when calling Nokogiri::CSS.xpath_for directly.
16
+ NEVER = :never
17
+
18
+ # Always use Nokogiri builtin functions whenever possible. This is probably only useful for testing.
19
+ ALWAYS = :always
20
+
21
+ # Only use Nokogiri builtin functions when they will be faster than vanilla XPath. This is
22
+ # the behavior chosen when searching for CSS selectors on a Nokogiri document, fragment, or
23
+ # node.
24
+ OPTIMAL = :optimal
25
+
26
+ # :nodoc: array of values for validation
27
+ VALUES = [NEVER, ALWAYS, OPTIMAL]
28
+ end
29
+
30
+ # Enum to direct XPathVisitor when to tweak the XPath query to suit the nature of the document
31
+ # being searched. Note that searches for CSS selectors from a Nokogiri document, fragment, or
32
+ # node will choose the correct option automatically.
33
+ module DoctypeConfig
34
+ # The document being searched is an XML document. This is the default.
35
+ XML = :xml
36
+
37
+ # The document being searched is an HTML4 document.
38
+ HTML4 = :html4
39
+
40
+ # The document being searched is an HTML5 document.
41
+ HTML5 = :html5
42
+
43
+ # :nodoc: array of values for validation
44
+ VALUES = [XML, HTML4, HTML5]
45
+ end
46
+
47
+ # :call-seq:
48
+ # new() → XPathVisitor
49
+ # new(builtins:, doctype:) → XPathVisitor
50
+ #
51
+ # [Parameters]
52
+ # - +builtins:+ (BuiltinsConfig) Determine when to use Nokogiri's built-in xpath functions for performance improvements.
53
+ # - +doctype:+ (DoctypeConfig) Make document-type-specific accommodations for CSS queries.
54
+ #
55
+ # [Returns] XPathVisitor
56
+ #
57
+ def initialize(builtins: BuiltinsConfig::NEVER, doctype: DoctypeConfig::XML)
58
+ unless BuiltinsConfig::VALUES.include?(builtins)
59
+ raise(ArgumentError, "Invalid values #{builtins.inspect} for builtins: keyword parameter")
60
+ end
61
+ unless DoctypeConfig::VALUES.include?(doctype)
62
+ raise(ArgumentError, "Invalid values #{doctype.inspect} for doctype: keyword parameter")
63
+ end
64
+
65
+ @builtins = builtins
66
+ @doctype = doctype
67
+ end
68
+
69
+ # :call-seq: config() → Hash
70
+ #
71
+ # [Returns]
72
+ # a Hash representing the configuration of the XPathVisitor, suitable for use as
73
+ # part of the CSS cache key.
74
+ def config
75
+ { builtins: @builtins, doctype: @doctype }
76
+ end
77
+
78
+ # :stopdoc:
79
+ def visit_function(node)
80
+ msg = :"visit_function_#{node.value.first.gsub(/[(]/, "")}"
81
+ return send(msg, node) if respond_to?(msg)
8
82
 
9
83
  case node.value.first
10
84
  when /^text\(/
11
- 'child::text()'
85
+ "child::text()"
12
86
  when /^self\(/
13
87
  "self::#{node.value[1]}"
14
88
  when /^eq\(/
15
- "position() = #{node.value[1]}"
16
- when /^(nth|nth-of-type|nth-child)\(/
17
- if node.value[1].is_a?(Nokogiri::CSS::Node) and node.value[1].type == :AN_PLUS_B
18
- an_plus_b(node.value[1])
89
+ "position()=#{node.value[1]}"
90
+ when /^(nth|nth-of-type)\(/
91
+ if node.value[1].is_a?(Nokogiri::CSS::Node) && (node.value[1].type == :NTH)
92
+ nth(node.value[1])
93
+ else
94
+ "position()=#{node.value[1]}"
95
+ end
96
+ when /^nth-child\(/
97
+ if node.value[1].is_a?(Nokogiri::CSS::Node) && (node.value[1].type == :NTH)
98
+ nth(node.value[1], child: true)
19
99
  else
20
- "position() = #{node.value[1]}"
100
+ "count(preceding-sibling::*)=#{node.value[1].to_i - 1}"
21
101
  end
22
- when /^(nth-last-child|nth-last-of-type)\(/
23
- if node.value[1].is_a?(Nokogiri::CSS::Node) and node.value[1].type == :AN_PLUS_B
24
- an_plus_b(node.value[1], :last => true)
102
+ when /^nth-last-of-type\(/
103
+ if node.value[1].is_a?(Nokogiri::CSS::Node) && (node.value[1].type == :NTH)
104
+ nth(node.value[1], last: true)
25
105
  else
26
106
  index = node.value[1].to_i - 1
27
- index == 0 ? "position() = last()" : "position() = last() - #{index}"
107
+ index == 0 ? "position()=last()" : "position()=last()-#{index}"
108
+ end
109
+ when /^nth-last-child\(/
110
+ if node.value[1].is_a?(Nokogiri::CSS::Node) && (node.value[1].type == :NTH)
111
+ nth(node.value[1], last: true, child: true)
112
+ else
113
+ "count(following-sibling::*)=#{node.value[1].to_i - 1}"
28
114
  end
29
115
  when /^(first|first-of-type)\(/
30
- "position() = 1"
116
+ "position()=1"
31
117
  when /^(last|last-of-type)\(/
32
- "position() = last()"
118
+ "position()=last()"
33
119
  when /^contains\(/
34
- "contains(., #{node.value[1]})"
120
+ "contains(.,#{node.value[1]})"
35
121
  when /^gt\(/
36
- "position() > #{node.value[1]}"
122
+ "position()>#{node.value[1]}"
37
123
  when /^only-child\(/
38
- "last() = 1"
124
+ "last()=1"
39
125
  when /^comment\(/
40
126
  "comment()"
41
127
  when /^has\(/
42
- node.value[1].accept(self)
128
+ is_direct = node.value[1].value[0].nil? # e.g. "has(> a)", "has(~ a)", "has(+ a)"
129
+ ".#{"//" unless is_direct}#{node.value[1].accept(self)}"
43
130
  else
44
- args = ['.'] + node.value[1..-1]
45
- "#{node.value.first}#{args.join(', ')})"
131
+ # non-standard. this looks like a function call.
132
+ args = ["."] + node.value[1..-1]
133
+ "#{node.value.first}#{args.join(",")})"
46
134
  end
47
135
  end
48
136
 
49
- def visit_not node
137
+ def visit_not(node)
50
138
  child = node.value.first
51
139
  if :ELEMENT_NAME == child.type
52
140
  "not(self::#{child.accept(self)})"
@@ -55,61 +143,72 @@ module Nokogiri
55
143
  end
56
144
  end
57
145
 
58
- def visit_id node
146
+ def visit_id(node)
59
147
  node.value.first =~ /^#(.*)$/
60
- "@id = '#{$1}'"
148
+ "@id='#{Regexp.last_match(1)}'"
61
149
  end
62
150
 
63
- def visit_attribute_condition node
64
- attribute = if (node.value.first.type == :FUNCTION) or (node.value.first.value.first =~ /::/)
65
- ''
66
- else
67
- '@'
68
- end
151
+ def visit_attribute_condition(node)
152
+ attribute = if (node.value.first.type == :FUNCTION) || (node.value.first.value.first =~ /::/)
153
+ ""
154
+ else
155
+ "@"
156
+ end
69
157
  attribute += node.value.first.accept(self)
70
158
 
71
- # Support non-standard css
72
- attribute.gsub!(/^@@/, '@')
159
+ # non-standard. attributes starting with '@'
160
+ attribute.gsub!(/^@@/, "@")
73
161
 
74
162
  return attribute unless node.value.length == 3
75
163
 
76
164
  value = node.value.last
77
- value = "'#{value}'" if value !~ /^['"]/
165
+ value = "'#{value}'" unless /^['"]/.match?(value)
166
+
167
+ # quoted values - see test_attribute_value_with_quotes in test/css/test_parser.rb
168
+ if (value[0] == value[-1]) && %q{"'}.include?(value[0])
169
+ str_value = value[1..-2]
170
+ if str_value.include?(value[0])
171
+ value = 'concat("' + str_value.split('"', -1).join(%q{",'"',"}) + '","")'
172
+ end
173
+ end
78
174
 
79
175
  case node.value[1]
80
176
  when :equal
81
- attribute + " = " + "#{value}"
177
+ attribute + "=" + value.to_s
82
178
  when :not_equal
83
- attribute + " != " + "#{value}"
179
+ attribute + "!=" + value.to_s
84
180
  when :substring_match
85
- "contains(#{attribute}, #{value})"
181
+ "contains(#{attribute},#{value})"
86
182
  when :prefix_match
87
- "starts-with(#{attribute}, #{value})"
183
+ "starts-with(#{attribute},#{value})"
88
184
  when :dash_match
89
- "#{attribute} = #{value} or starts-with(#{attribute}, concat(#{value}, '-'))"
185
+ "#{attribute}=#{value} or starts-with(#{attribute},concat(#{value},'-'))"
90
186
  when :includes
91
- "contains(concat(\" \", #{attribute}, \" \"),concat(\" \", #{value}, \" \"))"
187
+ value = value[1..-2] # strip quotes
188
+ css_class(attribute, value)
92
189
  when :suffix_match
93
- "substring(#{attribute}, string-length(#{attribute}) - " +
94
- "string-length(#{value}) + 1, string-length(#{value})) = #{value}"
190
+ "substring(#{attribute},string-length(#{attribute})-string-length(#{value})+1,string-length(#{value}))=#{value}"
95
191
  else
96
- attribute + " #{node.value[1]} " + "#{value}"
192
+ attribute + " #{node.value[1]} " + value.to_s
97
193
  end
98
194
  end
99
195
 
100
- def visit_pseudo_class node
101
- if node.value.first.is_a?(Nokogiri::CSS::Node) and node.value.first.type == :FUNCTION
196
+ def visit_pseudo_class(node)
197
+ if node.value.first.is_a?(Nokogiri::CSS::Node) && (node.value.first.type == :FUNCTION)
102
198
  node.value.first.accept(self)
103
199
  else
104
- msg = :"visit_pseudo_class_#{node.value.first.gsub(/[(]/, '')}"
105
- return self.send(msg, node) if self.respond_to?(msg)
200
+ msg = :"visit_pseudo_class_#{node.value.first.gsub(/[(]/, "")}"
201
+ return send(msg, node) if respond_to?(msg)
106
202
 
107
203
  case node.value.first
108
- when "first", "first-child" then "position() = 1"
109
- when "last", "last-child" then "position() = last()"
110
- when "first-of-type" then "position() = 1"
111
- when "last-of-type" then "position() = last()"
112
- when "only-of-type" then "last() = 1"
204
+ when "first" then "position()=1"
205
+ when "first-child" then "count(preceding-sibling::*)=0"
206
+ when "last" then "position()=last()"
207
+ when "last-child" then "count(following-sibling::*)=0"
208
+ when "first-of-type" then "position()=1"
209
+ when "last-of-type" then "position()=last()"
210
+ when "only-child" then "count(preceding-sibling::*)=0 and count(following-sibling::*)=0"
211
+ when "only-of-type" then "last()=1"
113
212
  when "empty" then "not(node())"
114
213
  when "parent" then "node()"
115
214
  when "root" then "not(parent::*)"
@@ -119,17 +218,24 @@ module Nokogiri
119
218
  end
120
219
  end
121
220
 
122
- def visit_class_condition node
123
- "contains(concat(' ', normalize-space(@class), ' '), ' #{node.value.first} ')"
221
+ def visit_class_condition(node)
222
+ css_class("@class", node.value.first)
223
+ end
224
+
225
+ def visit_combinator(node)
226
+ if is_of_type_pseudo_class?(node.value.last)
227
+ "#{node.value.first&.accept(self)}][#{node.value.last.accept(self)}"
228
+ else
229
+ "#{node.value.first&.accept(self)} and #{node.value.last.accept(self)}"
230
+ end
124
231
  end
125
232
 
126
233
  {
127
- 'combinator' => ' and ',
128
- 'direct_adjacent_selector' => "/following-sibling::*[1]/self::",
129
- 'following_selector' => "/following-sibling::",
130
- 'descendant_selector' => '//',
131
- 'child_selector' => '/',
132
- }.each do |k,v|
234
+ "direct_adjacent_selector" => "/following-sibling::*[1]/self::",
235
+ "following_selector" => "/following-sibling::",
236
+ "descendant_selector" => "//",
237
+ "child_selector" => "/",
238
+ }.each do |k, v|
133
239
  class_eval %{
134
240
  def visit_#{k} node
135
241
  "\#{node.value.first.accept(self) if node.value.first}#{v}\#{node.value.last.accept(self)}"
@@ -137,35 +243,117 @@ module Nokogiri
137
243
  }
138
244
  end
139
245
 
140
- def visit_conditional_selector node
141
- node.value.first.accept(self) + '[' +
142
- node.value.last.accept(self) + ']'
246
+ def visit_conditional_selector(node)
247
+ node.value.first.accept(self) + "[" +
248
+ node.value.last.accept(self) + "]"
249
+ end
250
+
251
+ def visit_element_name(node)
252
+ if @doctype == DoctypeConfig::HTML5 && node.value.first != "*"
253
+ # if there is already a namespace, use it as normal
254
+ return node.value.first if node.value.first.include?(":")
255
+
256
+ # HTML5 has namespaces that should be ignored in CSS queries
257
+ # https://github.com/sparklemotion/nokogiri/issues/2376
258
+ if @builtins == BuiltinsConfig::ALWAYS || (@builtins == BuiltinsConfig::OPTIMAL && Nokogiri.uses_libxml?)
259
+ if WILDCARD_NAMESPACES
260
+ "*:#{node.value.first}"
261
+ else
262
+ "*[nokogiri-builtin:local-name-is('#{node.value.first}')]"
263
+ end
264
+ else
265
+ "*[local-name()='#{node.value.first}']"
266
+ end
267
+ else
268
+ node.value.first
269
+ end
143
270
  end
144
271
 
145
- def visit_element_name node
272
+ def visit_attrib_name(node)
146
273
  node.value.first
147
274
  end
148
275
 
149
- def accept node
276
+ def accept(node)
150
277
  node.accept(self)
151
278
  end
152
279
 
153
- private
154
- def an_plus_b node, options={}
280
+ private
281
+
282
+ def nth(node, options = {})
155
283
  raise ArgumentError, "expected an+b node to contain 4 tokens, but is #{node.value.inspect}" unless node.value.size == 4
156
284
 
157
- a = node.value[0].to_i
158
- b = node.value[3].to_i
159
- position = options[:last] ? "(last()-position()+1)" : "position()"
285
+ a, b = read_a_and_positive_b(node.value)
286
+ position = if options[:child]
287
+ options[:last] ? "(count(following-sibling::*)+1)" : "(count(preceding-sibling::*)+1)"
288
+ else
289
+ options[:last] ? "(last()-position()+1)" : "position()"
290
+ end
291
+
292
+ if b.zero?
293
+ "(#{position} mod #{a})=0"
294
+ else
295
+ compare = a < 0 ? "<=" : ">="
296
+ if a.abs == 1
297
+ "#{position}#{compare}#{b}"
298
+ else
299
+ "(#{position}#{compare}#{b}) and (((#{position}-#{b}) mod #{a.abs})=0)"
300
+ end
301
+ end
302
+ end
303
+
304
+ def read_a_and_positive_b(values)
305
+ op = values[2]
306
+ if op == "+"
307
+ a = values[0].to_i
308
+ b = values[3].to_i
309
+ elsif op == "-"
310
+ a = values[0].to_i
311
+ b = a - (values[3].to_i % a)
312
+ else
313
+ raise ArgumentError, "expected an+b node to have either + or - as the operator, but is #{op.inspect}"
314
+ end
315
+ [a, b]
316
+ end
160
317
 
161
- if (b == 0)
162
- return "(#{position} mod #{a}) = 0"
318
+ def is_of_type_pseudo_class?(node) # rubocop:disable Naming/PredicateName
319
+ if node.type == :PSEUDO_CLASS
320
+ if node.value[0].is_a?(Nokogiri::CSS::Node) && (node.value[0].type == :FUNCTION)
321
+ node.value[0].value[0]
322
+ else
323
+ node.value[0]
324
+ end =~ /(nth|first|last|only)-of-type(\()?/
325
+ end
326
+ end
327
+
328
+ def css_class(hay, needle)
329
+ if @builtins == BuiltinsConfig::ALWAYS || (@builtins == BuiltinsConfig::OPTIMAL && Nokogiri.uses_libxml?)
330
+ # use the builtin implementation
331
+ "nokogiri-builtin:css-class(#{hay},'#{needle}')"
163
332
  else
164
- compare = (a < 0) ? "<=" : ">="
165
- return "(#{position} #{compare} #{b}) and (((#{position}-#{b}) mod #{a.abs}) = 0)"
333
+ # use only ordinary xpath functions
334
+ "contains(concat(' ',normalize-space(#{hay}),' '),' #{needle} ')"
166
335
  end
167
336
  end
337
+ end
168
338
 
339
+ module XPathVisitorAlwaysUseBuiltins # :nodoc:
340
+ def self.new
341
+ warn(
342
+ "Nokogiri::CSS::XPathVisitorAlwaysUseBuiltins is deprecated and will be removed in a future version of Nokogiri",
343
+ { uplevel: 1 },
344
+ )
345
+ XPathVisitor.new(builtins: :always)
346
+ end
347
+ end
348
+
349
+ module XPathVisitorOptimallyUseBuiltins # :nodoc:
350
+ def self.new
351
+ warn(
352
+ "Nokogiri::CSS::XPathVisitorOptimallyUseBuiltins is deprecated and will be removed in a future version of Nokogiri",
353
+ { uplevel: 1 },
354
+ )
355
+ XPathVisitor.new(builtins: :optimal)
356
+ end
169
357
  end
170
358
  end
171
359
  end
data/lib/nokogiri/css.rb CHANGED
@@ -1,27 +1,60 @@
1
- require 'nokogiri/css/node'
2
- require 'nokogiri/css/xpath_visitor'
3
- x = $-w
4
- $-w = false
5
- require 'nokogiri/css/parser'
6
- $-w = x
7
-
8
- require 'nokogiri/css/tokenizer'
9
- require 'nokogiri/css/syntax_error'
1
+ # coding: utf-8
2
+ # frozen_string_literal: true
10
3
 
11
4
  module Nokogiri
5
+ # Translate a CSS selector into an XPath 1.0 query
12
6
  module CSS
13
7
  class << self
14
- ###
15
- # Parse this CSS selector in +selector+. Returns an AST.
16
- def parse selector
17
- Parser.new.parse selector
8
+ # TODO: Deprecate this method ahead of 2.0 and delete it in 2.0.
9
+ # It is not used by Nokogiri and shouldn't be part of the public API.
10
+ def parse(selector) # :nodoc:
11
+ Parser.new.parse(selector)
18
12
  end
19
13
 
20
- ###
21
- # Get the XPath for +selector+.
22
- def xpath_for selector, options={}
23
- Parser.new(options[:ns] || {}).xpath_for selector, options
14
+ # :call-seq:
15
+ # xpath_for(selector) String
16
+ # xpath_for(selector [, prefix:] [, visitor:] [, ns:]) → String
17
+ #
18
+ # Translate a CSS selector to the equivalent XPath query.
19
+ #
20
+ # [Parameters]
21
+ # - +selector+ (String) The CSS selector to be translated into XPath
22
+ #
23
+ # - +prefix:+ (String)
24
+ #
25
+ # The XPath prefix for the query, see Nokogiri::XML::XPath for some options. Default is
26
+ # +XML::XPath::GLOBAL_SEARCH_PREFIX+.
27
+ #
28
+ # - +visitor:+ (Nokogiri::CSS::XPathVisitor)
29
+ #
30
+ # The visitor class to use to transform the AST into XPath. Default is
31
+ # +Nokogiri::CSS::XPathVisitor.new+.
32
+ #
33
+ # - +ns:+ (Hash<String ⇒ String>)
34
+ #
35
+ # The namespaces that are referenced in the query, if any. This is a hash where the keys are
36
+ # the namespace prefix and the values are the namespace URIs. Default is an empty Hash.
37
+ #
38
+ # [Returns] (String) The equivalent XPath query for +selector+
39
+ #
40
+ # 💡 Note that translated queries are cached for performance concerns.
41
+ #
42
+ def xpath_for(selector, options = {})
43
+ prefix = options.fetch(:prefix, Nokogiri::XML::XPath::GLOBAL_SEARCH_PREFIX)
44
+ visitor = options.fetch(:visitor) { Nokogiri::CSS::XPathVisitor.new }
45
+ ns = options.fetch(:ns, {})
46
+ Parser.new(ns).xpath_for(selector, prefix, visitor)
24
47
  end
25
48
  end
26
49
  end
27
50
  end
51
+
52
+ require_relative "css/node"
53
+ require_relative "css/xpath_visitor"
54
+ x = $-w
55
+ $-w = false
56
+ require_relative "css/parser"
57
+ $-w = x
58
+
59
+ require_relative "css/tokenizer"
60
+ require_relative "css/syntax_error"
@@ -1,28 +1,31 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Nokogiri
2
4
  module Decorators
3
5
  ###
4
6
  # The Slop decorator implements method missing such that a methods may be
5
7
  # used instead of XPath or CSS. See Nokogiri.Slop
6
8
  module Slop
9
+ # The default XPath search context for Slop
10
+ XPATH_PREFIX = "./"
11
+
7
12
  ###
8
13
  # look for node with +name+. See Nokogiri.Slop
9
- def method_missing name, *args, &block
10
- prefix = implied_xpath_context
11
-
14
+ def method_missing(name, *args, &block)
12
15
  if args.empty?
13
- list = xpath("#{prefix}#{name.to_s.sub(/^_/, '')}")
14
- elsif args.first.is_a? Hash
16
+ list = xpath("#{XPATH_PREFIX}#{name.to_s.sub(/^_/, "")}")
17
+ elsif args.first.is_a?(Hash)
15
18
  hash = args.first
16
19
  if hash[:css]
17
20
  list = css("#{name}#{hash[:css]}")
18
21
  elsif hash[:xpath]
19
- conds = Array(hash[:xpath]).join(' and ')
20
- list = xpath("#{prefix}#{name}[#{conds}]")
22
+ conds = Array(hash[:xpath]).join(" and ")
23
+ list = xpath("#{XPATH_PREFIX}#{name}[#{conds}]")
21
24
  end
22
25
  else
23
26
  CSS::Parser.without_cache do
24
27
  list = xpath(
25
- *CSS.xpath_for("#{name}#{args.first}", :prefix => prefix)
28
+ *CSS.xpath_for("#{name}#{args.first}", prefix: XPATH_PREFIX)
26
29
  )
27
30
  end
28
31
  end
@@ -30,6 +33,12 @@ module Nokogiri
30
33
  super if list.empty?
31
34
  list.length == 1 ? list.first : list
32
35
  end
36
+
37
+ def respond_to_missing?(name, include_private = false)
38
+ list = xpath("#{XPATH_PREFIX}#{name.to_s.sub(/^_/, "")}")
39
+
40
+ !list.empty?
41
+ end
33
42
  end
34
43
  end
35
44
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ # load the C or Java extension
4
+ begin
5
+ # native precompiled gems package shared libraries in <gem_dir>/lib/nokogiri/<ruby_version>
6
+ ::RUBY_VERSION =~ /(\d+\.\d+)/
7
+ require_relative "#{Regexp.last_match(1)}/nokogiri"
8
+ rescue LoadError => e
9
+ if /GLIBC/.match?(e.message)
10
+ warn(<<~EOM)
11
+
12
+ ERROR: It looks like you're trying to use Nokogiri as a precompiled native gem on a system with glibc < 2.17:
13
+
14
+ #{e.message}
15
+
16
+ If that's the case, then please install Nokogiri via the `ruby` platform gem:
17
+ gem install nokogiri --platform=ruby
18
+ or:
19
+ bundle config set force_ruby_platform true
20
+
21
+ Please visit https://nokogiri.org/tutorials/installing_nokogiri.html for more help.
22
+
23
+ EOM
24
+ raise e
25
+ end
26
+
27
+ # use "require" instead of "require_relative" because non-native gems will place C extension files
28
+ # in Gem::BasicSpecification#extension_dir after compilation (during normal installation), which
29
+ # is in $LOAD_PATH but not necessarily relative to this file (see #2300)
30
+ require "nokogiri/nokogiri"
31
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nokogiri
4
+ module Gumbo
5
+ # The default maximum number of attributes per element.
6
+ DEFAULT_MAX_ATTRIBUTES = 400
7
+
8
+ # The default maximum number of errors for parsing a document or a fragment.
9
+ DEFAULT_MAX_ERRORS = 0
10
+
11
+ # The default maximum depth of the DOM tree produced by parsing a document
12
+ # or fragment.
13
+ DEFAULT_MAX_TREE_DEPTH = 400
14
+ end
15
+ end