nokogiri 1.11.3 → 1.13.8

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 (179) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -0
  3. data/LICENSE-DEPENDENCIES.md +243 -22
  4. data/LICENSE.md +1 -1
  5. data/README.md +14 -11
  6. data/bin/nokogiri +63 -50
  7. data/dependencies.yml +13 -64
  8. data/ext/nokogiri/depend +35 -34
  9. data/ext/nokogiri/extconf.rb +237 -133
  10. data/ext/nokogiri/gumbo.c +584 -0
  11. data/ext/nokogiri/{html_document.c → html4_document.c} +8 -8
  12. data/ext/nokogiri/{html_element_description.c → html4_element_description.c} +21 -19
  13. data/ext/nokogiri/{html_entity_lookup.c → html4_entity_lookup.c} +7 -7
  14. data/ext/nokogiri/{html_sax_parser_context.c → html4_sax_parser_context.c} +8 -8
  15. data/ext/nokogiri/{html_sax_push_parser.c → html4_sax_push_parser.c} +4 -4
  16. data/ext/nokogiri/libxml2_backwards_compat.c +30 -30
  17. data/ext/nokogiri/nokogiri.c +70 -38
  18. data/ext/nokogiri/nokogiri.h +27 -9
  19. data/ext/nokogiri/xml_attr.c +2 -2
  20. data/ext/nokogiri/xml_attribute_decl.c +3 -3
  21. data/ext/nokogiri/xml_cdata.c +1 -1
  22. data/ext/nokogiri/xml_document.c +50 -50
  23. data/ext/nokogiri/xml_document_fragment.c +0 -2
  24. data/ext/nokogiri/xml_dtd.c +10 -10
  25. data/ext/nokogiri/xml_element_content.c +2 -0
  26. data/ext/nokogiri/xml_element_decl.c +3 -3
  27. data/ext/nokogiri/xml_encoding_handler.c +31 -12
  28. data/ext/nokogiri/xml_entity_decl.c +5 -5
  29. data/ext/nokogiri/xml_namespace.c +4 -2
  30. data/ext/nokogiri/xml_node.c +833 -492
  31. data/ext/nokogiri/xml_node_set.c +24 -24
  32. data/ext/nokogiri/xml_reader.c +90 -11
  33. data/ext/nokogiri/xml_sax_parser.c +6 -6
  34. data/ext/nokogiri/xml_sax_parser_context.c +12 -3
  35. data/ext/nokogiri/xml_schema.c +5 -3
  36. data/ext/nokogiri/xml_text.c +1 -1
  37. data/ext/nokogiri/xml_xpath_context.c +110 -85
  38. data/ext/nokogiri/xslt_stylesheet.c +109 -10
  39. data/gumbo-parser/CHANGES.md +63 -0
  40. data/gumbo-parser/Makefile +101 -0
  41. data/gumbo-parser/THANKS +27 -0
  42. data/gumbo-parser/src/Makefile +34 -0
  43. data/gumbo-parser/src/README.md +41 -0
  44. data/gumbo-parser/src/ascii.c +75 -0
  45. data/gumbo-parser/src/ascii.h +115 -0
  46. data/gumbo-parser/src/attribute.c +42 -0
  47. data/gumbo-parser/src/attribute.h +17 -0
  48. data/gumbo-parser/src/char_ref.c +22225 -0
  49. data/gumbo-parser/src/char_ref.h +29 -0
  50. data/gumbo-parser/src/char_ref.rl +2154 -0
  51. data/gumbo-parser/src/error.c +626 -0
  52. data/gumbo-parser/src/error.h +148 -0
  53. data/gumbo-parser/src/foreign_attrs.c +104 -0
  54. data/gumbo-parser/src/foreign_attrs.gperf +27 -0
  55. data/gumbo-parser/src/gumbo.h +943 -0
  56. data/gumbo-parser/src/insertion_mode.h +33 -0
  57. data/gumbo-parser/src/macros.h +91 -0
  58. data/gumbo-parser/src/parser.c +4875 -0
  59. data/gumbo-parser/src/parser.h +41 -0
  60. data/gumbo-parser/src/replacement.h +33 -0
  61. data/gumbo-parser/src/string_buffer.c +103 -0
  62. data/gumbo-parser/src/string_buffer.h +68 -0
  63. data/gumbo-parser/src/string_piece.c +48 -0
  64. data/gumbo-parser/src/svg_attrs.c +174 -0
  65. data/gumbo-parser/src/svg_attrs.gperf +77 -0
  66. data/gumbo-parser/src/svg_tags.c +137 -0
  67. data/gumbo-parser/src/svg_tags.gperf +55 -0
  68. data/gumbo-parser/src/tag.c +222 -0
  69. data/gumbo-parser/src/tag_lookup.c +382 -0
  70. data/gumbo-parser/src/tag_lookup.gperf +169 -0
  71. data/gumbo-parser/src/tag_lookup.h +13 -0
  72. data/gumbo-parser/src/token_buffer.c +79 -0
  73. data/gumbo-parser/src/token_buffer.h +71 -0
  74. data/gumbo-parser/src/token_type.h +17 -0
  75. data/gumbo-parser/src/tokenizer.c +3463 -0
  76. data/gumbo-parser/src/tokenizer.h +112 -0
  77. data/gumbo-parser/src/tokenizer_states.h +339 -0
  78. data/gumbo-parser/src/utf8.c +245 -0
  79. data/gumbo-parser/src/utf8.h +164 -0
  80. data/gumbo-parser/src/util.c +68 -0
  81. data/gumbo-parser/src/util.h +30 -0
  82. data/gumbo-parser/src/vector.c +111 -0
  83. data/gumbo-parser/src/vector.h +45 -0
  84. data/lib/nokogiri/class_resolver.rb +67 -0
  85. data/lib/nokogiri/css/node.rb +9 -8
  86. data/lib/nokogiri/css/parser.rb +361 -342
  87. data/lib/nokogiri/css/parser.y +250 -245
  88. data/lib/nokogiri/css/parser_extras.rb +22 -20
  89. data/lib/nokogiri/css/syntax_error.rb +2 -1
  90. data/lib/nokogiri/css/tokenizer.rb +4 -3
  91. data/lib/nokogiri/css/tokenizer.rex +3 -2
  92. data/lib/nokogiri/css/xpath_visitor.rb +179 -82
  93. data/lib/nokogiri/css.rb +49 -17
  94. data/lib/nokogiri/decorators/slop.rb +8 -7
  95. data/lib/nokogiri/extension.rb +8 -3
  96. data/lib/nokogiri/gumbo.rb +15 -0
  97. data/lib/nokogiri/html.rb +37 -27
  98. data/lib/nokogiri/{html → html4}/builder.rb +3 -2
  99. data/lib/nokogiri/{html → html4}/document.rb +92 -81
  100. data/lib/nokogiri/{html → html4}/document_fragment.rb +13 -9
  101. data/lib/nokogiri/{html → html4}/element_description.rb +2 -1
  102. data/lib/nokogiri/html4/element_description_defaults.rb +578 -0
  103. data/lib/nokogiri/{html → html4}/entity_lookup.rb +3 -2
  104. data/lib/nokogiri/{html → html4}/sax/parser.rb +16 -16
  105. data/lib/nokogiri/html4/sax/parser_context.rb +20 -0
  106. data/lib/nokogiri/{html → html4}/sax/push_parser.rb +11 -11
  107. data/lib/nokogiri/html4.rb +46 -0
  108. data/lib/nokogiri/html5/document.rb +91 -0
  109. data/lib/nokogiri/html5/document_fragment.rb +83 -0
  110. data/lib/nokogiri/html5/node.rb +100 -0
  111. data/lib/nokogiri/html5.rb +478 -0
  112. data/lib/nokogiri/jruby/dependencies.rb +10 -9
  113. data/lib/nokogiri/syntax_error.rb +1 -0
  114. data/lib/nokogiri/version/constant.rb +2 -1
  115. data/lib/nokogiri/version/info.rb +31 -14
  116. data/lib/nokogiri/version.rb +1 -0
  117. data/lib/nokogiri/xml/attr.rb +5 -3
  118. data/lib/nokogiri/xml/attribute_decl.rb +2 -1
  119. data/lib/nokogiri/xml/builder.rb +71 -31
  120. data/lib/nokogiri/xml/cdata.rb +2 -1
  121. data/lib/nokogiri/xml/character_data.rb +1 -0
  122. data/lib/nokogiri/xml/document.rb +183 -96
  123. data/lib/nokogiri/xml/document_fragment.rb +41 -38
  124. data/lib/nokogiri/xml/dtd.rb +3 -2
  125. data/lib/nokogiri/xml/element_content.rb +1 -0
  126. data/lib/nokogiri/xml/element_decl.rb +2 -1
  127. data/lib/nokogiri/xml/entity_decl.rb +3 -2
  128. data/lib/nokogiri/xml/entity_reference.rb +1 -0
  129. data/lib/nokogiri/xml/namespace.rb +2 -0
  130. data/lib/nokogiri/xml/node/save_options.rb +9 -5
  131. data/lib/nokogiri/xml/node.rb +525 -354
  132. data/lib/nokogiri/xml/node_set.rb +50 -54
  133. data/lib/nokogiri/xml/notation.rb +12 -0
  134. data/lib/nokogiri/xml/parse_options.rb +13 -6
  135. data/lib/nokogiri/xml/pp/character_data.rb +8 -6
  136. data/lib/nokogiri/xml/pp/node.rb +24 -26
  137. data/lib/nokogiri/xml/pp.rb +3 -2
  138. data/lib/nokogiri/xml/processing_instruction.rb +2 -1
  139. data/lib/nokogiri/xml/reader.rb +20 -24
  140. data/lib/nokogiri/xml/relax_ng.rb +1 -0
  141. data/lib/nokogiri/xml/sax/document.rb +44 -49
  142. data/lib/nokogiri/xml/sax/parser.rb +37 -34
  143. data/lib/nokogiri/xml/sax/parser_context.rb +7 -3
  144. data/lib/nokogiri/xml/sax/push_parser.rb +5 -5
  145. data/lib/nokogiri/xml/sax.rb +5 -4
  146. data/lib/nokogiri/xml/schema.rb +7 -6
  147. data/lib/nokogiri/xml/searchable.rb +93 -62
  148. data/lib/nokogiri/xml/syntax_error.rb +5 -4
  149. data/lib/nokogiri/xml/text.rb +1 -0
  150. data/lib/nokogiri/xml/xpath/syntax_error.rb +2 -1
  151. data/lib/nokogiri/xml/xpath.rb +13 -1
  152. data/lib/nokogiri/xml/xpath_context.rb +2 -3
  153. data/lib/nokogiri/xml.rb +37 -37
  154. data/lib/nokogiri/xslt/stylesheet.rb +2 -1
  155. data/lib/nokogiri/xslt.rb +28 -20
  156. data/lib/nokogiri.rb +48 -43
  157. data/lib/xsd/xmlparser/nokogiri.rb +25 -24
  158. data/patches/libxml2/{0002-Remove-script-macro-support.patch → 0001-Remove-script-macro-support.patch} +0 -0
  159. data/patches/libxml2/{0003-Update-entities-to-remove-handling-of-ssi.patch → 0002-Update-entities-to-remove-handling-of-ssi.patch} +0 -0
  160. data/patches/libxml2/{0004-libxml2.la-is-in-top_builddir.patch → 0003-libxml2.la-is-in-top_builddir.patch} +1 -1
  161. data/patches/libxml2/{0008-use-glibc-strlen.patch → 0004-use-glibc-strlen.patch} +3 -3
  162. data/patches/libxml2/{0009-avoid-isnan-isinf.patch → 0005-avoid-isnan-isinf.patch} +4 -4
  163. data/patches/libxml2/0006-update-automake-files-for-arm64.patch +3040 -0
  164. data/patches/libxml2/0008-htmlParseComment-handle-abruptly-closed-comments.patch +61 -0
  165. data/patches/libxml2/0009-allow-wildcard-namespaces.patch +77 -0
  166. data/patches/libxslt/0001-update-automake-files-for-arm64.patch +2445 -1919
  167. data/ports/archives/libxml2-2.9.14.tar.xz +0 -0
  168. data/ports/archives/libxslt-1.1.35.tar.xz +0 -0
  169. metadata +204 -93
  170. data/lib/nokogiri/html/element_description_defaults.rb +0 -672
  171. data/lib/nokogiri/html/sax/parser_context.rb +0 -17
  172. data/patches/libxml2/0001-Revert-Do-not-URI-escape-in-server-side-includes.patch +0 -78
  173. data/patches/libxml2/0005-Fix-infinite-loop-in-xmlStringLenDecodeEntities.patch +0 -32
  174. data/patches/libxml2/0006-htmlParseComment-treat-as-if-it-closed-the-comment.patch +0 -73
  175. data/patches/libxml2/0007-use-new-htmlParseLookupCommentEnd-to-find-comment-en.patch +0 -103
  176. data/patches/libxml2/0010-parser.c-shrink-the-input-buffer-when-appropriate.patch +0 -70
  177. data/patches/libxml2/0011-update-automake-files-for-arm64.patch +0 -2511
  178. data/ports/archives/libxml2-2.9.10.tar.gz +0 -0
  179. data/ports/archives/libxslt-1.1.34.tar.gz +0 -0
