nokogiri 1.4.7 → 1.5.0.beta.1

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 (164) hide show
  1. data/CHANGELOG.ja.rdoc +8 -83
  2. data/CHANGELOG.rdoc +6 -80
  3. data/Manifest.txt +4 -74
  4. data/README.ja.rdoc +5 -1
  5. data/README.rdoc +8 -22
  6. data/Rakefile +79 -60
  7. data/bin/nokogiri +1 -6
  8. data/deps.rip +5 -0
  9. data/ext/nokogiri/extconf.rb +32 -53
  10. data/ext/nokogiri/nokogiri.c +0 -2
  11. data/ext/nokogiri/nokogiri.h +0 -9
  12. data/ext/nokogiri/xml_document.c +0 -14
  13. data/ext/nokogiri/xml_dtd.c +2 -2
  14. data/ext/nokogiri/xml_io.c +7 -32
  15. data/ext/nokogiri/xml_node.c +31 -103
  16. data/ext/nokogiri/xml_node_set.c +8 -8
  17. data/ext/nokogiri/xml_reader.c +1 -20
  18. data/ext/nokogiri/xml_sax_parser.c +3 -5
  19. data/ext/nokogiri/xml_sax_parser_context.c +0 -40
  20. data/ext/nokogiri/xml_xpath_context.c +2 -35
  21. data/ext/nokogiri/xslt_stylesheet.c +6 -124
  22. data/lib/nokogiri.rb +7 -3
  23. data/lib/nokogiri/css.rb +3 -6
  24. data/lib/nokogiri/css/generated_parser.rb +669 -0
  25. data/lib/nokogiri/css/generated_tokenizer.rb +145 -0
  26. data/lib/nokogiri/css/parser.rb +70 -665
  27. data/lib/nokogiri/css/parser.y +1 -6
  28. data/lib/nokogiri/css/tokenizer.rb +3 -148
  29. data/lib/nokogiri/css/tokenizer.rex +1 -1
  30. data/lib/nokogiri/css/xpath_visitor.rb +14 -16
  31. data/lib/nokogiri/decorators/slop.rb +3 -5
  32. data/lib/nokogiri/html.rb +3 -2
  33. data/lib/nokogiri/html/document.rb +18 -134
  34. data/lib/nokogiri/html/document_fragment.rb +21 -26
  35. data/lib/nokogiri/html/element_description_defaults.rb +671 -0
  36. data/lib/nokogiri/html/sax/parser.rb +2 -6
  37. data/lib/nokogiri/version.rb +4 -9
  38. data/lib/nokogiri/xml/attribute_decl.rb +1 -1
  39. data/lib/nokogiri/xml/builder.rb +1 -1
  40. data/lib/nokogiri/xml/document.rb +3 -27
  41. data/lib/nokogiri/xml/document_fragment.rb +2 -9
  42. data/lib/nokogiri/xml/dtd.rb +1 -12
  43. data/lib/nokogiri/xml/element_decl.rb +1 -1
  44. data/lib/nokogiri/xml/entity_decl.rb +1 -1
  45. data/lib/nokogiri/xml/node.rb +75 -172
  46. data/lib/nokogiri/xml/node/save_options.rb +0 -10
  47. data/lib/nokogiri/xml/node_set.rb +3 -28
  48. data/lib/nokogiri/xml/parse_options.rb +0 -8
  49. data/lib/nokogiri/xml/reader.rb +6 -44
  50. data/lib/nokogiri/xml/sax/document.rb +5 -9
  51. data/lib/nokogiri/xml/schema.rb +1 -7
  52. data/lib/nokogiri/xslt.rb +5 -9
  53. data/tasks/cross_compile.rb +12 -27
  54. data/tasks/test.rb +0 -0
  55. data/test/css/test_parser.rb +19 -40
  56. data/test/css/test_tokenizer.rb +0 -8
  57. data/test/helper.rb +1 -4
  58. data/test/html/sax/test_parser.rb +21 -47
  59. data/test/html/sax/test_parser_context.rb +2 -2
  60. data/test/html/test_document.rb +3 -58
  61. data/test/html/test_document_encoding.rb +0 -53
  62. data/test/html/test_document_fragment.rb +13 -82
  63. data/test/html/test_element_description.rb +4 -2
  64. data/test/html/test_node.rb +0 -9
  65. data/test/test_memory_leak.rb +2 -57
  66. data/test/test_nokogiri.rb +14 -20
  67. data/test/test_reader.rb +7 -47
  68. data/test/test_xslt_transforms.rb +5 -8
  69. data/test/xml/sax/test_parser.rb +17 -34
  70. data/test/xml/sax/test_parser_context.rb +0 -50
  71. data/test/xml/sax/test_push_parser.rb +1 -18
  72. data/test/xml/test_attr.rb +4 -31
  73. data/test/xml/test_attribute_decl.rb +7 -3
  74. data/test/xml/test_builder.rb +5 -5
  75. data/test/xml/test_cdata.rb +3 -3
  76. data/test/xml/test_document.rb +18 -15
  77. data/test/xml/test_document_fragment.rb +20 -19
  78. data/test/xml/test_dtd.rb +13 -18
  79. data/test/xml/test_element_content.rb +1 -1
  80. data/test/xml/test_element_decl.rb +1 -1
  81. data/test/xml/test_entity_decl.rb +12 -10
  82. data/test/xml/test_namespace.rb +7 -5
  83. data/test/xml/test_node.rb +15 -54
  84. data/test/xml/test_node_reparenting.rb +42 -85
  85. data/test/xml/test_node_set.rb +2 -61
  86. data/test/xml/test_schema.rb +0 -5
  87. data/test/xml/test_text.rb +2 -11
  88. data/test/xml/test_unparented_node.rb +1 -1
  89. data/test/xml/test_xpath.rb +7 -43
  90. metadata +131 -155
  91. data/.gemtest +0 -0
  92. data/ext/nokogiri/depend +0 -358
  93. data/ext/nokogiri/xml_libxml2_hacks.c +0 -112
  94. data/ext/nokogiri/xml_libxml2_hacks.h +0 -12
  95. data/lib/nokogiri/css/parser_extras.rb +0 -91
  96. data/lib/nokogiri/ffi/encoding_handler.rb +0 -42
  97. data/lib/nokogiri/ffi/html/document.rb +0 -28
  98. data/lib/nokogiri/ffi/html/element_description.rb +0 -81
  99. data/lib/nokogiri/ffi/html/entity_lookup.rb +0 -16
  100. data/lib/nokogiri/ffi/html/sax/parser_context.rb +0 -38
  101. data/lib/nokogiri/ffi/io_callbacks.rb +0 -42
  102. data/lib/nokogiri/ffi/libxml.rb +0 -420
  103. data/lib/nokogiri/ffi/structs/common_node.rb +0 -38
  104. data/lib/nokogiri/ffi/structs/html_elem_desc.rb +0 -24
  105. data/lib/nokogiri/ffi/structs/html_entity_desc.rb +0 -13
  106. data/lib/nokogiri/ffi/structs/xml_alloc.rb +0 -16
  107. data/lib/nokogiri/ffi/structs/xml_attr.rb +0 -20
  108. data/lib/nokogiri/ffi/structs/xml_attribute.rb +0 -27
  109. data/lib/nokogiri/ffi/structs/xml_buffer.rb +0 -16
  110. data/lib/nokogiri/ffi/structs/xml_char_encoding_handler.rb +0 -11
  111. data/lib/nokogiri/ffi/structs/xml_document.rb +0 -117
  112. data/lib/nokogiri/ffi/structs/xml_dtd.rb +0 -28
  113. data/lib/nokogiri/ffi/structs/xml_element.rb +0 -26
  114. data/lib/nokogiri/ffi/structs/xml_element_content.rb +0 -17
  115. data/lib/nokogiri/ffi/structs/xml_entity.rb +0 -32
  116. data/lib/nokogiri/ffi/structs/xml_enumeration.rb +0 -12
  117. data/lib/nokogiri/ffi/structs/xml_node.rb +0 -28
  118. data/lib/nokogiri/ffi/structs/xml_node_set.rb +0 -53
  119. data/lib/nokogiri/ffi/structs/xml_notation.rb +0 -11
  120. data/lib/nokogiri/ffi/structs/xml_ns.rb +0 -15
  121. data/lib/nokogiri/ffi/structs/xml_parser_context.rb +0 -20
  122. data/lib/nokogiri/ffi/structs/xml_parser_input.rb +0 -19
  123. data/lib/nokogiri/ffi/structs/xml_relax_ng.rb +0 -14
  124. data/lib/nokogiri/ffi/structs/xml_sax_handler.rb +0 -51
  125. data/lib/nokogiri/ffi/structs/xml_sax_push_parser_context.rb +0 -124
  126. data/lib/nokogiri/ffi/structs/xml_schema.rb +0 -13
  127. data/lib/nokogiri/ffi/structs/xml_syntax_error.rb +0 -31
  128. data/lib/nokogiri/ffi/structs/xml_text_reader.rb +0 -12
  129. data/lib/nokogiri/ffi/structs/xml_xpath_context.rb +0 -38
  130. data/lib/nokogiri/ffi/structs/xml_xpath_object.rb +0 -35
  131. data/lib/nokogiri/ffi/structs/xml_xpath_parser_context.rb +0 -20
  132. data/lib/nokogiri/ffi/structs/xslt_stylesheet.rb +0 -13
  133. data/lib/nokogiri/ffi/weak_bucket.rb +0 -40
  134. data/lib/nokogiri/ffi/xml/attr.rb +0 -41
  135. data/lib/nokogiri/ffi/xml/attribute_decl.rb +0 -27
  136. data/lib/nokogiri/ffi/xml/cdata.rb +0 -19
  137. data/lib/nokogiri/ffi/xml/comment.rb +0 -18
  138. data/lib/nokogiri/ffi/xml/document.rb +0 -174
  139. data/lib/nokogiri/ffi/xml/document_fragment.rb +0 -21
  140. data/lib/nokogiri/ffi/xml/dtd.rb +0 -67
  141. data/lib/nokogiri/ffi/xml/element_content.rb +0 -43
  142. data/lib/nokogiri/ffi/xml/element_decl.rb +0 -19
  143. data/lib/nokogiri/ffi/xml/entity_decl.rb +0 -36
  144. data/lib/nokogiri/ffi/xml/entity_reference.rb +0 -19
  145. data/lib/nokogiri/ffi/xml/namespace.rb +0 -44
  146. data/lib/nokogiri/ffi/xml/node.rb +0 -559
  147. data/lib/nokogiri/ffi/xml/node_set.rb +0 -150
  148. data/lib/nokogiri/ffi/xml/processing_instruction.rb +0 -20
  149. data/lib/nokogiri/ffi/xml/reader.rb +0 -236
  150. data/lib/nokogiri/ffi/xml/relax_ng.rb +0 -85
  151. data/lib/nokogiri/ffi/xml/sax/parser.rb +0 -143
  152. data/lib/nokogiri/ffi/xml/sax/parser_context.rb +0 -79
  153. data/lib/nokogiri/ffi/xml/sax/push_parser.rb +0 -51
  154. data/lib/nokogiri/ffi/xml/schema.rb +0 -109
  155. data/lib/nokogiri/ffi/xml/syntax_error.rb +0 -98
  156. data/lib/nokogiri/ffi/xml/text.rb +0 -18
  157. data/lib/nokogiri/ffi/xml/xpath.rb +0 -9
  158. data/lib/nokogiri/ffi/xml/xpath_context.rb +0 -153
  159. data/lib/nokogiri/ffi/xslt/stylesheet.rb +0 -77
  160. data/test/decorators/test_slop.rb +0 -16
  161. data/test/ffi/test_document.rb +0 -35
  162. data/test/files/encoding.html +0 -82
  163. data/test/files/encoding.xhtml +0 -84
  164. data/test/xslt/test_custom_functions.rb +0 -94
