nokogiri 1.4.1 → 1.4.2
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 +45 -0
- data/CHANGELOG.rdoc +53 -1
- data/Manifest.txt +3 -3
- data/README.ja.rdoc +1 -1
- data/README.rdoc +11 -5
- data/Rakefile +13 -79
- data/ext/nokogiri/extconf.rb +22 -74
- data/ext/nokogiri/html_document.c +17 -8
- data/ext/nokogiri/html_element_description.c +20 -16
- data/ext/nokogiri/html_entity_lookup.c +2 -2
- data/ext/nokogiri/html_sax_parser_context.c +10 -8
- data/ext/nokogiri/nokogiri.c +0 -1
- data/ext/nokogiri/nokogiri.h +33 -28
- data/ext/nokogiri/xml_attr.c +7 -5
- data/ext/nokogiri/xml_attribute_decl.c +5 -2
- data/ext/nokogiri/xml_cdata.c +4 -2
- data/ext/nokogiri/xml_comment.c +4 -2
- data/ext/nokogiri/xml_document.c +93 -15
- data/ext/nokogiri/xml_document.h +0 -1
- data/ext/nokogiri/xml_document_fragment.c +4 -2
- data/ext/nokogiri/xml_dtd.c +18 -8
- data/ext/nokogiri/xml_element_content.c +2 -2
- data/ext/nokogiri/xml_entity_decl.c +15 -2
- data/ext/nokogiri/xml_entity_reference.c +4 -2
- data/ext/nokogiri/xml_io.c +1 -1
- data/ext/nokogiri/xml_namespace.c +5 -3
- data/ext/nokogiri/xml_node.c +353 -114
- data/ext/nokogiri/xml_node_set.c +35 -22
- data/ext/nokogiri/xml_node_set.h +1 -1
- data/ext/nokogiri/xml_processing_instruction.c +4 -2
- data/ext/nokogiri/xml_reader.c +119 -47
- data/ext/nokogiri/xml_relax_ng.c +21 -12
- data/ext/nokogiri/xml_sax_parser.c +6 -3
- data/ext/nokogiri/xml_sax_parser.h +13 -17
- data/ext/nokogiri/xml_sax_parser_context.c +8 -6
- data/ext/nokogiri/xml_sax_push_parser.c +7 -6
- data/ext/nokogiri/xml_schema.c +62 -13
- data/ext/nokogiri/xml_syntax_error.c +18 -12
- data/ext/nokogiri/xml_syntax_error.h +1 -1
- data/ext/nokogiri/xml_text.c +4 -2
- data/ext/nokogiri/xml_xpath_context.c +60 -23
- data/ext/nokogiri/xslt_stylesheet.c +14 -3
- data/lib/nokogiri.rb +17 -0
- data/lib/nokogiri/css/generated_parser.rb +72 -62
- data/lib/nokogiri/css/generated_tokenizer.rb +23 -24
- data/lib/nokogiri/css/parser.y +3 -1
- data/lib/nokogiri/css/tokenizer.rex +3 -3
- data/lib/nokogiri/css/xpath_visitor.rb +8 -3
- data/lib/nokogiri/ffi/html/sax/parser_context.rb +3 -3
- data/lib/nokogiri/ffi/libxml.rb +16 -2
- data/lib/nokogiri/ffi/structs/common_node.rb +15 -3
- data/lib/nokogiri/ffi/structs/xml_document.rb +13 -4
- data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +3 -2
- data/lib/nokogiri/ffi/weak_bucket.rb +40 -0
- data/lib/nokogiri/ffi/xml/document.rb +27 -0
- data/lib/nokogiri/ffi/xml/entity_decl.rb +9 -0
- data/lib/nokogiri/ffi/xml/node.rb +142 -61
- data/lib/nokogiri/ffi/xml/node_set.rb +15 -12
- data/lib/nokogiri/ffi/xml/reader.rb +5 -0
- data/lib/nokogiri/ffi/xml/schema.rb +17 -0
- data/lib/nokogiri/ffi/xml/syntax_error.rb +4 -4
- data/lib/nokogiri/ffi/xml/xpath.rb +0 -10
- data/lib/nokogiri/ffi/xml/xpath_context.rb +22 -9
- data/lib/nokogiri/ffi/xslt/stylesheet.rb +3 -0
- data/lib/nokogiri/html/document.rb +5 -3
- data/lib/nokogiri/html/document_fragment.rb +28 -7
- data/lib/nokogiri/version.rb +6 -2
- data/lib/nokogiri/version_warning.rb +6 -3
- data/lib/nokogiri/xml.rb +1 -1
- data/lib/nokogiri/xml/builder.rb +35 -22
- data/lib/nokogiri/xml/document.rb +44 -12
- data/lib/nokogiri/xml/document_fragment.rb +16 -12
- data/lib/nokogiri/xml/entity_decl.rb +4 -0
- data/lib/nokogiri/xml/node.rb +152 -95
- data/lib/nokogiri/xml/node_set.rb +2 -1
- data/lib/nokogiri/xml/sax/push_parser.rb +1 -1
- data/lib/nokogiri/xml/schema.rb +1 -5
- data/lib/nokogiri/xml/syntax_error.rb +4 -0
- data/lib/nokogiri/xml/text.rb +9 -0
- data/lib/nokogiri/xml/xpath/syntax_error.rb +3 -0
- data/tasks/cross_compile.rb +158 -0
- data/tasks/test.rb +0 -6
- data/test/css/test_xpath_visitor.rb +9 -0
- data/test/helper.rb +49 -11
- data/test/html/sax/test_parser.rb +11 -1
- data/test/html/test_document.rb +8 -0
- data/test/html/test_document_fragment.rb +14 -2
- data/test/html/test_element_description.rb +5 -1
- data/test/html/test_node.rb +5 -66
- data/test/test_reader.rb +28 -0
- data/test/test_xslt_transforms.rb +14 -0
- data/test/xml/test_builder.rb +43 -0
- data/test/xml/test_cdata.rb +12 -0
- data/test/xml/test_document.rb +74 -39
- data/test/xml/test_document_fragment.rb +36 -0
- data/test/xml/test_entity_decl.rb +37 -0
- data/test/xml/test_node.rb +192 -65
- data/test/xml/test_node_reparenting.rb +253 -236
- data/test/xml/test_node_set.rb +67 -0
- data/test/xml/test_text.rb +8 -0
- data/test/xml/test_xpath.rb +32 -0
- metadata +103 -48
- data.tar.gz.sig +0 -0
- data/ext/nokogiri/xml_xpath.c +0 -53
- data/ext/nokogiri/xml_xpath.h +0 -11
- data/lib/nokogiri/xml/fragment_handler.rb +0 -79
- metadata.gz.sig +0 -0
@@ -29,7 +29,6 @@ class GeneratedTokenizer < GeneratedParser
|
|
29
29
|
scan_setup(str)
|
30
30
|
do_parse
|
31
31
|
end
|
32
|
-
alias :scan :scan_str
|
33
32
|
|
34
33
|
def load_file( filename )
|
35
34
|
@filename = filename
|
@@ -52,79 +51,79 @@ class GeneratedTokenizer < GeneratedParser
|
|
52
51
|
token = case @state
|
53
52
|
when nil
|
54
53
|
case
|
55
|
-
when (text = @ss.scan(/has\([\s
|
54
|
+
when (text = @ss.scan(/has\([\s]*/))
|
56
55
|
action { [:HAS, text] }
|
57
56
|
|
58
|
-
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s
|
57
|
+
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*\([\s]*/))
|
59
58
|
action { [:FUNCTION, text] }
|
60
59
|
|
61
|
-
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s
|
60
|
+
when (text = @ss.scan(/[-@]?([_A-Za-z]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*/))
|
62
61
|
action { [:IDENT, text] }
|
63
62
|
|
64
|
-
when (text = @ss.scan(/\#([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s
|
63
|
+
when (text = @ss.scan(/\#([_A-Za-z0-9-]|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])+/))
|
65
64
|
action { [:HASH, text] }
|
66
65
|
|
67
|
-
when (text = @ss.scan(/[\s
|
66
|
+
when (text = @ss.scan(/[\s]*~=[\s]*/))
|
68
67
|
action { [:INCLUDES, text] }
|
69
68
|
|
70
|
-
when (text = @ss.scan(/[\s
|
69
|
+
when (text = @ss.scan(/[\s]*\|=[\s]*/))
|
71
70
|
action { [:DASHMATCH, text] }
|
72
71
|
|
73
|
-
when (text = @ss.scan(/[\s
|
72
|
+
when (text = @ss.scan(/[\s]*\^=[\s]*/))
|
74
73
|
action { [:PREFIXMATCH, text] }
|
75
74
|
|
76
|
-
when (text = @ss.scan(/[\s
|
75
|
+
when (text = @ss.scan(/[\s]*\$=[\s]*/))
|
77
76
|
action { [:SUFFIXMATCH, text] }
|
78
77
|
|
79
|
-
when (text = @ss.scan(/[\s
|
78
|
+
when (text = @ss.scan(/[\s]*\*=[\s]*/))
|
80
79
|
action { [:SUBSTRINGMATCH, text] }
|
81
80
|
|
82
|
-
when (text = @ss.scan(/[\s
|
81
|
+
when (text = @ss.scan(/[\s]*!=[\s]*/))
|
83
82
|
action { [:NOT_EQUAL, text] }
|
84
83
|
|
85
|
-
when (text = @ss.scan(/[\s
|
84
|
+
when (text = @ss.scan(/[\s]*=[\s]*/))
|
86
85
|
action { [:EQUAL, text] }
|
87
86
|
|
88
|
-
when (text = @ss.scan(/[\s
|
87
|
+
when (text = @ss.scan(/[\s]*\)/))
|
89
88
|
action { [:RPAREN, text] }
|
90
89
|
|
91
|
-
when (text = @ss.scan(/[\s
|
90
|
+
when (text = @ss.scan(/[\s]*\[[\s]*/))
|
92
91
|
action { [:LSQUARE, text] }
|
93
92
|
|
94
|
-
when (text = @ss.scan(/[\s
|
93
|
+
when (text = @ss.scan(/[\s]*\]/))
|
95
94
|
action { [:RSQUARE, text] }
|
96
95
|
|
97
|
-
when (text = @ss.scan(/[\s
|
96
|
+
when (text = @ss.scan(/[\s]*\+[\s]*/))
|
98
97
|
action { [:PLUS, text] }
|
99
98
|
|
100
|
-
when (text = @ss.scan(/[\s
|
99
|
+
when (text = @ss.scan(/[\s]*>[\s]*/))
|
101
100
|
action { [:GREATER, text] }
|
102
101
|
|
103
|
-
when (text = @ss.scan(/[\s
|
102
|
+
when (text = @ss.scan(/[\s]*,[\s]*/))
|
104
103
|
action { [:COMMA, text] }
|
105
104
|
|
106
|
-
when (text = @ss.scan(/[\s
|
105
|
+
when (text = @ss.scan(/[\s]*~[\s]*/))
|
107
106
|
action { [:TILDE, text] }
|
108
107
|
|
109
|
-
when (text = @ss.scan(/\:not\([\s
|
108
|
+
when (text = @ss.scan(/\:not\([\s]*/))
|
110
109
|
action { [:NOT, text] }
|
111
110
|
|
112
111
|
when (text = @ss.scan(/-?([0-9]+|[0-9]*\.[0-9]+)/))
|
113
112
|
action { [:NUMBER, text] }
|
114
113
|
|
115
|
-
when (text = @ss.scan(/[\s
|
114
|
+
when (text = @ss.scan(/[\s]*\/\/[\s]*/))
|
116
115
|
action { [:DOUBLESLASH, text] }
|
117
116
|
|
118
|
-
when (text = @ss.scan(/[\s
|
117
|
+
when (text = @ss.scan(/[\s]*\/[\s]*/))
|
119
118
|
action { [:SLASH, text] }
|
120
119
|
|
121
120
|
when (text = @ss.scan(/U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})?/))
|
122
121
|
action {[:UNICODE_RANGE, text] }
|
123
122
|
|
124
|
-
when (text = @ss.scan(/[\s
|
123
|
+
when (text = @ss.scan(/[\s]+/))
|
125
124
|
action { [:S, text] }
|
126
125
|
|
127
|
-
when (text = @ss.scan(/"([^\n\r\f"]|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s
|
126
|
+
when (text = @ss.scan(/"([^\n\r\f"]|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*"|'([^\n\r\f']|\n|\r\n|\r|\f|[^\0-\177]|\\[0-9A-Fa-f]{1,6}(\r\n|[\s])?|\\[^\n\r\f0-9A-Fa-f])*'/))
|
128
127
|
action { [:STRING, text] }
|
129
128
|
|
130
129
|
when (text = @ss.scan(/./))
|
data/lib/nokogiri/css/parser.y
CHANGED
@@ -4,10 +4,10 @@ class GeneratedTokenizer < GeneratedParser
|
|
4
4
|
|
5
5
|
macro
|
6
6
|
nl \n|\r\n|\r|\f
|
7
|
-
w [\s
|
7
|
+
w [\s]*
|
8
8
|
nonascii [^\0-\177]
|
9
9
|
num -?([0-9]+|[0-9]*\.[0-9]+)
|
10
|
-
unicode \\[0-9A-Fa-f]{1,6}(\r\n|[\s
|
10
|
+
unicode \\[0-9A-Fa-f]{1,6}(\r\n|[\s])?
|
11
11
|
|
12
12
|
escape {unicode}|\\[^\n\r\f0-9A-Fa-f]
|
13
13
|
nmchar [_A-Za-z0-9-]|{nonascii}|{escape}
|
@@ -47,7 +47,7 @@ rule
|
|
47
47
|
|
48
48
|
U\+[0-9a-f?]{1,6}(-[0-9a-f]{1,6})? {[:UNICODE_RANGE, text] }
|
49
49
|
|
50
|
-
[\s
|
50
|
+
[\s]+ { [:S, text] }
|
51
51
|
{string} { [:STRING, text] }
|
52
52
|
. { [text, text] }
|
53
53
|
end
|
@@ -40,7 +40,12 @@ module Nokogiri
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def visit_not node
|
43
|
-
|
43
|
+
child = node.value.first
|
44
|
+
if :ELEMENT_NAME == child.type
|
45
|
+
"not(self::#{child.accept(self)})"
|
46
|
+
else
|
47
|
+
"not(#{child.accept(self)})"
|
48
|
+
end
|
44
49
|
end
|
45
50
|
|
46
51
|
def visit_preceding_selector node
|
@@ -100,8 +105,8 @@ module Nokogiri
|
|
100
105
|
return self.send(msg, node) if self.respond_to?(msg)
|
101
106
|
|
102
107
|
case node.value.first
|
103
|
-
when "first" then "position() = 1"
|
104
|
-
when "last" then "position() = last()"
|
108
|
+
when "first", "first-child" then "position() = 1"
|
109
|
+
when "last", "last-child" then "position() = last()"
|
105
110
|
when "first-of-type" then "position() = 1"
|
106
111
|
when "last-of-type" then "position() = last()"
|
107
112
|
when "only-of-type" then "last() = 1"
|
@@ -20,9 +20,9 @@ module Nokogiri
|
|
20
20
|
pc = allocate
|
21
21
|
pc.cstruct = LibXML::XmlParserContext.new ctx
|
22
22
|
if encoding
|
23
|
-
enc = LibXML.
|
24
|
-
if enc
|
25
|
-
LibXML.
|
23
|
+
enc = LibXML.xmlFindCharEncodingHandler(encoding)
|
24
|
+
if !enc.null?
|
25
|
+
LibXML.xmlSwitchToEncoding(ctx, enc)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
pc
|
data/lib/nokogiri/ffi/libxml.rb
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
module Nokogiri
|
3
3
|
module LibXML
|
4
4
|
extend FFI::Library
|
5
|
-
if RUBY_PLATFORM =~ /java/ &&
|
5
|
+
if RUBY_PLATFORM =~ /java/ && RbConfig::CONFIG['host_os'] =~ /(mswin|mingw)/i
|
6
6
|
raise(RuntimeError, "Nokogiri requires JRuby 1.4.0 or later on Windows") if JRUBY_VERSION < "1.4.0"
|
7
7
|
dll_dir = File.expand_path(File.join(File.dirname(__FILE__), "..", "..", "..", "ext", "nokogiri"))
|
8
8
|
libs = ["libxml2.dll", "libxslt.dll", "libexslt.dll"].collect do |lib|
|
@@ -80,6 +80,7 @@ module Nokogiri
|
|
80
80
|
attach_function :htmlCreateMemoryParserCtxt, [:pointer, :int], :pointer
|
81
81
|
attach_function :htmlCreateFileParserCtxt, [:pointer, :pointer], :pointer
|
82
82
|
attach_function :htmlParseDocument, [:pointer], :int
|
83
|
+
attach_function :htmlHandleOmittedElem, [:int], :int
|
83
84
|
|
84
85
|
# HTMLtree.c
|
85
86
|
attach_function :htmlDocDumpMemory, [:pointer, :pointer, :pointer], :void
|
@@ -101,6 +102,7 @@ module Nokogiri
|
|
101
102
|
attach_function :xmlCreatePushParserCtxt, [:pointer, :pointer, :string, :int, :string], :pointer
|
102
103
|
attach_function :xmlParseChunk, [:pointer, :string, :int, :int], :int
|
103
104
|
attach_function :xmlCtxtUseOptions, [:pointer, :int], :int
|
105
|
+
attach_function :xmlParseInNodeContext, [:pointer, :string, :int, :int, :pointer], :pointer
|
104
106
|
|
105
107
|
# tree.c
|
106
108
|
attach_function :xmlNewDoc, [:string], :pointer
|
@@ -111,6 +113,10 @@ module Nokogiri
|
|
111
113
|
attach_function :xmlFreeDoc, [:pointer], :void
|
112
114
|
attach_function :xmlSetTreeDoc, [:pointer, :pointer], :void
|
113
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
|
114
120
|
attach_function :xmlNewNode, [:pointer, :string], :pointer
|
115
121
|
attach_function :xmlCopyNode, [:pointer, :int], :pointer
|
116
122
|
attach_function :xmlDocCopyNode, [:pointer, :pointer, :int], :pointer
|
@@ -149,6 +155,8 @@ module Nokogiri
|
|
149
155
|
attach_function :xmlFreePropList, [:pointer], :void
|
150
156
|
attach_function :xmlCreateIntSubset, [:pointer] * 4, :pointer
|
151
157
|
attach_function :xmlNewDtd, [:pointer] * 4, :pointer
|
158
|
+
attach_function :xmlGetNsList, [:pointer, :pointer], :pointer
|
159
|
+
attach_function :xmlTextMerge, [:pointer, :pointer], :pointer
|
152
160
|
|
153
161
|
# valid.c
|
154
162
|
attach_function :xmlNewValidCtxt, [], :pointer
|
@@ -165,6 +173,7 @@ module Nokogiri
|
|
165
173
|
|
166
174
|
# entities.c
|
167
175
|
attach_function :xmlEncodeSpecialChars, [:pointer, :string], :pointer # returns char* that must be freed
|
176
|
+
attach_function :xmlAddDocEntity, [:pointer, :string, :int, :string, :string, :string], :pointer
|
168
177
|
|
169
178
|
# xpath.c
|
170
179
|
attach_function :xmlXPathInit, [], :void
|
@@ -175,6 +184,7 @@ module Nokogiri
|
|
175
184
|
attach_function :xmlXPathCmpNodes, [:pointer, :pointer], :int
|
176
185
|
attach_function :xmlXPathNodeSetContains, [:pointer, :pointer], :int
|
177
186
|
attach_function :xmlXPathNodeSetAdd, [:pointer, :pointer], :void
|
187
|
+
attach_function :xmlXPathNodeSetAddUnique, [:pointer, :pointer], :void
|
178
188
|
attach_function :xmlXPathNodeSetRemove, [:pointer, :int], :void
|
179
189
|
attach_function :xmlXPathNodeSetCreate, [:pointer], :pointer
|
180
190
|
attach_function :xmlXPathNodeSetDel, [:pointer, :pointer], :void
|
@@ -248,6 +258,7 @@ module Nokogiri
|
|
248
258
|
attach_function :xmlTextReaderConstPrefix, [:pointer], :pointer # returns a const char* that is deallocated with the reader
|
249
259
|
attach_function :xmlTextReaderConstValue, [:pointer], :pointer # returns a const char* that is deallocated on the next read()
|
250
260
|
attach_function :xmlTextReaderConstXmlVersion, [:pointer], :pointer # returns a const char* that is deallocated with the reader
|
261
|
+
attach_function :xmlTextReaderConstBaseUri, [:pointer], :pointer # returns a const char* that is deallocated with the reader
|
251
262
|
attach_function :xmlTextReaderReadState, [:pointer], :int
|
252
263
|
attach_function :xmlTextReaderHasValue, [:pointer], :int
|
253
264
|
attach_function :xmlFreeTextReader, [:pointer], :void
|
@@ -274,6 +285,7 @@ module Nokogiri
|
|
274
285
|
attach_function :xmlSchemaParse, [:pointer], :pointer
|
275
286
|
attach_function :xmlSchemaFreeParserCtxt, [:pointer], :void
|
276
287
|
attach_function :xmlSchemaNewDocParserCtxt, [:pointer], :pointer
|
288
|
+
attach_function :xmlSchemaValidateFile, [:pointer, :string, :int], :int
|
277
289
|
|
278
290
|
# relaxng.c
|
279
291
|
attach_function :xmlRelaxNGNewValidCtxt, [:pointer], :pointer
|
@@ -285,13 +297,14 @@ module Nokogiri
|
|
285
297
|
attach_function :xmlRelaxNGParse, [:pointer], :pointer
|
286
298
|
attach_function :xmlRelaxNGFreeParserCtxt, [:pointer], :void
|
287
299
|
attach_function :xmlRelaxNGNewDocParserCtxt, [:pointer], :pointer
|
300
|
+
attach_function :xmlRelaxNGFree, [:pointer], :void
|
288
301
|
|
289
302
|
# libc
|
290
303
|
attach_function :calloc, [:int, :int], :pointer
|
291
304
|
attach_function :free, [:pointer], :void
|
292
305
|
|
293
306
|
attach_function :xmlParseCharEncoding, [:string], :int
|
294
|
-
attach_function :
|
307
|
+
attach_function :xmlSwitchToEncoding, [:pointer, :pointer], :void
|
295
308
|
|
296
309
|
# helpers
|
297
310
|
POINTER_SIZE = FFI.type_size(:pointer)
|
@@ -308,6 +321,7 @@ require 'nokogiri/xml/syntax_error'
|
|
308
321
|
|
309
322
|
[ "io_callbacks",
|
310
323
|
"encoding_handler",
|
324
|
+
"weak_bucket",
|
311
325
|
"structs/common_node",
|
312
326
|
"structs/xml_alloc",
|
313
327
|
"structs/xml_char_encoding_handler",
|
@@ -1,18 +1,25 @@
|
|
1
1
|
module Nokogiri
|
2
2
|
module LibXML # :nodoc:
|
3
3
|
module CommonNode # :nodoc:
|
4
|
-
|
5
4
|
def document
|
6
5
|
p = self[:doc]
|
7
6
|
p.null? ? nil : LibXML::XmlDocumentCast.new(p)
|
8
7
|
end
|
9
8
|
|
9
|
+
def ruby_node_pointer
|
10
|
+
self[:_private]
|
11
|
+
end
|
12
|
+
|
13
|
+
def ruby_node_pointer=(value)
|
14
|
+
self[:_private] = value
|
15
|
+
end
|
16
|
+
|
10
17
|
def ruby_node
|
11
|
-
|
18
|
+
Nokogiri::WeakBucket.get_object(self)
|
12
19
|
end
|
13
20
|
|
14
21
|
def ruby_node= object
|
15
|
-
self
|
22
|
+
Nokogiri::WeakBucket.set_object(self, object)
|
16
23
|
end
|
17
24
|
|
18
25
|
def keep_reference_from_document! # equivalent to NOKOGIRI_ROOT_NODE
|
@@ -20,6 +27,11 @@ module Nokogiri
|
|
20
27
|
raise "no document to add reference to" unless doc
|
21
28
|
LibXML.xmlXPathNodeSetAdd(doc.unlinked_nodes, self)
|
22
29
|
end
|
30
|
+
|
31
|
+
def keep_reference_from!(document) # equivalent to NOKOGIRI_ROOT_NSDEF
|
32
|
+
raise "no document to add reference to" unless document
|
33
|
+
LibXML.xmlXPathNodeSetAdd(document.unlinked_nodes, self)
|
34
|
+
end
|
23
35
|
end
|
24
36
|
end
|
25
37
|
end
|
@@ -36,14 +36,21 @@ module Nokogiri
|
|
36
36
|
p.null? ? nil : LibXML::XmlDocumentCast.new(p)
|
37
37
|
end
|
38
38
|
|
39
|
+
def ruby_node_pointer
|
40
|
+
tuple = self[:_private]
|
41
|
+
tuple.null? ? 0 : tuple.get_long(0)
|
42
|
+
end
|
43
|
+
|
44
|
+
def ruby_node_pointer=(value)
|
45
|
+
self[:_private].put_long(0, value)
|
46
|
+
end
|
47
|
+
|
39
48
|
def ruby_doc
|
40
|
-
|
41
|
-
return nil if ptr.null?
|
42
|
-
ObjectSpace._id2ref(ptr.get_long(0))
|
49
|
+
Nokogiri::WeakBucket.get_object(self)
|
43
50
|
end
|
44
51
|
|
45
52
|
def ruby_doc=(object)
|
46
|
-
|
53
|
+
Nokogiri::WeakBucket.set_object(self, object)
|
47
54
|
end
|
48
55
|
|
49
56
|
def unlinked_nodes
|
@@ -78,6 +85,8 @@ module Nokogiri
|
|
78
85
|
case node_cstruct[:type]
|
79
86
|
when Nokogiri::XML::Node::ATTRIBUTE_NODE
|
80
87
|
LibXML.xmlFreePropList(node_cstruct)
|
88
|
+
when Nokogiri::XML::Node::NAMESPACE_DECL
|
89
|
+
LibXML.xmlFree(node_cstruct)
|
81
90
|
else
|
82
91
|
LibXML.xmlAddChild(doc, node_cstruct) if node_cstruct[:parent].null?
|
83
92
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# :stopdoc:
|
2
|
+
if ENV['NOKOGIRI_ID2REF'] || RUBY_PLATFORM !~ /java/
|
3
|
+
Nokogiri::VERSION_INFO['refs'] = "id2ref"
|
4
|
+
else
|
5
|
+
require 'weakling'
|
6
|
+
Nokogiri::VERSION_INFO['refs'] = "weakling"
|
7
|
+
end
|
8
|
+
require 'singleton'
|
9
|
+
|
10
|
+
module Nokogiri
|
11
|
+
class WeakBucket
|
12
|
+
include Singleton
|
13
|
+
|
14
|
+
if Nokogiri::VERSION_INFO['refs'] == "weakling"
|
15
|
+
attr_accessor :bucket
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@bucket = Weakling::IdHash.new
|
19
|
+
end
|
20
|
+
|
21
|
+
def WeakBucket.get_object(cstruct)
|
22
|
+
instance.bucket[cstruct.ruby_node_pointer]
|
23
|
+
end
|
24
|
+
|
25
|
+
def WeakBucket.set_object(cstruct, object)
|
26
|
+
cstruct.ruby_node_pointer = instance.bucket.add(object)
|
27
|
+
end
|
28
|
+
else
|
29
|
+
def WeakBucket.get_object(cstruct)
|
30
|
+
ptr = cstruct.ruby_node_pointer
|
31
|
+
ptr != 0 ? ObjectSpace._id2ref(ptr) : nil
|
32
|
+
end
|
33
|
+
|
34
|
+
def WeakBucket.set_object(cstruct, object)
|
35
|
+
cstruct.ruby_node_pointer = object.object_id
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# :startdoc:
|
@@ -11,6 +11,17 @@ module Nokogiri
|
|
11
11
|
|
12
12
|
def root= new_root
|
13
13
|
old_root = nil
|
14
|
+
|
15
|
+
if new_root.nil?
|
16
|
+
old_root_ptr = LibXML.xmlDocGetRootElement(cstruct)
|
17
|
+
if (! old_root_ptr.null?)
|
18
|
+
old_root = Node.wrap(old_root_ptr)
|
19
|
+
LibXML.xmlUnlinkNode(old_root.cstruct)
|
20
|
+
old_root.cstruct.keep_reference_from_document!
|
21
|
+
end
|
22
|
+
return new_root
|
23
|
+
end
|
24
|
+
|
14
25
|
if new_root.cstruct[:doc] != cstruct[:doc]
|
15
26
|
old_root_ptr = LibXML.xmlDocGetRootElement(cstruct)
|
16
27
|
new_root_ptr = LibXML.xmlDocCopyNode(new_root.cstruct, cstruct, 1)
|
@@ -70,6 +81,22 @@ module Nokogiri
|
|
70
81
|
self.class.recursively_remove_namespaces_from_node(root)
|
71
82
|
end
|
72
83
|
|
84
|
+
def create_entity(name, entity_type=Nokogiri::XML::EntityDecl::INTERNAL_GENERAL,
|
85
|
+
external_id=nil, system_id=nil, content=nil)
|
86
|
+
LibXML.xmlResetLastError()
|
87
|
+
ptr = LibXML.xmlAddDocEntity(cstruct, name, entity_type, external_id, system_id, content)
|
88
|
+
if ptr.null?
|
89
|
+
error = LibXML.xmlGetLastError()
|
90
|
+
if error
|
91
|
+
raise SyntaxError.wrap(error)
|
92
|
+
else
|
93
|
+
raise RuntimeError, "Could not create entity"
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
Node.wrap(LibXML::XmlEntity.new(ptr))
|
98
|
+
end
|
99
|
+
|
73
100
|
class << self
|
74
101
|
def new(*args)
|
75
102
|
version = args.first || "1.0"
|