@@ -1,18 +1,16 @@
1
1
  # coding: utf-8
2
2
  # frozen_string_literal: true
3
3
 
4
- require 'pathname'
4
+ require "pathname"
5
5
 
6
6
  module Nokogiri
7
7
  module XML
8
- ##
9
- # Nokogiri::XML::Document is the main entry point for dealing with
10
- # XML documents. The Document is created by parsing an XML document.
11
- # See Nokogiri::XML::Document.parse() for more information on parsing.
8
+ # Nokogiri::XML::Document is the main entry point for dealing with XML documents. The Document
9
+ # is created by parsing an XML document. See Nokogiri::XML::Document.parse for more information
10
+ # on parsing.
12
11
  #
13
12
  # For searching a Document, see Nokogiri::XML::Searchable#css and
14
13
  # Nokogiri::XML::Searchable#xpath
15
- #
16
14
  class Document < Nokogiri::XML::Node
17
15
  # See http://www.w3.org/TR/REC-xml-names/#ns-decl for more details. Note that we're not
18
16
  # attempting to handle unicode characters partly because libxml2 doesn't handle unicode
@@ -47,109 +45,178 @@ module Nokogiri
47
45
  #
48
46
  # Nokogiri.XML() is a convenience method which will call this method.
49
47
  #
