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,13 +1,15 @@
1
- # encoding: UTF-8
1
+ # encoding: utf-8
2
2
  # frozen_string_literal: true
3
+
3
4
  require "stringio"
4
- require "nokogiri/xml/node/save_options"
5
5
 
6
6
  module Nokogiri
7
7
  module XML
8
- ##
9
- # {Nokogiri::XML::Node} is your window to the fun filled world of dealing with XML and HTML
10
- # tags. A {Nokogiri::XML::Node} may be treated similarly to a hash with regard to attributes. For
8
+ # Nokogiri::XML::Node is the primary API you'll use to interact with your Document.
9
+ #
10
+ # == Attributes
11
+ #
12
+ # A Nokogiri::XML::Node may be treated similarly to a hash with regard to attributes. For
11
13
  # example:
12
14
  #
13
15
  # node = Nokogiri::XML::DocumentFragment.parse("<a href='#foo' id='link'>link</a>").at_css("a")
@@ -18,41 +20,52 @@ module Nokogiri
18
20
  # node['class'] = 'green' # => "green"
19
21
  # node.to_html # => "<a href=\"#foo\" id=\"link\" class=\"green\">link</a>"
20
22
  #
21
- # See the method group entitled "Working With Node Attributes" for the full set of methods.
23
+ # See the method group entitled Node@Working+With+Node+Attributes for the full set of methods.
24
+ #
25
+ # == Navigation
22
26
  #
23
- # {Nokogiri::XML::Node} also has methods that let you move around your
24
- # tree. For navigating your tree, see:
27
+ # Nokogiri::XML::Node also has methods that let you move around your tree:
25
28
  #
26
- # * {#parent}
27
- # * {#children}
28
- # * {#next}
29
- # * {#previous}
29
+ # [#parent, #children, #next, #previous]
30
+ # Navigate up, down, or through siblings.
30
31
  #
31
- # When printing or otherwise emitting a document or a node (and
32
- # its subtree), there are a few methods you might want to use:
32
+ # See the method group entitled Node@Traversing+Document+Structure for the full set of methods.
33
33
  #
34
- # * {#content}, {#text}, {#inner_text}, {#to_str}: These methods will all <b>emit plaintext</b>,
35
- # meaning that entities will be replaced (e.g., "&lt;" will be replaced with "<"), meaning
34
+ # == Serialization
35
+ #
36
+ # When printing or otherwise emitting a document or a node (and its subtree), there are a few
37
+ # methods you might want to use:
38
+ #
39
+ # [#content, #text, #inner_text, #to_str]
40
+ # These methods will all **emit plaintext**,
41
+ # meaning that entities will be replaced (e.g., +&lt;+ will be replaced with +<+), meaning
36
42
  # that any sanitizing will likely be un-done in the output.
37
43
  #
38
- # * {#to_s}, {#to_xml}, {#to_html}, {#inner_html}: These methods will all <b>emit
39
- # properly-escaped markup</b>, meaning that it's suitable for consumption by browsers,
40
- # parsers, etc.
44
+ # [#to_s, #to_xml, #to_html, #inner_html]
45
+ # These methods will all **emit properly-escaped markup**, meaning that it's suitable for
46
+ # consumption by browsers, parsers, etc.
47
+ #
48
+ # See the method group entitled Node@Serialization+and+Generating+Output for the full set of methods.
49
+ #
50
+ # == Searching
41
51
  #
42
- # You may search this node's subtree using {#xpath} and {#css}
52
+ # You may search this node's subtree using methods like #xpath and #css.
53
+ #
54
+ # See the method group entitled Node@Searching+via+XPath+or+CSS+Queries for the full set of methods.
43
55
  #
44
56
  class Node
45
57
  include Nokogiri::XML::PP::Node
46
58
  include Nokogiri::XML::Searchable
59
+ include Nokogiri::ClassResolver
47
60
  include Enumerable
48
61
 
49
- # Element node type, see {Nokogiri::XML::Node#element?}
62
+ # Element node type, see Nokogiri::XML::Node#element?
50
63
  ELEMENT_NODE = 1
51
64
  # Attribute node type
52
65
  ATTRIBUTE_NODE = 2
53
- # Text node type, see {Nokogiri::XML::Node#text?}
66
+ # Text node type, see Nokogiri::XML::Node#text?
54
67
  TEXT_NODE = 3
55
- # CDATA node type, see {Nokogiri::XML::Node#cdata?}
68
+ # CDATA node type, see Nokogiri::XML::Node#cdata?
56
69
  CDATA_SECTION_NODE = 4
57
70
  # Entity reference node type
58
71
  ENTITY_REF_NODE = 5
@@ -60,9 +73,9 @@ module Nokogiri
60
73
  ENTITY_NODE = 6
61
74
  # PI node type
62
75
  PI_NODE = 7
63
- # Comment node type, see {Nokogiri::XML::Node#comment?}
76
+ # Comment node type, see Nokogiri::XML::Node#comment?
64
77
  COMMENT_NODE = 8
65
- # Document node type, see {Nokogiri::XML::Node#xml?}
78
+ # Document node type, see Nokogiri::XML::Node#xml?
66
79
  DOCUMENT_NODE = 9
67
80
  # Document type node type
68
81
  DOCUMENT_TYPE_NODE = 10
@@ -70,7 +83,7 @@ module Nokogiri
70
83
  DOCUMENT_FRAG_NODE = 11
71
84
  # Notation node type
72
85
  NOTATION_NODE = 12
73
- # HTML document node type, see {Nokogiri::XML::Node#html?}
86
+ # HTML document node type, see Nokogiri::XML::Node#html?
74
87
  HTML_DOCUMENT_NODE = 13
75
88
  # DTD node type
76
89
  DTD_NODE = 14
@@ -89,15 +102,29 @@ module Nokogiri
89
102
  # DOCB document node type
90
103
  DOCB_DOCUMENT_NODE = 21
91
104
 
92
- ##
93
- # Create a new node with +name+ sharing GC lifecycle with +document+.
94
- # @param name [String]
95
- # @param document [Nokogiri::XML::Document]
96
- # @yieldparam node [Nokogiri::XML::Node]
97
- # @return [Nokogiri::XML::Node]
98
- # @see Nokogiri::XML::Node.new
105
+ #
106
+ # :call-seq:
107
+ # new(name, document) -> Nokogiri::XML::Node
108
+ # new(name, document) { |node| ... } -> Nokogiri::XML::Node
109
+ #
110
+ # Create a new node with +name+ that belongs to +document+.
111
+ #
112
+ # If you intend to add a node to a document tree, it's likely that you will prefer one of the
113
+ # Nokogiri::XML::Node methods like #add_child, #add_next_sibling, #replace, etc. which will
114
+ # both create an element (or subtree) and place it in the document tree.
115
+ #
116
+ # Another alternative, if you are concerned about performance, is
117
+ # Nokogiri::XML::Document#create_element which accepts additional arguments for contents or
118
+ # attributes but (like this method) avoids parsing markup.
119
+ #
120
+ # [Parameters]
121
+ # - +name+ (String)
122
+ # - +document+ (Nokogiri::XML::Document) The document to which the the returned node will belong.
123
+ # [Yields] Nokogiri::XML::Node
124
+ # [Returns] Nokogiri::XML::Node
125
+ #
99
126
  def initialize(name, document)
100
- # This is intentionally empty.
127
+ # This is intentionally empty, and sets the method signature for subclasses.
101
128
  end
102
129
 
103
130
  ###
@@ -106,18 +133,7 @@ module Nokogiri
106
133
  document.decorate(self)
107
134
  end
108
135
 
109
- # @!group Searching via XPath or CSS Queries
110
-
111
- ###
112
- # Search this node's immediate children using CSS selector +selector+
113
- def >(selector)
114
- ns = document.root.namespaces
115
- xpath CSS.xpath_for(selector, :prefix => "./", :ns => ns).first
116
- end
117
-
118
- # @!endgroup
119
-
120
- # @!group Manipulating Document Structure
136
+ # :section: Manipulating Document Structure
121
137
 
122
138
  ###
123
139
  # Add +node_or_tags+ as a child of this Node.
@@ -129,9 +145,9 @@ module Nokogiri
129
145
  def add_child(node_or_tags)
130
146
  node_or_tags = coerce(node_or_tags)
