pocxxeci 0.30.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of pocxxeci might be problematic. Click here for more details.

Files changed (160) hide show
  1. package/LICENSE +19 -0
  2. package/Makefile +18 -0
  3. package/README.md +52 -0
  4. package/binding.gyp +81 -0
  5. package/index.d.ts +273 -0
  6. package/index.js +45 -0
  7. package/lib/bindings.js +1 -0
  8. package/lib/document.js +122 -0
  9. package/lib/element.js +82 -0
  10. package/lib/sax_parser.js +38 -0
  11. package/package.json +70 -0
  12. package/src/html_document.cc +7 -0
  13. package/src/html_document.h +18 -0
  14. package/src/libxmljs.cc +252 -0
  15. package/src/libxmljs.h +53 -0
  16. package/src/xml_attribute.cc +173 -0
  17. package/src/xml_attribute.h +40 -0
  18. package/src/xml_comment.cc +117 -0
  19. package/src/xml_comment.h +30 -0
  20. package/src/xml_document.cc +810 -0
  21. package/src/xml_document.h +67 -0
  22. package/src/xml_element.cc +565 -0
  23. package/src/xml_element.h +61 -0
  24. package/src/xml_namespace.cc +158 -0
  25. package/src/xml_namespace.h +39 -0
  26. package/src/xml_node.cc +761 -0
  27. package/src/xml_node.h +73 -0
  28. package/src/xml_pi.cc +161 -0
  29. package/src/xml_pi.h +34 -0
  30. package/src/xml_sax_parser.cc +424 -0
  31. package/src/xml_sax_parser.h +73 -0
  32. package/src/xml_syntax_error.cc +66 -0
  33. package/src/xml_syntax_error.h +25 -0
  34. package/src/xml_text.cc +320 -0
  35. package/src/xml_text.h +48 -0
  36. package/src/xml_textwriter.cc +315 -0
  37. package/src/xml_textwriter.h +62 -0
  38. package/src/xml_xpath_context.cc +70 -0
  39. package/src/xml_xpath_context.h +23 -0
  40. package/vendor/libxml/Copyright +23 -0
  41. package/vendor/libxml/DOCBparser.c +305 -0
  42. package/vendor/libxml/HTMLparser.c +7287 -0
  43. package/vendor/libxml/HTMLtree.c +1200 -0
  44. package/vendor/libxml/Makefile +2983 -0
  45. package/vendor/libxml/SAX.c +180 -0
  46. package/vendor/libxml/SAX2.c +3036 -0
  47. package/vendor/libxml/buf.c +1351 -0
  48. package/vendor/libxml/buf.h +72 -0
  49. package/vendor/libxml/c14n.c +2234 -0
  50. package/vendor/libxml/catalog.c +3828 -0
  51. package/vendor/libxml/chvalid.c +336 -0
  52. package/vendor/libxml/config.h +294 -0
  53. package/vendor/libxml/config.h.gch +0 -0
  54. package/vendor/libxml/debugXML.c +3423 -0
  55. package/vendor/libxml/dict.c +1298 -0
  56. package/vendor/libxml/elfgcchack.h +17818 -0
  57. package/vendor/libxml/enc.h +32 -0
  58. package/vendor/libxml/encoding.c +3975 -0
  59. package/vendor/libxml/entities.c +1163 -0
  60. package/vendor/libxml/error.c +998 -0
  61. package/vendor/libxml/globals.c +1126 -0
  62. package/vendor/libxml/hash.c +1146 -0
  63. package/vendor/libxml/include/libxml/DOCBparser.h +96 -0
  64. package/vendor/libxml/include/libxml/HTMLparser.h +306 -0
  65. package/vendor/libxml/include/libxml/HTMLtree.h +147 -0
  66. package/vendor/libxml/include/libxml/Makefile +725 -0
  67. package/vendor/libxml/include/libxml/Makefile.am +54 -0
  68. package/vendor/libxml/include/libxml/Makefile.in +725 -0
  69. package/vendor/libxml/include/libxml/SAX.h +173 -0
  70. package/vendor/libxml/include/libxml/SAX2.h +178 -0
  71. package/vendor/libxml/include/libxml/c14n.h +128 -0
  72. package/vendor/libxml/include/libxml/catalog.h +182 -0
  73. package/vendor/libxml/include/libxml/chvalid.h +230 -0
  74. package/vendor/libxml/include/libxml/debugXML.h +217 -0
  75. package/vendor/libxml/include/libxml/dict.h +79 -0
  76. package/vendor/libxml/include/libxml/encoding.h +245 -0
  77. package/vendor/libxml/include/libxml/entities.h +151 -0
  78. package/vendor/libxml/include/libxml/globals.h +508 -0
  79. package/vendor/libxml/include/libxml/hash.h +236 -0
  80. package/vendor/libxml/include/libxml/list.h +137 -0
  81. package/vendor/libxml/include/libxml/nanoftp.h +163 -0
  82. package/vendor/libxml/include/libxml/nanohttp.h +81 -0
  83. package/vendor/libxml/include/libxml/parser.h +1243 -0
  84. package/vendor/libxml/include/libxml/parserInternals.h +644 -0
  85. package/vendor/libxml/include/libxml/pattern.h +100 -0
  86. package/vendor/libxml/include/libxml/relaxng.h +217 -0
  87. package/vendor/libxml/include/libxml/schemasInternals.h +958 -0
  88. package/vendor/libxml/include/libxml/schematron.h +142 -0
  89. package/vendor/libxml/include/libxml/threads.h +89 -0
  90. package/vendor/libxml/include/libxml/tree.h +1311 -0
  91. package/vendor/libxml/include/libxml/uri.h +94 -0
  92. package/vendor/libxml/include/libxml/valid.h +458 -0
  93. package/vendor/libxml/include/libxml/xinclude.h +129 -0
  94. package/vendor/libxml/include/libxml/xlink.h +189 -0
  95. package/vendor/libxml/include/libxml/xmlIO.h +368 -0
  96. package/vendor/libxml/include/libxml/xmlautomata.h +146 -0
  97. package/vendor/libxml/include/libxml/xmlerror.h +945 -0
  98. package/vendor/libxml/include/libxml/xmlexports.h +77 -0
  99. package/vendor/libxml/include/libxml/xmlmemory.h +224 -0
  100. package/vendor/libxml/include/libxml/xmlmodule.h +57 -0
  101. package/vendor/libxml/include/libxml/xmlreader.h +428 -0
  102. package/vendor/libxml/include/libxml/xmlregexp.h +222 -0
  103. package/vendor/libxml/include/libxml/xmlsave.h +88 -0
  104. package/vendor/libxml/include/libxml/xmlschemas.h +246 -0
  105. package/vendor/libxml/include/libxml/xmlschemastypes.h +151 -0
  106. package/vendor/libxml/include/libxml/xmlstring.h +140 -0
  107. package/vendor/libxml/include/libxml/xmlunicode.h +202 -0
  108. package/vendor/libxml/include/libxml/xmlversion.h +484 -0
  109. package/vendor/libxml/include/libxml/xmlwin32version.h +239 -0
  110. package/vendor/libxml/include/libxml/xmlwriter.h +488 -0
  111. package/vendor/libxml/include/libxml/xpath.h +564 -0
  112. package/vendor/libxml/include/libxml/xpathInternals.h +632 -0
  113. package/vendor/libxml/include/libxml/xpointer.h +114 -0
  114. package/vendor/libxml/include/win32config.h +122 -0
  115. package/vendor/libxml/include/wsockcompat.h +54 -0
  116. package/vendor/libxml/legacy.c +1343 -0
  117. package/vendor/libxml/libxml.h +134 -0
  118. package/vendor/libxml/list.c +779 -0
  119. package/vendor/libxml/nanoftp.c +2118 -0
  120. package/vendor/libxml/nanohttp.c +1899 -0
  121. package/vendor/libxml/parser.c +15553 -0
  122. package/vendor/libxml/parserInternals.c +2164 -0
  123. package/vendor/libxml/pattern.c +2621 -0
  124. package/vendor/libxml/relaxng.c +11101 -0
  125. package/vendor/libxml/rngparser.c +1595 -0
  126. package/vendor/libxml/runsuite.c +1157 -0
  127. package/vendor/libxml/save.h +36 -0
  128. package/vendor/libxml/schematron.c +1787 -0
  129. package/vendor/libxml/threads.c +1049 -0
  130. package/vendor/libxml/timsort.h +601 -0
  131. package/vendor/libxml/tree.c +10183 -0
  132. package/vendor/libxml/trio.c +6895 -0
  133. package/vendor/libxml/trio.h +230 -0
  134. package/vendor/libxml/triodef.h +228 -0
  135. package/vendor/libxml/trionan.c +914 -0
  136. package/vendor/libxml/trionan.h +84 -0
  137. package/vendor/libxml/triop.h +150 -0
  138. package/vendor/libxml/triostr.c +2112 -0
  139. package/vendor/libxml/triostr.h +144 -0
  140. package/vendor/libxml/uri.c +2561 -0
  141. package/vendor/libxml/valid.c +7138 -0
  142. package/vendor/libxml/xinclude.c +2657 -0
  143. package/vendor/libxml/xlink.c +183 -0
  144. package/vendor/libxml/xmlIO.c +4135 -0
  145. package/vendor/libxml/xmlcatalog.c +624 -0
  146. package/vendor/libxml/xmllint.c +3796 -0
  147. package/vendor/libxml/xmlmemory.c +1163 -0
  148. package/vendor/libxml/xmlmodule.c +468 -0
  149. package/vendor/libxml/xmlreader.c +6033 -0
  150. package/vendor/libxml/xmlregexp.c +8271 -0
  151. package/vendor/libxml/xmlsave.c +2735 -0
  152. package/vendor/libxml/xmlschemas.c +29173 -0
  153. package/vendor/libxml/xmlschemastypes.c +6276 -0
  154. package/vendor/libxml/xmlstring.c +1050 -0
  155. package/vendor/libxml/xmlunicode.c +3179 -0
  156. package/vendor/libxml/xmlwriter.c +4738 -0
  157. package/vendor/libxml/xpath.c +14734 -0
  158. package/vendor/libxml/xpointer.c +2969 -0
  159. package/vendor/libxml/xzlib.c +815 -0
  160. package/vendor/libxml/xzlib.h +19 -0