50
- def self.parse string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML
48
+ def self.parse(string_or_io, url = nil, encoding = nil, options = ParseOptions::DEFAULT_XML)
51
49
  options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
52
-
53
50
  yield options if block_given?
54
51
 
55
52
  url ||= string_or_io.respond_to?(:path) ? string_or_io.path : nil
56
53
 
57
54
  if empty_doc?(string_or_io)
58
55
  if options.strict?
59
- raise Nokogiri::XML::SyntaxError.new("Empty document")
56
+ raise Nokogiri::XML::SyntaxError, "Empty document"
60
57
  else
61
58
  return encoding ? new.tap { |i| i.encoding = encoding } : new
62
59
  end
63
60
  end
64
61
 
65
62
  doc = if string_or_io.respond_to?(:read)
66
- if string_or_io.is_a?(Pathname)
67
- # resolve the Pathname to the file and open it as an IO object, see #2110
68
- string_or_io = string_or_io.expand_path.open
69
- url ||= string_or_io.path
70
- end
63
+ if string_or_io.is_a?(Pathname)
64
+ # resolve the Pathname to the file and open it as an IO object, see #2110
65
+ string_or_io = string_or_io.expand_path.open
66
+ url ||= string_or_io.path
67
+ end
71
68
 
72
- read_io(string_or_io, url, encoding, options.to_i)
73
- else
74
- # read_memory pukes on empty docs
75
- read_memory(string_or_io, url, encoding, options.to_i)
76
- end
69
+ read_io(string_or_io, url, encoding, options.to_i)
70
+ else
71
+ # read_memory pukes on empty docs
72
+ read_memory(string_or_io, url, encoding, options.to_i)
73
+ end
77
74
 