131
147
  if node_or_tags.is_a?(XML::NodeSet)
132
- node_or_tags.each { |n| add_child_node_and_reparent_attrs n }
148
+ node_or_tags.each { |n| add_child_node_and_reparent_attrs(n) }
133
149
  else
134
- add_child_node_and_reparent_attrs node_or_tags
150
+ add_child_node_and_reparent_attrs(node_or_tags)
135
151
  end
136
152
  node_or_tags
137
153
  end
@@ -144,9 +160,10 @@ module Nokogiri
144
160
  #
145
161
  # Also see related method +add_child+.
146
162
  def prepend_child(node_or_tags)
147
- if first = children.first
163
+ if (first = children.first)
148
164
  # Mimic the error add_child would raise.
149
- raise RuntimeError, "Document already has a root node" if document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
165
+ raise "Document already has a root node" if document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
166
+
150
167
  first.__send__(:add_sibling, :previous, node_or_tags)
151
168
  else
152
169
  add_child(node_or_tags)
@@ -172,7 +189,7 @@ module Nokogiri
172
189
  #
173
190
  # Also see related method +add_child+.
174
191
  def <<(node_or_tags)
175
- add_child node_or_tags
192
+ add_child(node_or_tags)
176
193
  self
177
194
  end
178
195
 
@@ -184,9 +201,10 @@ module Nokogiri
184
201
  #
185
202
  # Also see related method +before+.
186
203
  def add_previous_sibling(node_or_tags)
187
- raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
204
+ raise ArgumentError,
205
+ "A document may not have multiple root nodes." if parent&.document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
188
206
 
189
- add_sibling :previous, node_or_tags
207
+ add_sibling(:previous, node_or_tags)
190
208
  end
191
209
 
192
210
  ###
@@ -197,9 +215,10 @@ module Nokogiri
197
215
  #
198
216
  # Also see related method +after+.
199
217
  def add_next_sibling(node_or_tags)
200
- raise ArgumentError.new("A document may not have multiple root nodes.") if (parent && parent.document?) && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
218
+ raise ArgumentError,
219
+ "A document may not have multiple root nodes." if parent&.document? && !(node_or_tags.comment? || node_or_tags.processing_instruction?)
201
220
 
202
- add_sibling :next, node_or_tags
221
+ add_sibling(:next, node_or_tags)
203
222
  end
204
223
 
205
224
  ####
@@ -210,7 +229,7 @@ module Nokogiri
210
229
  #
211
230
  # Also see related method +add_previous_sibling+.
212
231
  def before(node_or_tags)
213
- add_previous_sibling node_or_tags
232
+ add_previous_sibling(node_or_tags)
214
233
  self
215
234
  end
216
235
 
@@ -222,7 +241,7 @@ module Nokogiri
222
241
  #
223
242
  # Also see related method +add_next_sibling+.
224
243
  def after(node_or_tags)
225
- add_next_sibling node_or_tags
244
+ add_next_sibling(node_or_tags)
226
245
  self
227
246
  end
228
247
 
@@ -230,30 +249,24 @@ module Nokogiri
230
249
  # Set the inner html for this Node to +node_or_tags+
231
250
  # +node_or_tags+ can be a Nokogiri::XML::Node, a Nokogiri::XML::DocumentFragment, or a string containing markup.
232
251
  #
233
- # Returns self.
234
- #
235
252
  # Also see related method +children=+
236
253
  def inner_html=(node_or_tags)
237
254
  self.children = node_or_tags
238
- self
239
255
  end
240
256
 
241
257
  ####
242
258
  # Set the inner html for this Node +node_or_tags+
243
259
  # +node_or_tags+ can be a Nokogiri::XML::Node, a Nokogiri::XML::DocumentFragment, or a string containing markup.
244
260
  #
245
- # Returns the reparented node (if +node_or_tags+ is a Node), or NodeSet (if +node_or_tags+ is a DocumentFragment, NodeSet, or string).
246
- #
247
261
  # Also see related method +inner_html=+
248
262
  def children=(node_or_tags)
249
263
  node_or_tags = coerce(node_or_tags)
250
264
  children.unlink
251
265
  if node_or_tags.is_a?(XML::NodeSet)
252
- node_or_tags.each { |n| add_child_node_and_reparent_attrs n }
266
+ node_or_tags.each { |n| add_child_node_and_reparent_attrs(n) }
253
267
  else
254
- add_child_node_and_reparent_attrs node_or_tags
268
+ add_child_node_and_reparent_attrs(node_or_tags)
255
269
  end
256
- node_or_tags
257
270
  end
258
271
 
259
272
  ####
@@ -271,19 +284,19 @@ module Nokogiri
271
284
  # libxml is trying to find a parent node that is an element or document
272
285
  # so I can't tell if this is bug in libxml or not. issue #775.
273
286
  if text?
274
- replacee = Nokogiri::XML::Node.new "dummy", document
275
- add_previous_sibling_node replacee
287
+ replacee = Nokogiri::XML::Node.new("dummy", document)
288
+ add_previous_sibling_node(replacee)
276
289
  unlink
277
- return replacee.replace node_or_tags
290
+ return replacee.replace(node_or_tags)
278
291
  end
279
292
 
280
293
  node_or_tags = parent.coerce(node_or_tags)
281
294
 
282
295
  if node_or_tags.is_a?(XML::NodeSet)
283
- node_or_tags.each { |n| add_previous_sibling n }
296
+ node_or_tags.each { |n| add_previous_sibling(n) }
284
297
  unlink
285
298
  else
286
- replace_node node_or_tags
299
+ replace_node(node_or_tags)
287
300
  end
288
301
  node_or_tags
289
302
  end
@@ -296,7 +309,7 @@ module Nokogiri
296
309
  #
297
310
  # Also see related method +replace+.
298
311
  def swap(node_or_tags)
299
- replace node_or_tags
312
+ replace(node_or_tags)
300
313
  self
301
314
  end
302
315
 
@@ -310,7 +323,6 @@ module Nokogiri
310
323
  # Set the parent Node for this Node
311
324
  def parent=(parent_node)
312
325
  parent_node.add_child(self)
313
- parent_node
314
326
  end
315
327
 
316
328
  ###
@@ -339,7 +351,7 @@ module Nokogiri
339
351
  raise ArgumentError, "namespace must be declared on the same document"
340
352
  end
341
353
 
342
- set_namespace ns
354
+ set_namespace(ns)
343
355
  end
344
356
 
345
357
  ###
@@ -348,52 +360,159 @@ module Nokogiri
348
360
  # passed to it, allowing more convenient modification of the parser options.
349
361
  def do_xinclude(options = XML::ParseOptions::DEFAULT_XML)
350
362
  options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
351
-
352
- # give options to user
353
363
  yield options if block_given?
354
364
 
355
365
  # call c extension
356
366
  process_xincludes(options.to_i)
357
367
  end
358
368
 
359
- alias :next :next_sibling
360
- alias :previous :previous_sibling
361
- alias :next= :add_next_sibling
362
- alias :previous= :add_previous_sibling
363
- alias :remove :unlink
364
- alias :name= :node_name=
365
- alias :add_namespace :add_namespace_definition
369
+ alias_method :next, :next_sibling
370
+ alias_method :previous, :previous_sibling
371
+ alias_method :next=, :add_next_sibling
372
+ alias_method :previous=, :add_previous_sibling
373
+ alias_method :remove, :unlink
374
+ alias_method :name=, :node_name=
375
+ alias_method :add_namespace, :add_namespace_definition
366
376
 
367
- # @!endgroup
377
+ # :section:
368
378
 
369
- alias :text :content
370
- alias :inner_text :content
371
- alias :name :node_name
372
- alias :type :node_type
373
- alias :to_str :text
374
- alias :clone :dup
375
- alias :elements :element_children
379
+ alias_method :inner_text, :content
380
+ alias_method :text, :content
381
+ alias_method :to_str, :content
382
+ alias_method :name, :node_name
383
+ alias_method :type, :node_type
384
+ alias_method :clone, :dup
385
+ alias_method :elements, :element_children
376
386
 
377
- # @!group Working With Node Attributes
387
+ # :section: Working With Node Attributes
378
388
 
