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.
- checksums.yaml +7 -0
- data/Gemfile +5 -0
- data/LICENSE-DEPENDENCIES.md +1903 -0
- data/LICENSE.md +9 -0
- data/README.md +280 -0
- data/bin/nokogiri +84 -31
- data/dependencies.yml +73 -0
- data/ext/nokogiri/depend +38 -358
- data/ext/nokogiri/extconf.rb +956 -100
- data/ext/nokogiri/gumbo.c +584 -0
- data/ext/nokogiri/html4_document.c +166 -0
- data/ext/nokogiri/html4_element_description.c +294 -0
- data/ext/nokogiri/html4_entity_lookup.c +37 -0
- data/ext/nokogiri/html4_sax_parser_context.c +120 -0
- data/ext/nokogiri/html4_sax_push_parser.c +95 -0
- data/ext/nokogiri/libxml2_backwards_compat.c +121 -0
- data/ext/nokogiri/nokogiri.c +232 -87
- data/ext/nokogiri/nokogiri.h +188 -129
- data/ext/nokogiri/test_global_handlers.c +40 -0
- data/ext/nokogiri/xml_attr.c +49 -40
- data/ext/nokogiri/xml_attribute_decl.c +18 -18
- data/ext/nokogiri/xml_cdata.c +24 -23
- data/ext/nokogiri/xml_comment.c +29 -21
- data/ext/nokogiri/xml_document.c +327 -223
- data/ext/nokogiri/xml_document_fragment.c +12 -16
- data/ext/nokogiri/xml_dtd.c +56 -50
- data/ext/nokogiri/xml_element_content.c +31 -26
- data/ext/nokogiri/xml_element_decl.c +22 -22
- data/ext/nokogiri/xml_encoding_handler.c +45 -20
- data/ext/nokogiri/xml_entity_decl.c +32 -30
- data/ext/nokogiri/xml_entity_reference.c +16 -18
- data/ext/nokogiri/xml_namespace.c +74 -32
- data/ext/nokogiri/xml_node.c +1290 -680
- data/ext/nokogiri/xml_node_set.c +239 -208
- data/ext/nokogiri/xml_processing_instruction.c +17 -19
- data/ext/nokogiri/xml_reader.c +227 -189
- data/ext/nokogiri/xml_relax_ng.c +52 -28
- data/ext/nokogiri/xml_sax_parser.c +123 -125
- data/ext/nokogiri/xml_sax_parser_context.c +138 -79
- data/ext/nokogiri/xml_sax_push_parser.c +88 -35
- data/ext/nokogiri/xml_schema.c +112 -33
- data/ext/nokogiri/xml_syntax_error.c +50 -23
- data/ext/nokogiri/xml_text.c +14 -18
- data/ext/nokogiri/xml_xpath_context.c +227 -140
- data/ext/nokogiri/xslt_stylesheet.c +162 -168
- data/gumbo-parser/CHANGES.md +63 -0
- data/gumbo-parser/Makefile +101 -0
- data/gumbo-parser/THANKS +27 -0
- data/gumbo-parser/src/Makefile +34 -0
- data/gumbo-parser/src/README.md +41 -0
- data/gumbo-parser/src/ascii.c +75 -0
- data/gumbo-parser/src/ascii.h +115 -0
- data/gumbo-parser/src/attribute.c +42 -0
- data/gumbo-parser/src/attribute.h +17 -0
- data/gumbo-parser/src/char_ref.c +22225 -0
- data/gumbo-parser/src/char_ref.h +29 -0
- data/gumbo-parser/src/char_ref.rl +2154 -0
- data/gumbo-parser/src/error.c +626 -0
- data/gumbo-parser/src/error.h +148 -0
- data/gumbo-parser/src/foreign_attrs.c +104 -0
- data/gumbo-parser/src/foreign_attrs.gperf +27 -0
- data/gumbo-parser/src/gumbo.h +943 -0
- data/gumbo-parser/src/insertion_mode.h +33 -0
- data/gumbo-parser/src/macros.h +91 -0
- data/gumbo-parser/src/parser.c +4875 -0
- data/gumbo-parser/src/parser.h +41 -0
- data/gumbo-parser/src/replacement.h +33 -0
- data/gumbo-parser/src/string_buffer.c +103 -0
- data/gumbo-parser/src/string_buffer.h +68 -0
- data/gumbo-parser/src/string_piece.c +48 -0
- data/gumbo-parser/src/svg_attrs.c +174 -0
- data/gumbo-parser/src/svg_attrs.gperf +77 -0
- data/gumbo-parser/src/svg_tags.c +137 -0
- data/gumbo-parser/src/svg_tags.gperf +55 -0
- data/gumbo-parser/src/tag.c +222 -0
- data/gumbo-parser/src/tag_lookup.c +382 -0
- data/gumbo-parser/src/tag_lookup.gperf +169 -0
- data/gumbo-parser/src/tag_lookup.h +13 -0
- data/gumbo-parser/src/token_buffer.c +79 -0
- data/gumbo-parser/src/token_buffer.h +71 -0
- data/gumbo-parser/src/token_type.h +17 -0
- data/gumbo-parser/src/tokenizer.c +3463 -0
- data/gumbo-parser/src/tokenizer.h +112 -0
- data/gumbo-parser/src/tokenizer_states.h +339 -0
- data/gumbo-parser/src/utf8.c +245 -0
- data/gumbo-parser/src/utf8.h +164 -0
- data/gumbo-parser/src/util.c +68 -0
- data/gumbo-parser/src/util.h +30 -0
- data/gumbo-parser/src/vector.c +111 -0
- data/gumbo-parser/src/vector.h +45 -0
- data/lib/nokogiri/class_resolver.rb +67 -0
- data/lib/nokogiri/css/node.rb +10 -58
- data/lib/nokogiri/css/parser.rb +327 -288
- data/lib/nokogiri/css/parser.y +67 -45
- data/lib/nokogiri/css/parser_extras.rb +52 -49
- data/lib/nokogiri/css/syntax_error.rb +3 -1
- data/lib/nokogiri/css/tokenizer.rb +107 -104
- data/lib/nokogiri/css/tokenizer.rex +7 -6
- data/lib/nokogiri/css/xpath_visitor.rb +263 -75
- data/lib/nokogiri/css.rb +50 -17
- data/lib/nokogiri/decorators/slop.rb +17 -8
- data/lib/nokogiri/extension.rb +31 -0
- data/lib/nokogiri/gumbo.rb +15 -0
- data/lib/nokogiri/html.rb +38 -27
- data/lib/nokogiri/{html → html4}/builder.rb +4 -2
- data/lib/nokogiri/html4/document.rb +331 -0
- data/lib/nokogiri/html4/document_fragment.rb +54 -0
- data/lib/nokogiri/{html → html4}/element_description.rb +3 -1
- data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
- data/lib/nokogiri/{html → html4}/entity_lookup.rb +4 -2
- data/lib/nokogiri/{html → html4}/sax/parser.rb +24 -15
- data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
- data/lib/nokogiri/html4/sax/push_parser.rb +37 -0
- data/lib/nokogiri/html4.rb +46 -0
- data/lib/nokogiri/html5/document.rb +88 -0
- data/lib/nokogiri/html5/document_fragment.rb +83 -0
- data/lib/nokogiri/html5/node.rb +96 -0
- data/lib/nokogiri/html5.rb +477 -0
- data/lib/nokogiri/jruby/dependencies.rb +21 -0
- data/lib/nokogiri/syntax_error.rb +2 -0
- data/lib/nokogiri/version/constant.rb +6 -0
- data/lib/nokogiri/version/info.rb +221 -0
- data/lib/nokogiri/version.rb +3 -90
- data/lib/nokogiri/xml/attr.rb +6 -3
- data/lib/nokogiri/xml/attribute_decl.rb +3 -1
- data/lib/nokogiri/xml/builder.rb +96 -54
- data/lib/nokogiri/xml/cdata.rb +3 -1
- data/lib/nokogiri/xml/character_data.rb +2 -0
- data/lib/nokogiri/xml/document.rb +234 -95
- data/lib/nokogiri/xml/document_fragment.rb +86 -36
- data/lib/nokogiri/xml/dtd.rb +16 -4
- data/lib/nokogiri/xml/element_content.rb +2 -0
- data/lib/nokogiri/xml/element_decl.rb +3 -1
- data/lib/nokogiri/xml/entity_decl.rb +4 -2
- data/lib/nokogiri/xml/entity_reference.rb +20 -0
- data/lib/nokogiri/xml/namespace.rb +3 -0
- data/lib/nokogiri/xml/node/save_options.rb +8 -4
- data/lib/nokogiri/xml/node.rb +947 -502
- data/lib/nokogiri/xml/node_set.rb +168 -159
- data/lib/nokogiri/xml/notation.rb +13 -0
- data/lib/nokogiri/xml/parse_options.rb +40 -5
- data/lib/nokogiri/xml/pp/character_data.rb +9 -6
- data/lib/nokogiri/xml/pp/node.rb +25 -26
- data/lib/nokogiri/xml/pp.rb +4 -2
- data/lib/nokogiri/xml/processing_instruction.rb +3 -1
- data/lib/nokogiri/xml/reader.rb +23 -28
- data/lib/nokogiri/xml/relax_ng.rb +8 -2
- data/lib/nokogiri/xml/sax/document.rb +45 -49
- data/lib/nokogiri/xml/sax/parser.rb +43 -41
- data/lib/nokogiri/xml/sax/parser_context.rb +8 -3
- data/lib/nokogiri/xml/sax/push_parser.rb +6 -5
- data/lib/nokogiri/xml/sax.rb +6 -4
- data/lib/nokogiri/xml/schema.rb +19 -9
- data/lib/nokogiri/xml/searchable.rb +259 -0
- data/lib/nokogiri/xml/syntax_error.rb +25 -1
- data/lib/nokogiri/xml/text.rb +2 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +4 -2
- data/lib/nokogiri/xml/xpath.rb +15 -4
- data/lib/nokogiri/xml/xpath_context.rb +3 -3
- data/lib/nokogiri/xml.rb +38 -36
- data/lib/nokogiri/xslt/stylesheet.rb +3 -1
- data/lib/nokogiri/xslt.rb +18 -16
- data/lib/nokogiri.rb +69 -69
- data/lib/xsd/xmlparser/nokogiri.rb +26 -24
- data/patches/libxml2/0001-Remove-script-macro-support.patch +40 -0
- data/patches/libxml2/0002-Update-entities-to-remove-handling-of-ssi.patch +44 -0
- data/patches/libxml2/0003-libxml2.la-is-in-top_builddir.patch +25 -0
- data/patches/libxml2/0004-use-glibc-strlen.patch +53 -0
- data/patches/libxml2/0005-avoid-isnan-isinf.patch +81 -0
- data/patches/libxml2/0006-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxml2/0007-Fix-XPath-recursion-limit.patch +31 -0
- data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
- data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
- data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2511 -0
- data/patches/libxslt/0002-Fix-xml2-config-check-in-configure-script.patch +19 -0
- data/ports/archives/libxml2-2.9.12.tar.gz +0 -0
- data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
- metadata +382 -460
- data/.autotest +0 -26
- data/.gemtest +0 -0
- data/CHANGELOG.ja.rdoc +0 -785
- data/CHANGELOG.rdoc +0 -783
- data/C_CODING_STYLE.rdoc +0 -33
- data/Manifest.txt +0 -303
- data/README.ja.rdoc +0 -106
- data/README.rdoc +0 -175
- data/ROADMAP.md +0 -90
- data/Rakefile +0 -228
- data/STANDARD_RESPONSES.md +0 -47
- data/Y_U_NO_GEMSPEC.md +0 -155
- data/build_all +0 -105
- data/ext/nokogiri/html_document.c +0 -170
- data/ext/nokogiri/html_document.h +0 -10
- data/ext/nokogiri/html_element_description.c +0 -279
- data/ext/nokogiri/html_element_description.h +0 -10
- data/ext/nokogiri/html_entity_lookup.c +0 -32
- data/ext/nokogiri/html_entity_lookup.h +0 -8
- data/ext/nokogiri/html_sax_parser_context.c +0 -116
- data/ext/nokogiri/html_sax_parser_context.h +0 -11
- data/ext/nokogiri/html_sax_push_parser.c +0 -87
- data/ext/nokogiri/html_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_attr.h +0 -9
- data/ext/nokogiri/xml_attribute_decl.h +0 -9
- data/ext/nokogiri/xml_cdata.h +0 -9
- data/ext/nokogiri/xml_comment.h +0 -9
- data/ext/nokogiri/xml_document.h +0 -23
- data/ext/nokogiri/xml_document_fragment.h +0 -10
- data/ext/nokogiri/xml_dtd.h +0 -10
- data/ext/nokogiri/xml_element_content.h +0 -10
- data/ext/nokogiri/xml_element_decl.h +0 -9
- data/ext/nokogiri/xml_encoding_handler.h +0 -8
- data/ext/nokogiri/xml_entity_decl.h +0 -10
- data/ext/nokogiri/xml_entity_reference.h +0 -9
- data/ext/nokogiri/xml_io.c +0 -56
- data/ext/nokogiri/xml_io.h +0 -11
- data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
- data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
- data/ext/nokogiri/xml_namespace.h +0 -13
- data/ext/nokogiri/xml_node.h +0 -13
- data/ext/nokogiri/xml_node_set.h +0 -14
- data/ext/nokogiri/xml_processing_instruction.h +0 -9
- data/ext/nokogiri/xml_reader.h +0 -10
- data/ext/nokogiri/xml_relax_ng.h +0 -9
- data/ext/nokogiri/xml_sax_parser.h +0 -39
- data/ext/nokogiri/xml_sax_parser_context.h +0 -10
- data/ext/nokogiri/xml_sax_push_parser.h +0 -9
- data/ext/nokogiri/xml_schema.h +0 -9
- data/ext/nokogiri/xml_syntax_error.h +0 -13
- data/ext/nokogiri/xml_text.h +0 -9
- data/ext/nokogiri/xml_xpath_context.h +0 -10
- data/ext/nokogiri/xslt_stylesheet.h +0 -14
- data/lib/nokogiri/html/document.rb +0 -254
- data/lib/nokogiri/html/document_fragment.rb +0 -41
- data/lib/nokogiri/html/element_description_defaults.rb +0 -671
- data/lib/nokogiri/html/sax/parser_context.rb +0 -16
- data/lib/nokogiri/html/sax/push_parser.rb +0 -16
- data/tasks/cross_compile.rb +0 -150
- data/tasks/nokogiri.org.rb +0 -24
- data/tasks/test.rb +0 -95
- data/test/css/test_nthiness.rb +0 -159
- data/test/css/test_parser.rb +0 -341
- data/test/css/test_tokenizer.rb +0 -198
- data/test/css/test_xpath_visitor.rb +0 -91
- data/test/decorators/test_slop.rb +0 -16
- data/test/files/2ch.html +0 -108
- data/test/files/address_book.rlx +0 -12
- data/test/files/address_book.xml +0 -10
- data/test/files/bar/bar.xsd +0 -4
- data/test/files/dont_hurt_em_why.xml +0 -422
- data/test/files/encoding.html +0 -82
- data/test/files/encoding.xhtml +0 -84
- data/test/files/exslt.xml +0 -8
- data/test/files/exslt.xslt +0 -35
- data/test/files/foo/foo.xsd +0 -4
- data/test/files/metacharset.html +0 -10
- data/test/files/noencoding.html +0 -47
- data/test/files/po.xml +0 -32
- data/test/files/po.xsd +0 -66
- data/test/files/shift_jis.html +0 -10
- data/test/files/shift_jis.xml +0 -5
- data/test/files/snuggles.xml +0 -3
- data/test/files/staff.dtd +0 -10
- data/test/files/staff.xml +0 -59
- data/test/files/staff.xslt +0 -32
- data/test/files/test_document_url/bar.xml +0 -2
- data/test/files/test_document_url/document.dtd +0 -4
- data/test/files/test_document_url/document.xml +0 -6
- data/test/files/tlm.html +0 -850
- data/test/files/to_be_xincluded.xml +0 -2
- data/test/files/valid_bar.xml +0 -2
- data/test/files/xinclude.xml +0 -4
- data/test/helper.rb +0 -154
- data/test/html/sax/test_parser.rb +0 -141
- data/test/html/sax/test_parser_context.rb +0 -46
- data/test/html/test_builder.rb +0 -164
- data/test/html/test_document.rb +0 -552
- data/test/html/test_document_encoding.rb +0 -138
- data/test/html/test_document_fragment.rb +0 -261
- data/test/html/test_element_description.rb +0 -105
- data/test/html/test_named_characters.rb +0 -14
- data/test/html/test_node.rb +0 -196
- data/test/html/test_node_encoding.rb +0 -27
- data/test/namespaces/test_additional_namespaces_in_builder_doc.rb +0 -14
- data/test/namespaces/test_namespaces_in_builder_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_created_doc.rb +0 -75
- data/test/namespaces/test_namespaces_in_parsed_doc.rb +0 -66
- data/test/test_convert_xpath.rb +0 -135
- data/test/test_css_cache.rb +0 -45
- data/test/test_encoding_handler.rb +0 -46
- data/test/test_memory_leak.rb +0 -156
- data/test/test_nokogiri.rb +0 -132
- data/test/test_reader.rb +0 -555
- data/test/test_soap4r_sax.rb +0 -52
- data/test/test_xslt_transforms.rb +0 -254
- data/test/xml/node/test_save_options.rb +0 -28
- data/test/xml/node/test_subclass.rb +0 -44
- data/test/xml/sax/test_parser.rb +0 -366
- data/test/xml/sax/test_parser_context.rb +0 -106
- data/test/xml/sax/test_push_parser.rb +0 -157
- data/test/xml/test_attr.rb +0 -64
- data/test/xml/test_attribute_decl.rb +0 -86
- data/test/xml/test_builder.rb +0 -306
- data/test/xml/test_c14n.rb +0 -151
- data/test/xml/test_cdata.rb +0 -48
- data/test/xml/test_comment.rb +0 -29
- data/test/xml/test_document.rb +0 -828
- data/test/xml/test_document_encoding.rb +0 -28
- data/test/xml/test_document_fragment.rb +0 -223
- data/test/xml/test_dtd.rb +0 -103
- data/test/xml/test_dtd_encoding.rb +0 -33
- data/test/xml/test_element_content.rb +0 -56
- data/test/xml/test_element_decl.rb +0 -73
- data/test/xml/test_entity_decl.rb +0 -122
- data/test/xml/test_entity_reference.rb +0 -245
- data/test/xml/test_namespace.rb +0 -95
- data/test/xml/test_node.rb +0 -1137
- data/test/xml/test_node_attributes.rb +0 -96
- data/test/xml/test_node_encoding.rb +0 -107
- data/test/xml/test_node_inheritance.rb +0 -32
- data/test/xml/test_node_reparenting.rb +0 -374
- data/test/xml/test_node_set.rb +0 -755
- data/test/xml/test_parse_options.rb +0 -64
- data/test/xml/test_processing_instruction.rb +0 -30
- data/test/xml/test_reader_encoding.rb +0 -142
- data/test/xml/test_relax_ng.rb +0 -60
- data/test/xml/test_schema.rb +0 -103
- data/test/xml/test_syntax_error.rb +0 -12
- data/test/xml/test_text.rb +0 -45
- data/test/xml/test_unparented_node.rb +0 -422
- data/test/xml/test_xinclude.rb +0 -83
- data/test/xml/test_xpath.rb +0 -295
- data/test/xslt/test_custom_functions.rb +0 -133
- data/test/xslt/test_exception_handling.rb +0 -37
- data/test_all +0 -81
@@ -1,6 +1,7 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module CSS
|
3
|
-
|
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
|
-
|
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
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
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
|
-
|
85
|
+
"child::text()"
|
12
86
|
when /^self\(/
|
13
87
|
"self::#{node.value[1]}"
|
14
88
|
when /^eq\(/
|
15
|
-
"position()
|
16
|
-
when /^(nth|nth-of-type
|
17
|
-
if node.value[1].is_a?(Nokogiri::CSS::Node)
|
18
|
-
|
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
|
-
"
|
100
|
+
"count(preceding-sibling::*)=#{node.value[1].to_i - 1}"
|
21
101
|
end
|
22
|
-
when /^
|
23
|
-
if node.value[1].is_a?(Nokogiri::CSS::Node)
|
24
|
-
|
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()
|
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()
|
116
|
+
"position()=1"
|
31
117
|
when /^(last|last-of-type)\(/
|
32
|
-
"position()
|
118
|
+
"position()=last()"
|
33
119
|
when /^contains\(/
|
34
|
-
"contains(
|
120
|
+
"contains(.,#{node.value[1]})"
|
35
121
|
when /^gt\(/
|
36
|
-
"position()
|
122
|
+
"position()>#{node.value[1]}"
|
37
123
|
when /^only-child\(/
|
38
|
-
"last()
|
124
|
+
"last()=1"
|
39
125
|
when /^comment\(/
|
40
126
|
"comment()"
|
41
127
|
when /^has\(/
|
42
|
-
node.value[1].
|
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
|
-
|
45
|
-
"
|
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
|
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
|
146
|
+
def visit_id(node)
|
59
147
|
node.value.first =~ /^#(.*)$/
|
60
|
-
"@id
|
148
|
+
"@id='#{Regexp.last_match(1)}'"
|
61
149
|
end
|
62
150
|
|
63
|
-
def visit_attribute_condition
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
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
|
-
#
|
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}'"
|
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 + "
|
177
|
+
attribute + "=" + value.to_s
|
82
178
|
when :not_equal
|
83
|
-
attribute + "
|
179
|
+
attribute + "!=" + value.to_s
|
84
180
|
when :substring_match
|
85
|
-
"contains(#{attribute}
|
181
|
+
"contains(#{attribute},#{value})"
|
86
182
|
when :prefix_match
|
87
|
-
"starts-with(#{attribute}
|
183
|
+
"starts-with(#{attribute},#{value})"
|
88
184
|
when :dash_match
|
89
|
-
"#{attribute}
|
185
|
+
"#{attribute}=#{value} or starts-with(#{attribute},concat(#{value},'-'))"
|
90
186
|
when :includes
|
91
|
-
|
187
|
+
value = value[1..-2] # strip quotes
|
188
|
+
css_class(attribute, value)
|
92
189
|
when :suffix_match
|
93
|
-
"substring(#{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]} " +
|
192
|
+
attribute + " #{node.value[1]} " + value.to_s
|
97
193
|
end
|
98
194
|
end
|
99
195
|
|
100
|
-
def visit_pseudo_class
|
101
|
-
if node.value.first.is_a?(Nokogiri::CSS::Node)
|
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
|
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"
|
109
|
-
when "
|
110
|
-
when "
|
111
|
-
when "last-
|
112
|
-
when "
|
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
|
123
|
-
"
|
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
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
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
|
141
|
-
node.value.first.accept(self) +
|
142
|
-
|
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
|
272
|
+
def visit_attrib_name(node)
|
146
273
|
node.value.first
|
147
274
|
end
|
148
275
|
|
149
|
-
def accept
|
276
|
+
def accept(node)
|
150
277
|
node.accept(self)
|
151
278
|
end
|
152
279
|
|
153
|
-
|
154
|
-
|
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
|
158
|
-
|
159
|
-
|
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
|
-
|
162
|
-
|
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
|
-
|
165
|
-
|
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
|
-
|
2
|
-
|
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
|
-
#
|
16
|
-
def parse
|
17
|
-
Parser.new.parse
|
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
|
-
#
|
22
|
-
|
23
|
-
|
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
|
10
|
-
prefix = implied_xpath_context
|
11
|
-
|
14
|
+
def method_missing(name, *args, &block)
|
12
15
|
if args.empty?
|
13
|
-
list = xpath("#{
|
14
|
-
elsif args.first.is_a?
|
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(
|
20
|
-
list = xpath("#{
|
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}", :
|
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
|