@@ -0,0 +1,761 @@
1
+ // Copyright 2009, Squish Tech, LLC.
2
+
3
+ #include <node.h>
4
+
5
+ #include <libxml/xmlsave.h>
6
+
7
+ #include "xml_attribute.h"
8
+ #include "xml_comment.h"
9
+ #include "xml_document.h"
10
+ #include "xml_element.h"
11
+ #include "xml_namespace.h"
12
+ #include "xml_node.h"
13
+ #include "xml_pi.h"
14
+ #include "xml_text.h"
15
+
16
+ using namespace v8;
17
+
18
+ namespace libxmljs {
19
+
20
+ Nan::Persistent<FunctionTemplate> XmlNode::constructor_template;
21
+
22
+ NAN_METHOD(XmlNode::Doc) {
23
+ Nan::HandleScope scope;
24
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
25
+ assert(node);
26
+
27
+ return info.GetReturnValue().Set(node->get_doc());
28
+ }
29
+
30
+ NAN_METHOD(XmlNode::Namespace) {
31
+ Nan::HandleScope scope;
32
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
33
+ assert(node);
34
+
35
+ // #namespace() Get the node's namespace
36
+ if (info.Length() == 0) {
37
+ return info.GetReturnValue().Set(node->get_namespace());
38
+ }
39
+
40
+ if (info[0]->IsNull())
41
+ return info.GetReturnValue().Set(node->remove_namespace());
42
+
43
+ XmlNamespace *ns = NULL;
44
+
45
+ // #namespace(ns) libxml.Namespace object was provided
46
+ // TODO(sprsquish): check that it was actually given a namespace obj
47
+ if (info[0]->IsObject())
48
+ ns = Nan::ObjectWrap::Unwrap<XmlNamespace>(
49
+ Nan::To<Object>(info[0]).ToLocalChecked());
50
+
51
+ // #namespace(href) or #namespace(prefix, href)
52
+ // if the namespace has already been defined on the node, just set it
53
+ if (info[0]->IsString()) {
54
+ Nan::Utf8String ns_to_find(Nan::To<String>(info[0]).ToLocalChecked());
55
+ xmlNs *found_ns = node->find_namespace(*ns_to_find);
56
+ if (found_ns) {
57
+ // maybe build
58
+ Local<Object> existing = XmlNamespace::New(found_ns);
59
+ ns = Nan::ObjectWrap::Unwrap<XmlNamespace>(existing);
60
+ }
61
+ }
62
+
63
+ // Namespace does not seem to exist, so create it.
64
+ if (!ns) {
65
+ const unsigned int argc = 3;
66
+ Local<Value> argv[argc];
67
+ argv[0] = info.Holder();
68
+
69
+ if (info.Length() == 1) {
70
+ argv[1] = Nan::Null();
71
+ argv[2] = info[0];
72
+ } else {
73
+ argv[1] = info[0];
74
+ argv[2] = info[1];
75
+ }
76
+
77
+ Local<Function> define_namespace =
78
+ Nan::GetFunction(Nan::New(XmlNamespace::constructor_template))
79
+ .ToLocalChecked();
80
+
81
+ // will create a new namespace attached to this node
82
+ // since we keep the document around, the namespace, like the node, won't be
83
+ // garbage collected
84
+ Local<Value> new_ns =
85
+ Nan::NewInstance(define_namespace, argc, argv).ToLocalChecked();
86
+ ns = Nan::ObjectWrap::Unwrap<XmlNamespace>(
87
+ Nan::To<Object>(new_ns).ToLocalChecked());
88
+ }
89
+
90
+ node->set_namespace(ns->xml_obj);
91
+ return info.GetReturnValue().Set(info.Holder());
92
+ }
93
+
94
+ NAN_METHOD(XmlNode::Namespaces) {
95
+ Nan::HandleScope scope;
96
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
97
+ assert(node);
98
+
99
+ // ignore everything but a literal true; different from IsFalse
100
+ if ((info.Length() == 0) || !info[0]->IsTrue()) {
101
+ return info.GetReturnValue().Set(node->get_all_namespaces());
102
+ }
103
+
104
+ return info.GetReturnValue().Set(node->get_local_namespaces());
105
+ }
106
+
107
+ NAN_METHOD(XmlNode::Parent) {
108
+ Nan::HandleScope scope;
109
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
110
+ assert(node);
111
+
112
+ return info.GetReturnValue().Set(node->get_parent());
113
+ }
114
+
115
+ NAN_METHOD(XmlNode::PrevSibling) {
116
+ Nan::HandleScope scope;
117
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
118
+ assert(node);
119
+
120
+ return info.GetReturnValue().Set(node->get_prev_sibling());
121
+ }
122
+
123
+ NAN_METHOD(XmlNode::NextSibling) {
124
+ Nan::HandleScope scope;
125
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
126
+ assert(node);
127
+
128
+ return info.GetReturnValue().Set(node->get_next_sibling());
129
+ }
130
+
131
+ NAN_METHOD(XmlNode::LineNumber) {
132
+ Nan::HandleScope scope;
133
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
134
+ assert(node);
135
+
136
+ return info.GetReturnValue().Set(node->get_line_number());
137
+ }
138
+
139
+ NAN_METHOD(XmlNode::Type) {
140
+ Nan::HandleScope scope;
141
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
142
+ assert(node);
143
+
144
+ return info.GetReturnValue().Set(node->get_type());
145
+ }
146
+
147
+ NAN_METHOD(XmlNode::ToString) {
148
+ Nan::HandleScope scope;
149
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
150
+ assert(node);
151
+
152
+ int options = 0;
153
+
154
+ if (info.Length() > 0) {
155
+ if (info[0]->IsBoolean()) {
156
+ if (info[0]->IsTrue()) {
157
+ options |= XML_SAVE_FORMAT;
158
+ }
159
+ } else if (info[0]->IsObject()) {
160
+ Local<Object> obj = Nan::To<Object>(info[0]).ToLocalChecked();
161
+
162
+ // drop the xml declaration
163
+ if (Nan::Get(obj, Nan::New<String>("declaration").ToLocalChecked())
164
+ .ToLocalChecked()
165
+ ->IsFalse()) {
166
+ options |= XML_SAVE_NO_DECL;
167
+ }
168
+
169
+ // format save output
170
+ if (Nan::Get(obj, Nan::New<String>("format").ToLocalChecked())
171
+ .ToLocalChecked()
172
+ ->IsTrue()) {
173
+ options |= XML_SAVE_FORMAT;
174
+ }
175
+
176
+ // no empty tags (only works with XML) ex: <title></title> becomes
177
+ // <title/>
178
+ if (Nan::Get(obj, Nan::New<String>("selfCloseEmpty").ToLocalChecked())
179
+ .ToLocalChecked()
180
+ ->IsFalse()) {
181
+ options |= XML_SAVE_NO_EMPTY;
182
+ }
183
+
184
+ // format with non-significant whitespace
185
+ if (Nan::Get(obj, Nan::New<String>("whitespace").ToLocalChecked())
186
+ .ToLocalChecked()
187
+ ->IsTrue()) {
188
+ options |= XML_SAVE_WSNONSIG;
189
+ }
190
+
191
+ Local<Value> type =
192
+ Nan::Get(obj, Nan::New<String>("type").ToLocalChecked())
193
+ .ToLocalChecked();
194
+ if (Nan::Equals(type, Nan::New<String>("XML").ToLocalChecked())
195
+ .ToChecked() ||
196
+ Nan::Equals(type, Nan::New<String>("xml").ToLocalChecked())
197
+ .ToChecked()) {
198
+ options |= XML_SAVE_AS_XML; // force XML serialization on HTML doc
199
+ } else if (Nan::Equals(type, Nan::New<String>("HTML").ToLocalChecked())
200
+ .ToChecked() ||
201
+ Nan::Equals(type, Nan::New<String>("html").ToLocalChecked())
202
+ .ToChecked()) {
203
+ options |= XML_SAVE_AS_HTML; // force HTML serialization on XML doc
204
+ // if the document is XML and we want formatted HTML output
205
+ // we must use the XHTML serializer because the default HTML
206
+ // serializer only formats node->type = HTML_NODE and not XML_NODEs
207
+ if ((options & XML_SAVE_FORMAT) &&
208
+ (options & XML_SAVE_XHTML) == false) {
209
+ options |= XML_SAVE_XHTML;
210
+ }
211
+ } else if (Nan::Equals(type, Nan::New<String>("XHTML").ToLocalChecked())
212
+ .ToChecked() ||
213
+ Nan::Equals(type, Nan::New<String>("xhtml").ToLocalChecked())
214
+ .ToChecked()) {
215
+ options |= XML_SAVE_XHTML; // force XHTML serialization
216
+ }
217
+ }
218
+ }
219
+ return info.GetReturnValue().Set(node->to_string(options));
220
+ }
221
+
222
+ NAN_METHOD(XmlNode::Remove) {
223
+ Nan::HandleScope scope;
224
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
225
+ assert(node);
226
+
227
+ node->remove();
228
+
229
+ return info.GetReturnValue().Set(info.Holder());
230
+ }
231
+
232
+ NAN_METHOD(XmlNode::Clone) {
233
+ Nan::HandleScope scope;
234
+ XmlNode *node = Nan::ObjectWrap::Unwrap<XmlNode>(info.Holder());
235
+ assert(node);
236
+
237
+ bool recurse = true;
238
+
239
+ if (info.Length() == 1 && info[0]->IsBoolean())
240
+ recurse = Nan::To<bool>(info[0]).ToChecked();
241
+
242
+ return info.GetReturnValue().Set(node->clone(recurse));
243
+ }
244
+
245
+ Local<Value> XmlNode::New(xmlNode *node) {
246
+ Nan::EscapableHandleScope scope;
247
+ switch (node->type) {
248
+ case XML_ATTRIBUTE_NODE:
249
+ return scope.Escape(XmlAttribute::New(reinterpret_cast<xmlAttr *>(node)));
250
+ case XML_TEXT_NODE:
251
+ return scope.Escape(XmlText::New(node));
252
+ case XML_PI_NODE:
253
+ return scope.Escape(XmlProcessingInstruction::New(node));
254
+ case XML_COMMENT_NODE:
255
+ return scope.Escape(XmlComment::New(node));
256
+
257
+ default:
258
+ // if we don't know how to convert to specific libxmljs wrapper,
259
+ // wrap in an XmlElement. There should probably be specific
260
+ // wrapper types for text nodes etc., but this is what existing
261
+ // code expects.
262
+ return scope.Escape(XmlElement::New(node));
263
+ }
264
+ }
265
+
266
+ XmlNode::XmlNode(xmlNode *node) : xml_obj(node) {
267
+ xml_obj->_private = this;
268
+ this->ancestor = NULL;
269
+
270
+ if ((xml_obj->doc != NULL) && (xml_obj->doc->_private != NULL)) {
271
+ this->doc = xml_obj->doc;
272
+ static_cast<XmlDocument *>(this->doc->_private)->Ref();
273
+ }
274
+
275
+ this->ref_wrapped_ancestor();
276
+ }
277
+
278
+ /*
279
+ * Return the (non-document) root, or a wrapped ancestor: whichever is closest
280
+ */
281
+ xmlNode *get_wrapped_ancestor_or_root(xmlNode *xml_obj) {
282
+ while ((xml_obj->parent != NULL) &&
283
+ (static_cast<void *>(xml_obj->doc) !=
284
+ static_cast<void *>(xml_obj->parent)) &&
285
+ (xml_obj->parent->_private == NULL)) {
286
+ xml_obj = xml_obj->parent;
287
+ }
288
+ return ((xml_obj->parent != NULL) && (static_cast<void *>(xml_obj->doc) !=
289
+ static_cast<void *>(xml_obj->parent)))
290
+ ? xml_obj->parent
291
+ : xml_obj;
292
+ }
293
+
294
+ /*
295
+ * Search linked list for javascript wrapper, ignoring given node.
296
+ */
297
+ xmlAttr *get_wrapped_attr_in_list(xmlAttr *xml_obj, void *skip_xml_obj) {
298
+ xmlAttr *wrapped_attr = NULL;
299
+ while (xml_obj != NULL) {
300
+ if ((xml_obj != skip_xml_obj) && (xml_obj->_private != NULL)) {
301
+ wrapped_attr = xml_obj;
302
+ xml_obj = NULL;
303
+ } else {
304
+ xml_obj = xml_obj->next;
305
+ }
306
+ }
307
+ return wrapped_attr;
308
+ }
309
+
310
+ xmlNs *get_wrapped_ns_in_list(xmlNs *xml_obj, void *skip_xml_obj) {
311
+ xmlNs *wrapped_ns = NULL;
312
+ while (xml_obj != NULL) {
313
+ if ((xml_obj != skip_xml_obj) && (xml_obj->_private != NULL)) {
314
+ wrapped_ns = xml_obj;
315
+ xml_obj = NULL;
316
+ } else {
317
+ xml_obj = xml_obj->next;
318
+ }
319
+ }
320
+ return wrapped_ns;
321
+ }
322
+
323
+ xmlNode *get_wrapped_node_in_children(xmlNode *xml_obj, xmlNode *skip_xml_obj);
324
+
325
+ /*
326
+ * Search document for javascript wrapper, ignoring given node.
327
+ * Based on xmlFreeDoc.
328
+ */
329
+ xmlNode *get_wrapped_node_in_document(xmlDoc *xml_obj, xmlNode *skip_xml_obj) {
330
+ xmlNode *wrapped_node = NULL;
331
+ if ((xml_obj->extSubset != NULL) && (xml_obj->extSubset->_private != NULL) &&
332
+ (static_cast<void *>(xml_obj->extSubset) != skip_xml_obj)) {
333
+ wrapped_node = reinterpret_cast<xmlNode *>(xml_obj->extSubset);
334
+ }
335
+ if ((wrapped_node == NULL) && (xml_obj->intSubset != NULL) &&
336
+ (xml_obj->intSubset->_private != NULL) &&
337
+ (static_cast<void *>(xml_obj->intSubset) != skip_xml_obj)) {
338
+ wrapped_node = reinterpret_cast<xmlNode *>(xml_obj->intSubset);
339
+ }
340
+ if ((wrapped_node == NULL) && (xml_obj->children != NULL)) {
341
+ wrapped_node =
342
+ get_wrapped_node_in_children(xml_obj->children, skip_xml_obj);
343
+ }
344
+ if ((wrapped_node == NULL) && (xml_obj->oldNs != NULL)) {
345
+ wrapped_node = reinterpret_cast<xmlNode *>(
346
+ get_wrapped_ns_in_list(xml_obj->oldNs, skip_xml_obj));
347
+ }
348
+ return wrapped_node;
349
+ }
350
+
351
+ /*
352
+ * Search children of node for javascript wrapper, ignoring given node.
353
+ * Based on xmlFreeNodeList.
354
+ */
355
+ xmlNode *get_wrapped_node_in_children(xmlNode *xml_obj, xmlNode *skip_xml_obj) {
356
+
357
+ xmlNode *wrapped_node = NULL;
358
+
359
+ if (xml_obj->type == XML_NAMESPACE_DECL) {
360
+ return reinterpret_cast<xmlNode *>(get_wrapped_ns_in_list(
361
+ reinterpret_cast<xmlNs *>(xml_obj), skip_xml_obj));
362
+ }
363
+
364
+ if ((xml_obj->type == XML_DOCUMENT_NODE) ||
365
+ #ifdef LIBXML_DOCB_ENABLED
366
+ (xml_obj->type == XML_DOCB_DOCUMENT_NODE) ||
367
+ #endif
368
+ (xml_obj->type == XML_HTML_DOCUMENT_NODE)) {
369
+ return get_wrapped_node_in_document(reinterpret_cast<xmlDoc *>(xml_obj),
370
+ skip_xml_obj);
371
+ }
372
+
373
+ xmlNode *next;
374
+ while (xml_obj != NULL) {
375
+ next = xml_obj->next;
376
+
377
+ if ((xml_obj != skip_xml_obj) && (xml_obj->_private != NULL)) {
378
+ wrapped_node = xml_obj;
379
+ } else {
380
+
381
+ if ((xml_obj->children != NULL) &&
382
+ (xml_obj->type != XML_ENTITY_REF_NODE)) {
383
+ wrapped_node =
384
+ get_wrapped_node_in_children(xml_obj->children, skip_xml_obj);
385
+ }
386
+
387
+ if ((wrapped_node == NULL) && ((xml_obj->type == XML_ELEMENT_NODE) ||
388
+ (xml_obj->type == XML_XINCLUDE_START) ||
389
+ (xml_obj->type == XML_XINCLUDE_END))) {
390
+
391
+ if ((wrapped_node == NULL) && (xml_obj->properties != NULL)) {
392
+ wrapped_node = reinterpret_cast<xmlNode *>(
393
+ get_wrapped_attr_in_list(xml_obj->properties, skip_xml_obj));
394
+ }
395
+
396
+ if ((wrapped_node == NULL) && (xml_obj->nsDef != NULL)) {
397
+ wrapped_node = reinterpret_cast<xmlNode *>(
398
+ get_wrapped_ns_in_list(xml_obj->nsDef, skip_xml_obj));
399
+ }
400
+ }
401
+ }
402
+
403
+ if (wrapped_node != NULL) {
404
+ break;
405
+ }
406
+
407
+ xml_obj = next;
408
+ }
409
+
410
+ return wrapped_node;
411
+ }
412
+
413
+ /*
414
+ * Search descendants of node to find javascript wrapper,
415
+ * optionally ignoring given node. Based on xmlFreeNode.
416
+ */
417
+ xmlNode *get_wrapped_descendant(xmlNode *xml_obj,
418
+ xmlNode *skip_xml_obj = NULL) {
419
+
420
+ xmlNode *wrapped_descendant = NULL;
421
+
422
+ if (xml_obj->type == XML_DTD_NODE) {
423
+ return (xml_obj->children == NULL)
424
+ ? NULL
425
+ : get_wrapped_node_in_children(xml_obj->children, skip_xml_obj);
426
+ }
427
+
428
+ if (xml_obj->type == XML_NAMESPACE_DECL) {
429
+ return NULL;
430
+ }
431
+
432
+ if (xml_obj->type == XML_ATTRIBUTE_NODE) {
433
+ return (xml_obj->children == NULL)
434
+ ? NULL
435
+ : get_wrapped_node_in_children(xml_obj->children, skip_xml_obj);
436
+ }
437
+
438
+ if ((xml_obj->children != NULL) && (xml_obj->type != XML_ENTITY_REF_NODE)) {
439
+ wrapped_descendant =
440
+ get_wrapped_node_in_children(xml_obj->children, skip_xml_obj);
441
+ }
442
+
443
+ if ((xml_obj->type == XML_ELEMENT_NODE) ||
444
+ (xml_obj->type == XML_XINCLUDE_START) ||
445
+ (xml_obj->type == XML_XINCLUDE_END)) {
446
+
447
+ if ((wrapped_descendant == NULL) && (xml_obj->properties != NULL)) {
448
+ wrapped_descendant = reinterpret_cast<xmlNode *>(
449
+ get_wrapped_attr_in_list(xml_obj->properties, skip_xml_obj));
450
+ }
451
+
452
+ if ((wrapped_descendant == NULL) && (xml_obj->nsDef != NULL)) {
453
+ wrapped_descendant = reinterpret_cast<xmlNode *>(
454
+ get_wrapped_ns_in_list(xml_obj->nsDef, skip_xml_obj));
455
+ }
456
+ }
457
+
458
+ return wrapped_descendant;
459
+ }
460
+
461
+ XmlNode::~XmlNode() {
462
+ if ((this->doc != NULL) && (this->doc->_private != NULL)) {
463
+ static_cast<XmlDocument *>(this->doc->_private)->Unref();
464
+ }
465
+ this->unref_wrapped_ancestor();
466
+ if (xml_obj == NULL)
467
+ return;
468
+
469
+ xml_obj->_private = NULL;
470
+ if (xml_obj->parent == NULL) {
471
+ if (get_wrapped_descendant(xml_obj) == NULL) {
472
+ xmlFreeNode(xml_obj);
473
+ }
474
+ } else {
475
+ xmlNode *ancestor = get_wrapped_ancestor_or_root(xml_obj);
476
+ if ((ancestor->_private == NULL) && (ancestor->parent == NULL) &&
477
+ (get_wrapped_descendant(ancestor, xml_obj) == NULL)) {
478
+ xmlFreeNode(ancestor);
479
+ }
480
+ }
481
+ }
482
+
483
+ xmlNode *XmlNode::get_wrapped_ancestor() {
484
+ xmlNode *ancestor = get_wrapped_ancestor_or_root(xml_obj);
485
+ return ((xml_obj == ancestor) || (ancestor->_private == NULL)) ? NULL
486
+ : ancestor;
487
+ }
488
+
489
+ void XmlNode::ref_wrapped_ancestor() {
490
+ xmlNode *ancestor = this->get_wrapped_ancestor();
491
+
492
+ // if our closest wrapped ancestor has changed then we either
493
+ // got removed, added, or a closer ancestor was wrapped
494
+ if (ancestor != this->ancestor) {
495
+ this->unref_wrapped_ancestor();
496
+ this->ancestor = ancestor;
497
+ }
498
+
499
+ if (this->ancestor != NULL) {
500
+ XmlNode *node = static_cast<XmlNode *>(this->ancestor->_private);
501
+ node->Ref();
502
+ }
503
+ }
504
+
505
+ void XmlNode::unref_wrapped_ancestor() {
506
+ if ((this->ancestor != NULL) && (this->ancestor->_private != NULL)) {
507
+ (static_cast<XmlNode *>(this->ancestor->_private))->Unref();
508
+ }
509
+ this->ancestor = NULL;
510
+ }
511
+
512
+ Local<Value> XmlNode::get_doc() {
513
+ Nan::EscapableHandleScope scope;
514
+ return scope.Escape(XmlDocument::New(xml_obj->doc));
515
+ }
516
+
517
+ Local<Value> XmlNode::remove_namespace() {
518
+ xml_obj->ns = NULL;
519
+ return Nan::Null();
520
+ }
521
+
522
+ Local<Value> XmlNode::get_namespace() {
523
+ Nan::EscapableHandleScope scope;
524
+ if (!xml_obj->ns) {
525
+ return scope.Escape(Nan::Null());
526
+ }
527
+
528
+ return scope.Escape(XmlNamespace::New(xml_obj->ns));
529
+ }
530
+
531
+ void XmlNode::set_namespace(xmlNs *ns) {
532
+ xmlSetNs(xml_obj, ns);
533
+ assert(xml_obj->ns);
534
+ }
535
+
536
+ xmlNs *XmlNode::find_namespace(const char *search_str) {
537
+ xmlNs *ns = NULL;
538
+
539
+ // Find by prefix first
540
+ ns = xmlSearchNs(xml_obj->doc, xml_obj, (const xmlChar *)search_str);
541
+
542
+ // Or find by href
543
+ if (!ns)
544
+ ns = xmlSearchNsByHref(xml_obj->doc, xml_obj, (const xmlChar *)search_str);
545
+
546
+ return ns;
547
+ }
548
+
549
+ Local<Value> XmlNode::get_all_namespaces() {
550
+ Nan::EscapableHandleScope scope;
551
+
552
+ // Iterate through namespaces
553
+ Local<Array> namespaces = Nan::New<Array>();
554
+ xmlNs **nsList = xmlGetNsList(xml_obj->doc, xml_obj);
555
+ if (nsList != NULL) {
556
+ for (int i = 0; nsList[i] != NULL; i++) {
557
+ Local<Number> index = Nan::New<Number>(i);
558
+ Local<Object> ns = XmlNamespace::New(nsList[i]);
559
+ Nan::Set(namespaces, index, ns);
560
+ }
561
+ xmlFree(nsList);
562
+ }
563
+
564
+ return scope.Escape(namespaces);
565
+ }
566
+
567
+ Local<Value> XmlNode::get_local_namespaces() {
568
+ Nan::EscapableHandleScope scope;
569
+
570
+ // Iterate through local namespaces
571
+ Local<Array> namespaces = Nan::New<Array>();
572
+ xmlNs *nsDef = xml_obj->nsDef;
573
+ for (int i = 0; nsDef; i++, nsDef = nsDef->next) {
574
+ Local<Number> index = Nan::New<Number>(i);
575
+ Local<Object> ns = XmlNamespace::New(nsDef);
576
+ Nan::Set(namespaces, index, ns);
577
+ }
578
+
579
+ return scope.Escape(namespaces);
580
+ }
581
+
582
+ Local<Value> XmlNode::get_parent() {
583
+ Nan::EscapableHandleScope scope;
584
+
585
+ if (xml_obj->parent) {
586
+ return scope.Escape(XmlElement::New(xml_obj->parent));
587
+ }
588
+
589
+ return scope.Escape(XmlDocument::New(xml_obj->doc));
590
+ }
591
+
592
+ Local<Value> XmlNode::get_prev_sibling() {
593
+ Nan::EscapableHandleScope scope;
594
+ if (xml_obj->prev) {
595
+ return scope.Escape(XmlNode::New(xml_obj->prev));
596
+ }
597
+
598
+ return scope.Escape(Nan::Null());
599
+ }
600
+
601
+ Local<Value> XmlNode::get_next_sibling() {
602
+ Nan::EscapableHandleScope scope;
603
+ if (xml_obj->next) {
604
+ return scope.Escape(XmlNode::New(xml_obj->next));
605
+ }
606
+
607
+ return scope.Escape(Nan::Null());
608
+ }
609
+
610
+ Local<Value> XmlNode::get_line_number() {
611
+ Nan::EscapableHandleScope scope;
612
+ return scope.Escape(Nan::New<Integer>(uint32_t(xmlGetLineNo(xml_obj))));
613
+ }
614
+
615
+ Local<Value> XmlNode::clone(bool recurse) {
616
+ Nan::EscapableHandleScope scope;
617
+
618
+ xmlNode *new_xml_obj = xmlDocCopyNode(xml_obj, xml_obj->doc, recurse);
619
+ return scope.Escape(XmlNode::New(new_xml_obj));
620
+ }
621
+
622
+ Local<Value> XmlNode::to_string(int options) {
623
+ Nan::EscapableHandleScope scope;
624
+
625
+ xmlBuffer *buf = xmlBufferCreate();
626
+ const char *enc = "UTF-8";
627
+
628
+ xmlSaveCtxt *savectx = xmlSaveToBuffer(buf, enc, options);
629
+ xmlSaveTree(savectx, xml_obj);
630
+ xmlSaveFlush(savectx);
631
+
632
+ const xmlChar *xmlstr = xmlBufferContent(buf);
633
+
634
+ if (xmlstr) {
635
+ Local<String> str =
636
+ Nan::New<String>((char *)xmlstr, xmlBufferLength(buf)).ToLocalChecked();
637
+ xmlSaveClose(savectx);
638
+
639
+ xmlBufferFree(buf);
640
+
641
+ return scope.Escape(str);
642
+ } else {
643
+ xmlSaveClose(savectx);
644
+
645
+ xmlBufferFree(buf);
646
+
647
+ return scope.Escape(Nan::Null());
648
+ }
649
+ }
650
+
651
+ void XmlNode::remove() {
652
+ this->unref_wrapped_ancestor();
653
+ xmlUnlinkNode(xml_obj);
654
+ }
655
+
656
+ void XmlNode::add_child(xmlNode *child) { xmlAddChild(xml_obj, child); }
657
+
658
+ void XmlNode::add_prev_sibling(xmlNode *node) {
659
+ xmlAddPrevSibling(xml_obj, node);
660
+ }
661
+
662
+ void XmlNode::add_next_sibling(xmlNode *node) {
663
+ xmlAddNextSibling(xml_obj, node);
664
+ }
665
+
666
+ xmlNode *XmlNode::import_node(xmlNode *node) {
667
+ if (xml_obj->doc == node->doc) {
668
+ if ((node->parent != NULL) && (node->_private != NULL)) {
669
+ static_cast<XmlNode *>(node->_private)->remove();
670
+ }
671
+ return node;
672
+ } else {
673
+ return xmlDocCopyNode(node, xml_obj->doc, 1);
674
+ }
675
+ }
676
+
677
+ Local<Value> XmlNode::get_type() {
678
+ Nan::EscapableHandleScope scope;
679
+ switch (xml_obj->type) {
680
+ case XML_ELEMENT_NODE:
681
+ return scope.Escape(Nan::New<String>("element").ToLocalChecked());
682
+ case XML_ATTRIBUTE_NODE:
683
+ return scope.Escape(Nan::New<String>("attribute").ToLocalChecked());
684
+ case XML_TEXT_NODE:
685
+ return scope.Escape(Nan::New<String>("text").ToLocalChecked());
686
+ case XML_CDATA_SECTION_NODE:
687
+ return scope.Escape(Nan::New<String>("cdata").ToLocalChecked());
688
+ case XML_ENTITY_REF_NODE:
689
+ return scope.Escape(Nan::New<String>("entity_ref").ToLocalChecked());
690
+ case XML_ENTITY_NODE:
691
+ return scope.Escape(Nan::New<String>("entity").ToLocalChecked());
692
+ case XML_PI_NODE:
693
+ return scope.Escape(Nan::New<String>("pi").ToLocalChecked());
694
+ case XML_COMMENT_NODE:
695
+ return scope.Escape(Nan::New<String>("comment").ToLocalChecked());
696
+ case XML_DOCUMENT_NODE:
697
+ return scope.Escape(Nan::New<String>("document").ToLocalChecked());
698
+ case XML_DOCUMENT_TYPE_NODE:
699
+ return scope.Escape(Nan::New<String>("document_type").ToLocalChecked());
700
+ case XML_DOCUMENT_FRAG_NODE:
701
+ return scope.Escape(Nan::New<String>("document_frag").ToLocalChecked());
702
+ case XML_NOTATION_NODE:
703
+ return scope.Escape(Nan::New<String>("notation").ToLocalChecked());
704
+ case XML_HTML_DOCUMENT_NODE:
705
+ return scope.Escape(Nan::New<String>("html_document").ToLocalChecked());
706
+ case XML_DTD_NODE:
707
+ return scope.Escape(Nan::New<String>("dtd").ToLocalChecked());
708
+ case XML_ELEMENT_DECL:
709
+ return scope.Escape(Nan::New<String>("element_decl").ToLocalChecked());
710
+ case XML_ATTRIBUTE_DECL:
711
+ return scope.Escape(Nan::New<String>("attribute_decl").ToLocalChecked());
712
+ case XML_ENTITY_DECL:
713
+ return scope.Escape(Nan::New<String>("entity_decl").ToLocalChecked());
714
+ case XML_NAMESPACE_DECL:
715
+ return scope.Escape(Nan::New<String>("namespace_decl").ToLocalChecked());
716
+ case XML_XINCLUDE_START:
717
+ return scope.Escape(Nan::New<String>("xinclude_start").ToLocalChecked());
718
+ case XML_XINCLUDE_END:
719
+ return scope.Escape(Nan::New<String>("xinclude_end").ToLocalChecked());
720
+ case XML_DOCB_DOCUMENT_NODE:
721
+ return scope.Escape(Nan::New<String>("docb_document").ToLocalChecked());
722
+ }
723
+
724
+ return scope.Escape(Nan::Null());
725
+ }
726
+
727
+ void XmlNode::Initialize(Local<Object> target) {
728
+ Nan::HandleScope scope;
729
+ Local<FunctionTemplate> tmpl = Nan::New<FunctionTemplate>();
730
+ constructor_template.Reset(tmpl);
731
+ tmpl->InstanceTemplate()->SetInternalFieldCount(1);
732
+
733
+ Nan::SetPrototypeMethod(tmpl, "doc", XmlNode::Doc);
734
+
735
+ Nan::SetPrototypeMethod(tmpl, "parent", XmlNode::Parent);
736
+
737
+ Nan::SetPrototypeMethod(tmpl, "namespace", XmlNode::Namespace);
738
+
739
+ Nan::SetPrototypeMethod(tmpl, "namespaces", XmlNode::Namespaces);
740
+
741
+ Nan::SetPrototypeMethod(tmpl, "prevSibling", XmlNode::PrevSibling);
742
+
743
+ Nan::SetPrototypeMethod(tmpl, "nextSibling", XmlNode::NextSibling);
744
+
745
+ Nan::SetPrototypeMethod(tmpl, "line", XmlNode::LineNumber);
746
+
747
+ Nan::SetPrototypeMethod(tmpl, "type", XmlNode::Type);
748
+
749
+ Nan::SetPrototypeMethod(tmpl, "remove", XmlNode::Remove);
750
+
751
+ Nan::SetPrototypeMethod(tmpl, "clone", XmlNode::Clone);
752
+
753
+ Nan::SetPrototypeMethod(tmpl, "toString", XmlNode::ToString);
754
+
755
+ XmlElement::Initialize(target);
756
+ XmlText::Initialize(target);
757
+ XmlComment::Initialize(target);
758
+ XmlProcessingInstruction::Initialize(target);
759
+ XmlAttribute::Initialize(target);
760
+ }
761
+ } // namespace libxmljs