379
- ###
380
- # Get the attribute value for the attribute +name+
389
+ # :call-seq: [](name) → (String, nil)
390
+ #
391
+ # Fetch an attribute from this node.
392
+ #
393
+ # ⚠ Note that attributes with namespaces cannot be accessed with this method. To access
394
+ # namespaced attributes, use #attribute_with_ns.
395
+ #
396
+ # [Returns] (String, nil) value of the attribute +name+, or +nil+ if no matching attribute exists
397
+ #
398
+ # *Example*
399
+ #
400
+ # doc = Nokogiri::XML("<root><child size='large' class='big wide tall'/></root>")
401
+ # child = doc.at_css("child")
402
+ # child["size"] # => "large"
403
+ # child["class"] # => "big wide tall"
404
+ #
405
+ # *Example:* Namespaced attributes will not be returned.
406
+ #
407
+ # ⚠ Note namespaced attributes may be accessed with #attribute or #attribute_with_ns
408
+ #
409
+ # doc = Nokogiri::XML(<<~EOF)
410
+ # <root xmlns:width='http://example.com/widths'>
411
+ # <child width:size='broad'/>
412
+ # </root>
413
+ # EOF
414
+ # doc.at_css("child")["size"] # => nil
415
+ # doc.at_css("child").attribute("size").value # => "broad"
416
+ # doc.at_css("child").attribute_with_ns("size", "http://example.com/widths").value
417
+ # # => "broad"
418
+ #
381
419
  def [](name)
382
420
  get(name.to_s)
383
421
  end
384
422
 
385
- ###
386
- # Set the attribute value for the attribute +name+ to +value+
423
+ # :call-seq: []=(name, value) → value
424
+ #
425
+ # Update the attribute +name+ to +value+, or create the attribute if it does not exist.
426
+ #
427
+ # ⚠ Note that attributes with namespaces cannot be accessed with this method. To access
428
+ # namespaced attributes for update, use #attribute_with_ns. To add a namespaced attribute,
429
+ # see the example below.
430
+ #
431
+ # [Returns] +value+
432
+ #
433
+ # *Example*
434
+ #
435
+ # doc = Nokogiri::XML("<root><child/></root>")
436
+ # child = doc.at_css("child")
437
+ # child["size"] = "broad"
438
+ # child.to_html
439
+ # # => "<child size=\"broad\"></child>"
440
+ #
441
+ # *Example:* Add a namespaced attribute.
442
+ #
443
+ # doc = Nokogiri::XML(<<~EOF)
444
+ # <root xmlns:width='http://example.com/widths'>
445
+ # <child/>
446
+ # </root>
447
+ # EOF
448
+ # child = doc.at_css("child")
449
+ # child["size"] = "broad"
450
+ # ns = doc.root.namespace_definitions.find { |ns| ns.prefix == "width" }
451
+ # child.attribute("size").namespace = ns
452
+ # doc.to_html
453
+ # # => "<root xmlns:width=\"http://example.com/widths\">\n" +
454
+ # # " <child width:size=\"broad\"></child>\n" +
455
+ # # "</root>\n"
456
+ #
387
457
  def []=(name, value)
388
- set name.to_s, value.to_s
458
+ set(name.to_s, value.to_s)
389
459
  end
390
460
 
391
- ####
392
- # Returns a hash containing the node's attributes. The key is
393
- # the attribute name without any namespace, the value is a Nokogiri::XML::Attr
394
- # representing the attribute.
395
- # If you need to distinguish attributes with the same name, with different namespaces
396
- # use #attribute_nodes instead.
461
+ #
462
+ # :call-seq: attributes() Hash<String Nokogiri::XML::Attr>
463
+ #
464
+ # Fetch this node's attributes.
465
+ #
466
+ # Because the keys do not include any namespace information for the attribute, in case of a
467
+ # simple name collision, not all attributes will be returned. In this case, you will need to
468
+ # use #attribute_nodes.
469
+ #
470
+ # [Returns]
471
+ # Hash containing attributes belonging to +self+. The hash keys are String attribute
472
+ # names (without the namespace), and the hash values are Nokogiri::XML::Attr.
473
+ #
474
+ # *Example* with no namespaces:
475
+ #
476
+ # doc = Nokogiri::XML("<root><child size='large' class='big wide tall'/></root>")
477
+ # doc.at_css("child").attributes
478
+ # # => {"size"=>#(Attr:0x550 { name = "size", value = "large" }),
479
+ # # "class"=>#(Attr:0x564 { name = "class", value = "big wide tall" })}
480
+ #
481
+ # *Example* with a namespace:
482
+ #
483
+ # doc = Nokogiri::XML("<root xmlns:desc='http://example.com/sizes'><child desc:size='large'/></root>")
484
+ # doc.at_css("child").attributes
485
+ # # => {"size"=>
486
+ # # #(Attr:0x550 {
487
+ # # name = "size",
488
+ # # namespace = #(Namespace:0x564 {
489
+ # # prefix = "desc",
490
+ # # href = "http://example.com/sizes"
491
+ # # }),
492
+ # # value = "large"
493
+ # # })}
494
+ #
495
+ # *Example* with an attribute name collision:
496
+ #
497
+ # ⚠ Note that only one of the attributes is returned in the Hash.
498
+ #
499
+ # doc = Nokogiri::XML(<<~EOF)
500
+ # <root xmlns:width='http://example.com/widths'
501
+ # xmlns:height='http://example.com/heights'>
502
+ # <child width:size='broad' height:size='tall'/>
503
+ # </root>
504
+ # EOF
505
+ # doc.at_css("child").attributes
506
+ # # => {"size"=>
507
+ # # #(Attr:0x550 {
508
+ # # name = "size",
509
+ # # namespace = #(Namespace:0x564 {
510
+ # # prefix = "height",
511
+ # # href = "http://example.com/heights"
512
+ # # }),
513
+ # # value = "tall"
514
+ # # })}
515
+ #
397
516
  def attributes
398
517
  attribute_nodes.each_with_object({}) do |node, hash|
399
518
  hash[node.node_name] = node
@@ -409,7 +528,7 @@ module Nokogiri
409
528
  ###
410
529
  # Does this Node's attributes include <value>
411
530
  def value?(value)
412
- values.include? value
531
+ values.include?(value)
413
532
  end
414
533
 
415
534
  ###
@@ -421,36 +540,36 @@ module Nokogiri
421
540
  ###
422
541
  # Iterate over each attribute name and value pair for this Node.
423
542
  def each
424
- attribute_nodes.each { |node|
543
+ attribute_nodes.each do |node|
425
544
  yield [node.node_name, node.value]
426
- }
545
+ end
427
546
  end
428
547
 
429
548
  ###
430
549
  # Remove the attribute named +name+
431
550
  def remove_attribute(name)
432
- attr = attributes[name].remove if key? name
551
+ attr = attributes[name].remove if key?(name)
433
552
  clear_xpath_context if Nokogiri.jruby?
434
553
  attr
435
554
  end
436
555
 
437
- # Get the CSS class names of a Node.
556
+ #
557
+ # :call-seq: classes() → Array<String>
558
+ #
559
+ # Fetch CSS class names of a Node.
438
560
  #
439
561
  # This is a convenience function and is equivalent to:
562
+ #
440
563
  # node.kwattr_values("class")
441
564
  #
442
- # @see #kwattr_values
443
- # @see #add_class
444
- # @see #append_class
445
- # @see #remove_class
565
+ # See related: #kwattr_values, #add_class, #append_class, #remove_class
446
566
  #
447
- # @return [Array<String>]
567
+ # [Returns]
568
+ # The CSS classes (Array of String) present in the Node's "class" attribute. If the
569
+ # attribute is empty or non-existent, the return value is an empty array.
448
570
  #
449
- # The CSS classes present in the Node's +class+ attribute. If
450
- # the attribute is empty or non-existent, the return value is
451
- # an empty array.
571
+ # *Example*
452
572
  #
453
- # @example
454
573
  # node # => <div class="section title header"></div>
455
574
  # node.classes # => ["section", "title", "header"]
456
575
  #
@@ -458,42 +577,45 @@ module Nokogiri
458
577
  kwattr_values("class")
459
578
  end
460
579
 
