nokogiri 1.4.2 → 1.4.3
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.
- data/CHANGELOG.ja.rdoc +28 -8
- data/CHANGELOG.rdoc +24 -1
- data/Manifest.txt +2 -1
- data/README.ja.rdoc +1 -1
- data/README.rdoc +22 -4
- data/Rakefile +6 -2
- data/ext/nokogiri/extconf.rb +55 -32
- data/ext/nokogiri/nokogiri.h +2 -0
- data/ext/nokogiri/xml_document.c +5 -0
- data/ext/nokogiri/xml_libxml2_hacks.c +112 -0
- data/ext/nokogiri/xml_libxml2_hacks.h +12 -0
- data/ext/nokogiri/xml_node.c +58 -12
- data/ext/nokogiri/xml_node_set.c +7 -7
- data/ext/nokogiri/xml_reader.c +20 -1
- data/ext/nokogiri/xml_xpath_context.c +2 -0
- data/lib/nokogiri/css/generated_parser.rb +155 -148
- data/lib/nokogiri/css/generated_tokenizer.rb +2 -1
- data/lib/nokogiri/css/parser.y +3 -0
- data/lib/nokogiri/css/xpath_visitor.rb +1 -7
- data/lib/nokogiri/ffi/libxml.rb +29 -4
- data/lib/nokogiri/ffi/xml/document.rb +4 -0
- data/lib/nokogiri/ffi/xml/node.rb +27 -19
- data/lib/nokogiri/ffi/xml/node_set.rb +3 -3
- data/lib/nokogiri/ffi/xml/reader.rb +4 -0
- data/lib/nokogiri/html.rb +2 -2
- data/lib/nokogiri/html/document_fragment.rb +7 -4
- data/lib/nokogiri/version.rb +2 -1
- data/lib/nokogiri/xml/builder.rb +1 -1
- data/lib/nokogiri/xml/document.rb +1 -2
- data/lib/nokogiri/xml/document_fragment.rb +7 -0
- data/lib/nokogiri/xml/node.rb +4 -2
- data/lib/nokogiri/xml/node_set.rb +25 -0
- data/lib/nokogiri/xml/reader.rb +2 -0
- data/lib/nokogiri/xml/sax/document.rb +3 -1
- data/test/css/test_parser.rb +11 -1
- data/test/html/sax/test_parser_context.rb +2 -2
- data/test/html/test_document.rb +2 -2
- data/test/html/test_document_fragment.rb +34 -6
- data/test/test_memory_leak.rb +2 -2
- data/test/test_reader.rb +28 -6
- data/test/test_xslt_transforms.rb +29 -28
- data/test/xml/test_attr.rb +31 -4
- data/test/xml/test_builder.rb +5 -5
- data/test/xml/test_cdata.rb +3 -3
- data/test/xml/test_document.rb +8 -8
- data/test/xml/test_document_fragment.rb +2 -2
- data/test/xml/test_node.rb +1 -1
- data/test/xml/test_node_reparenting.rb +26 -11
- data/test/xml/test_node_set.rb +38 -2
- data/test/xml/test_text.rb +11 -2
- data/test/xml/test_unparented_node.rb +1 -1
- data/test/xml/test_xpath.rb +78 -11
- metadata +24 -5
- data/lib/nokogiri/version_warning.rb +0 -14
@@ -1,6 +1,6 @@
|
|
1
1
|
#--
|
2
2
|
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by rex 1.0.
|
3
|
+
# This file is automatically generated by rex 1.0.5.beta1
|
4
4
|
# from lexical definition file "lib/nokogiri/css/tokenizer.rex".
|
5
5
|
#++
|
6
6
|
|
@@ -29,6 +29,7 @@ class GeneratedTokenizer < GeneratedParser
|
|
29
29
|
scan_setup(str)
|
30
30
|
do_parse
|
31
31
|
end
|
32
|
+
alias :scan :scan_str
|
32
33
|
|
33
34
|
def load_file( filename )
|
34
35
|
@filename = filename
|
data/lib/nokogiri/css/parser.y
CHANGED
@@ -48,13 +48,6 @@ module Nokogiri
|
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
def visit_preceding_selector node
|
52
|
-
node.value.last.accept(self) +
|
53
|
-
'[preceding-sibling::' +
|
54
|
-
node.value.first.accept(self) +
|
55
|
-
']'
|
56
|
-
end
|
57
|
-
|
58
51
|
def visit_id node
|
59
52
|
node.value.first =~ /^#(.*)$/
|
60
53
|
"@id = '#{$1}'"
|
@@ -126,6 +119,7 @@ module Nokogiri
|
|
126
119
|
{
|
127
120
|
'combinator' => ' and ',
|
128
121
|
'direct_adjacent_selector' => "/following-sibling::*[1]/self::",
|
122
|
+
'preceding_selector' => "/following-sibling::",
|
129
123
|
'descendant_selector' => '//',
|
130
124
|
'child_selector' => '/',
|
131
125
|
}.each do |k,v|
|
data/lib/nokogiri/ffi/libxml.rb
CHANGED
@@ -113,10 +113,9 @@ module Nokogiri
|
|
113
113
|
attach_function :xmlFreeDoc, [:pointer], :void
|
114
114
|
attach_function :xmlSetTreeDoc, [:pointer, :pointer], :void
|
115
115
|
attach_function :xmlNewReference, [:pointer, :string], :pointer
|
116
|
-
attach_function :xmlFirstElementChild, [:pointer], :pointer
|
117
|
-
attach_function :xmlLastElementChild, [:pointer], :pointer
|
118
|
-
attach_function :xmlNextElementSibling, [:pointer], :pointer
|
119
|
-
attach_function :xmlPreviousElementSibling, [:pointer], :pointer
|
116
|
+
# attach_function :xmlFirstElementChild, [:pointer], :pointer
|
117
|
+
# attach_function :xmlLastElementChild, [:pointer], :pointer
|
118
|
+
# attach_function :xmlNextElementSibling, [:pointer], :pointer
|
120
119
|
attach_function :xmlNewNode, [:pointer, :string], :pointer
|
121
120
|
attach_function :xmlCopyNode, [:pointer, :int], :pointer
|
122
121
|
attach_function :xmlDocCopyNode, [:pointer, :pointer, :int], :pointer
|
@@ -157,6 +156,7 @@ module Nokogiri
|
|
157
156
|
attach_function :xmlNewDtd, [:pointer] * 4, :pointer
|
158
157
|
attach_function :xmlGetNsList, [:pointer, :pointer], :pointer
|
159
158
|
attach_function :xmlTextMerge, [:pointer, :pointer], :pointer
|
159
|
+
attach_function :xmlFreeNsList, [:pointer], :void
|
160
160
|
|
161
161
|
# valid.c
|
162
162
|
attach_function :xmlNewValidCtxt, [], :pointer
|
@@ -264,6 +264,7 @@ module Nokogiri
|
|
264
264
|
attach_function :xmlFreeTextReader, [:pointer], :void
|
265
265
|
attach_function :xmlReaderForIO, [:io_read_callback, :io_close_callback, :pointer, :string, :string, :int], :pointer
|
266
266
|
attach_function :xmlTextReaderNodeType, [:pointer], :int
|
267
|
+
attach_function :xmlTextReaderIsEmptyElement, [:pointer], :int
|
267
268
|
|
268
269
|
# xslt.c
|
269
270
|
attach_function :xsltParseStylesheetDoc, [:pointer], :pointer
|
@@ -311,6 +312,30 @@ module Nokogiri
|
|
311
312
|
def self.pointer_offset(n)
|
312
313
|
n * POINTER_SIZE # byte offset of nth pointer in an array of pointers
|
313
314
|
end
|
315
|
+
|
316
|
+
# ZOMG hacks. see GH#303
|
317
|
+
class << self
|
318
|
+
def xmlFirstElementChildHack(parent)
|
319
|
+
return nil if parent.nil?
|
320
|
+
return nil unless [Nokogiri::XML::Node::ELEMENT_NODE, Nokogiri::XML::Node::ENTITY_NODE, Nokogiri::XML::Node::DOCUMENT_NODE, Nokogiri::XML::Node::HTML_DOCUMENT_NODE].include?(parent.type)
|
321
|
+
parent.children.find { |child| child.element? }
|
322
|
+
end
|
323
|
+
|
324
|
+
def xmlLastElementChildHack(parent)
|
325
|
+
return nil if parent.nil?
|
326
|
+
return nil unless [Nokogiri::XML::Node::ELEMENT_NODE, Nokogiri::XML::Node::ENTITY_NODE, Nokogiri::XML::Node::DOCUMENT_NODE, Nokogiri::XML::Node::HTML_DOCUMENT_NODE].include?(parent.type)
|
327
|
+
parent.children.reverse.find { |child| child.element? }
|
328
|
+
end
|
329
|
+
|
330
|
+
def xmlNextElementSiblingHack(sibling)
|
331
|
+
return nil if sibling.nil?
|
332
|
+
return nil unless [Nokogiri::XML::Node::ELEMENT_NODE, Nokogiri::XML::Node::ENTITY_NODE, Nokogiri::XML::Node::DOCUMENT_NODE, Nokogiri::XML::Node::HTML_DOCUMENT_NODE].include?(sibling.type)
|
333
|
+
while (sibling = sibling.next_sibling)
|
334
|
+
return sibling if sibling.element?
|
335
|
+
end
|
336
|
+
nil
|
337
|
+
end
|
338
|
+
end
|
314
339
|
end
|
315
340
|
end
|
316
341
|
|
@@ -153,6 +153,10 @@ module Nokogiri
|
|
153
153
|
node.children.each do |child|
|
154
154
|
recursively_remove_namespaces_from_node(child)
|
155
155
|
end
|
156
|
+
unless node.cstruct[:nsDef].nil?
|
157
|
+
LibXML.xmlFreeNsList(node.cstruct[:nsDef])
|
158
|
+
node.cstruct[:nsDef] = nil
|
159
|
+
end
|
156
160
|
end
|
157
161
|
end
|
158
162
|
|
@@ -78,8 +78,7 @@ module Nokogiri
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def next_element
|
81
|
-
|
82
|
-
sibling_ptr.null? ? nil : Node.wrap(sibling_ptr)
|
81
|
+
LibXML.xmlNextElementSiblingHack self
|
83
82
|
end
|
84
83
|
|
85
84
|
def previous_element
|
@@ -103,10 +102,10 @@ module Nokogiri
|
|
103
102
|
retval = reparentee_struct if retval == pivot_struct.pointer # for reparent_node_with semantics
|
104
103
|
retval = LibXML::XmlNode.new(retval) if retval.is_a?(FFI::Pointer)
|
105
104
|
if retval[:type] == TEXT_NODE
|
106
|
-
if retval[:prev] && LibXML::XmlNode.new(retval[:prev])[:type] == TEXT_NODE
|
105
|
+
if !retval[:prev].null? && LibXML::XmlNode.new(retval[:prev])[:type] == TEXT_NODE
|
107
106
|
retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval[:prev], retval))
|
108
107
|
end
|
109
|
-
if retval[:next] && LibXML::XmlNode.new(retval[:next])[:type] == TEXT_NODE
|
108
|
+
if !retval[:next].null? && LibXML::XmlNode.new(retval[:next])[:type] == TEXT_NODE
|
110
109
|
retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval, retval[:next]))
|
111
110
|
end
|
112
111
|
end
|
@@ -132,18 +131,17 @@ module Nokogiri
|
|
132
131
|
end
|
133
132
|
|
134
133
|
def element_children
|
135
|
-
child = LibXML.
|
136
|
-
return NodeSet.new(nil) if child.
|
137
|
-
child = Node.wrap(child)
|
134
|
+
child = LibXML.xmlFirstElementChildHack(self)
|
135
|
+
return NodeSet.new(nil) if child.nil?
|
138
136
|
|
139
137
|
set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(child.cstruct), self.document)
|
140
138
|
return set unless child
|
141
139
|
|
142
|
-
next_sibling = LibXML.
|
143
|
-
while ! next_sibling.
|
144
|
-
child =
|
140
|
+
next_sibling = LibXML.xmlNextElementSiblingHack(child)
|
141
|
+
while ! next_sibling.nil?
|
142
|
+
child = next_sibling
|
145
143
|
LibXML.xmlXPathNodeSetAddUnique(set.cstruct, child.cstruct)
|
146
|
-
next_sibling = LibXML.
|
144
|
+
next_sibling = LibXML.xmlNextElementSiblingHack(child)
|
147
145
|
end
|
148
146
|
|
149
147
|
return set
|
@@ -154,13 +152,11 @@ module Nokogiri
|
|
154
152
|
end
|
155
153
|
|
156
154
|
def first_element_child
|
157
|
-
|
158
|
-
element_child.null? ? nil : Node.wrap(element_child)
|
155
|
+
LibXML.xmlFirstElementChildHack(self)
|
159
156
|
end
|
160
157
|
|
161
158
|
def last_element_child
|
162
|
-
|
163
|
-
element_child.null? ? nil : Node.wrap(element_child)
|
159
|
+
LibXML.xmlLastElementChildHack(self)
|
164
160
|
end
|
165
161
|
|
166
162
|
def key?(attribute)
|
@@ -313,12 +309,14 @@ module Nokogiri
|
|
313
309
|
end
|
314
310
|
|
315
311
|
def add_namespace_definition(prefix, href)
|
316
|
-
ns = LibXML.
|
312
|
+
ns = LibXML.xmlSearchNs(cstruct.document, cstruct, prefix.nil? ? nil : prefix.to_s)
|
313
|
+
namespacee = self
|
317
314
|
if ns.null?
|
318
|
-
|
319
|
-
|
315
|
+
namespacee = parent if type != ELEMENT_NODE
|
316
|
+
ns = LibXML.xmlNewNs(namespacee.cstruct, href, prefix)
|
320
317
|
end
|
321
|
-
|
318
|
+
return nil if ns.null?
|
319
|
+
LibXML.xmlSetNs(cstruct, ns) if (prefix.nil? || self != namespacee)
|
322
320
|
Namespace.wrap(cstruct.document, ns)
|
323
321
|
end
|
324
322
|
|
@@ -460,6 +458,16 @@ module Nokogiri
|
|
460
458
|
reparentee_struct = LibXML::XmlNode.new(reparentee_struct)
|
461
459
|
end
|
462
460
|
|
461
|
+
if reparentee_struct[:type] == TEXT_NODE && !pivot_struct[:next].null?
|
462
|
+
next_text = Node.wrap(pivot_struct[:next])
|
463
|
+
if next_text.cstruct[:type] == TEXT_NODE
|
464
|
+
new_next_text = LibXML.xmlDocCopyNode(next_text.cstruct, pivot_struct[:doc], 1)
|
465
|
+
LibXML.xmlUnlinkNode(next_text.cstruct)
|
466
|
+
next_text.cstruct.keep_reference_from_document!
|
467
|
+
LibXML.xmlAddNextSibling(pivot_struct, new_next_text);
|
468
|
+
end
|
469
|
+
end
|
470
|
+
|
463
471
|
if reparentee_struct[:type] == TEXT_NODE && pivot_struct[:type] == TEXT_NODE && Nokogiri.is_2_6_16?
|
464
472
|
pivot_struct.pointer.put_pointer(pivot_struct.offset_of(:content), LibXML.xmlStrdup(pivot_struct[:content]))
|
465
473
|
end
|
@@ -14,7 +14,7 @@ module Nokogiri
|
|
14
14
|
end
|
15
15
|
|
16
16
|
def push(node) # :nodoc:
|
17
|
-
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node)
|
17
|
+
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node) || node.is_a?(XML::Namespace)
|
18
18
|
LibXML.xmlXPathNodeSetAdd(cstruct, node.cstruct)
|
19
19
|
self
|
20
20
|
end
|
@@ -39,7 +39,7 @@ module Nokogiri
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def delete(node) # :nodoc:
|
42
|
-
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node)
|
42
|
+
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node) || node.is_a?(XML::Namespace)
|
43
43
|
if LibXML.xmlXPathNodeSetContains(cstruct, node.cstruct) != 0
|
44
44
|
LibXML.xmlXPathNodeSetDel(cstruct, node.cstruct)
|
45
45
|
return node
|
@@ -71,7 +71,7 @@ module Nokogiri
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def include?(node) # :nodoc:
|
74
|
-
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node)
|
74
|
+
raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless node.is_a?(XML::Node) || node.is_a?(XML::Namespace)
|
75
75
|
(LibXML.xmlXPathNodeSetContains(cstruct, node.cstruct) != 0) ? true : false
|
76
76
|
end
|
77
77
|
|
@@ -176,6 +176,10 @@ module Nokogiri
|
|
176
176
|
LibXML.xmlTextReaderNodeType(cstruct)
|
177
177
|
end
|
178
178
|
|
179
|
+
def empty_element?
|
180
|
+
LibXML.xmlTextReaderIsEmptyElement(cstruct) != 0
|
181
|
+
end
|
182
|
+
|
179
183
|
def self.from_memory(buffer, url=nil, encoding=nil, options=0)
|
180
184
|
raise(ArgumentError, "string cannot be nil") if buffer.nil?
|
181
185
|
|
data/lib/nokogiri/html.rb
CHANGED
@@ -2,11 +2,14 @@ module Nokogiri
|
|
2
2
|
module HTML
|
3
3
|
class DocumentFragment < Nokogiri::XML::DocumentFragment
|
4
4
|
####
|
5
|
-
# Create a Nokogiri::XML::DocumentFragment from +tags+
|
6
|
-
def self.parse tags
|
5
|
+
# Create a Nokogiri::XML::DocumentFragment from +tags+, using +encoding+
|
6
|
+
def self.parse tags, encoding = nil
|
7
7
|
doc = HTML::Document.new
|
8
|
-
|
9
|
-
|
8
|
+
|
9
|
+
encoding ||= tags.respond_to?(:encoding) ? tags.encoding.name : 'UTF-8'
|
10
|
+
doc.encoding = encoding
|
11
|
+
|
12
|
+
new(doc, tags)
|
10
13
|
end
|
11
14
|
|
12
15
|
def initialize document, tags = nil, ctx = nil
|
data/lib/nokogiri/version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
# The version of Nokogiri you are using
|
3
|
-
VERSION = '1.4.
|
3
|
+
VERSION = '1.4.3'
|
4
4
|
|
5
5
|
# More complete version information about libxml
|
6
6
|
VERSION_INFO = {}
|
@@ -9,6 +9,7 @@ module Nokogiri
|
|
9
9
|
VERSION_INFO['ruby'] = {}
|
10
10
|
VERSION_INFO['ruby']['version'] = ::RUBY_VERSION
|
11
11
|
VERSION_INFO['ruby']['platform'] = ::RUBY_PLATFORM
|
12
|
+
VERSION_INFO['ruby']['engine'] = defined?(RUBY_ENGINE) ? RUBY_ENGINE : 'mri'
|
12
13
|
VERSION_INFO['ruby']['jruby'] = ::JRUBY_VERSION if RUBY_PLATFORM == "java"
|
13
14
|
if defined?(LIBXML_VERSION)
|
14
15
|
VERSION_INFO['libxml'] = {}
|
data/lib/nokogiri/xml/builder.rb
CHANGED
@@ -7,7 +7,7 @@ module Nokogiri
|
|
7
7
|
#
|
8
8
|
# For searching a Document, see Nokogiri::XML::Node#css and
|
9
9
|
# Nokogiri::XML::Node#xpath
|
10
|
-
class Document < Node
|
10
|
+
class Document < Nokogiri::XML::Node
|
11
11
|
##
|
12
12
|
# Parse an XML file. +thing+ may be a String, or any object that
|
13
13
|
# responds to _read_ and _close_ such as an IO, or StringIO.
|
@@ -172,7 +172,6 @@ module Nokogiri
|
|
172
172
|
undef_method :swap, :parent, :namespace, :default_namespace=
|
173
173
|
undef_method :add_namespace_definition, :attributes
|
174
174
|
undef_method :namespace_definitions, :line, :add_namespace
|
175
|
-
undef_method :parse, :in_context
|
176
175
|
|
177
176
|
def add_child child
|
178
177
|
raise "Document already has a root node" if root
|
data/lib/nokogiri/xml/node.rb
CHANGED
@@ -375,8 +375,10 @@ module Nokogiri
|
|
375
375
|
|
376
376
|
####
|
377
377
|
# Returns a hash containing the node's attributes. The key is
|
378
|
-
# the attribute name, the value is a Nokogiri::XML::Attr
|
378
|
+
# the attribute name without any namespace, the value is a Nokogiri::XML::Attr
|
379
379
|
# representing the attribute.
|
380
|
+
# If you need to distinguish attributes with the same name, with different namespaces
|
381
|
+
# use #attribute_nodes instead.
|
380
382
|
def attributes
|
381
383
|
Hash[*(attribute_nodes.map { |node|
|
382
384
|
[node.node_name, node]
|
@@ -770,7 +772,7 @@ module Nokogiri
|
|
770
772
|
|
771
773
|
private
|
772
774
|
|
773
|
-
def coerce
|
775
|
+
def coerce data # :nodoc:
|
774
776
|
return data if data.is_a?(XML::NodeSet)
|
775
777
|
return data.children if data.is_a?(XML::DocumentFragment)
|
776
778
|
return fragment(data).children if data.is_a?(String)
|
@@ -138,6 +138,13 @@ module Nokogiri
|
|
138
138
|
sub_set
|
139
139
|
end
|
140
140
|
|
141
|
+
###
|
142
|
+
# Search this NodeSet's nodes' immediate children using CSS selector +selector+
|
143
|
+
def > selector
|
144
|
+
ns = document.root.namespaces
|
145
|
+
xpath CSS.xpath_for(selector, :prefix => "./", :ns => ns).first
|
146
|
+
end
|
147
|
+
|
141
148
|
###
|
142
149
|
# If path is a string, search this document for +path+ returning the
|
143
150
|
# first Node. Otherwise, index in to the array with +path+.
|
@@ -147,6 +154,24 @@ module Nokogiri
|
|
147
154
|
end
|
148
155
|
alias :% :at
|
149
156
|
|
157
|
+
##
|
158
|
+
# Search this NodeSet for the first occurrence of XPath +paths+.
|
159
|
+
# Equivalent to <tt>xpath(paths).first</tt>
|
160
|
+
# See NodeSet#xpath for more information.
|
161
|
+
#
|
162
|
+
def at_xpath *paths
|
163
|
+
xpath(*paths).first
|
164
|
+
end
|
165
|
+
|
166
|
+
##
|
167
|
+
# Search this NodeSet for the first occurrence of CSS +rules+.
|
168
|
+
# Equivalent to <tt>css(rules).first</tt>
|
169
|
+
# See NodeSet#css for more information.
|
170
|
+
#
|
171
|
+
def at_css *rules
|
172
|
+
css(*rules).first
|
173
|
+
end
|
174
|
+
|
150
175
|
###
|
151
176
|
# Filter this list for nodes that match +expr+
|
152
177
|
def filter expr
|
data/lib/nokogiri/xml/reader.rb
CHANGED
@@ -126,7 +126,9 @@ module Nokogiri
|
|
126
126
|
end
|
127
127
|
|
128
128
|
###
|
129
|
-
# Characters read between a tag
|
129
|
+
# Characters read between a tag. This method might be called multiple
|
130
|
+
# times given one contiguous string of characters.
|
131
|
+
#
|
130
132
|
# +string+ contains the character data
|
131
133
|
def characters string
|
132
134
|
end
|
data/test/css/test_parser.rb
CHANGED
@@ -16,6 +16,10 @@ module Nokogiri
|
|
16
16
|
assert_raises(CSS::SyntaxError) { @parser.parse("a[x=]") }
|
17
17
|
end
|
18
18
|
|
19
|
+
def test_function_and_pseudo
|
20
|
+
assert_xpath '//child::text()[position() = 99]', @parser.parse('text():nth-of-type(99)')
|
21
|
+
end
|
22
|
+
|
19
23
|
def test_find_by_type
|
20
24
|
ast = @parser.parse("a:nth-child(2)").first
|
21
25
|
matches = ast.find_by_type(
|
@@ -184,13 +188,19 @@ module Nokogiri
|
|
184
188
|
end
|
185
189
|
|
186
190
|
def test_preceding_selector
|
187
|
-
assert_xpath "//
|
191
|
+
assert_xpath "//E/following-sibling::F",
|
188
192
|
@parser.parse("E ~ F")
|
193
|
+
|
194
|
+
assert_xpath "//E/following-sibling::F//G",
|
195
|
+
@parser.parse("E ~ F G")
|
189
196
|
end
|
190
197
|
|
191
198
|
def test_direct_preceding_selector
|
192
199
|
assert_xpath "//E/following-sibling::*[1]/self::F",
|
193
200
|
@parser.parse("E + F")
|
201
|
+
|
202
|
+
assert_xpath "//E/following-sibling::*[1]/self::F//G",
|
203
|
+
@parser.parse("E + F G")
|
194
204
|
end
|
195
205
|
|
196
206
|
def test_attribute
|