78
75
  # do xinclude processing
79
76
  doc.do_xinclude(options) if options.xinclude?
80
77
 
81
- return doc
78
+ doc
82
79
  end
83
80
 
84
81
  ##
85
- # @!method wrap(java_document)
86
- # @!scope class
82
+ # :singleton-method: wrap
83
+ # :call-seq: wrap(java_document) → Nokogiri::XML::Document
84
+ #
85
+ # ⚠ This method is only available when running JRuby.
87
86
  #
88
- # Create a {Document} using an existing Java DOM document object.
87
+ # Create a Document using an existing Java DOM document object.
89
88
  #
90
- # The returned {Document} shares the same underlying data structure as the Java object, so
89
+ # The returned Document shares the same underlying data structure as the Java object, so
91
90
  # changes in one are reflected in the other.
92
91
  #
93
- # @param java_document [Java::OrgW3cDom::Document]
94
- # @return [Nokogiri::XML::Document]
95
- # @note This method is only available when running JRuby.
96
- # @note The class +Java::OrgW3cDom::Document+ is also accessible as +org.w3c.dom.Document+.
97
- # @see #to_java
92
+ # [Parameters]
93
+ # - `java_document` (Java::OrgW3cDom::Document)
94
+ # (The class `Java::OrgW3cDom::Document` is also accessible as `org.w3c.dom.Document`.)
95
+ #
96
+ # [Returns] Nokogiri::XML::Document
97
+ #
98
+ # See also \#to_java
98
99
 
99
- ##
100
- # @!method to_java()
100
+ # :method: to_java
101
+ # :call-seq: to_java() → Java::OrgW3cDom::Document
101
102
  #
102
- # Returns the underlying Java DOM document object for the {Document}.
103
+ # This method is only available when running JRuby.
103
104
  #
104
- # The returned Java object shares the same underlying data structure as the {Document}, so
105
+ # Returns the underlying Java DOM document object for this document.
106
+ #
107
+ # The returned Java object shares the same underlying data structure as this document, so
105
108
  # changes in one are reflected in the other.
106
109
  #
107
- # @return [Java::OrgW3cDom::Document]
108
- # @note This method is only available when running JRuby.
109
- # @note The class +Java::OrgW3cDom::Document+ is also accessible as +org.w3c.dom.Document+.
110
- # @see .wrap
111
-
110
+ # [Returns]
111
+ # Java::OrgW3cDom::Document
112
+ # (The class `Java::OrgW3cDom::Document` is also accessible as `org.w3c.dom.Document`.)
113
+ #
114
+ # See also Document.wrap
112
115
 
113
- # A list of Nokogiri::XML::SyntaxError found when parsing a document
116
+ # The errors found while parsing a document.
117
+ #
118
+ # [Returns] Array<Nokogiri::XML::SyntaxError>
114
119
  attr_accessor :errors
115
120
 