461
- # Ensure HTML CSS classes are present on a +Node+. Any CSS
462
- # classes in +names+ that already exist in the +Node+'s +class+
463
- # attribute are _not_ added. Note that any existing duplicates
464
- # in the +class+ attribute are not removed. Compare with
465
- # {#append_class}.
580
+ #
581
+ # :call-seq: add_class(names) self
582
+ #
583
+ # Ensure HTML CSS classes are present on +self+. Any CSS classes in +names+ that already exist
584
+ # in the "class" attribute are _not_ added. Note that any existing duplicates in the
585
+ # "class" attribute are not removed. Compare with #append_class.
466
586
  #
467
587
  # This is a convenience function and is equivalent to:
588
+ #
468
589
  # node.kwattr_add("class", names)
469
590
  #
470
- # @see #kwattr_add
471
- # @see #classes
472
- # @see #append_class
473
- # @see #remove_class
591
+ # See related: #kwattr_add, #classes, #append_class, #remove_class
474
592
  #
475
- # @param names [String, Array<String>]
593
+ # [Parameters]
594
+ # - +names+ (String, Array<String>)
476
595
  #
477
- # CSS class names to be added to the Node's +class+
478
- # attribute. May be a string containing whitespace-delimited
479
- # names, or an Array of String names. Any class names already
480
- # present will not be added. Any class names not present will
481
- # be added. If no +class+ attribute exists, one is created.
596
+ # CSS class names to be added to the Node's "class" attribute. May be a string containing
597
+ # whitespace-delimited names, or an Array of String names. Any class names already present
598
+ # will not be added. Any class names not present will be added. If no "class" attribute
599
+ # exists, one is created.
482
600
  #
483
- # @return [Node] Returns +self+ for ease of chaining method calls.
601
+ # [Returns] +self+ (Node) for ease of chaining method calls.
602
+ #
603
+ # *Example:* Ensure that the node has CSS class "section"
484
604
  #
485
- # @example Ensure that a +Node+ has CSS class "section"
486
605
  # node # => <div></div>
487
606
  # node.add_class("section") # => <div class="section"></div>
488
607
  # node.add_class("section") # => <div class="section"></div> # duplicate not added
489
608
  #
490
- # @example Ensure that a +Node+ has CSS classes "section" and "header", via a String argument.
609
+ # *Example:* Ensure that the node has CSS classes "section" and "header", via a String argument
610
+ #
611
+ # Note that the CSS class "section" is not added because it is already present.
612
+ # Note also that the pre-existing duplicate CSS class "section" is not removed.
613
+ #
491
614
  # node # => <div class="section section"></div>
492
615
  # node.add_class("section header") # => <div class="section section header"></div>
493
- # # Note that the CSS class "section" is not added because it is already present.
494
- # # Note also that the pre-existing duplicate CSS class "section" is not removed.
495
616
  #
496
- # @example Ensure that a +Node+ has CSS classes "section" and "header", via an Array argument.
617
+ # *Example:* Ensure that the node has CSS classes "section" and "header", via an Array argument
618
+ #
497
619
  # node # => <div></div>
498
620
  # node.add_class(["section", "header"]) # => <div class="section header"></div>
499
621
  #
@@ -501,39 +623,42 @@ module Nokogiri
501
623
  kwattr_add("class", names)
502
624
  end
503
625
 
504
- # Add HTML CSS classes to a +Node+, regardless of
505
- # duplication. Compare with {#add_class}.
626
+ #
627
+ # :call-seq: append_class(names) self
628
+ #
629
+ # Add HTML CSS classes to +self+, regardless of duplication. Compare with #add_class.
506
630
  #
507
631
  # This is a convenience function and is equivalent to:
632
+ #
508
633
  # node.kwattr_append("class", names)
509
634
  #
510
- # @see #kwattr_append
511
- # @see #classes
512
- # @see #add_class
513
- # @see #remove_class
635
+ # See related: #kwattr_append, #classes, #add_class, #remove_class
636
+ #
637
+ # [Parameters]
638
+ # - +names+ (String, Array<String>)
514
639
  #
515
- # @param names [String, Array<String>]
640
+ # CSS class names to be appended to the Node's "class" attribute. May be a string containing
641
+ # whitespace-delimited names, or an Array of String names. All class names passed in will be
642
+ # appended to the "class" attribute even if they are already present in the attribute
643
+ # value. If no "class" attribute exists, one is created.
516
644
  #
517
- # CSS class names to be appended to the Node's +class+
518
- # attribute. May be a string containing whitespace-delimited
519
- # names, or an Array of String names. All class names passed
520
- # in will be appended to the +class+ attribute even if they
521
- # are already present in the attribute value. If no +class+
522
- # attribute exists, one is created.
645
+ # [Returns] +self+ (Node) for ease of chaining method calls.
523
646
  #
524
- # @return [Node] Returns +self+ for ease of chaining method calls.
647
+ # *Example:* Append "section" to the node's CSS "class" attribute
525
648
  #
526
- # @example Append "section" to a +Node+'s CSS +class+ attriubute
527
649
  # node # => <div></div>
528
650
  # node.append_class("section") # => <div class="section"></div>
529
651
  # node.append_class("section") # => <div class="section section"></div> # duplicate added!
530
652
  #
531
- # @example Append "section" and "header" to a +Node+'s CSS +class+ attribute, via a String argument.
653
+ # *Example:* Append "section" and "header" to the noded's CSS "class" attribute, via a String argument
654
+ #
655
+ # Note that the CSS class "section" is appended even though it is already present
656
+ #
532
657
  # node # => <div class="section section"></div>
533
658
  # node.append_class("section header") # => <div class="section section section header"></div>
534
- # # Note that the CSS class "section" is appended even though it is already present.
535
659
  #
536
- # @example Append "section" and "header" to a +Node+'s CSS +class+ attribute, via an Array argument.
660
+ # *Example:* Append "section" and "header" to the node's CSS "class" attribute, via an Array argument
661
+ #
537
662
  # node # => <div></div>
538
663
  # node.append_class(["section", "header"]) # => <div class="section header"></div>
539
664
  # node.append_class(["section", "header"]) # => <div class="section header section header"></div>
@@ -542,118 +667,135 @@ module Nokogiri
542
667
  kwattr_append("class", names)
543
668
  end
544
669
 
545
- # Remove HTML CSS classes from a +Node+. Any CSS classes in +names+ that
546
- # exist in the +Node+'s +class+ attribute are removed, including any
547
- # multiple entries.
670
+ # :call-seq:
671
+ # remove_class(css_classes) self
672
+ #
673
+ # Remove HTML CSS classes from this node. Any CSS class names in +css_classes+ that exist in
674
+ # this node's "class" attribute are removed, including any multiple entries.
548
675
  #
549
- # If no CSS classes remain after this operation, or if +names+ is
550
- # +nil+, the +class+ attribute is deleted from the node.
676
+ # If no CSS classes remain after this operation, or if +css_classes+ is +nil+, the "class"
677
+ # attribute is deleted from the node.
551
678
  #
552
679
  # This is a convenience function and is equivalent to:
553
- # node.kwattr_remove("class", names)
554
680
  #
555
- # @see #kwattr_remove
556
- # @see #classes
557
- # @see #add_class
558
- # @see #append_class
681
+ # node.kwattr_remove("class", css_classes)
559
682
  #
560
- # @param names [String, Array<String>]
683
+ # Also see #kwattr_remove, #classes, #add_class, #append_class
561
684
  #
562
- # CSS class names to be removed from the Node's +class+ attribute. May
563
- # be a string containing whitespace-delimited names, or an Array of
564
- # String names. Any class names already present will be removed. If no
565
- # CSS classes remain, the +class+ attribute is deleted.
685
+ # [Parameters]
686
+ # - +css_classes+ (String, Array<String>)
566
687
  #
567
- # @return [Node] Returns +self+ for ease of chaining method calls.
688
+ # CSS class names to be removed from the Node's
689
+ # "class" attribute. May be a string containing whitespace-delimited names, or an Array of
690
+ # String names. Any class names already present will be removed. If no CSS classes remain,
691
+ # the "class" attribute is deleted.
568
692
  #
569
- # @example
570
- # node # => <div class="section header"></div>
693
+ # [Returns] +self+ (Nokogiri::XML::Node) for ease of chaining method calls.
694
+ #
695
+ # *Example*: Deleting a CSS class
696
+ #
697
+ # Note that all instances of the class "section" are removed from the "class" attribute.
698
+ #
699
+ # node # => <div class="section header section"></div>
571
700
  # node.remove_class("section") # => <div class="header"></div>