@@ -1,43 +0,0 @@
1
- # :stopdoc:
2
- module Nokogiri
3
- module XML
4
- class ElementContent
5
- attr_accessor :cstruct
6
-
7
- def self.wrap pointer, document
8
- return nil if pointer.null?
9
-
10
- c = ElementContent.allocate
11
- c.cstruct = LibXML::XmlElementContent.new pointer
12
- c.instance_variable_set :@document, document
13
- c
14
- end
15
-
16
- def type
17
- cstruct[:type]
18
- end
19
-
20
- def prefix
21
- cstruct[:prefix]
22
- end
23
-
24
- def occur
25
- cstruct[:ocur]
26
- end
27
-
28
- def name
29
- cstruct[:name]
30
- end
31
-
32
- private
33
- def c1
34
- self.class.wrap cstruct[:c1], document
35
- end
36
-
37
- def c2
38
- self.class.wrap cstruct[:c2], document
39
- end
40
- end
41
- end
42
- end
43
- # :startdoc:
@@ -1,19 +0,0 @@
1
- # :stopdoc:
2
- module Nokogiri
3
- module XML
4
- class ElementDecl < Nokogiri::XML::Node
5
- def element_type
6
- cstruct[:etype]
7
- end
8
-
9
- def prefix
10
- cstruct[:prefix]
11
- end
12
-
13
- def content
14
- ElementContent.wrap cstruct[:content], document
15
- end
16
- end
17
- end
18
- end
19
- # :startdoc:
@@ -1,36 +0,0 @@
1
- # :stopdoc:
2
- module Nokogiri
3
- module XML
4
- class EntityDecl < Nokogiri::XML::Node
5
-
6
- # from libxml/entities.h
7
- INTERNAL_GENERAL = 1
8
- EXTERNAL_GENERAL_PARSED = 2
9
- EXTERNAL_GENERAL_UNPARSED = 3
10
- INTERNAL_PARAMETER = 4
11
- EXTERNAL_PARAMETER = 5
12
- INTERNAL_PREDEFINED = 6
13
-
14
- def content
15
- cstruct[:content]
16
- end
17
-
18
- def entity_type
19
- cstruct[:etype]
20
- end
21
-
22
- def external_id
23
- cstruct[:external_id]
24
- end
25
-
26
- def system_id
27
- cstruct[:system_id]
28
- end
29
-
30
- def original_content
31
- cstruct[:orig]
32
- end
33
- end
34
- end
35
- end
36
- # :startdoc:
@@ -1,19 +0,0 @@
1
- module Nokogiri
2
- module XML
3
- class EntityReference < Node
4
-
5
- def self.new(document, name, *rest) # :nodoc:
6
- node_ptr = LibXML.xmlNewReference(document.cstruct, name)
7
- node_cstruct = LibXML::XmlNode.new(node_ptr)
8
- node_cstruct.keep_reference_from_document!
9
-
10
- node = Node.wrap(node_cstruct, self)
11
- node.send :initialize, document, name, *rest
12
- yield node if block_given?
13
- node
14
- end
15
-
16
- end
17
- end
18
- end
19
-
@@ -1,44 +0,0 @@
1
- module Nokogiri
2
- module XML
3
- class Namespace
4
- # :stopdoc:
5
-
6
- attr_accessor :cstruct
7
- attr_accessor :document
8
-
9
- def prefix
10
- cstruct[:prefix].nil? ? nil : cstruct[:prefix] # TODO: encoding?
11
- end
12
-
13
- def href
14
- cstruct[:href].nil? ? nil : cstruct[:href] # TODO: encoding?
15
- end
16
-
17
- class << self
18
- def wrap(document, node_struct)
19
- if node_struct.is_a?(FFI::Pointer)
20
- # cast native pointers up into a node cstruct
21
- return nil if node_struct.null?
22
- node_struct = LibXML::XmlNs.new(node_struct)
23
- end
24
-
25
- ruby_node = node_struct.ruby_node
26
- return ruby_node unless ruby_node.nil?
27
-
28
- ns = Nokogiri::XML::Namespace.allocate
29
- ns.document = document.ruby_doc
30
- ns.cstruct = node_struct
31
-
32
- ns.cstruct.ruby_node = ns
33
-
34
- cache = ns.document.instance_variable_get(:@node_cache)
35
- cache << ns
36
-
37
- ns
38
- end
39
- end
40
-
41
- # :startdoc:
42
- end
43
- end
44
- end
@@ -1,559 +0,0 @@
1
- module Nokogiri
2
- module XML
3
- class Node
4
- # :stopdoc:
5
-
6
- attr_accessor :cstruct
7
-
8
- def pointer_id
9
- cstruct.pointer
10
- end
11
-
12
- def encode_special_chars(string)
13
- char_ptr = LibXML.xmlEncodeSpecialChars(self[:doc], string)
14
- encoded = char_ptr.read_string
15
- # TODO: encoding?
16
- LibXML.xmlFree(char_ptr)
17
- encoded
18
- end
19
-
20
- def internal_subset
21
- doc = cstruct.document
22
- dtd = LibXML.xmlGetIntSubset(doc)
23
- return nil if dtd.null?
24
- Node.wrap(dtd)
25
- end
26
-
27
- def external_subset
28
- doc = cstruct.document
29
- return nil if doc[:extSubset].null?
30
-
31
- Node.wrap(doc[:extSubset])
32
- end
33
-
34
- def create_internal_subset name, external_id, system_id
35
- raise("Document already has an internal subset") if internal_subset
36
-
37
- doc = cstruct.document
38
- dtd_ptr = LibXML.xmlCreateIntSubset doc, name, external_id, system_id
39
-
40
- return nil if dtd_ptr.null?
41
-
42
- Node.wrap dtd_ptr
43
- end
44
-
45
- def create_external_subset name, external_id, system_id
46
- raise("Document already has an external subset") if external_subset
47
-
48
- doc = cstruct.document
49
- dtd_ptr = LibXML.xmlNewDtd doc, name, external_id, system_id
50
-
51
- return nil if dtd_ptr.null?
52
-
53
- Node.wrap dtd_ptr
54
- end
55
-
56
- def dup(deep = 1)
57
- dup_ptr = LibXML.xmlDocCopyNode(cstruct, cstruct.document, deep)
58
- return nil if dup_ptr.null?
59
- Node.wrap(dup_ptr, self.class)
60
- end
61
-
62
- def unlink
63
- LibXML.xmlUnlinkNode(cstruct)
64
- cstruct.keep_reference_from_document!
65
- self
66
- end
67
-
68
- def blank?
69
- LibXML.xmlIsBlankNode(cstruct) == 1
70
- end
71
-
72
- def next_sibling
73
- cstruct_node_from :next
74
- end
75
-
76
- def previous_sibling
77
- cstruct_node_from :prev
78
- end
79
-
80
- def next_element
81
- LibXML.xmlNextElementSiblingHack self
82
- end
83
-
84
- def previous_element
85
- #
86
- # note that we don't use xmlPreviousElementSibling here because it's buggy pre-2.7.7.
87
- #
88
- sibling_ptr = cstruct[:prev]
89
-
90
- while ! sibling_ptr.null?
91
- sibling_cstruct = LibXML::XmlNode.new(sibling_ptr)
92
- break if sibling_cstruct[:type] == ELEMENT_NODE
93
- sibling_ptr = sibling_cstruct[:prev]
94
- end
95
-
96
- return sibling_ptr.null? ? nil : Node.wrap(sibling_ptr)
97
- end
98
-
99
- def replace_node new_node
100
- Node.reparent_node_with(self, new_node) do |pivot_struct, reparentee_struct|
101
- retval = LibXML.xmlReplaceNode(pivot_struct, reparentee_struct)
102
- retval = reparentee_struct if retval == pivot_struct.pointer # for reparent_node_with semantics
103
- retval = LibXML::XmlNode.new(retval) if retval.is_a?(FFI::Pointer)
104
- if retval[:type] == TEXT_NODE
105
- if !retval[:prev].null? && LibXML::XmlNode.new(retval[:prev])[:type] == TEXT_NODE
106
- retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval[:prev], retval))
107
- end
108
- if !retval[:next].null? && LibXML::XmlNode.new(retval[:next])[:type] == TEXT_NODE
109
- retval = LibXML::XmlNode.new(LibXML.xmlTextMerge(retval, retval[:next]))
110
- end
111
- end
112
- retval
113
- end
114
- end
115
-
116
- def children
117
- return NodeSet.new(nil) if cstruct[:children].null?
118
- child = Node.wrap(cstruct[:children])
119
-
120
- set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(child.cstruct), self.document)
121
- return set unless child
122
-
123
- child_ptr = child.cstruct[:next]
124
- while ! child_ptr.null?
125
- child = Node.wrap(child_ptr)
126
- LibXML.xmlXPathNodeSetAddUnique(set.cstruct, child.cstruct)
127
- child_ptr = child.cstruct[:next]
128
- end
129
-
130
- return set
131
- end
132
-
133
- def element_children
134
- child = LibXML.xmlFirstElementChildHack(self)
135
- return NodeSet.new(nil) if child.nil?
136
-
137
- set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(child.cstruct), self.document)
138
- return set unless child
139
-
140
- next_sibling = LibXML.xmlNextElementSiblingHack(child)
141
- while ! next_sibling.nil?
142
- child = next_sibling
143
- LibXML.xmlXPathNodeSetAddUnique(set.cstruct, child.cstruct)
144
- next_sibling = LibXML.xmlNextElementSiblingHack(child)
145
- end
146
-
147
- return set
148
- end
149
-
150
- def child
151
- (val = cstruct[:children]).null? ? nil : Node.wrap(val)
152
- end
153
-
154
- def first_element_child
155
- LibXML.xmlFirstElementChildHack(self)
156
- end
157
-
158
- def last_element_child
159
- LibXML.xmlLastElementChildHack(self)
160
- end
161
-
162
- def key?(attribute)
163
- ! (prop = LibXML.xmlHasProp(cstruct, attribute.to_s)).null?
164
- end
165
-
166
- def namespaced_key?(attribute, namespace)
167
- prop = LibXML.xmlHasNsProp(cstruct, attribute.to_s,
168
- namespace.nil? ? nil : namespace.to_s)
169
- !prop.null?
170
- end
171
-
172
- def []=(property, value)
173
- LibXML.xmlSetProp(cstruct, property, value)
174
- value
175
- end
176
-
177
- def get(attribute)
178
- return nil unless attribute
179
- propstr = LibXML.xmlGetProp(cstruct, attribute.to_s)
180
- return nil if propstr.null?
181
- rval = propstr.read_string # TODO: encoding?
182
- LibXML.xmlFree(propstr)
183
- rval
184
- end
185
-
186
- def set_namespace(namespace)
187
- LibXML.xmlSetNs(cstruct, namespace ? namespace.cstruct : nil)
188
- self
189
- end
190
-
191
- def attribute(name)
192
- attribute_nodes.find { |x| x.name == name }
193
- end
194
-
195
- def attribute_with_ns(name, namespace)
196
- prop = LibXML.xmlHasNsProp(cstruct, name.to_s,
197
- namespace.nil? ? NULL : namespace.to_s)
198
- return prop if prop.null?
199
- Node.wrap(prop)
200
- end
201
-
202
- def attribute_nodes
203
- Node.node_properties cstruct
204
- end
205
-
206
- def namespace
207
- cstruct[:ns].null? ? nil : Namespace.wrap(cstruct.document, cstruct[:ns])
208
- end
209
-
210
- def namespace_definitions
211
- list = []
212
- ns_ptr = cstruct[:nsDef]
213
- return list if ns_ptr.null?
214
- while ! ns_ptr.null?
215
- ns = Namespace.wrap(cstruct.document, ns_ptr)
216
- list << ns
217
- ns_ptr = ns.cstruct[:next]
218
- end
219
- list
220
- end
221
-
222
- def namespace_scopes
223
- ns_list = LibXML.xmlGetNsList(self.cstruct[:doc], self.cstruct)
224
- return [] if ns_list.null?
225
-
226
- list = []
227
- until (ns_ptr = ns_list.get_pointer(LibXML.pointer_offset(list.length))).null?
228
- list << Namespace.wrap(cstruct.document, ns_ptr)
229
- end
230
-
231
- LibXML.xmlFree(ns_list)
232
- list
233
- end
234
-
235
- def node_type
236
- cstruct[:type]
237
- end
238
-
239
- def native_content=(content)
240
- child_ptr = cstruct[:children]
241
- while ! child_ptr.null?
242
- child = Node.wrap(child_ptr)
243
- next_ptr = child.cstruct[:next]
244
- LibXML.xmlUnlinkNode(child.cstruct)
245
- cstruct.keep_reference_from_document!
246
- child_ptr = next_ptr
247
- end
248
- LibXML.xmlNodeSetContent(cstruct, content)
249
- content
250
- end
251
-
252
- def content
253
- content_ptr = LibXML.xmlNodeGetContent(cstruct)
254
- return nil if content_ptr.null?
255
- content = content_ptr.read_string # TODO: encoding?
256
- LibXML.xmlFree(content_ptr)
257
- content
258
- end
259
-
260
- def add_child_node child
261
- Node.reparent_node_with(self, child) do |pivot_struct, reparentee_struct|
262
- LibXML.xmlAddChild(pivot_struct, reparentee_struct)
263
- end
264
- end
265
-
266
- def parent
267
- cstruct_node_from :parent
268
- end
269
-
270
- def node_name=(string)
271
- LibXML.xmlNodeSetName(cstruct, string)
272
- string
273
- end
274
-
275
- def node_name
276
- cstruct[:name] # TODO: encoding?
277
- end
278
-
279
- def path
280
- path_ptr = LibXML.xmlGetNodePath(cstruct)
281
- val = path_ptr.null? ? nil : path_ptr.read_string # TODO: encoding?
282
- LibXML.xmlFree(path_ptr)
283
- val
284
- end
285
-
286
- def add_next_sibling_node next_sibling
287
- Node.reparent_node_with(self, next_sibling) do |pivot_struct, reparentee_struct|
288
- LibXML.xmlAddNextSibling(pivot_struct, reparentee_struct)
289
- end
290
- end
291
-
292
- def add_previous_sibling_node prev_sibling
293
- Node.reparent_node_with(self, prev_sibling) do |pivot_struct, reparentee_struct|
294
- LibXML.xmlAddPrevSibling(pivot_struct, reparentee_struct)
295
- end
296
- end
297
-
298
- def native_write_to(io, encoding, indent_string, options)
299
- set_xml_indent_tree_output 1
300
- set_xml_tree_indent_string indent_string
301
- savectx = LibXML.xmlSaveToIO(IoCallbacks.writer(io), nil, nil, encoding, options)
302
- LibXML.xmlSaveTree(savectx, cstruct)
303
- LibXML.xmlSaveClose(savectx)
304
- io
305
- end
306
-
307
- def line
308
- cstruct[:line]
309
- end
310
-
311
- def add_namespace_definition(prefix, href)
312
- ns = LibXML.xmlSearchNs(cstruct.document, cstruct, prefix.nil? ? nil : prefix.to_s)
313
- namespacee = self
314
- if ns.null?
315
- namespacee = parent if type != ELEMENT_NODE
316
- ns = LibXML.xmlNewNs(namespacee.cstruct, href, prefix)
317
- end
318
- return nil if ns.null?
319
- LibXML.xmlSetNs(cstruct, ns) if (prefix.nil? || self != namespacee)
320
- Namespace.wrap(cstruct.document, ns)
321
- end
322
-
323
- def self.new(name, doc, *rest)
324
- ptr = LibXML.xmlNewNode(nil, name.to_s)
325
-
326
- node_cstruct = LibXML::XmlNode.new(ptr)
327
- node_cstruct[:doc] = doc.cstruct[:doc]
328
- node_cstruct.keep_reference_from_document!
329
-
330
- node = Node.wrap(
331
- node_cstruct,
332
- Node == self ? nil : self
333
- )
334
- node.send :initialize, name, doc, *rest
335
- yield node if block_given?
336
- node
337
- end
338
-
339
- def dump_html
340
- return to_xml if type == DOCUMENT_NODE
341
- buffer = LibXML::XmlBuffer.new(LibXML.xmlBufferCreate())
342
- LibXML.htmlNodeDump(buffer, cstruct[:doc], cstruct)
343
- buffer[:content] # TODO: encoding?
344
- end
345
-
346
- def compare(other)
347
- LibXML.xmlXPathCmpNodes(other.cstruct, self.cstruct)
348
- end
349
-
350
- def self.wrap(node_struct, klass=nil)
351
- if node_struct.is_a?(FFI::Pointer)
352
- # cast native pointers up into a node cstruct
353
- return nil if node_struct.null?
354
- node_struct = LibXML::XmlNode.new(node_struct)
355
- end
356
-
357
- raise "wrapping a node without a document" unless node_struct.document
358
-
359
- document_struct = node_struct.document
360
- document_obj = document_struct.nil? ? nil : document_struct.ruby_doc
361
- if node_struct[:type] == DOCUMENT_NODE || node_struct[:type] == HTML_DOCUMENT_NODE
362
- return document_obj
363
- end
364
-
365
- ruby_node = node_struct.ruby_node
366
- return ruby_node unless ruby_node.nil?
367
-
368
- klasses = case node_struct[:type]
369
- when ELEMENT_NODE then [XML::Element]
370
- when TEXT_NODE then [XML::Text]
371
- when ENTITY_REF_NODE then [XML::EntityReference]
372
- when ATTRIBUTE_DECL then [XML::AttributeDecl, LibXML::XmlAttribute]
373
- when ELEMENT_DECL then [XML::ElementDecl, LibXML::XmlElement]
374
- when COMMENT_NODE then [XML::Comment]
375
- when DOCUMENT_FRAG_NODE then [XML::DocumentFragment]
376
- when PI_NODE then [XML::ProcessingInstruction]
377
- when ATTRIBUTE_NODE then [XML::Attr]
378
- when ENTITY_DECL then [XML::EntityDecl, LibXML::XmlEntity]
379
- when CDATA_SECTION_NODE then [XML::CDATA]
380
- when DTD_NODE then [XML::DTD, LibXML::XmlDtd]
381
- else [XML::Node]
382
- end
383
-
384
- if klass
385
- node = klass.allocate
386
- else
387
- node = klasses.first.allocate
388
- end
389
- node.cstruct = klasses[1] ? klasses[1].new(node_struct.pointer) : node_struct
390
-
391
- node.cstruct.ruby_node = node
392
-
393
- if document_obj
394
- node.instance_variable_set(:@document, document_obj)
395
- cache = document_obj.instance_variable_get(:@node_cache)
396
- cache << node
397
- document_obj.decorate(node)
398
- end
399
-
400
- node
401
- end
402
-
403
- def document
404
- cstruct.document.ruby_doc
405
- end
406
-
407
- def in_context(string, options)
408
- errors = []
409
- LibXML.xmlSetStructuredErrorFunc(nil, SyntaxError.error_array_pusher(errors))
410
- LibXML.htmlHandleOmittedElem(0)
411
-
412
- list_memory = FFI::MemoryPointer.new :pointer
413
- LibXML.xmlParseInNodeContext(cstruct, string, string.length, options, list_memory)
414
-
415
- self.document.children.each do |child|
416
- if child.cstruct[:parent] != cstruct[:doc]
417
- child.cstruct[:parent] = cstruct[:doc]
418
- end
419
- end
420
-
421
- LibXML.htmlHandleOmittedElem(1)
422
- LibXML.xmlSetStructuredErrorFunc(nil, nil)
423
- self.document.errors = errors
424
-
425
- set = NodeSet.wrap(LibXML.xmlXPathNodeSetCreate(nil), document)
426
- list_ptr = list_memory.get_pointer(0)
427
- while ! list_ptr.null?
428
- list = Node.wrap(list_ptr)
429
- LibXML.xmlXPathNodeSetAddUnique(set.cstruct, list.cstruct)
430
- list_ptr = list.cstruct[:next]
431
- end
432
- set
433
- end
434
-
435
- class << self
436
- def node_properties(cstruct)
437
- attr = []
438
- prop_cstruct = cstruct[:properties]
439
- while ! prop_cstruct.null?
440
- prop = Node.wrap(prop_cstruct)
441
- attr << prop
442
- prop_cstruct = prop.cstruct[:next]
443
- end
444
- attr
445
- end
446
- end
447
-
448
- private
449
-
450
- def self.reparent_node_with(pivot, reparentee, &block)
451
- raise(ArgumentError, "node must be a Nokogiri::XML::Node") unless reparentee.is_a?(Nokogiri::XML::Node)
452
- raise(ArgumentError, "cannot reparent a document node") if reparentee.node_type == DOCUMENT_NODE || reparentee.node_type == HTML_DOCUMENT_NODE
453
-
454
- pivot_struct = pivot.cstruct
455
- reparentee_struct = reparentee.cstruct
456
-
457
- LibXML.xmlUnlinkNode(reparentee_struct)
458
-
459
- if reparentee_struct[:doc] != pivot_struct[:doc] || reparentee_struct[:type] == TEXT_NODE
460
- reparentee_struct.keep_reference_from_document!
461
- reparentee_struct = LibXML.xmlDocCopyNode(reparentee_struct, pivot_struct.document, 1)
462
- raise(RuntimeError, "Could not reparent node (xmlDocCopyNode)") unless reparentee_struct
463
- reparentee_struct = LibXML::XmlNode.new(reparentee_struct)
464
- end
465
-
466
- if reparentee_struct[:type] == TEXT_NODE && !pivot_struct[:next].null?
467
- next_text = Node.wrap(pivot_struct[:next])
468
- if next_text.cstruct[:type] == TEXT_NODE
469
- new_next_text = LibXML.xmlDocCopyNode(next_text.cstruct, pivot_struct[:doc], 1)
470
- LibXML.xmlUnlinkNode(next_text.cstruct)
471
- next_text.cstruct.keep_reference_from_document!
472
- LibXML.xmlAddNextSibling(pivot_struct, new_next_text);
473
- end
474
- end
475
-
476
- if reparentee_struct[:type] == TEXT_NODE && pivot_struct[:type] == TEXT_NODE && Nokogiri.is_2_6_16?
477
- pivot_struct.pointer.put_pointer(pivot_struct.offset_of(:content), LibXML.xmlStrdup(pivot_struct[:content]))
478
- end
479
-
480
- reparented_struct = block.call(pivot_struct, reparentee_struct)
481
- raise(RuntimeError, "Could not reparent node") unless reparented_struct
482
-
483
- reparented_struct = LibXML::XmlNode.new(reparented_struct) if reparented_struct.is_a?(FFI::Pointer)
484
- reparentee.cstruct = reparented_struct
485
-
486
- relink_namespace reparented_struct
487
-
488
- reparented = Node.wrap(reparented_struct)
489
- reparented.decorate!
490
- reparented
491
- end
492
-
493
- def self.relink_namespace(reparented_struct)
494
- return if reparented_struct[:parent].null?
495
-
496
- # Make sure that our reparented node has the correct namespaces
497
- if reparented_struct[:ns].null? && reparented_struct[:doc] != reparented_struct[:parent]
498
- LibXML.xmlSetNs(reparented_struct, LibXML::XmlNode.new(reparented_struct[:parent])[:ns])
499
- end
500
-
501
- # Search our parents for an existing definition
502
- if ! reparented_struct[:nsDef].null?
503
- curr = reparented_struct[:nsDef]
504
- prev = nil
505
-
506
- while (! curr.null?)
507
- curr_ns = LibXML::XmlNs.new(curr)
508
- ns = LibXML.xmlSearchNsByHref(
509
- reparented_struct[:doc],
510
- reparented_struct[:parent],
511
- curr_ns[:href]
512
- )
513
- # If we find the namespace is already declared, remove it from this
514
- # definition list.
515
- if (! ns.null? && ns != curr)
516
- if prev
517
- prev[:next] = curr_ns[:next]
518
- else
519
- reparented_struct[:nsDef] = curr_ns[:next]
520
- end
521
- curr_ns.keep_reference_from!(reparented_struct.document)
522
- else
523
- prev = curr_ns
524
- end
525
- curr = curr_ns[:next]
526
- end
527
- end
528
-
529
- # Only walk all children if there actually is a namespace we need to reparent.
530
- return if reparented_struct[:ns].null?
531
-
532
- # When a node gets reparented, walk it's children to make sure that
533
- # their namespaces are reparented as well.
534
- child_ptr = reparented_struct[:children]
535
- while ! child_ptr.null?
536
- child_struct = LibXML::XmlNode.new(child_ptr)
537
- relink_namespace child_struct
538
- child_ptr = child_struct[:next]
539
- end
540
- end
541
-
542
- def cstruct_node_from(sym)
543
- (val = cstruct[sym]).null? ? nil : Node.wrap(val)
544
- end
545
-
546
- def set_xml_indent_tree_output(value)
547
- LibXML.__xmlIndentTreeOutput.write_int(value)
548
- end
549
-
550
- def set_xml_tree_indent_string(value)
551
- LibXML.__xmlTreeIndentString.write_pointer(LibXML.xmlStrdup(value.to_s))
552
- end
553
-
554
- # :startdoc:
555
- end
556
- end
557
- end
558
- class Nokogiri::XML::Element < Nokogiri::XML::Node; end
559
- class Nokogiri::XML::CharacterData < Nokogiri::XML::Node; end