116
- def initialize *args # :nodoc:
121
+ # When `true`, reparented elements without a namespace will inherit their new parent's
122
+ # namespace (if one exists). Defaults to `false`.
123
+ #
124
+ # [Returns] Boolean
125
+ #
126
+ # *Example:* Default behavior of namespace inheritance
127
+ #
128
+ # xml = <<~EOF
129
+ # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
130
+ # <foo:parent>
131
+ # </foo:parent>
132
+ # </root>
133
+ # EOF
134
+ # doc = Nokogiri::XML(xml)
135
+ # parent = doc.at_xpath("//foo:parent", "foo" => "http://nokogiri.org/default_ns/test/foo")
136
+ # parent.add_child("<child></child>")
137
+ # doc.to_xml
138
+ # # => <?xml version="1.0"?>
139
+ # # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
140
+ # # <foo:parent>
141
+ # # <child/>
142
+ # # </foo:parent>
143
+ # # </root>
144
+ #
145
+ # *Example:* Setting namespace inheritance to `true`
146
+ #
147
+ # xml = <<~EOF
148
+ # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
149
+ # <foo:parent>
150
+ # </foo:parent>
151
+ # </root>
152
+ # EOF
153
+ # doc = Nokogiri::XML(xml)
154
+ # doc.namespace_inheritance = true
155
+ # parent = doc.at_xpath("//foo:parent", "foo" => "http://nokogiri.org/default_ns/test/foo")
156
+ # parent.add_child("<child></child>")
157
+ # doc.to_xml
158
+ # # => <?xml version="1.0"?>
159
+ # # <root xmlns:foo="http://nokogiri.org/default_ns/test/foo">
160
+ # # <foo:parent>
161
+ # # <foo:child/>
162
+ # # </foo:parent>
163
+ # # </root>
164
+ #
165
+ # Since v1.12.4
166
+ attr_accessor :namespace_inheritance
167
+
168
+ def initialize(*args) # :nodoc:
117
169
  @errors = []
118
170
  @decorators = nil
171
+ @namespace_inheritance = false
119
172
  end
120
173
 
121
- ##
122
- # Create a new +Element+ with +name+ sharing GC lifecycle with the document, optionally
123
- # setting contents or attributes.
174
+ # :call-seq:
175
+ # create_element(name, *contents_or_attrs, &block) Nokogiri::XML::Element
176
+ #
177
+ # Create a new Element with `name` belonging to this document, optionally setting contents or
178
+ # attributes.
179
+ #
180
+ # This method is _not_ the most user-friendly option if your intention is to add a node to the
181
+ # document tree. Prefer one of the Nokogiri::XML::Node methods like Node#add_child,
182
+ # Node#add_next_sibling, Node#replace, etc. which will both create an element (or subtree) and
183
+ # place it in the document tree.
124
184
  #
125
185
  # Arguments may be passed to initialize the element:
126
- # - a +Hash+ argument will be used to set attributes
127
- # - a non-Hash object that responds to +#to_s+ will be used to set the new node's contents
186
+ #
187
+ # - a Hash argument will be used to set attributes
188
+ # - a non-Hash object that responds to \#to_s will be used to set the new node's contents
128
189
  #
129
190
  # A block may be passed to mutate the node.
130
191
  #
131
- # @param name [String]
132
- # @param contents_or_attrs [#to_s,Hash]
133
- # @yieldparam node [Nokogiri::XML::Element]
134
- # @return [Nokogiri::XML::Element]
192
+ # [Parameters]
193
+ # - `name` (String)
194
+ # - `contents_or_attrs` (\#to_s, Hash)
195
+ # [Yields] `node` (Nokogiri::XML::Element)
196
+ # [Returns] Nokogiri::XML::Element
197
+ #
198
+ # *Example:* An empty element without attributes
135
199
  #
136
- # @example An empty element without attributes
137
200
  # doc.create_element("div")
138
201
  # # => <div></div>
139
202
  #
140
- # @example An element with contents
203
+ # *Example:* An element with contents
204
+ #
141
205
  # doc.create_element("div", "contents")
142
206
  # # => <div>contents</div>
143
207
  #
144
- # @example An element with attributes
208
+ # *Example:* An element with attributes
209
+ #
145
210
  # doc.create_element("div", {"class" => "container"})
146
211
  # # => <div class='container'></div>
147
212
  #
148
- # @example An element with contents and attributes
213
+ # *Example:* An element with contents and attributes
214
+ #
149
215
  # doc.create_element("div", "contents", {"class" => "container"})
150
216
  # # => <div class='container'>contents</div>
151
217
  #
152
- # @example Passing a block to mutate the element
218
+ # *Example:* Passing a block to mutate the element
219
+ #
153
220
  # doc.create_element("div") { |node| node["class"] = "blue" if before_noon? }
154
221
  #
155
222
  def create_element(name, *contents_or_attrs, &block)
@@ -170,30 +237,30 @@ module Nokogiri
170
237
  elm.content = arg
171
238
  end
172
239
  end
173
- if ns = elm.namespace_definitions.find { |n| n.prefix.nil? || (n.prefix == '') }
240
+ if (ns = elm.namespace_definitions.find { |n| n.prefix.nil? || (n.prefix == "") })
174
241
  elm.namespace = ns
175
242
  end
176
243
  elm
177
244
  end
178
245
 
179
246
  # Create a Text Node with +string+
180
- def create_text_node string, &block
181
- Nokogiri::XML::Text.new string.to_s, self, &block
247
+ def create_text_node(string, &block)
248
+ Nokogiri::XML::Text.new(string.to_s, self, &block)
182
249
  end
183
250
 
184
251
  # Create a CDATA Node containing +string+
185
- def create_cdata string, &block
186
- Nokogiri::XML::CDATA.new self, string.to_s, &block
252
+ def create_cdata(string, &block)
253
+ Nokogiri::XML::CDATA.new(self, string.to_s, &block)
187
254
  end