572
- # node.remove_class("header") # => <div></div> # attribute is deleted when empty
701
+ #
702
+ # *Example*: Deleting the only remaining CSS class
703
+ #
704
+ # Note that the attribute is removed once there are no remaining classes.
705
+ #
706
+ # node # => <div class="section"></div>
707
+ # node.remove_class("section") # => <div></div>
708
+ #
709
+ # *Example*: Deleting multiple CSS classes
710
+ #
711
+ # Note that the "class" attribute is deleted once it's empty.
712
+ #
713
+ # node # => <div class="section header float"></div>
714
+ # node.remove_class(["section", "float"]) # => <div class="header"></div>
573
715
  #
574
716
  def remove_class(names = nil)
575
717
  kwattr_remove("class", names)
576
718
  end
577
719
 
578
- # Retrieve values from a keyword attribute of a Node.
720
+ # :call-seq:
721
+ # kwattr_values(attribute_name) → Array<String>
722
+ #
723
+ # Fetch values from a keyword attribute of a Node.
579
724
  #
580
- # A "keyword attribute" is a node attribute that contains a set
581
- # of space-delimited values. Perhaps the most familiar example
582
- # of this is the HTML +class+ attribute used to contain CSS
583
- # classes. But other keyword attributes exist, for instance
584
- # [`rel`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).
725
+ # A "keyword attribute" is a node attribute that contains a set of space-delimited
726
+ # values. Perhaps the most familiar example of this is the HTML "class" attribute used to
727
+ # contain CSS classes. But other keyword attributes exist, for instance
728
+ # {the "rel" attribute}[https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel].
585
729
  #
586
- # @see #classes
587
- # @see #kwattr_add
588
- # @see #kwattr_append
589
- # @see #kwattr_remove
730
+ # See also #classes, #kwattr_add, #kwattr_append, #kwattr_remove
590
731
  #
591
- # @param attribute_name [String] The name of the keyword attribute to be inspected.
732
+ # [Parameters]
733
+ # - +attribute_name+ (String) The name of the keyword attribute to be inspected.
592
734
  #
593
- # @return [Array<String>]
735
+ # [Returns]
736
+ # (Array<String>) The values present in the Node's +attribute_name+ attribute. If the
737
+ # attribute is empty or non-existent, the return value is an empty array.
594
738
  #
595
- # The values present in the Node's +attribute_name+
596
- # attribute. If the attribute is empty or non-existent, the
597
- # return value is an empty array.
739
+ # *Example:*
598
740
  #
599
- # @example
600
741
  # node # => <a rel="nofollow noopener external">link</a>
601
742
  # node.kwattr_values("rel") # => ["nofollow", "noopener", "external"]
602
743
  #
603
- # @since v1.11.0
604
- #
744
+ # Since v1.11.0
605
745
  def kwattr_values(attribute_name)
606
746
  keywordify(get_attribute(attribute_name) || [])
607
747
  end
608
748
 
749
+ # :call-seq:
750
+ # kwattr_add(attribute_name, keywords) → self
751
+ #
609
752
  # Ensure that values are present in a keyword attribute.
610
753
  #
611
- # Any values in +keywords+ that already exist in the +Node+'s
612
- # attribute values are _not_ added. Note that any existing
613
- # duplicates in the attribute values are not removed. Compare
614
- # with {#kwattr_append}.
754
+ # Any values in +keywords+ that already exist in the Node's attribute values are _not_
755
+ # added. Note that any existing duplicates in the attribute values are not removed. Compare
756
+ # with #kwattr_append.
615
757
  #
616
- # A "keyword attribute" is a node attribute that contains a set
617
- # of space-delimited values. Perhaps the most familiar example
618
- # of this is the HTML +class+ attribute used to contain CSS
619
- # classes. But other keyword attributes exist, for instance
620
- # [`rel`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).
758
+ # A "keyword attribute" is a node attribute that contains a set of space-delimited
759
+ # values. Perhaps the most familiar example of this is the HTML "class" attribute used to
760
+ # contain CSS classes. But other keyword attributes exist, for instance
761
+ # {the "rel" attribute}[https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel].
621
762
  #
622
- # @see #add_class
623
- # @see #kwattr_values
624
- # @see #kwattr_append
625
- # @see #kwattr_remove
763
+ # See also #add_class, #kwattr_values, #kwattr_append, #kwattr_remove
626
764
  #
627
- # @param attribute_name [String] The name of the keyword attribute to be modified.
765
+ # [Parameters]
766
+ # - +attribute_name+ (String) The name of the keyword attribute to be modified.
767
+ # - +keywords+ (String, Array<String>)
768
+ # Keywords to be added to the attribute named +attribute_name+. May be a string containing
769
+ # whitespace-delimited values, or an Array of String values. Any values already present will
770
+ # not be added. Any values not present will be added. If the named attribute does not exist,
771
+ # it is created.
628
772
  #
629
- # @param keywords [String, Array<String>]
773
+ # [Returns] +self+ (Nokogiri::XML::Node) for ease of chaining method calls.
630
774
  #
631
- # Keywords to be added to the attribute named
632
- # +attribute_name+. May be a string containing
633
- # whitespace-delimited values, or an Array of String
634
- # values. Any values already present will not be added. Any
635
- # values not present will be added. If the named attribute
636
- # does not exist, it is created.
775
+ # *Example:* Ensure that a +Node+ has "nofollow" in its +rel+ attribute.
637
776
  #
638
- # @return [Node] Returns +self+ for ease of chaining method calls.
777
+ # Note that duplicates are not added.
639
778
  #
640
- # @example Ensure that a +Node+ has "nofollow" in its +rel+ attribute.
641
779
  # node # => <a></a>
642
780
  # node.kwattr_add("rel", "nofollow") # => <a rel="nofollow"></a>
643
- # node.kwattr_add("rel", "nofollow") # => <a rel="nofollow"></a> # duplicate not added
781
+ # node.kwattr_add("rel", "nofollow") # => <a rel="nofollow"></a>
782
+ #
783
+ # *Example:* Ensure that a +Node+ has "nofollow" and "noreferrer" in its +rel+ attribute, via a
784
+ # String argument.
785
+ #
786
+ # Note that "nofollow" is not added because it is already present. Note also that the
787
+ # pre-existing duplicate "nofollow" is not removed.
644
788
  #
645
- # @example Ensure that a +Node+ has "nofollow" and "noreferrer" in its +rel+ attribute, via a String argument.
646
789
  # node # => <a rel="nofollow nofollow"></a>
647
790
  # node.kwattr_add("rel", "nofollow noreferrer") # => <a rel="nofollow nofollow noreferrer"></a>
648
- # # Note that "nofollow" is not added because it is already present.
649
- # # Note also that the pre-existing duplicate "nofollow" is not removed.
650
791
  #
651
- # @example Ensure that a +Node+ has "nofollow" and "noreferrer" in its +rel+ attribute, via an Array argument.
792
+ # *Example:* Ensure that a +Node+ has "nofollow" and "noreferrer" in its +rel+ attribute, via
793
+ # an Array argument.
794
+ #
652
795
  # node # => <a></a>
653
796
  # node.kwattr_add("rel", ["nofollow", "noreferrer"]) # => <a rel="nofollow noreferrer"></a>
654
797
  #
655
- # @since v1.11.0
656
- #
798
+ # Since v1.11.0
657
799
  def kwattr_add(attribute_name, keywords)
658
800
  keywords = keywordify(keywords)
659
801
  current_kws = kwattr_values(attribute_name)
@@ -662,50 +804,51 @@ module Nokogiri
662
804
  self
663
805
  end
664
806
 
665
- # Add keywords to a Node's keyword attribute, regardless of
666
- # duplication. Compare with {#kwattr_add}.
807
+ # :call-seq:
808
+ # kwattr_append(attribute_name, keywords) self
667
809
  #
668
- # A "keyword attribute" is a node attribute that contains a set
669
- # of space-delimited values. Perhaps the most familiar example
670
- # of this is the HTML +class+ attribute used to contain CSS
671
- # classes. But other keyword attributes exist, for instance
672
- # [`rel`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).
810
+ # Add keywords to a Node's keyword attribute, regardless of duplication. Compare with
811
+ # #kwattr_add.
673
812
  #
674
- # @see #append_class
675
- # @see #kwattr_values
676
- # @see #kwattr_add
677
- # @see #kwattr_remove
813
+ # A "keyword attribute" is a node attribute that contains a set of space-delimited
814
+ # values. Perhaps the most familiar example of this is the HTML "class" attribute used to
815
+ # contain CSS classes. But other keyword attributes exist, for instance
816
+ # {the "rel" attribute}[https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel].
678
817
  #
679
- # @param attribute_name [String] The name of the keyword attribute to be modified.
818
+ # See also #append_class, #kwattr_values, #kwattr_add, #kwattr_remove
680
819
  #
681
- # @param keywords [String, Array<String>]
820
+ # [Parameters]
821
+ # - +attribute_name+ (String) The name of the keyword attribute to be modified.
822
+ # - +keywords+ (String, Array<String>)
823
+ # Keywords to be added to the attribute named +attribute_name+. May be a string containing
824
+ # whitespace-delimited values, or an Array of String values. All values passed in will be
825
+ # appended to the named attribute even if they are already present in the attribute. If the
826
+ # named attribute does not exist, it is created.
682
827
  #
683
- # Keywords to be added to the attribute named
684
- # +attribute_name+. May be a string containing
685
- # whitespace-delimited values, or an Array of String
686
- # values. All values passed in will be appended to the named
687
- # attribute even if they are already present in the
688
- # attribute. If the named attribute does not exist, it is
689
- # created.
828
+ # [Returns] +self+ (Node) for ease of chaining method calls.
690
829
  #
691
- # @return [Node] Returns +self+ for ease of chaining method calls.
830
+ # *Example:* Append "nofollow" to the +rel+ attribute.
831
+ #
832
+ # Note that duplicates are added.
692
833
  #
693
- # @example Append "nofollow" to the +rel+ attribute.
694
834
  # node # => <a></a>
695
835
  # node.kwattr_append("rel", "nofollow") # => <a rel="nofollow"></a>
696
- # node.kwattr_append("rel", "nofollow") # => <a rel="nofollow nofollow"></a> # duplicate added!
836
+ # node.kwattr_append("rel", "nofollow") # => <a rel="nofollow nofollow"></a>
837
+ #
838
+ # *Example:* Append "nofollow" and "noreferrer" to the +rel+ attribute, via a String argument.
839
+ #
840
+ # Note that "nofollow" is appended even though it is already present.
697
841
  #
698
- # @example Append "nofollow" and "noreferrer" to the +rel+ attribute, via a String argument.
699
842
  # node # => <a rel="nofollow"></a>
700
843
  # node.kwattr_append("rel", "nofollow noreferrer") # => <a rel="nofollow nofollow noreferrer"></a>
701
- # # Note that "nofollow" is appended even though it is already present.
702
844
  #
703
- # @example Append "nofollow" and "noreferrer" to the +rel+ attribute, via an Array argument.
845
+ #
846
+ # *Example:* Append "nofollow" and "noreferrer" to the +rel+ attribute, via an Array argument.
847
+ #
704
848
  # node # => <a></a>
705
849
  # node.kwattr_append("rel", ["nofollow", "noreferrer"]) # => <a rel="nofollow noreferrer"></a>
706
850
  #
707
- # @since v1.11.0
708
- #
851
+ # Since v1.11.0
709
852
  def kwattr_append(attribute_name, keywords)
710
853
  keywords = keywordify(keywords)
711
854
  current_kws = kwattr_values(attribute_name)
@@ -714,44 +857,41 @@ module Nokogiri
714
857
  self
715
858
  end
716
859
 
717
- # Remove keywords from a keyword attribute. Any matching
718
- # keywords that exist in the named attribute are removed,
719
- # including any multiple entries.
860
+ # :call-seq:
861
+ # kwattr_remove(attribute_name, keywords) self
720
862
  #
721
- # If no keywords remain after this operation, or if +keywords+
722
- # is +nil+, the attribute is deleted from the node.
863
+ # Remove keywords from a keyword attribute. Any matching keywords that exist in the named
864
+ # attribute are removed, including any multiple entries.
723
865
  #
724
- # A "keyword attribute" is a node attribute that contains a set
725
- # of space-delimited values. Perhaps the most familiar example
726
- # of this is the HTML +class+ attribute used to contain CSS
727
- # classes. But other keyword attributes exist, for instance
728
- # [`rel`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel).
866
+ # If no keywords remain after this operation, or if +keywords+ is +nil+, the attribute is
867
+ # deleted from the node.
729
868
  #
730
- # @see #remove_class
731
- # @see #kwattr_values
732
- # @see #kwattr_add
733
- # @see #kwattr_append
869
+ # A "keyword attribute" is a node attribute that contains a set of space-delimited
870
+ # values. Perhaps the most familiar example of this is the HTML "class" attribute used to
871
+ # contain CSS classes. But other keyword attributes exist, for instance
872
+ # {the "rel" attribute}[https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel].
734
873
  #
735
- # @param attribute_name [String] The name of the keyword attribute to be modified.
874
+ # See also #remove_class, #kwattr_values, #kwattr_add, #kwattr_append
736
875
  #
737
- # @param keywords [String, Array<String>]
876
+ # [Parameters]
877
+ # - +attribute_name+ (String) The name of the keyword attribute to be modified.
878
+ # - +keywords+ (String, Array<String>)
879
+ # Keywords to be removed from the attribute named +attribute_name+. May be a string
880
+ # containing whitespace-delimited values, or an Array of String values. Any keywords present
881
+ # in the named attribute will be removed. If no keywords remain, or if +keywords+ is nil,
882
+ # the attribute is deleted.
738
883
  #
739
- # Keywords to be removed from the attribute named
740
- # +attribute_name+. May be a string containing
741
- # whitespace-delimited values, or an Array of String
742
- # values. Any keywords present in the named attribute will be
743
- # removed. If no keywords remain, or if +keywords+ is nil, the
744
- # attribute is deleted.
884
+ # [Returns] +self+ (Node) for ease of chaining method calls.
745
885
  #
746
- # @return [Node] Returns +self+ for ease of chaining method calls.
886
+ # *Example:*
887
+ #
888
+ # Note that the +rel+ attribute is deleted when empty.
747
889
  #
748
- # @example
749
890
  # node # => <a rel="nofollow noreferrer">link</a>
750
891
  # node.kwattr_remove("rel", "nofollow") # => <a rel="noreferrer">link</a>
751
- # node.kwattr_remove("rel", "noreferrer") # => <a>link</a> # attribute is deleted when empty
752
- #
753
- # @since v1.11.0
892
+ # node.kwattr_remove("rel", "noreferrer") # => <a>link</a>
754
893
  #
894
+ # Since v1.11.0
755
895
  def kwattr_remove(attribute_name, keywords)
756
896
  if keywords.nil?
757
897
  remove_attribute(attribute_name)
@@ -769,13 +909,13 @@ module Nokogiri
769
909
  self
770
910
  end
771
911
 
772
- alias :delete :remove_attribute
773
- alias :get_attribute :[]
774
- alias :attr :[]
775
- alias :set_attribute :[]=
776
- alias :has_attribute? :key?
912
+ alias_method :delete, :remove_attribute
913
+ alias_method :get_attribute, :[]
914
+ alias_method :attr, :[]
915
+ alias_method :set_attribute, :[]=
916
+ alias_method :has_attribute?, :key?
777
917
 
778
- # @!endgroup
918
+ # :section:
779
919
 
780
920
  ###
781
921
  # Returns true if this Node matches +selector+
@@ -787,8 +927,7 @@ module Nokogiri
787
927
  # Create a DocumentFragment containing +tags+ that is relative to _this_
788
928
  # context node.
789
929
  def fragment(tags)
790
- type = document.html? ? Nokogiri::HTML : Nokogiri::XML
791
- type::DocumentFragment.new(document, tags, self)
930
+ document.related_class("DocumentFragment").new(document, tags, self)
792
931
  end
793
932
 
794
933
  ###
@@ -806,19 +945,18 @@ module Nokogiri
806
945
  end
807
946
 
808
947
  options ||= (document.html? ? ParseOptions::DEFAULT_HTML : ParseOptions::DEFAULT_XML)