188
255
 
189
256
  # Create a Comment Node containing +string+
190
- def create_comment string, &block
191
- Nokogiri::XML::Comment.new self, string.to_s, &block
257
+ def create_comment(string, &block)
258
+ Nokogiri::XML::Comment.new(self, string.to_s, &block)
192
259
  end
193
260
 
194
261
  # The name of this document. Always returns "document"
195
262
  def name
196
- 'document'
263
+ "document"
197
264
  end
198
265
 
199
266
  # A reference to +self+
@@ -201,46 +268,51 @@ module Nokogiri
201
268
  self
202
269
  end
203
270
 
204
- ##
205
- # Recursively get all namespaces from this node and its subtree and
206
- # return them as a hash.
271
+ # :call-seq:
272
+ # collect_namespaces() Hash<String(Namespace#prefix) String(Namespace#href)>
207
273
  #
208
- # For example, given this document:
274
+ # Recursively get all namespaces from this node and its subtree and return them as a
275
+ # hash.
209
276
  #
210
- # <root xmlns:foo="bar">
277
+ # ⚠ This method will not handle duplicate namespace prefixes, since the return value is a hash.
278
+ #
279
+ # Note that this method does an xpath lookup for nodes with namespaces, and as a result the
280
+ # order (and which duplicate prefix "wins") may be dependent on the implementation of the
281
+ # underlying XML library.
282
+ #
283
+ # *Example:* Basic usage
284
+ #
285
+ # Given this document:
286
+ #
287
+ # <root xmlns="default" xmlns:foo="bar">
211
288
  # <bar xmlns:hello="world" />
212
289
  # </root>
213
290
  #
214
291
  # This method will return:
215
292
  #
216
- # { 'xmlns:foo' => 'bar', 'xmlns:hello' => 'world' }
293
+ # {"xmlns:foo"=>"bar", "xmlns"=>"default", "xmlns:hello"=>"world"}
217
294
  #
218
- # WARNING: this method will clobber duplicate names in the keys.
219
- # For example, given this document:
295
+ # *Example:* Duplicate prefixes
296
+ #
297
+ # Given this document:
220
298
  #
221
299
  # <root xmlns:foo="bar">
222
300
  # <bar xmlns:foo="baz" />
223
301
  # </root>
224
302
  #
225
- # The hash returned will look like this: { 'xmlns:foo' => 'bar' }
226
- #
227
- # Non-prefixed default namespaces (as in "xmlns=") are not included
228
- # in the hash.
303
+ # The hash returned will be something like:
229
304
  #
230
- # Note that this method does an xpath lookup for nodes with
231
- # namespaces, and as a result the order may be dependent on the
232
- # implementation of the underlying XML library.
305
+ # {"xmlns:foo" => "baz"}
233
306
  #
234
307
  def collect_namespaces