809
- if Integer === options
810
- options = Nokogiri::XML::ParseOptions.new(options)
811
- end
812
- # Give the options to the user
948
+ options = Nokogiri::XML::ParseOptions.new(options) if Integer === options
813
949
  yield options if block_given?
814
950
 
815
- contents = string_or_io.respond_to?(:read) ?
816
- string_or_io.read :
951
+ contents = if string_or_io.respond_to?(:read)
952
+ string_or_io.read
953
+ else
817
954
  string_or_io
955
+ end
818
956
 
819
957
  return Nokogiri::XML::NodeSet.new(document) if contents.empty?
820
958
 
821
- # libxml2 does not obey the `recover` option after encountering errors during `in_context`
959
+ # libxml2 does not obey the +recover+ option after encountering errors during +in_context+
822
960
  # parsing, and so this horrible hack is here to try to emulate recovery behavior.
823
961
  #
824
962
  # Unfortunately, this means we're no longer parsing "in context" and so namespaces that
@@ -828,16 +966,16 @@ module Nokogiri
828
966
  #
829
967
  # I think preferable behavior would be to either:
830
968
  #
831
- # a. add an error noting that we "fell back" and pointing the user to turning off the `recover` option
969
+ # a. add an error noting that we "fell back" and pointing the user to turning off the +recover+ option
832
970
  # b. don't recover, but raise a sensible exception
833
971
  #
834
972
  # For context and background: https://github.com/sparklemotion/nokogiri/issues/313
835
973
  # FIXME bug report: https://github.com/sparklemotion/nokogiri/issues/2092
836
974
  error_count = document.errors.length
837
975
  node_set = in_context(contents, options.to_i)
838
- if (node_set.empty? && (document.errors.length > error_count))
976
+ if node_set.empty? && (document.errors.length > error_count)
839
977
  if options.recover?
840
- fragment = Nokogiri::HTML::DocumentFragment.parse contents
978
+ fragment = document.related_class("DocumentFragment").parse(contents)
841
979
  node_set = fragment.children
842
980
  else
843
981
  raise document.errors[error_count]
@@ -846,20 +984,42 @@ module Nokogiri
846
984
  node_set
847
985
  end
848
986
 
849
- ###
850
- # Returns a Hash of +{prefix => value}+ for all namespaces on this
851
- # node and its ancestors.
852
- #
853
- # This method returns the same namespaces as #namespace_scopes.
854
- #
855
- # Returns namespaces in scope for self -- those defined on self
856
- # element directly or any ancestor node -- as a Hash of
857
- # attribute-name/value pairs. Note that the keys in this hash
858
- # XML attributes that would be used to define this namespace,
859
- # such as "xmlns:prefix", not just the prefix. Default namespace
860
- # set on self will be included with key "xmlns". However,
861
- # default namespaces set on ancestor will NOT be, even if self
862
- # has no explicit default namespace.
987
+ # :call-seq:
988
+ # namespaces() Hash<String(Namespace#prefix) String(Namespace#href)>
989
+ #
990
+ # Fetch all the namespaces on this node and its ancestors.
991
+ #
992
+ # Note that the keys in this hash XML attributes that would be used to define this namespace,
993
+ # such as "xmlns:prefix", not just the prefix.
994
+ #
995
+ # The default namespace for this node will be included with key "xmlns".
996
+ #
997
+ # See also #namespace_scopes
998
+ #
999
+ # [Returns]
1000
+ # Hash containing all the namespaces on this node and its ancestors. The hash keys are the
1001
+ # namespace prefix, and the hash value for each key is the namespace URI.
1002
+ #
1003
+ # *Example:*
1004
+ #
1005
+ # doc = Nokogiri::XML(<<~EOF)
1006
+ # <root xmlns="http://example.com/root" xmlns:in_scope="http://example.com/in_scope">
1007
+ # <first/>
1008
+ # <second xmlns="http://example.com/child"/>
1009
+ # <third xmlns:foo="http://example.com/foo"/>
1010
+ # </root>
1011
+ # EOF
1012
+ # doc.at_xpath("//root:first", "root" => "http://example.com/root").namespaces
1013
+ # # => {"xmlns"=>"http://example.com/root",
1014
+ # # "xmlns:in_scope"=>"http://example.com/in_scope"}
1015
+ # doc.at_xpath("//child:second", "child" => "http://example.com/child").namespaces
1016
+ # # => {"xmlns"=>"http://example.com/child",
1017
+ # # "xmlns:in_scope"=>"http://example.com/in_scope"}
1018
+ # doc.at_xpath("//root:third", "root" => "http://example.com/root").namespaces
1019
+ # # => {"xmlns:foo"=>"http://example.com/foo",
1020
+ # # "xmlns"=>"http://example.com/root",
1021
+ # # "xmlns:in_scope"=>"http://example.com/in_scope"}
1022
+ #
863
1023
  def namespaces
864
1024
  namespace_scopes.each_with_object({}) do |ns, hash|
865
1025
  prefix = ns.prefix
@@ -883,14 +1043,14 @@ module Nokogiri
883
1043
  type == DOCUMENT_NODE
884
1044
  end
885
1045
 
886
- # Returns true if this is an HTML::Document node
1046
+ # Returns true if this is an HTML4::Document or HTML5::Document node
887
1047
  def html?
888
1048
  type == HTML_DOCUMENT_NODE
889
1049
  end
890
1050
 
891
1051
  # Returns true if this is a Document
892
1052
  def document?
893
- is_a? XML::Document
1053
+ is_a?(XML::Document)
894
1054
  end
895
1055
 
896
1056
  # Returns true if this is a ProcessingInstruction node
@@ -909,11 +1069,12 @@ module Nokogiri
909
1069
  end
910
1070
 
911
1071
  ###
912
- # Fetch the Nokogiri::HTML::ElementDescription for this node. Returns
1072
+ # Fetch the Nokogiri::HTML4::ElementDescription for this node. Returns
913
1073
  # nil on XML documents and on unknown tags.
914
1074
  def description
915
1075
  return nil if document.xml?
916
- Nokogiri::HTML::ElementDescription[name]
1076
+
1077
+ Nokogiri::HTML4::ElementDescription[name]
917
1078
  end
918
1079
 
919
1080
  ###
@@ -928,7 +1089,7 @@ module Nokogiri
928
1089
  type == ELEMENT_NODE
929
1090
  end
930
1091
 
931
- alias :elem? :element?
1092
+ alias_method :elem?, :element?
932
1093
 
933
1094
  ###
934
1095
  # Turn this node in to a string. If the document is HTML, this method
@@ -944,9 +1105,9 @@ module Nokogiri
944
1105
 
945
1106
  # Get the path to this node as a CSS expression
946
1107
  def css_path
947
- path.split(/\//).map { |part|
948
- part.length == 0 ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
949
- }.compact.join(" > ")
1108
+ path.split(%r{/}).map do |part|
1109
+ part.empty? ? nil : part.gsub(/\[(\d+)\]/, ':nth-of-type(\1)')
1110
+ end.compact.join(" > ")
950
1111
  end
951
1112
 
952
1113
  ###
@@ -959,7 +1120,8 @@ module Nokogiri
959
1120
  parents = [parent]
960
1121
 
961
1122
  while parents.last.respond_to?(:parent)
962
- break unless ctx_parent = parents.last.parent
1123
+ break unless (ctx_parent = parents.last.parent)
1124
+
963
1125
  parents << ctx_parent
964
1126
  end
965
1127
 
@@ -968,16 +1130,16 @@ module Nokogiri
968
1130
  root = parents.last
969
1131
  search_results = root.search(selector)
970
1132
 
971
- NodeSet.new(document, parents.find_all { |parent|
1133
+ NodeSet.new(document, parents.find_all do |parent|
972
1134
  search_results.include?(parent)
973
- })
1135
+ end)
974
1136
  end
975
1137
 
976
1138
  ####
977
1139
  # Yields self and all children to +block+ recursively.
978
1140
  def traverse(&block)
979
1141
  children.each { |j| j.traverse(&block) }
980
- block.call(self)
1142
+ yield(self)
981
1143
  end
982
1144
 
983
1145
  ###
@@ -991,6 +1153,7 @@ module Nokogiri
991
1153
  def ==(other)
992
1154
  return false unless other