235
- xpath("//namespace::*").inject({}) do |hash, ns|
236
- hash[["xmlns",ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
237
- hash
308
+ xpath("//namespace::*").each_with_object({}) do |ns, hash|
309
+ hash[["xmlns", ns.prefix].compact.join(":")] = ns.href if ns.prefix != "xml"
238
310
  end
239
311
  end
240
312
 
241
313
  # Get the list of decorators given +key+
242
- def decorators key
243
- @decorators ||= Hash.new
314
+ def decorators(key)
315
+ @decorators ||= {}
244
316
  @decorators[key] ||= []
245
317
  end
246
318
 
@@ -249,7 +321,8 @@ module Nokogiri
249
321
  # the document or +nil+ when there is no DTD.
250
322
  def validate
251
323
  return nil unless internal_subset
252
- internal_subset.validate self
324
+
325
+ internal_subset.validate(self)
253
326
  end
254
327
 
255
328
  ##
@@ -269,7 +342,7 @@ module Nokogiri
269
342
  # ... which does absolutely nothing.
270
343
  #
271
344
  def slop!
272
- unless decorators(XML::Node).include? Nokogiri::Decorators::Slop
345
+ unless decorators(XML::Node).include?(Nokogiri::Decorators::Slop)
273
346
  decorators(XML::Node) << Nokogiri::Decorators::Slop
274
347
  decorate!
275
348
  end
@@ -279,16 +352,18 @@ module Nokogiri
279
352
 
280
353
  ##
281
354
  # Apply any decorators to +node+
282
- def decorate node
355
+ def decorate(node)
283
356
  return unless @decorators
284
- @decorators.each { |klass,list|
357
+
358
+ @decorators.each do |klass, list|
285
359
  next unless node.is_a?(klass)
360
+
286
361
  list.each { |moodule| node.extend(moodule) }
287
- }
362
+ end
288
363
  end
289
364
 
290
- alias :to_xml :serialize
291
- alias :clone :dup
365
+ alias_method :to_xml, :serialize
366
+ alias_method :clone, :dup
292
367
 
293
368
  # Get the hash of namespaces on the root Nokogiri::XML::Node
294
369
  def namespaces
@@ -298,35 +373,47 @@ module Nokogiri
298
373
  ##
299
374
  # Create a Nokogiri::XML::DocumentFragment from +tags+
300
375
  # Returns an empty fragment if +tags+ is nil.
301
- def fragment tags = nil
302
- DocumentFragment.new(self, tags, self.root)
376
+ def fragment(tags = nil)
377
+ DocumentFragment.new(self, tags, root)
303
378
  end
304
379
 
305
380
  undef_method :swap, :parent, :namespace, :default_namespace=
306
381
  undef_method :add_namespace_definition, :attributes
307
382
  undef_method :namespace_definitions, :line, :add_namespace
308
383
 
309
- def add_child node_or_tags
310
- raise "A document may not have multiple root nodes." if (root && root.name != 'nokogiri_text_wrapper') && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
384
+ def add_child(node_or_tags)
385
+ raise "A document may not have multiple root nodes." if (root && root.name != "nokogiri_text_wrapper") && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
386
+
311
387
  node_or_tags = coerce(node_or_tags)
312
388
  if node_or_tags.is_a?(XML::NodeSet)
313
389
  raise "A document may not have multiple root nodes." if node_or_tags.size > 1
390
+
314
391
  super(node_or_tags.first)
315
392
  else
316
393
  super
317
394
  end
318
395
  end
319
- alias :<< :add_child
396
+ alias_method :<<, :add_child
397
+
398
+ # :call-seq:
399
+ # xpath_doctype() → Nokogiri::CSS::XPathVisitor::DoctypeConfig
400
+ #
401
+ # [Returns] The document type which determines CSS-to-XPath translation.
402
+ #
403
+ # See XPathVisitor for more information.
404
+ def xpath_doctype
405
+ Nokogiri::CSS::XPathVisitor::DoctypeConfig::XML
406
+ end
320
407
 
321
408
  private
322
409
 
323
- def self.empty_doc? string_or_io
410
+ def self.empty_doc?(string_or_io)
324
411
  string_or_io.nil? ||
325
412
  (string_or_io.respond_to?(:empty?) && string_or_io.empty?) ||
326
413
  (string_or_io.respond_to?(:eof?) && string_or_io.eof?)
327
414
  end
328
415
 
329
- IMPLIED_XPATH_CONTEXTS = [ '//'.freeze ].freeze # :nodoc:
416
+ IMPLIED_XPATH_CONTEXTS = ["//"].freeze # :nodoc:
330
417
 
331
418
  def inspect_attributes
332
419
  [:name, :children]
@@ -1,28 +1,39 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Nokogiri
3
4
  module XML
4
5
  class DocumentFragment < Nokogiri::XML::Node
6
+ ####
7
+ # Create a Nokogiri::XML::DocumentFragment from +tags+
8
+ def self.parse(tags, options = ParseOptions::DEFAULT_XML, &block)
9
+ new(XML::Document.new, tags, nil, options, &block)
10
+ end
11
+
5
12
  ##
6
13
  # Create a new DocumentFragment from +tags+.
7
14
  #
8
15
  # If +ctx+ is present, it is used as a context node for the
9
16
  # subtree created, e.g., namespaces will be resolved relative
10
17
  # to +ctx+.
11
- def initialize document, tags = nil, ctx = nil
18
+ def initialize(document, tags = nil, ctx = nil, options = ParseOptions::DEFAULT_XML)
12
19
  return self unless tags
13
20
 
21
+ options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
22
+ yield options if block_given?
23
+
14
24
  children = if ctx
15
- # Fix for issue#490
16
- if Nokogiri.jruby?
17
- # fix for issue #770
18
- ctx.parse("<root #{namespace_declarations(ctx)}>#{tags}</root>").children
19
- else
20
- ctx.parse(tags)
21
- end
22
- else
23
- XML::Document.parse("<root>#{tags}</root>") \
24
- .xpath("/root/node()")
25
- end
25
+ # Fix for issue#490
26
+ if Nokogiri.jruby?
27
+ # fix for issue #770
28
+ ctx.parse("<root #{namespace_declarations(ctx)}>#{tags}</root>", options).children
29
+ else
30
+ ctx.parse(tags, options)
31
+ end
32
+ else
33
+ wrapper_doc = XML::Document.parse("<root>#{tags}</root>", nil, nil, options)
34
+ self.errors = wrapper_doc.errors
35
+ wrapper_doc.xpath("/root/node()")
36
+ end
26
37
  children.each { |child| child.parent = self }
27
38
  end
28
39
 
@@ -40,7 +51,7 @@ module Nokogiri
40
51
  ###
41
52
  # return the name for DocumentFragment
42
53
  def name
43
- '#document-fragment'
54
+ "#document-fragment"
44
55
  end
45
56
 
46
57
  ###
@@ -52,10 +63,10 @@ module Nokogiri
52
63
  ###
53
64
  # Convert this DocumentFragment to html
54
65
  # See Nokogiri::XML::NodeSet#to_html
55
- def to_html *args
66
+ def to_html(*args)
56
67
  if Nokogiri.jruby?
57
68
  options = args.first.is_a?(Hash) ? args.shift : {}
58
- if !options[:save_with]
69
+ unless options[:save_with]
59
70
  options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_HTML
60
71
  end
61
72
  args.insert(0, options)
@@ -66,10 +77,10 @@ module Nokogiri
66
77
  ###
67
78
  # Convert this DocumentFragment to xhtml
68
79
  # See Nokogiri::XML::NodeSet#to_xhtml
69
- def to_xhtml *args
80
+ def to_xhtml(*args)
70
81
  if Nokogiri.jruby?
71
82
  options = args.first.is_a?(Hash) ? args.shift : {}
72
- if !options[:save_with]
83
+ unless options[:save_with]
73
84
  options[:save_with] = Node::SaveOptions::NO_DECLARATION | Node::SaveOptions::NO_EMPTY_TAGS | Node::SaveOptions::AS_XHTML
74
85
  end
75
86
  args.insert(0, options)
@@ -80,7 +91,7 @@ module Nokogiri
80
91
  ###
81
92
  # Convert this DocumentFragment to xml
82
93
  # See Nokogiri::XML::NodeSet#to_xml
83
- def to_xml *args
94
+ def to_xml(*args)
84
95
  children.to_xml(*args)
85
96
  end
86
97
 
@@ -91,7 +102,7 @@ module Nokogiri
91
102
  # selectors. For example:
92
103
  #
93
104
  # For more information see Nokogiri::XML::Searchable#css
94
- def css *args
105
+ def css(*args)
95
106
  if children.any?
96
107
  children.css(*args) # 'children' is a smell here
97
108
  else
@@ -110,34 +121,26 @@ module Nokogiri
110
121
  # Search this fragment for +paths+. +paths+ must be one or more XPath or CSS queries.
111
122
  #
112
123
  # For more information see Nokogiri::XML::Searchable#search
113
- def search *rules
124
+ def search(*rules)
114
125
  rules, handler, ns, binds = extract_params(rules)
115
126
 
116
127
  rules.inject(NodeSet.new(document)) do |set, rule|
117
- set += if rule =~ Searchable::LOOKS_LIKE_XPATH
118
- xpath(*([rule, ns, handler, binds].compact))
119
- else
120
- children.css(*([rule, ns, handler].compact)) # 'children' is a smell here
121
- end
128
+ set + if Searchable::LOOKS_LIKE_XPATH.match?(rule)
129
+ xpath(*[rule, ns, handler, binds].compact)
130
+ else
131
+ children.css(*[rule, ns, handler].compact) # 'children' is a smell here
132
+ end
122
133
  end
123
134
  end
124
135
 
125
- alias :serialize :to_s
126
-
127
- class << self
128
- ####
129
- # Create a Nokogiri::XML::DocumentFragment from +tags+
130
- def parse tags
131
- self.new(XML::Document.new, tags)
132
- end
133
- end
136
+ alias_method :serialize, :to_s
134
137
 
135
138
  # A list of Nokogiri::XML::SyntaxError found when parsing a document
136
139
  def errors
137
140
  document.errors
138
141
  end
139
142
 
140
- def errors= things # :nodoc:
143
+ def errors=(things) # :nodoc:
141
144
  document.errors = things
142
145
  end
143
146
 
@@ -148,11 +151,11 @@ module Nokogiri
148
151
  private
149
152
 
150
153
  # fix for issue 770
151
- def namespace_declarations ctx
154
+ def namespace_declarations(ctx)
152
155
  ctx.namespace_scopes.map do |namespace|
153
156
  prefix = namespace.prefix.nil? ? "" : ":#{namespace.prefix}"
154
- %Q{xmlns#{prefix}="#{namespace.href}"}
155
- end.join ' '
157
+ %{xmlns#{prefix}="#{namespace.href}"}
158
+ end.join(" ")
156
159
  end
157
160
  end
158
161
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Nokogiri
3
4
  module XML
4
5
  class DTD < Nokogiri::XML::Node
@@ -20,13 +21,13 @@ module Nokogiri
20
21
  end
21
22
 
22
23
  def html_dtd?
23
- name.casecmp('html').zero?
24
+ name.casecmp("html").zero?
24
25
  end
25
26
 
26
27
  def html5_dtd?
27
28
  html_dtd? &&
28
29
  external_id.nil? &&
29
- (system_id.nil? || system_id == 'about:legacy-compat')
30
+ (system_id.nil? || system_id == "about:legacy-compat")
30
31
  end
31
32
  end
32
33
  end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Nokogiri
3
4
  module XML
4
5
  ###
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Nokogiri
3
4
  module XML
4
5
  class ElementDecl < Nokogiri::XML::Node
@@ -7,7 +8,7 @@ module Nokogiri
7
8
  undef_method :line if method_defined?(:line)
8
9
 
9
10
  def inspect
10
- "#<#{self.class.name}:#{sprintf("0x%x", object_id)} #{to_s.inspect}>"
11
+ "#<#{self.class.name}:#{format("0x%x", object_id)} #{to_s.inspect}>"
11
12
  end
12
13
  end
13
14
  end