993
1155
  return false unless other.respond_to?(:pointer_id)
1156
+
994
1157
  pointer_id == other.pointer_id
995
1158
  end
996
1159
 
@@ -1000,14 +1163,16 @@ module Nokogiri
1000
1163
  def <=>(other)
1001
1164
  return nil unless other.is_a?(Nokogiri::XML::Node)
1002
1165
  return nil unless document == other.document
1003
- compare other
1166
+
1167
+ compare(other)
1004
1168
  end
1005
1169
 
1006
- # @!group Serialization and Generating Output
1170
+ # :section: Serialization and Generating Output
1007
1171
 
1008
1172
  ###
1009
- # Serialize Node using +options+. Save options can also be set using a
1010
- # block. See SaveOptions.
1173
+ # Serialize Node using +options+. Save options can also be set using a block.
1174
+ #
1175
+ # See also Nokogiri::XML::Node::SaveOptions and Node@Serialization+and+Generating+Output.
1011
1176
  #
1012
1177
  # These two statements are equivalent:
1013
1178
  #
@@ -1020,18 +1185,22 @@ module Nokogiri
1020
1185
  # end
1021
1186
  #
1022
1187
  def serialize(*args, &block)
1023
- options = args.first.is_a?(Hash) ? args.shift : {
1024
- :encoding => args[0],
1025
- :save_with => args[1],
1026
- }
1188
+ options = if args.first.is_a?(Hash)
1189
+ args.shift
1190
+ else
1191
+ {
1192
+ encoding: args[0],
1193
+ save_with: args[1],
1194
+ }
1195
+ end
1027
1196
 
1028
1197
  encoding = options[:encoding] || document.encoding
1029
1198
  options[:encoding] = encoding
1030
1199
 
1031
- outstring = String.new
1200
+ outstring = +""
1032
1201
  outstring.force_encoding(Encoding.find(encoding || "utf-8"))
1033
1202
  io = StringIO.new(outstring)
1034
- write_to io, options, &block
1203
+ write_to(io, options, &block)
1035
1204
  io.string
1036
1205
  end
1037
1206
 
@@ -1043,7 +1212,7 @@ module Nokogiri
1043
1212
  # See Node#write_to for a list of +options+. For formatted output,
1044
1213
  # use Node#to_xhtml instead.
1045
1214
  def to_html(options = {})
1046
- to_format SaveOptions::DEFAULT_HTML, options
1215
+ to_format(SaveOptions::DEFAULT_HTML, options)
1047
1216
  end
1048
1217
 
1049
1218
  ###
@@ -1064,7 +1233,7 @@ module Nokogiri
1064
1233
  #
1065
1234
  # See Node#write_to for a list of +options+
1066
1235
  def to_xhtml(options = {})
1067
- to_format SaveOptions::DEFAULT_XHTML, options
1236
+ to_format(SaveOptions::DEFAULT_XHTML, options)
1068
1237
  end
1069
1238
 
1070
1239
  ###
@@ -1112,7 +1281,7 @@ module Nokogiri
1112
1281
  #
1113
1282
  # See Node#write_to for a list of +options+
1114
1283
  def write_html_to(io, options = {})
1115
- write_format_to SaveOptions::DEFAULT_HTML, io, options
1284
+ write_format_to(SaveOptions::DEFAULT_HTML, io, options)
1116
1285
  end
1117
1286
 
1118
1287
  ###
@@ -1120,7 +1289,7 @@ module Nokogiri
1120
1289
  #
1121
1290
  # See Node#write_to for a list of +options+
1122
1291
  def write_xhtml_to(io, options = {})
1123
- write_format_to SaveOptions::DEFAULT_XHTML, io, options
1292
+ write_format_to(SaveOptions::DEFAULT_XHTML, io, options)
1124
1293
  end
1125
1294
 
1126
1295
  ###
@@ -1131,7 +1300,7 @@ module Nokogiri
1131
1300
  # See Node#write_to for a list of options
1132
1301
  def write_xml_to(io, options = {})
1133
1302
  options[:save_with] ||= SaveOptions::DEFAULT_XML
1134
- write_to io, options
1303
+ write_to(io, options)
1135
1304
  end
1136
1305
 
1137
1306
  def canonicalize(mode = XML::XML_C14N_1_0, inclusive_namespaces = nil, with_comments = false)
@@ -1142,7 +1311,7 @@ module Nokogiri
1142
1311
  end
1143
1312
  end
1144
1313
 
1145
- # @!endgroup
1314
+ # :section:
1146
1315
 
1147
1316
  protected
1148
1317
 
@@ -1160,9 +1329,9 @@ module Nokogiri
1160
1329
  return data
1161
1330
  end
1162
1331
 
1163
- raise ArgumentError, <<-EOERR
1164
- Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
1165
- (You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
1332
+ raise ArgumentError, <<~EOERR
1333
+ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
1334
+ (You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
1166
1335
  EOERR
1167
1336
  end
1168
1337
 
@@ -1171,32 +1340,33 @@ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
1171
1340
  def keywordify(keywords)
1172
1341
  case keywords
1173
1342
  when Enumerable
1174
- return keywords
1343
+ keywords
1175
1344
  when String
1176
- return keywords.scan(/\S+/)
1345
+ keywords.scan(/\S+/)
1177
1346
  else
1178
- raise ArgumentError.new("Keyword attributes must be passed as either a String or an Enumerable, but received #{keywords.class}")
1347
+ raise ArgumentError,
1348
+ "Keyword attributes must be passed as either a String or an Enumerable, but received #{keywords.class}"
1179
1349
  end
1180
1350
  end
1181
1351
 
1182
1352
  def add_sibling(next_or_previous, node_or_tags)
1183
1353
  raise("Cannot add sibling to a node with no parent") unless parent
1184
1354
 
1185
- impl = (next_or_previous == :next) ? :add_next_sibling_node : :add_previous_sibling_node
1186
- iter = (next_or_previous == :next) ? :reverse_each : :each
1355
+ impl = next_or_previous == :next ? :add_next_sibling_node : :add_previous_sibling_node
1356
+ iter = next_or_previous == :next ? :reverse_each : :each
1187
1357
 
1188
1358
  node_or_tags = parent.coerce(node_or_tags)
1189
1359
  if node_or_tags.is_a?(XML::NodeSet)
1190
1360
  if text?
1191
- pivot = Nokogiri::XML::Node.new "dummy", document
1192
- send impl, pivot
1361
+ pivot = Nokogiri::XML::Node.new("dummy", document)
1362
+ send(impl, pivot)
1193
1363
  else
1194
1364
  pivot = self
1195
1365
  end
1196
- node_or_tags.send(iter) { |n| pivot.send impl, n }
1366
+ node_or_tags.send(iter) { |n| pivot.send(impl, n) }
1197
1367
  pivot.unlink if text?
1198
1368
  else
1199
- send impl, node_or_tags
1369
+ send(impl, node_or_tags)
1200
1370
  end
1201
1371
  node_or_tags
1202
1372
  end
@@ -1215,19 +1385,18 @@ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
1215
1385
  return (io << dump_html) if USING_LIBXML_WITH_BROKEN_SERIALIZATION
1216
1386
 
1217
1387
  options[:save_with] ||= save_option
1218
- write_to io, options
1388
+ write_to(io, options)
1219
1389
  end
1220
1390
 
1221
1391
  def inspect_attributes
1222
1392
  [:name, :namespace, :attribute_nodes, :children]
1223
1393
  end
1224
1394
 
1225
- # @private
1226
- IMPLIED_XPATH_CONTEXTS = [".//".freeze].freeze
1395
+ IMPLIED_XPATH_CONTEXTS = [".//"].freeze
1227
1396
 
1228
1397
  def add_child_node_and_reparent_attrs(node)
1229
- add_child_node node
1230
- node.attribute_nodes.find_all { |a| a.name =~ /:/ }.each do |attr_node|
1398
+ add_child_node(node)
1399
+ node.attribute_nodes.find_all { |a| a.name.include?(":") }.each do |attr_node|
1231
1400
  attr_node.remove
1232
1401
  node[attr_node.name] = attr_node.value
1233
1402
  end
@@ -1235,3 +1404,5 @@ Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
1235
1404
  end
1236
1405
  end
1237
1406
  end
1407
+
1408
+ require_relative "node/save_options"