jbarnette-johnson 1.0.0.200806240111

Sign up to get free protection for your applications and to get access to all the features.
Files changed (137) hide show
  1. data/CHANGELOG +5 -0
  2. data/MANIFEST +385 -0
  3. data/MINGW32.mk +124 -0
  4. data/README.rdoc +51 -0
  5. data/Rakefile +166 -0
  6. data/bin/johnson +107 -0
  7. data/cross-compile.txt +38 -0
  8. data/ext/spidermonkey/context.c +122 -0
  9. data/ext/spidermonkey/context.h +19 -0
  10. data/ext/spidermonkey/conversions.c +286 -0
  11. data/ext/spidermonkey/conversions.h +18 -0
  12. data/ext/spidermonkey/debugger.c +208 -0
  13. data/ext/spidermonkey/debugger.h +9 -0
  14. data/ext/spidermonkey/extconf.rb +25 -0
  15. data/ext/spidermonkey/extensions.c +37 -0
  16. data/ext/spidermonkey/extensions.h +12 -0
  17. data/ext/spidermonkey/global.c +40 -0
  18. data/ext/spidermonkey/global.h +11 -0
  19. data/ext/spidermonkey/idhash.c +16 -0
  20. data/ext/spidermonkey/idhash.h +8 -0
  21. data/ext/spidermonkey/immutable_node.c.erb +522 -0
  22. data/ext/spidermonkey/immutable_node.h +22 -0
  23. data/ext/spidermonkey/jroot.h +187 -0
  24. data/ext/spidermonkey/js_land_proxy.c +609 -0
  25. data/ext/spidermonkey/js_land_proxy.h +20 -0
  26. data/ext/spidermonkey/ruby_land_proxy.c +537 -0
  27. data/ext/spidermonkey/ruby_land_proxy.h +17 -0
  28. data/ext/spidermonkey/runtime.c +304 -0
  29. data/ext/spidermonkey/runtime.h +25 -0
  30. data/ext/spidermonkey/spidermonkey.c +20 -0
  31. data/ext/spidermonkey/spidermonkey.h +29 -0
  32. data/js/johnson/browser.js +9 -0
  33. data/js/johnson/browser/env.js +687 -0
  34. data/js/johnson/browser/jquery.js +3444 -0
  35. data/js/johnson/browser/xmlsax.js +1564 -0
  36. data/js/johnson/browser/xmlw3cdom.js +4189 -0
  37. data/js/johnson/cli.js +30 -0
  38. data/js/johnson/prelude.js +80 -0
  39. data/js/johnson/template.js +29 -0
  40. data/lib/hoe.rb +748 -0
  41. data/lib/johnson.rb +46 -0
  42. data/lib/johnson/cli.rb +7 -0
  43. data/lib/johnson/cli/options.rb +56 -0
  44. data/lib/johnson/error.rb +4 -0
  45. data/lib/johnson/nodes.rb +7 -0
  46. data/lib/johnson/nodes/binary_node.rb +64 -0
  47. data/lib/johnson/nodes/for.rb +14 -0
  48. data/lib/johnson/nodes/for_in.rb +12 -0
  49. data/lib/johnson/nodes/function.rb +13 -0
  50. data/lib/johnson/nodes/list.rb +27 -0
  51. data/lib/johnson/nodes/node.rb +68 -0
  52. data/lib/johnson/nodes/ternary_node.rb +20 -0
  53. data/lib/johnson/parser.rb +21 -0
  54. data/lib/johnson/parser/syntax_error.rb +13 -0
  55. data/lib/johnson/runtime.rb +55 -0
  56. data/lib/johnson/spidermonkey/context.rb +10 -0
  57. data/lib/johnson/spidermonkey/debugger.rb +67 -0
  58. data/lib/johnson/spidermonkey/immutable_node.rb +280 -0
  59. data/lib/johnson/spidermonkey/js_land_proxy.rb +62 -0
  60. data/lib/johnson/spidermonkey/mutable_tree_visitor.rb +233 -0
  61. data/lib/johnson/spidermonkey/ruby_land_proxy.rb +52 -0
  62. data/lib/johnson/spidermonkey/runtime.rb +94 -0
  63. data/lib/johnson/version.rb +4 -0
  64. data/lib/johnson/visitable.rb +16 -0
  65. data/lib/johnson/visitors.rb +4 -0
  66. data/lib/johnson/visitors/dot_visitor.rb +167 -0
  67. data/lib/johnson/visitors/ecma_visitor.rb +315 -0
  68. data/lib/johnson/visitors/enumerating_visitor.rb +115 -0
  69. data/lib/johnson/visitors/sexp_visitor.rb +172 -0
  70. data/lib/rails/init.rb +37 -0
  71. data/test/assets/index.html +38 -0
  72. data/test/assets/jquery_test.html +186 -0
  73. data/test/helper.rb +58 -0
  74. data/test/johnson/browser_test.rb +38 -0
  75. data/test/johnson/conversions/array_test.rb +32 -0
  76. data/test/johnson/conversions/boolean_test.rb +17 -0
  77. data/test/johnson/conversions/callable_test.rb +34 -0
  78. data/test/johnson/conversions/file_test.rb +15 -0
  79. data/test/johnson/conversions/nil_test.rb +20 -0
  80. data/test/johnson/conversions/number_test.rb +34 -0
  81. data/test/johnson/conversions/regexp_test.rb +24 -0
  82. data/test/johnson/conversions/string_test.rb +26 -0
  83. data/test/johnson/conversions/struct_test.rb +15 -0
  84. data/test/johnson/conversions/symbol_test.rb +19 -0
  85. data/test/johnson/conversions/thread_test.rb +24 -0
  86. data/test/johnson/error_test.rb +9 -0
  87. data/test/johnson/extensions_test.rb +56 -0
  88. data/test/johnson/nodes/array_literal_test.rb +57 -0
  89. data/test/johnson/nodes/array_node_test.rb +26 -0
  90. data/test/johnson/nodes/binary_node_test.rb +61 -0
  91. data/test/johnson/nodes/bracket_access_test.rb +16 -0
  92. data/test/johnson/nodes/delete_test.rb +11 -0
  93. data/test/johnson/nodes/do_while_test.rb +12 -0
  94. data/test/johnson/nodes/dot_accessor_test.rb +15 -0
  95. data/test/johnson/nodes/export_test.rb +9 -0
  96. data/test/johnson/nodes/for_test.rb +54 -0
  97. data/test/johnson/nodes/function_test.rb +71 -0
  98. data/test/johnson/nodes/if_test.rb +41 -0
  99. data/test/johnson/nodes/import_test.rb +13 -0
  100. data/test/johnson/nodes/label_test.rb +19 -0
  101. data/test/johnson/nodes/object_literal_test.rb +110 -0
  102. data/test/johnson/nodes/return_test.rb +16 -0
  103. data/test/johnson/nodes/semi_test.rb +8 -0
  104. data/test/johnson/nodes/switch_test.rb +55 -0
  105. data/test/johnson/nodes/ternary_test.rb +25 -0
  106. data/test/johnson/nodes/throw_test.rb +9 -0
  107. data/test/johnson/nodes/try_node_test.rb +59 -0
  108. data/test/johnson/nodes/typeof_test.rb +11 -0
  109. data/test/johnson/nodes/unary_node_test.rb +23 -0
  110. data/test/johnson/nodes/void_test.rb +11 -0
  111. data/test/johnson/nodes/while_test.rb +26 -0
  112. data/test/johnson/nodes/with_test.rb +10 -0
  113. data/test/johnson/prelude_test.rb +56 -0
  114. data/test/johnson/runtime_test.rb +46 -0
  115. data/test/johnson/spidermonkey/context_test.rb +21 -0
  116. data/test/johnson/spidermonkey/immutable_node_test.rb +34 -0
  117. data/test/johnson/spidermonkey/js_land_proxy_test.rb +236 -0
  118. data/test/johnson/spidermonkey/ruby_land_proxy_test.rb +225 -0
  119. data/test/johnson/spidermonkey/runtime_test.rb +17 -0
  120. data/test/johnson/version_test.rb +13 -0
  121. data/test/johnson/visitors/dot_visitor_test.rb +39 -0
  122. data/test/johnson/visitors/enumerating_visitor_test.rb +12 -0
  123. data/test/johnson_test.rb +16 -0
  124. data/test/jquery_units/test.js +27 -0
  125. data/test/jquery_units/test_helper.js +197 -0
  126. data/test/jquery_units/units/ajax.js +795 -0
  127. data/test/jquery_units/units/core.js +1563 -0
  128. data/test/jquery_units/units/event.js +299 -0
  129. data/test/jquery_units/units/fx.js +427 -0
  130. data/test/jquery_units/units/offset.js +112 -0
  131. data/test/jquery_units/units/selector.js +224 -0
  132. data/test/jspec/helper.js +7 -0
  133. data/test/jspec/jspec.js +192 -0
  134. data/test/jspec/simple_spec.js +68 -0
  135. data/test/parser_test.rb +276 -0
  136. data/todo/.keep +0 -0
  137. metadata +501 -0
@@ -0,0 +1,4189 @@
1
+ // =========================================================================
2
+ //
3
+ // xmlw3cdom.js - a W3C compliant W3CDOM parser for XML for <SCRIPT>
4
+ //
5
+ // version 3.1
6
+ //
7
+ // =========================================================================
8
+ //
9
+ // Copyright (C) 2002, 2003, 2004 Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
10
+ //
11
+ // This library is free software; you can redistribute it and/or
12
+ // modify it under the terms of the GNU Lesser General Public
13
+ // License as published by the Free Software Foundation; either
14
+ // version 2.1 of the License, or (at your option) any later version.
15
+
16
+ // This library is distributed in the hope that it will be useful,
17
+ // but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
+ // Lesser General Public License for more details.
20
+
21
+ // You should have received a copy of the GNU Lesser General Public
22
+ // License along with this library; if not, write to the Free Software
23
+ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
+ //
25
+ // visit the XML for <SCRIPT> home page at xmljs.sourceforge.net
26
+ //
27
+ // Contains text (used within comments to methods) from the
28
+ // XML Path Language (XPath) Version 1.0 W3C Recommendation
29
+ // Copyright � 16 November 1999 World Wide Web Consortium,
30
+ // (Massachusetts Institute of Technology,
31
+ // European Research Consortium for Informatics and Mathematics, Keio University).
32
+ // All Rights Reserved.
33
+ // (see: http://www.w3.org/TR/2000/WD-W3CDOM-Level-1-20000929/)
34
+
35
+ /**
36
+ * @function addClass - add new className to classCollection
37
+ *
38
+ * @author Jon van Noort (jon@webarcana.com.au)
39
+ *
40
+ * @param classCollectionStr : string - list of existing class names
41
+ * (separated and top and tailed with '|'s)
42
+ * @param newClass : string - new class name to add
43
+ *
44
+ * @return : string - the new classCollection, with new className appended,
45
+ * (separated and top and tailed with '|'s)
46
+ */
47
+ function addClass(classCollectionStr, newClass) {
48
+ if (classCollectionStr) {
49
+ if (classCollectionStr.indexOf("|"+ newClass +"|") < 0) {
50
+ classCollectionStr += newClass + "|";
51
+ }
52
+ }
53
+ else {
54
+ classCollectionStr = "|"+ newClass + "|";
55
+ }
56
+
57
+ return classCollectionStr;
58
+ }
59
+
60
+ /**
61
+ * @class W3CDOMException - raised when an operation is impossible to perform
62
+ *
63
+ * @author Jon van Noort (jon@webarcana.com.au)
64
+ *
65
+ * @param code : int - the exception code (one of the W3CDOMException constants)
66
+ */
67
+ W3CDOMException = function(code) {
68
+ this._class = addClass(this._class, "W3CDOMException");
69
+
70
+ this.code = code;
71
+ };
72
+
73
+ // W3CDOMException constants
74
+ // Introduced in W3CDOM Level 1:
75
+ W3CDOMException.INDEX_SIZE_ERR = 1;
76
+ W3CDOMException.W3CDOMSTRING_SIZE_ERR = 2;
77
+ W3CDOMException.HIERARCHY_REQUEST_ERR = 3;
78
+ W3CDOMException.WRONG_DOCUMENT_ERR = 4;
79
+ W3CDOMException.INVALID_CHARACTER_ERR = 5;
80
+ W3CDOMException.NO_DATA_ALLOWED_ERR = 6;
81
+ W3CDOMException.NO_MODIFICATION_ALLOWED_ERR = 7;
82
+ W3CDOMException.NOT_FOUND_ERR = 8;
83
+ W3CDOMException.NOT_SUPPORTED_ERR = 9;
84
+ W3CDOMException.INUSE_ATTRIBUTE_ERR = 10;
85
+
86
+ // Introduced in W3CDOM Level 2:
87
+ W3CDOMException.INVALID_STATE_ERR = 11;
88
+ W3CDOMException.SYNTAX_ERR = 12;
89
+ W3CDOMException.INVALID_MODIFICATION_ERR = 13;
90
+ W3CDOMException.NAMESPACE_ERR = 14;
91
+ W3CDOMException.INVALID_ACCESS_ERR = 15;
92
+
93
+
94
+ /**
95
+ * @class W3CDOMImplementation - provides a number of methods for performing operations
96
+ * that are independent of any particular instance of the document object model.
97
+ *
98
+ * @author Jon van Noort (jon@webarcana.com.au)
99
+ */
100
+ W3CDOMImplementation = function() {
101
+ this._class = addClass(this._class, "W3CDOMImplementation");
102
+ this._p = null;
103
+
104
+ this.preserveWhiteSpace = false; // by default, ignore whitespace
105
+ this.namespaceAware = true; // by default, handle namespaces
106
+ this.errorChecking = true; // by default, test for exceptions
107
+ };
108
+
109
+
110
+ /**
111
+ * @method W3CDOMImplementation.escapeString - escape special characters
112
+ *
113
+ * @author Jon van Noort (jon@webarcana.com.au)
114
+ *
115
+ * @param str : string - The string to be escaped
116
+ *
117
+ * @return : string - The escaped string
118
+ */
119
+ W3CDOMImplementation.prototype.escapeString = function W3CDOMNode__escapeString(str) {
120
+
121
+ //the sax processor already has this function. Just wrap it
122
+ return __escapeString(str);
123
+ };
124
+
125
+ /**
126
+ * @method W3CDOMImplementation.unescapeString - unescape special characters
127
+ *
128
+ * @author Jon van Noort (jon@webarcana.com.au)
129
+ *
130
+ * @param str : string - The string to be unescaped
131
+ *
132
+ * @return : string - The unescaped string
133
+ */
134
+ W3CDOMImplementation.prototype.unescapeString = function W3CDOMNode__unescapeString(str) {
135
+
136
+ //the sax processor already has this function. Just wrap it
137
+ return __unescapeString(str);
138
+ };
139
+
140
+ /**
141
+ * @method W3CDOMImplementation.hasFeature - Test if the W3CDOM implementation implements a specific feature
142
+ *
143
+ * @author Jon van Noort (jon@webarcana.com.au)
144
+ *
145
+ * @param feature : string - The package name of the feature to test. the legal only values are "XML" and "CORE" (case-insensitive).
146
+ * @param version : string - This is the version number of the package name to test. In Level 1, this is the string "1.0".
147
+ *
148
+ * @return : boolean
149
+ */
150
+ W3CDOMImplementation.prototype.hasFeature = function W3CDOMImplementation_hasFeature(feature, version) {
151
+
152
+ var ret = false;
153
+ if (feature.toLowerCase() == "xml") {
154
+ ret = (!version || (version == "1.0") || (version == "2.0"));
155
+ }
156
+ else if (feature.toLowerCase() == "core") {
157
+ ret = (!version || (version == "2.0"));
158
+ }
159
+
160
+ return ret;
161
+ };
162
+
163
+ /**
164
+ * @method W3CDOMImplementation.loadXML - parse XML string
165
+ *
166
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
167
+ *
168
+ * @param xmlStr : string - the XML string
169
+ *
170
+ * @return : W3CDOMDocument
171
+ */
172
+ W3CDOMImplementation.prototype.loadXML = function W3CDOMImplementation_loadXML(xmlStr) {
173
+ // create SAX Parser
174
+ var parser;
175
+
176
+ try {
177
+ parser = new XMLP(xmlStr);
178
+ }
179
+ catch (e) {
180
+ alert("Error Creating the SAX Parser. Did you include xmlsax.js or tinyxmlsax.js in your web page?\nThe SAX parser is needed to populate XML for <SCRIPT>'s W3C W3CDOM Parser with data.");
181
+ }
182
+
183
+ // create W3CDOM Document
184
+ var doc = new W3CDOMDocument(this);
185
+
186
+ // populate Document with Parsed Nodes
187
+ this._parseLoop(doc, parser);
188
+
189
+ // set parseComplete flag, (Some validation Rules are relaxed if this is false)
190
+ doc._parseComplete = true;
191
+
192
+ return doc;
193
+ };
194
+
195
+
196
+ /**
197
+ * @method W3CDOMImplementation.translateErrCode - convert W3CDOMException Code
198
+ * to human readable error message;
199
+ *
200
+ * @author Jon van Noort (jon@webarcana.com.au)
201
+ *
202
+ * @param code : int - the W3CDOMException code
203
+ *
204
+ * @return : string - the human readbale error message
205
+ */
206
+ W3CDOMImplementation.prototype.translateErrCode = function W3CDOMImplementation_translateErrCode(code) {
207
+ var msg = "";
208
+
209
+ switch (code) {
210
+ case W3CDOMException.INDEX_SIZE_ERR : // 1
211
+ msg = "INDEX_SIZE_ERR: Index out of bounds";
212
+ break;
213
+
214
+ case W3CDOMException.W3CDOMSTRING_SIZE_ERR : // 2
215
+ msg = "W3CDOMSTRING_SIZE_ERR: The resulting string is too long to fit in a W3CDOMString";
216
+ break;
217
+
218
+ case W3CDOMException.HIERARCHY_REQUEST_ERR : // 3
219
+ msg = "HIERARCHY_REQUEST_ERR: The Node can not be inserted at this location";
220
+ break;
221
+
222
+ case W3CDOMException.WRONG_DOCUMENT_ERR : // 4
223
+ msg = "WRONG_DOCUMENT_ERR: The source and the destination Documents are not the same";
224
+ break;
225
+
226
+ case W3CDOMException.INVALID_CHARACTER_ERR : // 5
227
+ msg = "INVALID_CHARACTER_ERR: The string contains an invalid character";
228
+ break;
229
+
230
+ case W3CDOMException.NO_DATA_ALLOWED_ERR : // 6
231
+ msg = "NO_DATA_ALLOWED_ERR: This Node / NodeList does not support data";
232
+ break;
233
+
234
+ case W3CDOMException.NO_MODIFICATION_ALLOWED_ERR : // 7
235
+ msg = "NO_MODIFICATION_ALLOWED_ERR: This object cannot be modified";
236
+ break;
237
+
238
+ case W3CDOMException.NOT_FOUND_ERR : // 8
239
+ msg = "NOT_FOUND_ERR: The item cannot be found";
240
+ break;
241
+
242
+ case W3CDOMException.NOT_SUPPORTED_ERR : // 9
243
+ msg = "NOT_SUPPORTED_ERR: This implementation does not support function";
244
+ break;
245
+
246
+ case W3CDOMException.INUSE_ATTRIBUTE_ERR : // 10
247
+ msg = "INUSE_ATTRIBUTE_ERR: The Attribute has already been assigned to another Element";
248
+ break;
249
+
250
+ // Introduced in W3CDOM Level 2:
251
+ case W3CDOMException.INVALID_STATE_ERR : // 11
252
+ msg = "INVALID_STATE_ERR: The object is no longer usable";
253
+ break;
254
+
255
+ case W3CDOMException.SYNTAX_ERR : // 12
256
+ msg = "SYNTAX_ERR: Syntax error";
257
+ break;
258
+
259
+ case W3CDOMException.INVALID_MODIFICATION_ERR : // 13
260
+ msg = "INVALID_MODIFICATION_ERR: Cannot change the type of the object";
261
+ break;
262
+
263
+ case W3CDOMException.NAMESPACE_ERR : // 14
264
+ msg = "NAMESPACE_ERR: The namespace declaration is incorrect";
265
+ break;
266
+
267
+ case W3CDOMException.INVALID_ACCESS_ERR : // 15
268
+ msg = "INVALID_ACCESS_ERR: The object does not support this function";
269
+ break;
270
+
271
+ default :
272
+ msg = "UNKNOWN: Unknown Exception Code ("+ code +")";
273
+ }
274
+
275
+ return msg;
276
+ }
277
+
278
+ /**
279
+ * @method W3CDOMImplementation._parseLoop - process SAX events
280
+ *
281
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
282
+ *
283
+ * @param doc : W3CDOMDocument - the Document to contain the parsed XML string
284
+ * @param p : XMLP - the SAX Parser
285
+ *
286
+ * @return : W3CDOMDocument
287
+ */
288
+ W3CDOMImplementation.prototype._parseLoop = function W3CDOMImplementation__parseLoop(doc, p) {
289
+ var iEvt, iNode, iAttr, strName;
290
+ iNodeParent = doc;
291
+
292
+ var el_close_count = 0;
293
+
294
+ var entitiesList = new Array();
295
+ var textNodesList = new Array();
296
+
297
+ // if namespaceAware, add default namespace
298
+ if (this.namespaceAware) {
299
+ var iNS = doc.createNamespace(""); // add the default-default namespace
300
+ iNS.setValue("http://www.w3.org/2000/xmlns/");
301
+ doc._namespaces.setNamedItem(iNS);
302
+ }
303
+
304
+ // loop until SAX parser stops emitting events
305
+ while(true) {
306
+ // get next event
307
+ iEvt = p.next();
308
+
309
+ if (iEvt == XMLP._ELM_B) { // Begin-Element Event
310
+ var pName = p.getName(); // get the Element name
311
+ pName = trim(pName, true, true); // strip spaces from Element name
312
+
313
+ if (!this.namespaceAware) {
314
+ iNode = doc.createElement(p.getName()); // create the Element
315
+
316
+ // add attributes to Element
317
+ for(var i = 0; i < p.getAttributeCount(); i++) {
318
+ strName = p.getAttributeName(i); // get Attribute name
319
+ iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
320
+
321
+ if(!iAttr) {
322
+ iAttr = doc.createAttribute(strName); // otherwise create it
323
+ }
324
+
325
+ iAttr.setValue(p.getAttributeValue(i)); // set Attribute value
326
+ iNode.setAttributeNode(iAttr); // attach Attribute to Element
327
+ }
328
+ }
329
+ else { // Namespace Aware
330
+ // create element (with empty namespaceURI,
331
+ // resolve after namespace 'attributes' have been parsed)
332
+ iNode = doc.createElementNS("", p.getName());
333
+
334
+ // duplicate ParentNode's Namespace definitions
335
+ iNode._namespaces = iNodeParent._namespaces._cloneNodes(iNode);
336
+
337
+ // add attributes to Element
338
+ for(var i = 0; i < p.getAttributeCount(); i++) {
339
+ strName = p.getAttributeName(i); // get Attribute name
340
+
341
+ // if attribute is a namespace declaration
342
+ if (this._isNamespaceDeclaration(strName)) {
343
+ // parse Namespace Declaration
344
+ var namespaceDec = this._parseNSName(strName);
345
+
346
+ if (strName != "xmlns") {
347
+ iNS = doc.createNamespace(strName); // define namespace
348
+ }
349
+ else {
350
+ iNS = doc.createNamespace(""); // redefine default namespace
351
+ }
352
+ iNS.setValue(p.getAttributeValue(i)); // set value = namespaceURI
353
+
354
+ iNode._namespaces.setNamedItem(iNS); // attach namespace to namespace collection
355
+ }
356
+ else { // otherwise, it is a normal attribute
357
+ iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
358
+
359
+ if(!iAttr) {
360
+ iAttr = doc.createAttributeNS("", strName); // otherwise create it
361
+ }
362
+
363
+ iAttr.setValue(p.getAttributeValue(i)); // set Attribute value
364
+ iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
365
+
366
+ if (this._isIdDeclaration(strName)) {
367
+ iNode.id = p.getAttributeValue(i); // cache ID for getElementById()
368
+ }
369
+ }
370
+ }
371
+
372
+ // resolve namespaceURIs for this Element
373
+ if (iNode._namespaces.getNamedItem(iNode.prefix)) {
374
+ iNode.namespaceURI = iNode._namespaces.getNamedItem(iNode.prefix).value;
375
+ }
376
+
377
+ // for this Element's attributes
378
+ for (var i = 0; i < iNode.attributes.length; i++) {
379
+ if (iNode.attributes.item(i).prefix != "") { // attributes do not have a default namespace
380
+ if (iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix)) {
381
+ iNode.attributes.item(i).namespaceURI = iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix).value;
382
+ }
383
+ }
384
+ }
385
+ }
386
+
387
+ // if this is the Root Element
388
+ if (iNodeParent.nodeType == W3CDOMNode.DOCUMENT_NODE) {
389
+ iNodeParent.documentElement = iNode; // register this Element as the Document.documentElement
390
+ }
391
+
392
+ iNodeParent.appendChild(iNode); // attach Element to parentNode
393
+ iNodeParent = iNode; // descend one level of the W3CDOM Tree
394
+ }
395
+
396
+ else if(iEvt == XMLP._ELM_E) { // End-Element Event
397
+ iNodeParent = iNodeParent.parentNode; // ascend one level of the W3CDOM Tree
398
+ }
399
+
400
+ else if(iEvt == XMLP._ELM_EMP) { // Empty Element Event
401
+ pName = p.getName(); // get the Element name
402
+ pName = trim(pName, true, true); // strip spaces from Element name
403
+
404
+ if (!this.namespaceAware) {
405
+ iNode = doc.createElement(pName); // create the Element
406
+
407
+ // add attributes to Element
408
+ for(var i = 0; i < p.getAttributeCount(); i++) {
409
+ strName = p.getAttributeName(i); // get Attribute name
410
+ iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
411
+
412
+ if(!iAttr) {
413
+ iAttr = doc.createAttribute(strName); // otherwise create it
414
+ }
415
+
416
+ iAttr.setValue(p.getAttributeValue(i)); // set Attribute value
417
+ iNode.setAttributeNode(iAttr); // attach Attribute to Element
418
+ }
419
+ }
420
+ else { // Namespace Aware
421
+ // create element (with empty namespaceURI,
422
+ // resolve after namespace 'attributes' have been parsed)
423
+ iNode = doc.createElementNS("", p.getName());
424
+
425
+ // duplicate ParentNode's Namespace definitions
426
+ iNode._namespaces = iNodeParent._namespaces._cloneNodes(iNode);
427
+
428
+ // add attributes to Element
429
+ for(var i = 0; i < p.getAttributeCount(); i++) {
430
+ strName = p.getAttributeName(i); // get Attribute name
431
+
432
+ // if attribute is a namespace declaration
433
+ if (this._isNamespaceDeclaration(strName)) {
434
+ // parse Namespace Declaration
435
+ var namespaceDec = this._parseNSName(strName);
436
+
437
+ if (strName != "xmlns") {
438
+ iNS = doc.createNamespace(strName); // define namespace
439
+ }
440
+ else {
441
+ iNS = doc.createNamespace(""); // redefine default namespace
442
+ }
443
+ iNS.setValue(p.getAttributeValue(i)); // set value = namespaceURI
444
+
445
+ iNode._namespaces.setNamedItem(iNS); // attach namespace to namespace collection
446
+ }
447
+ else { // otherwise, it is a normal attribute
448
+ iAttr = iNode.getAttributeNode(strName); // if Attribute exists, use it
449
+
450
+ if(!iAttr) {
451
+ iAttr = doc.createAttributeNS("", strName); // otherwise create it
452
+ }
453
+
454
+ iAttr.setValue(p.getAttributeValue(i)); // set Attribute value
455
+ iNode.setAttributeNodeNS(iAttr); // attach Attribute to Element
456
+
457
+ if (this._isIdDeclaration(strName)) {
458
+ iNode.id = p.getAttributeValue(i); // cache ID for getElementById()
459
+ }
460
+ }
461
+ }
462
+
463
+ // resolve namespaceURIs for this Element
464
+ if (iNode._namespaces.getNamedItem(iNode.prefix)) {
465
+ iNode.namespaceURI = iNode._namespaces.getNamedItem(iNode.prefix).value;
466
+ }
467
+
468
+ // for this Element's attributes
469
+ for (var i = 0; i < iNode.attributes.length; i++) {
470
+ if (iNode.attributes.item(i).prefix != "") { // attributes do not have a default namespace
471
+ if (iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix)) {
472
+ iNode.attributes.item(i).namespaceURI = iNode._namespaces.getNamedItem(iNode.attributes.item(i).prefix).value;
473
+ }
474
+ }
475
+ }
476
+ }
477
+
478
+ // if this is the Root Element
479
+ if (iNodeParent.nodeType == W3CDOMNode.DOCUMENT_NODE) {
480
+ iNodeParent.documentElement = iNode; // register this Element as the Document.documentElement
481
+ }
482
+
483
+ iNodeParent.appendChild(iNode); // attach Element to parentNode
484
+ }
485
+ else if(iEvt == XMLP._TEXT || iEvt == XMLP._ENTITY) { // TextNode and entity Events
486
+ // get Text content
487
+ var pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
488
+
489
+ if (!this.preserveWhiteSpace ) {
490
+ if (trim(pContent, true, true) == "") {
491
+ pContent = ""; //this will cause us not to create the text node below
492
+ }
493
+ }
494
+
495
+ if (pContent.length > 0) { // ignore empty TextNodes
496
+ var textNode = doc.createTextNode(pContent);
497
+ iNodeParent.appendChild(textNode); // attach TextNode to parentNode
498
+
499
+ //the sax parser breaks up text nodes when it finds an entity. For
500
+ //example hello&lt;there will fire a text, an entity and another text
501
+ //this sucks for the dom parser because it looks to us in this logic
502
+ //as three text nodes. I fix this by keeping track of the entity nodes
503
+ //and when we're done parsing, calling normalize on their parent to
504
+ //turn the multiple text nodes into one, which is what W3CDOM users expect
505
+ //the code to do this is at the bottom of this function
506
+ if (iEvt == XMLP._ENTITY) {
507
+ entitiesList[entitiesList.length] = textNode;
508
+ }
509
+ else {
510
+ //I can't properly decide how to handle preserve whitespace
511
+ //until the siblings of the text node are built due to
512
+ //the entitiy handling described above. I don't know that this
513
+ //will be all of the text node or not, so trimming is not appropriate
514
+ //at this time. Keep a list of all the text nodes for now
515
+ //and we'll process the preserve whitespace stuff at a later time.
516
+ textNodesList[textNodesList.length] = textNode;
517
+ }
518
+ }
519
+ }
520
+ else if(iEvt == XMLP._PI) { // ProcessingInstruction Event
521
+ // attach ProcessingInstruction to parentNode
522
+ iNodeParent.appendChild(doc.createProcessingInstruction(p.getName(), p.getContent().substring(p.getContentBegin(), p.getContentEnd())));
523
+ }
524
+ else if(iEvt == XMLP._CDATA) { // CDATA Event
525
+ // get CDATA data
526
+ pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
527
+
528
+ if (!this.preserveWhiteSpace) {
529
+ pContent = trim(pContent, true, true); // trim whitespace
530
+ pContent.replace(/ +/g, ' '); // collapse multiple spaces to 1 space
531
+ }
532
+
533
+ if (pContent.length > 0) { // ignore empty CDATANodes
534
+ iNodeParent.appendChild(doc.createCDATASection(pContent)); // attach CDATA to parentNode
535
+ }
536
+ }
537
+ else if(iEvt == XMLP._COMMENT) { // Comment Event
538
+ // get COMMENT data
539
+ var pContent = p.getContent().substring(p.getContentBegin(), p.getContentEnd());
540
+
541
+ if (!this.preserveWhiteSpace) {
542
+ pContent = trim(pContent, true, true); // trim whitespace
543
+ pContent.replace(/ +/g, ' '); // collapse multiple spaces to 1 space
544
+ }
545
+
546
+ if (pContent.length > 0) { // ignore empty CommentNodes
547
+ iNodeParent.appendChild(doc.createComment(pContent)); // attach Comment to parentNode
548
+ }
549
+ }
550
+ else if(iEvt == XMLP._DTD) { // ignore DTD events
551
+ }
552
+ else if(iEvt == XMLP._ERROR) {
553
+ throw(new W3CDOMException(W3CDOMException.SYNTAX_ERR));
554
+ // alert("Fatal Error: " + p.getContent() + "\nLine: " + p.getLineNumber() + "\nColumn: " + p.getColumnNumber() + "\n");
555
+ // break;
556
+ }
557
+ else if(iEvt == XMLP._NONE) { // no more events
558
+ if (iNodeParent == doc) { // confirm that we have recursed back up to root
559
+ break;
560
+ }
561
+ else {
562
+ throw(new W3CDOMException(W3CDOMException.SYNTAX_ERR)); // one or more Tags were not closed properly
563
+ }
564
+ }
565
+ }
566
+
567
+ //normalize any entities in the W3CDOM to a single textNode
568
+ var intCount = entitiesList.length;
569
+ for (intLoop = 0; intLoop < intCount; intLoop++) {
570
+ var entity = entitiesList[intLoop];
571
+ //its possible (if for example two entities were in the
572
+ //same domnode, that the normalize on the first entitiy
573
+ //will remove the parent for the second. Only do normalize
574
+ //if I can find a parent node
575
+ var parentNode = entity.getParentNode();
576
+ if (parentNode) {
577
+ parentNode.normalize();
578
+
579
+ //now do whitespace (if necessary)
580
+ //it was not done for text nodes that have entities
581
+ if(!this.preserveWhiteSpace) {
582
+ var children = parentNode.getChildNodes();
583
+ var intCount2 = children.getLength();
584
+ for ( intLoop2 = 0; intLoop2 < intCount2; intLoop2++) {
585
+ var child = children.item(intLoop2);
586
+ if (child.getNodeType() == W3CDOMNode.TEXT_NODE) {
587
+ var childData = child.getData();
588
+ childData = trim(childData, true, true);
589
+ childData.replace(/ +/g, ' ');
590
+ child.setData(childData);
591
+ }
592
+ }
593
+ }
594
+ }
595
+ }
596
+
597
+ //do the preserve whitespace processing on the rest of the text nodes
598
+ //It's possible (due to the processing above) that the node will have been
599
+ //removed from the tree. Only do whitespace checking if parentNode is not null.
600
+ //This may duplicate the whitespace processing for some nodes that had entities in them
601
+ //but there's no way around that
602
+ if (!this.preserveWhiteSpace) {
603
+ var intCount = textNodesList.length;
604
+ for (intLoop = 0; intLoop < intCount; intLoop++) {
605
+ var node = textNodesList[intLoop];
606
+ if (node.getParentNode() != null) {
607
+ var nodeData = node.getData();
608
+ nodeData = trim(nodeData, true, true);
609
+ nodeData.replace(/ +/g, ' ');
610
+ node.setData(nodeData);
611
+ }
612
+ }
613
+
614
+ }
615
+ };
616
+
617
+ /**
618
+ * @method W3CDOMImplementation._isNamespaceDeclaration - Return true, if attributeName is a namespace declaration
619
+ *
620
+ * @author Jon van Noort (jon@webarcana.com.au)
621
+ *
622
+ * @param attributeName : string - the attribute name
623
+ *
624
+ * @return : boolean
625
+ */
626
+ W3CDOMImplementation.prototype._isNamespaceDeclaration = function W3CDOMImplementation__isNamespaceDeclaration(attributeName) {
627
+ // test if attributeName is 'xmlns'
628
+ return (attributeName.indexOf('xmlns') > -1);
629
+ }
630
+
631
+ /**
632
+ * @method W3CDOMImplementation._isIdDeclaration - Return true, if attributeName is an id declaration
633
+ *
634
+ * @author Jon van Noort (jon@webarcana.com.au)
635
+ *
636
+ * @param attributeName : string - the attribute name
637
+ *
638
+ * @return : boolean
639
+ */
640
+ W3CDOMImplementation.prototype._isIdDeclaration = function W3CDOMImplementation__isIdDeclaration(attributeName) {
641
+ // test if attributeName is 'id' (case insensitive)
642
+ return (attributeName.toLowerCase() == 'id');
643
+ }
644
+
645
+ /**
646
+ * @method W3CDOMImplementation._isValidName - Return true,
647
+ * if name contains no invalid characters
648
+ *
649
+ * @author Jon van Noort (jon@webarcana.com.au)
650
+ *
651
+ * @param name : string - the candidate name
652
+ *
653
+ * @return : boolean
654
+ */
655
+ W3CDOMImplementation.prototype._isValidName = function W3CDOMImplementation__isValidName(name) {
656
+ // test if name contains only valid characters
657
+ return name.match(re_validName);
658
+ }
659
+ re_validName = /^[a-zA-Z_:][a-zA-Z0-9\.\-_:]*$/;
660
+
661
+ /**
662
+ * @method W3CDOMImplementation._isValidString - Return true, if string does not contain any illegal chars
663
+ * All of the characters 0 through 31 and character 127 are nonprinting control characters.
664
+ * With the exception of characters 09, 10, and 13, (Ox09, Ox0A, and Ox0D)
665
+ * Note: different from _isValidName in that ValidStrings may contain spaces
666
+ *
667
+ * @author Jon van Noort (jon@webarcana.com.au)
668
+ *
669
+ * @param name : string - the candidate string
670
+ *
671
+ * @return : boolean
672
+ */
673
+ W3CDOMImplementation.prototype._isValidString = function W3CDOMImplementation__isValidString(name) {
674
+ // test that string does not contains invalid characters
675
+ return (name.search(re_invalidStringChars) < 0);
676
+ }
677
+ re_invalidStringChars = /\x01|\x02|\x03|\x04|\x05|\x06|\x07|\x08|\x0B|\x0C|\x0E|\x0F|\x10|\x11|\x12|\x13|\x14|\x15|\x16|\x17|\x18|\x19|\x1A|\x1B|\x1C|\x1D|\x1E|\x1F|\x7F/
678
+
679
+ /**
680
+ * @method W3CDOMImplementation._parseNSName - parse the namespace name.
681
+ * if there is no colon, the
682
+ *
683
+ * @author Jon van Noort (jon@webarcana.com.au)
684
+ *
685
+ * @param qualifiedName : string - The qualified name
686
+ *
687
+ * @return : NSName - [
688
+ * .prefix : string - The prefix part of the qname
689
+ * .namespaceName : string - The namespaceURI part of the qname
690
+ * ]
691
+ */
692
+ W3CDOMImplementation.prototype._parseNSName = function W3CDOMImplementation__parseNSName(qualifiedName) {
693
+ var resultNSName = new Object();
694
+
695
+ resultNSName.prefix = qualifiedName; // unless the qname has a namespaceName, the prefix is the entire String
696
+ resultNSName.namespaceName = "";
697
+
698
+ // split on ':'
699
+ delimPos = qualifiedName.indexOf(':');
700
+
701
+ if (delimPos > -1) {
702
+ // get prefix
703
+ resultNSName.prefix = qualifiedName.substring(0, delimPos);
704
+
705
+ // get namespaceName
706
+ resultNSName.namespaceName = qualifiedName.substring(delimPos +1, qualifiedName.length);
707
+ }
708
+
709
+ return resultNSName;
710
+ }
711
+
712
+ /**
713
+ * @method W3CDOMImplementation._parseQName - parse the qualified name
714
+ *
715
+ * @author Jon van Noort (jon@webarcana.com.au)
716
+ *
717
+ * @param qualifiedName : string - The qualified name
718
+ *
719
+ * @return : QName
720
+ */
721
+ W3CDOMImplementation.prototype._parseQName = function W3CDOMImplementation__parseQName(qualifiedName) {
722
+ var resultQName = new Object();
723
+
724
+ resultQName.localName = qualifiedName; // unless the qname has a prefix, the local name is the entire String
725
+ resultQName.prefix = "";
726
+
727
+ // split on ':'
728
+ delimPos = qualifiedName.indexOf(':');
729
+
730
+ if (delimPos > -1) {
731
+ // get prefix
732
+ resultQName.prefix = qualifiedName.substring(0, delimPos);
733
+
734
+ // get localName
735
+ resultQName.localName = qualifiedName.substring(delimPos +1, qualifiedName.length);
736
+ }
737
+
738
+ return resultQName;
739
+ }
740
+
741
+ /**
742
+ * @class W3CDOMNodeList - provides the abstraction of an ordered collection of nodes
743
+ *
744
+ * @author Jon van Noort (jon@webarcana.com.au)
745
+ *
746
+ * @param ownerDocument : W3CDOMDocument - the ownerDocument
747
+ * @param parentNode : W3CDOMNode - the node that the W3CDOMNodeList is attached to (or null)
748
+ */
749
+ W3CDOMNodeList = function(ownerDocument, parentNode) {
750
+ this._class = addClass(this._class, "W3CDOMNodeList");
751
+ this._nodes = new Array();
752
+
753
+ this.length = 0;
754
+ this.parentNode = parentNode;
755
+ this.ownerDocument = ownerDocument;
756
+
757
+ this._readonly = false;
758
+ };
759
+
760
+ /**
761
+ * @method W3CDOMNodeList.getLength - Java style gettor for .length
762
+ *
763
+ * @author Jon van Noort (jon@webarcana.com.au)
764
+ *
765
+ * @return : int
766
+ */
767
+ W3CDOMNodeList.prototype.getLength = function W3CDOMNodeList_getLength() {
768
+ return this.length;
769
+ };
770
+
771
+ /**
772
+ * @method W3CDOMNodeList.item - Returns the indexth item in the collection.
773
+ * If index is greater than or equal to the number of nodes in the list, this returns null.
774
+ *
775
+ * @author Jon van Noort (jon@webarcana.com.au)
776
+ *
777
+ * @param index : int - Index into the collection.
778
+ *
779
+ * @return : W3CDOMNode - The node at the indexth position in the NodeList, or null if that is not a valid index
780
+ */
781
+ W3CDOMNodeList.prototype.item = function W3CDOMNodeList_item(index) {
782
+ var ret = null;
783
+
784
+ if ((index >= 0) && (index < this._nodes.length)) { // bounds check
785
+ ret = this._nodes[index]; // return selected Node
786
+ }
787
+
788
+ return ret; // if the index is out of bounds, default value null is returned
789
+ };
790
+
791
+ /**
792
+ * @method W3CDOMNodeList._findItemIndex - find the item index of the node with the specified internal id
793
+ *
794
+ * @author Jon van Noort (jon@webarcana.com.au)
795
+ *
796
+ * @param id : int - unique internal id
797
+ *
798
+ * @return : int
799
+ */
800
+ W3CDOMNodeList.prototype._findItemIndex = function W3CDOMNodeList__findItemIndex(id) {
801
+ var ret = -1;
802
+
803
+ // test that id is valid
804
+ if (id > -1) {
805
+ for (var i=0; i<this._nodes.length; i++) {
806
+ // compare id to each node's _id
807
+ if (this._nodes[i]._id == id) { // found it!
808
+ ret = i;
809
+ break;
810
+ }
811
+ }
812
+ }
813
+
814
+ return ret; // if node is not found, default value -1 is returned
815
+ };
816
+
817
+ /**
818
+ * @method W3CDOMNodeList._insertBefore - insert the specified Node into the NodeList before the specified index
819
+ * Used by W3CDOMNode.insertBefore(). Note: W3CDOMNode.insertBefore() is responsible for Node Pointer surgery
820
+ * W3CDOMNodeList._insertBefore() simply modifies the internal data structure (Array).
821
+ *
822
+ * @author Jon van Noort (jon@webarcana.com.au)
823
+ *
824
+ * @param newChild : W3CDOMNode - the Node to be inserted
825
+ * @param refChildIndex : int - the array index to insert the Node before
826
+ */
827
+ W3CDOMNodeList.prototype._insertBefore = function W3CDOMNodeList__insertBefore(newChild, refChildIndex) {
828
+ if ((refChildIndex >= 0) && (refChildIndex < this._nodes.length)) { // bounds check
829
+ // get array containing children prior to refChild
830
+ var tmpArr = new Array();
831
+ tmpArr = this._nodes.slice(0, refChildIndex);
832
+
833
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
834
+ // append the children of DocumentFragment
835
+ tmpArr = tmpArr.concat(newChild.childNodes._nodes);
836
+ }
837
+ else {
838
+ // append the newChild
839
+ tmpArr[tmpArr.length] = newChild;
840
+ }
841
+
842
+ // append the remaining original children (including refChild)
843
+ this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex));
844
+
845
+ this.length = this._nodes.length; // update length
846
+ }
847
+ };
848
+
849
+ /**
850
+ * @method W3CDOMNodeList._replaceChild - replace the specified Node in the NodeList at the specified index
851
+ * Used by W3CDOMNode.replaceChild(). Note: W3CDOMNode.replaceChild() is responsible for Node Pointer surgery
852
+ * W3CDOMNodeList._replaceChild() simply modifies the internal data structure (Array).
853
+ *
854
+ * @author Jon van Noort (jon@webarcana.com.au)
855
+ *
856
+ * @param newChild : W3CDOMNode - the Node to be inserted
857
+ * @param refChildIndex : int - the array index to hold the Node
858
+ */
859
+ W3CDOMNodeList.prototype._replaceChild = function W3CDOMNodeList__replaceChild(newChild, refChildIndex) {
860
+ var ret = null;
861
+
862
+ if ((refChildIndex >= 0) && (refChildIndex < this._nodes.length)) { // bounds check
863
+ ret = this._nodes[refChildIndex]; // preserve old child for return
864
+
865
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
866
+ // get array containing children prior to refChild
867
+ var tmpArr = new Array();
868
+ tmpArr = this._nodes.slice(0, refChildIndex);
869
+
870
+ // append the children of DocumentFragment
871
+ tmpArr = tmpArr.concat(newChild.childNodes._nodes);
872
+
873
+ // append the remaining original children (not including refChild)
874
+ this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex + 1));
875
+ }
876
+ else {
877
+ // simply replace node in array (links between Nodes are made at higher level)
878
+ this._nodes[refChildIndex] = newChild;
879
+ }
880
+ }
881
+
882
+ return ret; // return replaced node
883
+ };
884
+
885
+ /**
886
+ * @method W3CDOMNodeList._removeChild - remove the specified Node in the NodeList at the specified index
887
+ * Used by W3CDOMNode.removeChild(). Note: W3CDOMNode.removeChild() is responsible for Node Pointer surgery
888
+ * W3CDOMNodeList._replaceChild() simply modifies the internal data structure (Array).
889
+ *
890
+ * @author Jon van Noort (jon@webarcana.com.au)
891
+ *
892
+ * @param refChildIndex : int - the array index holding the Node to be removed
893
+ */
894
+ W3CDOMNodeList.prototype._removeChild = function W3CDOMNodeList__removeChild(refChildIndex) {
895
+ var ret = null;
896
+
897
+ if (refChildIndex > -1) { // found it!
898
+ ret = this._nodes[refChildIndex]; // return removed node
899
+
900
+ // rebuild array without removed child
901
+ var tmpArr = new Array();
902
+ tmpArr = this._nodes.slice(0, refChildIndex);
903
+ this._nodes = tmpArr.concat(this._nodes.slice(refChildIndex +1));
904
+
905
+ this.length = this._nodes.length; // update length
906
+ }
907
+
908
+ return ret; // return removed node
909
+ };
910
+
911
+ /**
912
+ * @method W3CDOMNodeList._appendChild - append the specified Node to the NodeList
913
+ * Used by W3CDOMNode.appendChild(). Note: W3CDOMNode.appendChild() is responsible for Node Pointer surgery
914
+ * W3CDOMNodeList._appendChild() simply modifies the internal data structure (Array).
915
+ *
916
+ * @author Jon van Noort (jon@webarcana.com.au)
917
+ *
918
+ * @param newChild : W3CDOMNode - the Node to be inserted
919
+ */
920
+ W3CDOMNodeList.prototype._appendChild = function W3CDOMNodeList__appendChild(newChild) {
921
+
922
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) { // node is a DocumentFragment
923
+ // append the children of DocumentFragment
924
+ this._nodes = this._nodes.concat(newChild.childNodes._nodes);
925
+ }
926
+ else {
927
+ // simply add node to array (links between Nodes are made at higher level)
928
+ this._nodes[this._nodes.length] = newChild;
929
+ }
930
+
931
+ this.length = this._nodes.length; // update length
932
+ };
933
+
934
+ /**
935
+ * @method W3CDOMNodeList._cloneNodes - Returns a NodeList containing clones of the Nodes in this NodeList
936
+ *
937
+ * @author Jon van Noort (jon@webarcana.com.au)
938
+ *
939
+ * @param deep : boolean - If true, recursively clone the subtree under each of the nodes;
940
+ * if false, clone only the nodes themselves (and their attributes, if it is an Element).
941
+ * @param parentNode : W3CDOMNode - the new parent of the cloned NodeList
942
+ *
943
+ * @return : W3CDOMNodeList - NodeList containing clones of the Nodes in this NodeList
944
+ */
945
+ W3CDOMNodeList.prototype._cloneNodes = function W3CDOMNodeList__cloneNodes(deep, parentNode) {
946
+ var cloneNodeList = new W3CDOMNodeList(this.ownerDocument, parentNode);
947
+
948
+ // create list containing clones of each child
949
+ for (var i=0; i < this._nodes.length; i++) {
950
+ cloneNodeList._appendChild(this._nodes[i].cloneNode(deep));
951
+ }
952
+
953
+ return cloneNodeList;
954
+ };
955
+
956
+ /**
957
+ * @method W3CDOMNodeList.toString - Serialize this NodeList into an XML string
958
+ *
959
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
960
+ *
961
+ * @return : string
962
+ */
963
+ W3CDOMNodeList.prototype.toString = function W3CDOMNodeList_toString() {
964
+ var ret = "";
965
+
966
+ // create string containing the concatenation of the string values of each child
967
+ for (var i=0; i < this.length; i++) {
968
+ ret += this._nodes[i].toString();
969
+ }
970
+
971
+ return ret;
972
+ };
973
+
974
+ /**
975
+ * @class W3CDOMNamedNodeMap - used to represent collections of nodes that can be accessed by name
976
+ * typically a set of Element attributes
977
+ *
978
+ * @extends W3CDOMNodeList - note W3C spec says that this is not the case,
979
+ * but we need an item() method identicle to W3CDOMNodeList's, so why not?
980
+ *
981
+ * @author Jon van Noort (jon@webarcana.com.au)
982
+ *
983
+ * @param ownerDocument : W3CDOMDocument - the ownerDocument
984
+ * @param parentNode : W3CDOMNode - the node that the W3CDOMNamedNodeMap is attached to (or null)
985
+ */
986
+ W3CDOMNamedNodeMap = function(ownerDocument, parentNode) {
987
+ this._class = addClass(this._class, "W3CDOMNamedNodeMap");
988
+ this.W3CDOMNodeList = W3CDOMNodeList;
989
+ this.W3CDOMNodeList(ownerDocument, parentNode);
990
+ };
991
+ W3CDOMNamedNodeMap.prototype = new W3CDOMNodeList;
992
+
993
+ /**
994
+ * @method W3CDOMNamedNodeMap.getNamedItem - Retrieves a node specified by name
995
+ *
996
+ * @author Jon van Noort (jon@webarcana.com.au)
997
+ *
998
+ * @param name : string - Name of a node to retrieve
999
+ *
1000
+ * @return : W3CDOMNode
1001
+ */
1002
+ W3CDOMNamedNodeMap.prototype.getNamedItem = function W3CDOMNamedNodeMap_getNamedItem(name) {
1003
+ var ret = null;
1004
+
1005
+ // test that Named Node exists
1006
+ var itemIndex = this._findNamedItemIndex(name);
1007
+
1008
+ if (itemIndex > -1) { // found it!
1009
+ ret = this._nodes[itemIndex]; // return NamedNode
1010
+ }
1011
+
1012
+ return ret; // if node is not found, default value null is returned
1013
+ };
1014
+
1015
+ /**
1016
+ * @method W3CDOMNamedNodeMap.setNamedItem - Adds a node using its nodeName attribute
1017
+ *
1018
+ * @author Jon van Noort (jon@webarcana.com.au)
1019
+ *
1020
+ * @param arg : W3CDOMNode - A node to store in a named node map.
1021
+ * The node will later be accessible using the value of the nodeName attribute of the node.
1022
+ * If a node with that name is already present in the map, it is replaced by the new one.
1023
+ *
1024
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
1025
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
1026
+ * @throws : W3CDOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
1027
+ * The W3CDOM user must explicitly clone Attr nodes to re-use them in other elements.
1028
+ *
1029
+ * @return : W3CDOMNode - If the new Node replaces an existing node with the same name the previously existing Node is returned,
1030
+ * otherwise null is returned
1031
+ */
1032
+ W3CDOMNamedNodeMap.prototype.setNamedItem = function W3CDOMNamedNodeMap_setNamedItem(arg) {
1033
+ // test for exceptions
1034
+ if (this.ownerDocument.implementation.errorChecking) {
1035
+ // throw Exception if arg was not created by this Document
1036
+ if (this.ownerDocument != arg.ownerDocument) {
1037
+ throw(new W3CDOMException(W3CDOMException.WRONG_DOCUMENT_ERR));
1038
+ }
1039
+
1040
+ // throw Exception if W3CDOMNamedNodeMap is readonly
1041
+ if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
1042
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1043
+ }
1044
+
1045
+ // throw Exception if arg is already an attribute of another Element object
1046
+ if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
1047
+ throw(new W3CDOMException(W3CDOMException.INUSE_ATTRIBUTE_ERR));
1048
+ }
1049
+ }
1050
+
1051
+ // get item index
1052
+ var itemIndex = this._findNamedItemIndex(arg.name);
1053
+ var ret = null;
1054
+
1055
+ if (itemIndex > -1) { // found it!
1056
+ ret = this._nodes[itemIndex]; // use existing Attribute
1057
+
1058
+ // throw Exception if W3CDOMAttr is readonly
1059
+ if (this.ownerDocument.implementation.errorChecking && ret._readonly) {
1060
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1061
+ }
1062
+ else {
1063
+ this._nodes[itemIndex] = arg; // over-write existing NamedNode
1064
+ }
1065
+ }
1066
+ else {
1067
+ this._nodes[this.length] = arg; // add new NamedNode
1068
+ }
1069
+
1070
+ this.length = this._nodes.length; // update length
1071
+
1072
+ arg.ownerElement = this.parentNode; // update ownerElement
1073
+
1074
+ return ret; // return old node or null
1075
+ };
1076
+
1077
+ /**
1078
+ * @method W3CDOMNamedNodeMap.removeNamedItem - Removes a node specified by name.
1079
+ *
1080
+ * @author Jon van Noort (jon@webarcana.com.au)
1081
+ *
1082
+ * @param name : string - The name of a node to remove
1083
+ *
1084
+ * @throws : W3CDOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
1085
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
1086
+ *
1087
+ * @return : W3CDOMNode - The node removed from the map or null if no node with such a name exists.
1088
+ */
1089
+ W3CDOMNamedNodeMap.prototype.removeNamedItem = function W3CDOMNamedNodeMap_removeNamedItem(name) {
1090
+ var ret = null;
1091
+ // test for exceptions
1092
+ // throw Exception if W3CDOMNamedNodeMap is readonly
1093
+ if (this.ownerDocument.implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
1094
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1095
+ }
1096
+
1097
+ // get item index
1098
+ var itemIndex = this._findNamedItemIndex(name);
1099
+
1100
+ // throw Exception if there is no node named name in this map
1101
+ if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
1102
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
1103
+ }
1104
+
1105
+ // get Node
1106
+ var oldNode = this._nodes[itemIndex];
1107
+
1108
+ // throw Exception if Node is readonly
1109
+ if (this.ownerDocument.implementation.errorChecking && oldNode._readonly) {
1110
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1111
+ }
1112
+
1113
+ // return removed node
1114
+ return this._removeChild(itemIndex);
1115
+ };
1116
+
1117
+ /**
1118
+ * @method W3CDOMNamedNodeMap.getNamedItemNS - Retrieves a node specified by name
1119
+ *
1120
+ * @author Jon van Noort (jon@webarcana.com.au)
1121
+ *
1122
+ * @param namespaceURI : string - the namespace URI of the required node
1123
+ * @param localName : string - the local name of the required node
1124
+ *
1125
+ * @return : W3CDOMNode
1126
+ */
1127
+ W3CDOMNamedNodeMap.prototype.getNamedItemNS = function W3CDOMNamedNodeMap_getNamedItemNS(namespaceURI, localName) {
1128
+ var ret = null;
1129
+
1130
+ // test that Named Node exists
1131
+ var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
1132
+
1133
+ if (itemIndex > -1) { // found it!
1134
+ ret = this._nodes[itemIndex]; // return NamedNode
1135
+ }
1136
+
1137
+ return ret; // if node is not found, default value null is returned
1138
+ };
1139
+
1140
+ /**
1141
+ * @method W3CDOMNamedNodeMap.setNamedItemNS - Adds a node using
1142
+ *
1143
+ * @author Jon van Noort (jon@webarcana.com.au)
1144
+ *
1145
+ * @param arg : string - A node to store in a named node map.
1146
+ * The node will later be accessible using the value of the nodeName attribute of the node.
1147
+ * If a node with that name is already present in the map, it is replaced by the new one.
1148
+ *
1149
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
1150
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
1151
+ * @throws : W3CDOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
1152
+ * The W3CDOM user must explicitly clone Attr nodes to re-use them in other elements.
1153
+ *
1154
+ * @return : W3CDOMNode - If the new Node replaces an existing node with the same name the previously existing Node is returned,
1155
+ * otherwise null is returned
1156
+ */
1157
+ W3CDOMNamedNodeMap.prototype.setNamedItemNS = function W3CDOMNamedNodeMap_setNamedItemNS(arg) {
1158
+ // test for exceptions
1159
+ if (this.ownerDocument.implementation.errorChecking) {
1160
+ // throw Exception if W3CDOMNamedNodeMap is readonly
1161
+ if (this._readonly || (this.parentNode && this.parentNode._readonly)) {
1162
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1163
+ }
1164
+
1165
+ // throw Exception if arg was not created by this Document
1166
+ if (this.ownerDocument != arg.ownerDocument) {
1167
+ throw(new W3CDOMException(W3CDOMException.WRONG_DOCUMENT_ERR));
1168
+ }
1169
+
1170
+ // throw Exception if arg is already an attribute of another Element object
1171
+ if (arg.ownerElement && (arg.ownerElement != this.parentNode)) {
1172
+ throw(new W3CDOMException(W3CDOMException.INUSE_ATTRIBUTE_ERR));
1173
+ }
1174
+ }
1175
+
1176
+ // get item index
1177
+ var itemIndex = this._findNamedItemNSIndex(arg.namespaceURI, arg.localName);
1178
+ var ret = null;
1179
+
1180
+ if (itemIndex > -1) { // found it!
1181
+ ret = this._nodes[itemIndex]; // use existing Attribute
1182
+ // throw Exception if W3CDOMAttr is readonly
1183
+ if (this.ownerDocument.implementation.errorChecking && ret._readonly) {
1184
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1185
+ }
1186
+ else {
1187
+ this._nodes[itemIndex] = arg; // over-write existing NamedNode
1188
+ }
1189
+ }
1190
+ else {
1191
+ this._nodes[this.length] = arg; // add new NamedNode
1192
+ }
1193
+
1194
+ this.length = this._nodes.length; // update length
1195
+
1196
+ arg.ownerElement = this.parentNode;
1197
+
1198
+
1199
+ return ret; // return old node or null
1200
+ };
1201
+
1202
+ /**
1203
+ * @method W3CDOMNamedNodeMap.removeNamedItemNS - Removes a node specified by name.
1204
+ *
1205
+ * @author Jon van Noort (jon@webarcana.com.au)
1206
+ *
1207
+ * @param namespaceURI : string - the namespace URI of the required node
1208
+ * @param localName : string - the local name of the required node
1209
+ *
1210
+ * @throws : W3CDOMException - NOT_FOUND_ERR: Raised if there is no node with the specified namespaceURI and localName in this map.
1211
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this NamedNodeMap is readonly.
1212
+ *
1213
+ * @return : W3CDOMNode - The node removed from the map or null if no node with such a name exists.
1214
+ */
1215
+ W3CDOMNamedNodeMap.prototype.removeNamedItemNS = function W3CDOMNamedNodeMap_removeNamedItemNS(namespaceURI, localName) {
1216
+ var ret = null;
1217
+
1218
+ // test for exceptions
1219
+ // throw Exception if W3CDOMNamedNodeMap is readonly
1220
+ if (this.ownerDocument.implementation.errorChecking && (this._readonly || (this.parentNode && this.parentNode._readonly))) {
1221
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1222
+ }
1223
+
1224
+ // get item index
1225
+ var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
1226
+
1227
+ // throw Exception if there is no matching node in this map
1228
+ if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
1229
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
1230
+ }
1231
+
1232
+ // get Node
1233
+ var oldNode = this._nodes[itemIndex];
1234
+
1235
+ // throw Exception if Node is readonly
1236
+ if (this.ownerDocument.implementation.errorChecking && oldNode._readonly) {
1237
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1238
+ }
1239
+
1240
+ return this._removeChild(itemIndex); // return removed node
1241
+ };
1242
+
1243
+ /**
1244
+ * @method W3CDOMNamedNodeMap._findNamedItemIndex - find the item index of the node with the specified name
1245
+ *
1246
+ * @author Jon van Noort (jon@webarcana.com.au)
1247
+ *
1248
+ * @param name : string - the name of the required node
1249
+ *
1250
+ * @return : int
1251
+ */
1252
+ W3CDOMNamedNodeMap.prototype._findNamedItemIndex = function W3CDOMNamedNodeMap__findNamedItemIndex(name) {
1253
+ var ret = -1;
1254
+
1255
+ // loop through all nodes
1256
+ for (var i=0; i<this._nodes.length; i++) {
1257
+ // compare name to each node's nodeName
1258
+ if (this._nodes[i].name == name) { // found it!
1259
+ ret = i;
1260
+ break;
1261
+ }
1262
+ }
1263
+
1264
+ return ret; // if node is not found, default value -1 is returned
1265
+ };
1266
+
1267
+ /**
1268
+ * @method W3CDOMNamedNodeMap._findNamedItemNSIndex - find the item index of the node with the specified namespaceURI and localName
1269
+ *
1270
+ * @author Jon van Noort (jon@webarcana.com.au)
1271
+ *
1272
+ * @param namespaceURI : string - the namespace URI of the required node
1273
+ * @param localName : string - the local name of the required node
1274
+ *
1275
+ * @return : int
1276
+ */
1277
+ W3CDOMNamedNodeMap.prototype._findNamedItemNSIndex = function W3CDOMNamedNodeMap__findNamedItemNSIndex(namespaceURI, localName) {
1278
+ var ret = -1;
1279
+
1280
+ // test that localName is not null
1281
+ if (localName) {
1282
+ // loop through all nodes
1283
+ for (var i=0; i<this._nodes.length; i++) {
1284
+ // compare name to each node's namespaceURI and localName
1285
+ if ((this._nodes[i].namespaceURI == namespaceURI) && (this._nodes[i].localName == localName)) {
1286
+ ret = i; // found it!
1287
+ break;
1288
+ }
1289
+ }
1290
+ }
1291
+
1292
+ return ret; // if node is not found, default value -1 is returned
1293
+ };
1294
+
1295
+ /**
1296
+ * @method W3CDOMNamedNodeMap._hasAttribute - Returns true if specified node exists
1297
+ *
1298
+ * @author Jon van Noort (jon@webarcana.com.au)
1299
+ *
1300
+ * @param name : string - the name of the required node
1301
+ *
1302
+ * @return : boolean
1303
+ */
1304
+ W3CDOMNamedNodeMap.prototype._hasAttribute = function W3CDOMNamedNodeMap__hasAttribute(name) {
1305
+ var ret = false;
1306
+
1307
+ // test that Named Node exists
1308
+ var itemIndex = this._findNamedItemIndex(name);
1309
+
1310
+ if (itemIndex > -1) { // found it!
1311
+ ret = true; // return true
1312
+ }
1313
+
1314
+ return ret; // if node is not found, default value false is returned
1315
+ }
1316
+
1317
+ /**
1318
+ * @method W3CDOMNamedNodeMap._hasAttributeNS - Returns true if specified node exists
1319
+ *
1320
+ * @author Jon van Noort (jon@webarcana.com.au)
1321
+ *
1322
+ * @param namespaceURI : string - the namespace URI of the required node
1323
+ * @param localName : string - the local name of the required node
1324
+ *
1325
+ * @return : boolean
1326
+ */
1327
+ W3CDOMNamedNodeMap.prototype._hasAttributeNS = function W3CDOMNamedNodeMap__hasAttributeNS(namespaceURI, localName) {
1328
+ var ret = false;
1329
+
1330
+ // test that Named Node exists
1331
+ var itemIndex = this._findNamedItemNSIndex(namespaceURI, localName);
1332
+
1333
+ if (itemIndex > -1) { // found it!
1334
+ ret = true; // return true
1335
+ }
1336
+
1337
+ return ret; // if node is not found, default value false is returned
1338
+ }
1339
+
1340
+ /**
1341
+ * @method W3CDOMNamedNodeMap._cloneNodes - Returns a NamedNodeMap containing clones of the Nodes in this NamedNodeMap
1342
+ *
1343
+ * @author Jon van Noort (jon@webarcana.com.au)
1344
+ *
1345
+ * @param parentNode : W3CDOMNode - the new parent of the cloned NodeList
1346
+ *
1347
+ * @return : W3CDOMNamedNodeMap - NamedNodeMap containing clones of the Nodes in this W3CDOMNamedNodeMap
1348
+ */
1349
+ W3CDOMNamedNodeMap.prototype._cloneNodes = function W3CDOMNamedNodeMap__cloneNodes(parentNode) {
1350
+ var cloneNamedNodeMap = new W3CDOMNamedNodeMap(this.ownerDocument, parentNode);
1351
+
1352
+ // create list containing clones of all children
1353
+ for (var i=0; i < this._nodes.length; i++) {
1354
+ cloneNamedNodeMap._appendChild(this._nodes[i].cloneNode(false));
1355
+ }
1356
+
1357
+ return cloneNamedNodeMap;
1358
+ };
1359
+
1360
+ /**
1361
+ * @method W3CDOMNamedNodeMap.toString - Serialize this NodeMap into an XML string
1362
+ *
1363
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
1364
+ *
1365
+ * @return : string
1366
+ */
1367
+ W3CDOMNamedNodeMap.prototype.toString = function W3CDOMNamedNodeMap_toString() {
1368
+ var ret = "";
1369
+
1370
+ // create string containing concatenation of all (but last) Attribute string values (separated by spaces)
1371
+ for (var i=0; i < this.length -1; i++) {
1372
+ ret += this._nodes[i].toString() +" ";
1373
+ }
1374
+
1375
+ // add last Attribute to string (without trailing space)
1376
+ if (this.length > 0) {
1377
+ ret += this._nodes[this.length -1].toString();
1378
+ }
1379
+
1380
+ return ret;
1381
+ };
1382
+
1383
+ /**
1384
+ * @class W3CDOMNamespaceNodeMap - used to represent collections of namespace nodes that can be accessed by name
1385
+ * typically a set of Element attributes
1386
+ *
1387
+ * @extends W3CDOMNamedNodeMap
1388
+ *
1389
+ * @author Jon van Noort (jon@webarcana.com.au)
1390
+ *
1391
+ * @param ownerDocument : W3CDOMDocument - the ownerDocument
1392
+ * @param parentNode : W3CDOMNode - the node that the W3CDOMNamespaceNodeMap is attached to (or null)
1393
+ */
1394
+ W3CDOMNamespaceNodeMap = function(ownerDocument, parentNode) {
1395
+ this._class = addClass(this._class, "W3CDOMNamespaceNodeMap");
1396
+ this.W3CDOMNamedNodeMap = W3CDOMNamedNodeMap;
1397
+ this.W3CDOMNamedNodeMap(ownerDocument, parentNode);
1398
+ };
1399
+ W3CDOMNamespaceNodeMap.prototype = new W3CDOMNamedNodeMap;
1400
+
1401
+ /**
1402
+ * @method W3CDOMNamespaceNodeMap._findNamedItemIndex - find the item index of the node with the specified localName
1403
+ *
1404
+ * @author Jon van Noort (jon@webarcana.com.au)
1405
+ *
1406
+ * @param localName : string - the localName of the required node
1407
+ *
1408
+ * @return : int
1409
+ */
1410
+ W3CDOMNamespaceNodeMap.prototype._findNamedItemIndex = function W3CDOMNamespaceNodeMap__findNamedItemIndex(localName) {
1411
+ var ret = -1;
1412
+
1413
+ // loop through all nodes
1414
+ for (var i=0; i<this._nodes.length; i++) {
1415
+ // compare name to each node's nodeName
1416
+ if (this._nodes[i].localName == localName) { // found it!
1417
+ ret = i;
1418
+ break;
1419
+ }
1420
+ }
1421
+
1422
+ return ret; // if node is not found, default value -1 is returned
1423
+ };
1424
+
1425
+
1426
+ /**
1427
+ * @method W3CDOMNamespaceNodeMap._cloneNodes - Returns a NamespaceNodeMap containing clones of the Nodes in this NamespaceNodeMap
1428
+ *
1429
+ * @author Jon van Noort (jon@webarcana.com.au)
1430
+ *
1431
+ * @param parentNode : W3CDOMNode - the new parent of the cloned NodeList
1432
+ *
1433
+ * @return : W3CDOMNamespaceNodeMap - NamespaceNodeMap containing clones of the Nodes in this NamespaceNodeMap
1434
+ */
1435
+ W3CDOMNamespaceNodeMap.prototype._cloneNodes = function W3CDOMNamespaceNodeMap__cloneNodes(parentNode) {
1436
+ var cloneNamespaceNodeMap = new W3CDOMNamespaceNodeMap(this.ownerDocument, parentNode);
1437
+
1438
+ // create list containing clones of all children
1439
+ for (var i=0; i < this._nodes.length; i++) {
1440
+ cloneNamespaceNodeMap._appendChild(this._nodes[i].cloneNode(false));
1441
+ }
1442
+
1443
+ return cloneNamespaceNodeMap;
1444
+ };
1445
+
1446
+ /**
1447
+ * @method W3CDOMNamespaceNodeMap.toString - Serialize this NamespaceNodeMap into an XML string
1448
+ *
1449
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
1450
+ *
1451
+ * @return : string
1452
+ */
1453
+ W3CDOMNamespaceNodeMap.prototype.toString = function W3CDOMNamespaceNodeMap_toString() {
1454
+ var ret = "";
1455
+
1456
+ // identify namespaces declared local to this Element (ie, not inherited)
1457
+ for (var ind = 0; ind < this._nodes.length; ind++) {
1458
+ // if namespace declaration does not exist in the containing node's, parentNode's namespaces
1459
+ var ns = null;
1460
+ try {
1461
+ var ns = this.parentNode.parentNode._namespaces.getNamedItem(this._nodes[ind].localName);
1462
+ }
1463
+ catch (e) {
1464
+ //breaking to prevent default namespace being inserted into return value
1465
+ break;
1466
+ }
1467
+ if (!(ns && (""+ ns.nodeValue == ""+ this._nodes[ind].nodeValue))) {
1468
+ // display the namespace declaration
1469
+ ret += this._nodes[ind].toString() +" ";
1470
+ }
1471
+ }
1472
+
1473
+ return ret;
1474
+ };
1475
+
1476
+ /**
1477
+ * @class W3CDOMNode - The Node interface is the primary datatype for the entire Document Object Model.
1478
+ * It represents a single node in the document tree.
1479
+ *
1480
+ * @author Jon van Noort (jon@webarcana.com.au)
1481
+ *
1482
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
1483
+ */
1484
+ W3CDOMNode = function(ownerDocument) {
1485
+ this._class = addClass(this._class, "W3CDOMNode");
1486
+
1487
+ if (ownerDocument) {
1488
+ this._id = ownerDocument._genId(); // generate unique internal id
1489
+ }
1490
+
1491
+ this.namespaceURI = ""; // The namespace URI of this node (Level 2)
1492
+ this.prefix = ""; // The namespace prefix of this node (Level 2)
1493
+ this.localName = ""; // The localName of this node (Level 2)
1494
+
1495
+ this.nodeName = ""; // The name of this node
1496
+ this.nodeValue = ""; // The value of this node
1497
+ this.nodeType = 0; // A code representing the type of the underlying object
1498
+
1499
+ // The parent of this node. All nodes, except Document, DocumentFragment, and Attr may have a parent.
1500
+ // However, if a node has just been created and not yet added to the tree, or if it has been removed from the tree, this is null
1501
+ this.parentNode = null;
1502
+
1503
+ // A NodeList that contains all children of this node. If there are no children, this is a NodeList containing no nodes.
1504
+ // The content of the returned NodeList is "live" in the sense that, for instance, changes to the children of the node object
1505
+ // that it was created from are immediately reflected in the nodes returned by the NodeList accessors;
1506
+ // it is not a static snapshot of the content of the node. This is true for every NodeList, including the ones returned by the getElementsByTagName method.
1507
+ this.childNodes = new W3CDOMNodeList(ownerDocument, this);
1508
+
1509
+ this.firstChild = null; // The first child of this node. If there is no such node, this is null
1510
+ this.lastChild = null; // The last child of this node. If there is no such node, this is null.
1511
+ this.previousSibling = null; // The node immediately preceding this node. If there is no such node, this is null.
1512
+ this.nextSibling = null; // The node immediately following this node. If there is no such node, this is null.
1513
+
1514
+ this.attributes = new W3CDOMNamedNodeMap(ownerDocument, this); // A NamedNodeMap containing the attributes of this node (if it is an Element) or null otherwise.
1515
+ this.ownerDocument = ownerDocument; // The Document object associated with this node
1516
+ this._namespaces = new W3CDOMNamespaceNodeMap(ownerDocument, this); // The namespaces in scope for this node
1517
+
1518
+ this._readonly = false;
1519
+ };
1520
+
1521
+ // nodeType constants
1522
+ W3CDOMNode.ELEMENT_NODE = 1;
1523
+ W3CDOMNode.ATTRIBUTE_NODE = 2;
1524
+ W3CDOMNode.TEXT_NODE = 3;
1525
+ W3CDOMNode.CDATA_SECTION_NODE = 4;
1526
+ W3CDOMNode.ENTITY_REFERENCE_NODE = 5;
1527
+ W3CDOMNode.ENTITY_NODE = 6;
1528
+ W3CDOMNode.PROCESSING_INSTRUCTION_NODE = 7;
1529
+ W3CDOMNode.COMMENT_NODE = 8;
1530
+ W3CDOMNode.DOCUMENT_NODE = 9;
1531
+ W3CDOMNode.DOCUMENT_TYPE_NODE = 10;
1532
+ W3CDOMNode.DOCUMENT_FRAGMENT_NODE = 11;
1533
+ W3CDOMNode.NOTATION_NODE = 12;
1534
+ W3CDOMNode.NAMESPACE_NODE = 13;
1535
+
1536
+ /**
1537
+ * @method W3CDOMNode.hasAttributes
1538
+ *
1539
+ * @author Jon van Noort (jon@webarcana.com.au) & David Joham (djoham@yahoo.com)
1540
+ *
1541
+ * @return : boolean
1542
+ */
1543
+ W3CDOMNode.prototype.hasAttributes = function W3CDOMNode_hasAttributes() {
1544
+ if (this.attributes.length == 0) {
1545
+ return false;
1546
+ }
1547
+ else {
1548
+ return true;
1549
+ }
1550
+ };
1551
+
1552
+ /**
1553
+ * @method W3CDOMNode.getNodeName - Java style gettor for .nodeName
1554
+ *
1555
+ * @author Jon van Noort (jon@webarcana.com.au)
1556
+ *
1557
+ * @return : string
1558
+ */
1559
+ W3CDOMNode.prototype.getNodeName = function W3CDOMNode_getNodeName() {
1560
+ return this.nodeName;
1561
+ };
1562
+
1563
+ /**
1564
+ * @method W3CDOMNode.getNodeValue - Java style gettor for .NodeValue
1565
+ *
1566
+ * @author Jon van Noort (jon@webarcana.com.au)
1567
+ *
1568
+ * @return : string
1569
+ */
1570
+ W3CDOMNode.prototype.getNodeValue = function W3CDOMNode_getNodeValue() {
1571
+ return this.nodeValue;
1572
+ };
1573
+
1574
+ /**
1575
+ * @method W3CDOMNode.setNodeValue - Java style settor for .NodeValue
1576
+ *
1577
+ * @author Jon van Noort (jon@webarcana.com.au)
1578
+ *
1579
+ * @param nodeValue : string - unique internal id
1580
+ */
1581
+ W3CDOMNode.prototype.setNodeValue = function W3CDOMNode_setNodeValue(nodeValue) {
1582
+ // throw Exception if W3CDOMNode is readonly
1583
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
1584
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1585
+ }
1586
+
1587
+ this.nodeValue = nodeValue;
1588
+ };
1589
+
1590
+ /**
1591
+ * @method W3CDOMNode.getNodeType - Java style gettor for .nodeType
1592
+ *
1593
+ * @author Jon van Noort (jon@webarcana.com.au)
1594
+ *
1595
+ * @return : int
1596
+ */
1597
+ W3CDOMNode.prototype.getNodeType = function W3CDOMNode_getNodeType() {
1598
+ return this.nodeType;
1599
+ };
1600
+
1601
+ /**
1602
+ * @method W3CDOMNode.getParentNode - Java style gettor for .parentNode
1603
+ *
1604
+ * @author Jon van Noort (jon@webarcana.com.au)
1605
+ *
1606
+ * @return : W3CDOMNode
1607
+ */
1608
+ W3CDOMNode.prototype.getParentNode = function W3CDOMNode_getParentNode() {
1609
+ return this.parentNode;
1610
+ };
1611
+
1612
+ /**
1613
+ * @method W3CDOMNode.getChildNodes - Java style gettor for .childNodes
1614
+ *
1615
+ * @author Jon van Noort (jon@webarcana.com.au)
1616
+ *
1617
+ * @return : W3CDOMNodeList
1618
+ */
1619
+ W3CDOMNode.prototype.getChildNodes = function W3CDOMNode_getChildNodes() {
1620
+ return this.childNodes;
1621
+ };
1622
+
1623
+ /**
1624
+ * @method W3CDOMNode.getFirstChild - Java style gettor for .firstChild
1625
+ *
1626
+ * @author Jon van Noort (jon@webarcana.com.au)
1627
+ *
1628
+ * @return : W3CDOMNode
1629
+ */
1630
+ W3CDOMNode.prototype.getFirstChild = function W3CDOMNode_getFirstChild() {
1631
+ return this.firstChild;
1632
+ };
1633
+
1634
+ /**
1635
+ * @method W3CDOMNode.getLastChild - Java style gettor for .lastChild
1636
+ *
1637
+ * @author Jon van Noort (jon@webarcana.com.au)
1638
+ *
1639
+ * @return : W3CDOMNode
1640
+ */
1641
+ W3CDOMNode.prototype.getLastChild = function W3CDOMNode_getLastChild() {
1642
+ return this.lastChild;
1643
+ };
1644
+
1645
+ /**
1646
+ * @method W3CDOMNode.getPreviousSibling - Java style gettor for .previousSibling
1647
+ *
1648
+ * @author Jon van Noort (jon@webarcana.com.au)
1649
+ *
1650
+ * @return : W3CDOMNode
1651
+ */
1652
+ W3CDOMNode.prototype.getPreviousSibling = function W3CDOMNode_getPreviousSibling() {
1653
+ return this.previousSibling;
1654
+ };
1655
+
1656
+ /**
1657
+ * @method W3CDOMNode.getNextSibling - Java style gettor for .nextSibling
1658
+ *
1659
+ * @author Jon van Noort (jon@webarcana.com.au)
1660
+ *
1661
+ * @return : W3CDOMNode
1662
+ */
1663
+ W3CDOMNode.prototype.getNextSibling = function W3CDOMNode_getNextSibling() {
1664
+ return this.nextSibling;
1665
+ };
1666
+
1667
+ /**
1668
+ * @method W3CDOMNode.getAttributes - Java style gettor for .attributes
1669
+ *
1670
+ * @author Jon van Noort (jon@webarcana.com.au)
1671
+ *
1672
+ * @return : W3CDOMNamedNodeList
1673
+ */
1674
+ W3CDOMNode.prototype.getAttributes = function W3CDOMNode_getAttributes() {
1675
+ return this.attributes;
1676
+ };
1677
+
1678
+ /**
1679
+ * @method W3CDOMNode.getOwnerDocument - Java style gettor for .ownerDocument
1680
+ *
1681
+ * @author Jon van Noort (jon@webarcana.com.au)
1682
+ *
1683
+ * @return : W3CDOMDocument
1684
+ */
1685
+ W3CDOMNode.prototype.getOwnerDocument = function W3CDOMNode_getOwnerDocument() {
1686
+ return this.ownerDocument;
1687
+ };
1688
+
1689
+ /**
1690
+ * @method W3CDOMNode.getNamespaceURI - Java style gettor for .namespaceURI
1691
+ *
1692
+ * @author Jon van Noort (jon@webarcana.com.au)
1693
+ *
1694
+ * @return : String
1695
+ */
1696
+ W3CDOMNode.prototype.getNamespaceURI = function W3CDOMNode_getNamespaceURI() {
1697
+ return this.namespaceURI;
1698
+ };
1699
+
1700
+ /**
1701
+ * @method W3CDOMNode.getPrefix - Java style gettor for .prefix
1702
+ *
1703
+ * @author Jon van Noort (jon@webarcana.com.au)
1704
+ *
1705
+ * @return : String
1706
+ */
1707
+ W3CDOMNode.prototype.getPrefix = function W3CDOMNode_getPrefix() {
1708
+ return this.prefix;
1709
+ };
1710
+
1711
+ /**
1712
+ * @method W3CDOMNode.setPrefix - Java style settor for .prefix
1713
+ *
1714
+ * @author Jon van Noort (jon@webarcana.com.au)
1715
+ *
1716
+ * @param prefix : String
1717
+ *
1718
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
1719
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
1720
+ * @throws : W3CDOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
1721
+ *
1722
+ */
1723
+ W3CDOMNode.prototype.setPrefix = function W3CDOMNode_setPrefix(prefix) {
1724
+ // test for exceptions
1725
+ if (this.ownerDocument.implementation.errorChecking) {
1726
+ // throw Exception if W3CDOMNode is readonly
1727
+ if (this._readonly) {
1728
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1729
+ }
1730
+
1731
+ // throw Exception if the prefix string contains an illegal character
1732
+ if (!this.ownerDocument.implementation._isValidName(prefix)) {
1733
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
1734
+ }
1735
+
1736
+ // throw Exception if the Namespace is invalid;
1737
+ // if the specified prefix is malformed,
1738
+ // if the namespaceURI of this node is null,
1739
+ // if the specified prefix is "xml" and the namespaceURI of this node is
1740
+ // different from "http://www.w3.org/XML/1998/namespace",
1741
+ if (!this.ownerDocument._isValidNamespace(this.namespaceURI, prefix +":"+ this.localName)) {
1742
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
1743
+ }
1744
+
1745
+ // throw Exception if we are trying to make the attribute look like a namespace declaration;
1746
+ // if this node is an attribute and the specified prefix is "xmlns"
1747
+ // and the namespaceURI of this node is different from "http://www.w3.org/2000/xmlns/",
1748
+ if ((prefix == "xmlns") && (this.namespaceURI != "http://www.w3.org/2000/xmlns/")) {
1749
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
1750
+ }
1751
+
1752
+ // throw Exception if we are trying to make the attribute look like a default namespace declaration;
1753
+ // if this node is an attribute and the qualifiedName of this node is "xmlns" [Namespaces].
1754
+ if ((prefix == "") && (this.localName == "xmlns")) {
1755
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
1756
+ }
1757
+ }
1758
+
1759
+ // update prefix
1760
+ this.prefix = prefix;
1761
+
1762
+ // update nodeName (QName)
1763
+ if (this.prefix != "") {
1764
+ this.nodeName = this.prefix +":"+ this.localName;
1765
+ }
1766
+ else {
1767
+ this.nodeName = this.localName; // no prefix, therefore nodeName is simply localName
1768
+ }
1769
+ };
1770
+
1771
+ /**
1772
+ * @method W3CDOMNode.getLocalName - Java style gettor for .localName
1773
+ *
1774
+ * @author Jon van Noort (jon@webarcana.com.au)
1775
+ *
1776
+ * @return : String
1777
+ */
1778
+ W3CDOMNode.prototype.getLocalName = function W3CDOMNode_getLocalName() {
1779
+ return this.localName;
1780
+ };
1781
+
1782
+ /**
1783
+ * @method W3CDOMNode.insertBefore - Inserts the node newChild before the existing child node refChild.
1784
+ * If refChild is null, insert newChild at the end of the list of children.
1785
+ *
1786
+ * @author Jon van Noort (jon@webarcana.com.au)
1787
+ *
1788
+ * @param newChild : W3CDOMNode - The node to insert.
1789
+ * @param refChild : W3CDOMNode - The reference node, i.e., the node before which the new node must be inserted
1790
+ *
1791
+ * @throws : W3CDOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
1792
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
1793
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
1794
+ * @throws : W3CDOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
1795
+ *
1796
+ * @return : W3CDOMNode - The node being inserted.
1797
+ */
1798
+ W3CDOMNode.prototype.insertBefore = function W3CDOMNode_insertBefore(newChild, refChild) {
1799
+ var prevNode;
1800
+
1801
+ // test for exceptions
1802
+ if (this.ownerDocument.implementation.errorChecking) {
1803
+ // throw Exception if W3CDOMNode is readonly
1804
+ if (this._readonly) {
1805
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1806
+ }
1807
+
1808
+ // throw Exception if newChild was not created by this Document
1809
+ if (this.ownerDocument != newChild.ownerDocument) {
1810
+ throw(new W3CDOMException(W3CDOMException.WRONG_DOCUMENT_ERR));
1811
+ }
1812
+
1813
+ // throw Exception if the node is an ancestor
1814
+ if (this._isAncestor(newChild)) {
1815
+ throw(new W3CDOMException(W3CDOMException.HIERARCHY_REQUEST_ERR));
1816
+ }
1817
+ }
1818
+
1819
+ if (refChild) { // if refChild is specified, insert before it
1820
+ // find index of refChild
1821
+ var itemIndex = this.childNodes._findItemIndex(refChild._id);
1822
+
1823
+ // throw Exception if there is no child node with this id
1824
+ if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
1825
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
1826
+ }
1827
+
1828
+ // if the newChild is already in the tree,
1829
+ var newChildParent = newChild.parentNode;
1830
+ if (newChildParent) {
1831
+ // remove it
1832
+ newChildParent.removeChild(newChild);
1833
+ }
1834
+
1835
+ // insert newChild into childNodes
1836
+ this.childNodes._insertBefore(newChild, this.childNodes._findItemIndex(refChild._id));
1837
+
1838
+ // do node pointer surgery
1839
+ prevNode = refChild.previousSibling;
1840
+
1841
+ // handle DocumentFragment
1842
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) {
1843
+ if (newChild.childNodes._nodes.length > 0) {
1844
+ // set the parentNode of DocumentFragment's children
1845
+ for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
1846
+ newChild.childNodes._nodes[ind].parentNode = this;
1847
+ }
1848
+
1849
+ // link refChild to last child of DocumentFragment
1850
+ refChild.previousSibling = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
1851
+ }
1852
+ }
1853
+ else {
1854
+ newChild.parentNode = this; // set the parentNode of the newChild
1855
+ refChild.previousSibling = newChild; // link refChild to newChild
1856
+ }
1857
+ }
1858
+ else { // otherwise, append to end
1859
+ prevNode = this.lastChild;
1860
+ this.appendChild(newChild);
1861
+ }
1862
+
1863
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) {
1864
+ // do node pointer surgery for DocumentFragment
1865
+ if (newChild.childNodes._nodes.length > 0) {
1866
+ if (prevNode) {
1867
+ prevNode.nextSibling = newChild.childNodes._nodes[0];
1868
+ }
1869
+ else { // this is the first child in the list
1870
+ this.firstChild = newChild.childNodes._nodes[0];
1871
+ }
1872
+
1873
+ newChild.childNodes._nodes[0].previousSibling = prevNode;
1874
+ newChild.childNodes._nodes[newChild.childNodes._nodes.length-1].nextSibling = refChild;
1875
+ }
1876
+ }
1877
+ else {
1878
+ // do node pointer surgery for newChild
1879
+ if (prevNode) {
1880
+ prevNode.nextSibling = newChild;
1881
+ }
1882
+ else { // this is the first child in the list
1883
+ this.firstChild = newChild;
1884
+ }
1885
+
1886
+ newChild.previousSibling = prevNode;
1887
+ newChild.nextSibling = refChild;
1888
+ }
1889
+
1890
+ return newChild;
1891
+ };
1892
+
1893
+ /**
1894
+ * @method W3CDOMNode.replaceChild - Replaces the child node oldChild with newChild in the list of children,
1895
+ * and returns the oldChild node.
1896
+ * If the newChild is already in the tree, it is first removed.
1897
+ *
1898
+ * @author Jon van Noort (jon@webarcana.com.au)
1899
+ *
1900
+ * @param newChild : W3CDOMNode - The node to insert.
1901
+ * @param oldChild : W3CDOMNode - The node being replaced in the list.
1902
+ *
1903
+ * @throws : W3CDOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
1904
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
1905
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
1906
+ * @throws : W3CDOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
1907
+ *
1908
+ * @return : W3CDOMNode - The node that was replaced
1909
+ */
1910
+ W3CDOMNode.prototype.replaceChild = function W3CDOMNode_replaceChild(newChild, oldChild) {
1911
+ var ret = null;
1912
+
1913
+ // test for exceptions
1914
+ if (this.ownerDocument.implementation.errorChecking) {
1915
+ // throw Exception if W3CDOMNode is readonly
1916
+ if (this._readonly) {
1917
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
1918
+ }
1919
+
1920
+ // throw Exception if newChild was not created by this Document
1921
+ if (this.ownerDocument != newChild.ownerDocument) {
1922
+ throw(new W3CDOMException(W3CDOMException.WRONG_DOCUMENT_ERR));
1923
+ }
1924
+
1925
+ // throw Exception if the node is an ancestor
1926
+ if (this._isAncestor(newChild)) {
1927
+ throw(new W3CDOMException(W3CDOMException.HIERARCHY_REQUEST_ERR));
1928
+ }
1929
+ }
1930
+
1931
+ // get index of oldChild
1932
+ var index = this.childNodes._findItemIndex(oldChild._id);
1933
+
1934
+ // throw Exception if there is no child node with this id
1935
+ if (this.ownerDocument.implementation.errorChecking && (index < 0)) {
1936
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
1937
+ }
1938
+
1939
+ // if the newChild is already in the tree,
1940
+ var newChildParent = newChild.parentNode;
1941
+ if (newChildParent) {
1942
+ // remove it
1943
+ newChildParent.removeChild(newChild);
1944
+ }
1945
+
1946
+ // add newChild to childNodes
1947
+ ret = this.childNodes._replaceChild(newChild, index);
1948
+
1949
+
1950
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) {
1951
+ // do node pointer surgery for Document Fragment
1952
+ if (newChild.childNodes._nodes.length > 0) {
1953
+ for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
1954
+ newChild.childNodes._nodes[ind].parentNode = this;
1955
+ }
1956
+
1957
+ if (oldChild.previousSibling) {
1958
+ oldChild.previousSibling.nextSibling = newChild.childNodes._nodes[0];
1959
+ }
1960
+ else {
1961
+ this.firstChild = newChild.childNodes._nodes[0];
1962
+ }
1963
+
1964
+ if (oldChild.nextSibling) {
1965
+ oldChild.nextSibling.previousSibling = newChild;
1966
+ }
1967
+ else {
1968
+ this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
1969
+ }
1970
+
1971
+ newChild.childNodes._nodes[0].previousSibling = oldChild.previousSibling;
1972
+ newChild.childNodes._nodes[newChild.childNodes._nodes.length-1].nextSibling = oldChild.nextSibling;
1973
+ }
1974
+ }
1975
+ else {
1976
+ // do node pointer surgery for newChild
1977
+ newChild.parentNode = this;
1978
+
1979
+ if (oldChild.previousSibling) {
1980
+ oldChild.previousSibling.nextSibling = newChild;
1981
+ }
1982
+ else {
1983
+ this.firstChild = newChild;
1984
+ }
1985
+ if (oldChild.nextSibling) {
1986
+ oldChild.nextSibling.previousSibling = newChild;
1987
+ }
1988
+ else {
1989
+ this.lastChild = newChild;
1990
+ }
1991
+ newChild.previousSibling = oldChild.previousSibling;
1992
+ newChild.nextSibling = oldChild.nextSibling;
1993
+ }
1994
+ return ret;
1995
+ };
1996
+
1997
+ /**
1998
+ * @method W3CDOMNode.removeChild - Removes the child node indicated by oldChild from the list of children, and returns it.
1999
+ *
2000
+ * @author Jon van Noort (jon@webarcana.com.au)
2001
+ *
2002
+ * @param oldChild : W3CDOMNode - The node being removed.
2003
+ *
2004
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
2005
+ * @throws : W3CDOMException - NOT_FOUND_ERR: Raised if there is no node named name in this map.
2006
+ *
2007
+ * @return : W3CDOMNode - The node being removed.
2008
+ */
2009
+ W3CDOMNode.prototype.removeChild = function W3CDOMNode_removeChild(oldChild) {
2010
+ // throw Exception if W3CDOMNamedNodeMap is readonly
2011
+ if (this.ownerDocument.implementation.errorChecking && (this._readonly || oldChild._readonly)) {
2012
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
2013
+ }
2014
+
2015
+ // get index of oldChild
2016
+ var itemIndex = this.childNodes._findItemIndex(oldChild._id);
2017
+
2018
+ // throw Exception if there is no child node with this id
2019
+ if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
2020
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
2021
+ }
2022
+
2023
+ // remove oldChild from childNodes
2024
+ this.childNodes._removeChild(itemIndex);
2025
+
2026
+ // do node pointer surgery
2027
+ oldChild.parentNode = null;
2028
+
2029
+ if (oldChild.previousSibling) {
2030
+ oldChild.previousSibling.nextSibling = oldChild.nextSibling;
2031
+ }
2032
+ else {
2033
+ this.firstChild = oldChild.nextSibling;
2034
+ }
2035
+ if (oldChild.nextSibling) {
2036
+ oldChild.nextSibling.previousSibling = oldChild.previousSibling;
2037
+ }
2038
+ else {
2039
+ this.lastChild = oldChild.previousSibling;
2040
+ }
2041
+
2042
+ oldChild.previousSibling = null;
2043
+ oldChild.nextSibling = null;
2044
+ return oldChild;
2045
+ };
2046
+
2047
+ /**
2048
+ * @method W3CDOMNode.appendChild - Adds the node newChild to the end of the list of children of this node.
2049
+ * If the newChild is already in the tree, it is first removed.
2050
+ *
2051
+ * @author Jon van Noort (jon@webarcana.com.au)
2052
+ *
2053
+ * @param newChild : W3CDOMNode - The node to add
2054
+ *
2055
+ * @throws : W3CDOMException - HIERARCHY_REQUEST_ERR: Raised if the node to insert is one of this node's ancestors
2056
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
2057
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Node is readonly.
2058
+ *
2059
+ * @return : W3CDOMNode - The node added
2060
+ */
2061
+ W3CDOMNode.prototype.appendChild = function W3CDOMNode_appendChild(newChild) {
2062
+ // test for exceptions
2063
+ if (this.ownerDocument.implementation.errorChecking) {
2064
+ // throw Exception if Node is readonly
2065
+ if (this._readonly) {
2066
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
2067
+ }
2068
+
2069
+ // throw Exception if arg was not created by this Document
2070
+ if (this.ownerDocument != newChild.ownerDocument) {
2071
+ throw(new W3CDOMException(W3CDOMException.WRONG_DOCUMENT_ERR));
2072
+ }
2073
+
2074
+ // throw Exception if the node is an ancestor
2075
+ if (this._isAncestor(newChild)) {
2076
+ throw(new W3CDOMException(W3CDOMException.HIERARCHY_REQUEST_ERR));
2077
+ }
2078
+ }
2079
+
2080
+ // if the newChild is already in the tree,
2081
+ var newChildParent = newChild.parentNode;
2082
+ if (newChildParent) {
2083
+ // remove it
2084
+ newChildParent.removeChild(newChild);
2085
+ }
2086
+
2087
+ // add newChild to childNodes
2088
+ this.childNodes._appendChild(newChild);
2089
+
2090
+ if (newChild.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT_NODE) {
2091
+ // do node pointer surgery for DocumentFragment
2092
+ if (newChild.childNodes._nodes.length > 0) {
2093
+ for (var ind = 0; ind < newChild.childNodes._nodes.length; ind++) {
2094
+ newChild.childNodes._nodes[ind].parentNode = this;
2095
+ }
2096
+
2097
+ if (this.lastChild) {
2098
+ this.lastChild.nextSibling = newChild.childNodes._nodes[0];
2099
+ newChild.childNodes._nodes[0].previousSibling = this.lastChild;
2100
+ this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
2101
+ }
2102
+ else {
2103
+ this.lastChild = newChild.childNodes._nodes[newChild.childNodes._nodes.length-1];
2104
+ this.firstChild = newChild.childNodes._nodes[0];
2105
+ }
2106
+ }
2107
+ }
2108
+ else {
2109
+ // do node pointer surgery for newChild
2110
+ newChild.parentNode = this;
2111
+ if (this.lastChild) {
2112
+ this.lastChild.nextSibling = newChild;
2113
+ newChild.previousSibling = this.lastChild;
2114
+ this.lastChild = newChild;
2115
+ }
2116
+ else {
2117
+ this.lastChild = newChild;
2118
+ this.firstChild = newChild;
2119
+ }
2120
+ }
2121
+
2122
+ return newChild;
2123
+ };
2124
+
2125
+ /**
2126
+ * @method W3CDOMNode.hasChildNodes - This is a convenience method to allow easy determination of whether a node has any children.
2127
+ *
2128
+ * @author Jon van Noort (jon@webarcana.com.au)
2129
+ *
2130
+ * @return : boolean - true if the node has any children, false if the node has no children
2131
+ */
2132
+ W3CDOMNode.prototype.hasChildNodes = function W3CDOMNode_hasChildNodes() {
2133
+ return (this.childNodes.length > 0);
2134
+ };
2135
+
2136
+ /**
2137
+ * @method W3CDOMNode.cloneNode - Returns a duplicate of this node, i.e., serves as a generic copy constructor for nodes.
2138
+ * The duplicate node has no parent (parentNode returns null.).
2139
+ *
2140
+ * @author Jon van Noort (jon@webarcana.com.au)
2141
+ *
2142
+ * @param deep : boolean - If true, recursively clone the subtree under the specified node;
2143
+ * if false, clone only the node itself (and its attributes, if it is an Element).
2144
+ *
2145
+ * @return : W3CDOMNode
2146
+ */
2147
+ W3CDOMNode.prototype.cloneNode = function W3CDOMNode_cloneNode(deep) {
2148
+ // use importNode to clone this Node
2149
+ //do not throw any exceptions
2150
+ try {
2151
+ return this.ownerDocument.importNode(this, deep);
2152
+ }
2153
+ catch (e) {
2154
+ //there shouldn't be any exceptions, but if there are, return null
2155
+ return null;
2156
+ }
2157
+ };
2158
+
2159
+ /**
2160
+ * @method W3CDOMNode.normalize - Puts all Text nodes in the full depth of the sub-tree underneath this Element into a "normal" form
2161
+ * where only markup (e.g., tags, comments, processing instructions, CDATA sections, and entity references) separates Text nodes,
2162
+ * i.e., there are no adjacent Text nodes.
2163
+ *
2164
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
2165
+ */
2166
+ W3CDOMNode.prototype.normalize = function W3CDOMNode_normalize() {
2167
+ var inode;
2168
+ var nodesToRemove = new W3CDOMNodeList();
2169
+
2170
+ if (this.nodeType == W3CDOMNode.ELEMENT_NODE || this.nodeType == W3CDOMNode.DOCUMENT_NODE) {
2171
+ var adjacentTextNode = null;
2172
+
2173
+ // loop through all childNodes
2174
+ for(var i = 0; i < this.childNodes.length; i++) {
2175
+ inode = this.childNodes.item(i);
2176
+
2177
+ if (inode.nodeType == W3CDOMNode.TEXT_NODE) { // this node is a text node
2178
+ if (inode.length < 1) { // this text node is empty
2179
+ nodesToRemove._appendChild(inode); // add this node to the list of nodes to be remove
2180
+ }
2181
+ else {
2182
+ if (adjacentTextNode) { // if previous node was also text
2183
+ adjacentTextNode.appendData(inode.data); // merge the data in adjacent text nodes
2184
+ nodesToRemove._appendChild(inode); // add this node to the list of nodes to be removed
2185
+ }
2186
+ else {
2187
+ adjacentTextNode = inode; // remember this node for next cycle
2188
+ }
2189
+ }
2190
+ }
2191
+ else {
2192
+ adjacentTextNode = null; // (soon to be) previous node is not a text node
2193
+ inode.normalize(); // normalise non Text childNodes
2194
+ }
2195
+ }
2196
+
2197
+ // remove redundant Text Nodes
2198
+ for(var i = 0; i < nodesToRemove.length; i++) {
2199
+ inode = nodesToRemove.item(i);
2200
+ inode.parentNode.removeChild(inode);
2201
+ }
2202
+ }
2203
+ };
2204
+
2205
+ /**
2206
+ * @method W3CDOMNode.isSupported - Test if the W3CDOM implementation implements a specific feature
2207
+ *
2208
+ * @author Jon van Noort (jon@webarcana.com.au)
2209
+ *
2210
+ * @param feature : string - The package name of the feature to test. the legal only values are "XML" and "CORE" (case-insensitive).
2211
+ * @param version : string - This is the version number of the package name to test. In Level 1, this is the string "1.0".
2212
+ *
2213
+ * @return : boolean
2214
+ */
2215
+ W3CDOMNode.prototype.isSupported = function W3CDOMNode_isSupported(feature, version) {
2216
+ // use Implementation.hasFeature to determin if this feature is supported
2217
+ return this.ownerDocument.implementation.hasFeature(feature, version);
2218
+ }
2219
+
2220
+ /**
2221
+ * @method W3CDOMNode.getElementsByTagName - Returns a NodeList of all the Elements with a given tag name
2222
+ * in the order in which they would be encountered in a preorder traversal of the Document tree.
2223
+ *
2224
+ * @author Jon van Noort (jon@webarcana.com.au)
2225
+ *
2226
+ * @param tagname : string - The name of the tag to match on. The special value "*" matches all tags
2227
+ *
2228
+ * @return : W3CDOMNodeList
2229
+ */
2230
+ W3CDOMNode.prototype.getElementsByTagName = function W3CDOMNode_getElementsByTagName(tagname) {
2231
+ // delegate to _getElementsByTagNameRecursive
2232
+ return this._getElementsByTagNameRecursive(tagname, new W3CDOMNodeList(this.ownerDocument));
2233
+ };
2234
+
2235
+ /**
2236
+ * @method W3CDOMNode._getElementsByTagNameRecursive - implements getElementsByTagName()
2237
+ *
2238
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
2239
+ *
2240
+ * @param tagname : string - The name of the tag to match on. The special value "*" matches all tags
2241
+ * @param nodeList : W3CDOMNodeList - The accumulating list of matching nodes
2242
+ *
2243
+ * @return : W3CDOMNodeList
2244
+ */
2245
+ W3CDOMNode.prototype._getElementsByTagNameRecursive = function W3CDOMNode__getElementsByTagNameRecursive(tagname, nodeList) {
2246
+ if (this.nodeType == W3CDOMNode.ELEMENT_NODE || this.nodeType == W3CDOMNode.DOCUMENT_NODE) {
2247
+
2248
+ if((this.nodeName == tagname) || (tagname == "*")) {
2249
+ nodeList._appendChild(this); // add matching node to nodeList
2250
+ }
2251
+
2252
+ // recurse childNodes
2253
+ for(var i = 0; i < this.childNodes.length; i++) {
2254
+ nodeList = this.childNodes.item(i)._getElementsByTagNameRecursive(tagname, nodeList);
2255
+ }
2256
+ }
2257
+
2258
+ return nodeList;
2259
+ };
2260
+
2261
+ /**
2262
+ * @method W3CDOMNode.getXML - Returns the String XML of the node and all of its children
2263
+ *
2264
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
2265
+ *
2266
+ * @return : string - XML String of the XML of the node and all of its children
2267
+ */
2268
+ W3CDOMNode.prototype.getXML = function W3CDOMNode_getXML() {
2269
+ return this.toString();
2270
+ }
2271
+
2272
+
2273
+ /**
2274
+ * @method W3CDOMNode.getElementsByTagNameNS - Returns a NodeList of all the Elements with a given namespaceURI and localName
2275
+ * in the order in which they would be encountered in a preorder traversal of the Document tree.
2276
+ *
2277
+ * @author Jon van Noort (jon@webarcana.com.au)
2278
+ *
2279
+ * @param namespaceURI : string - the namespace URI of the required node
2280
+ * @param localName : string - the local name of the required node
2281
+ *
2282
+ * @return : W3CDOMNodeList
2283
+ */
2284
+ W3CDOMNode.prototype.getElementsByTagNameNS = function W3CDOMNode_getElementsByTagNameNS(namespaceURI, localName) {
2285
+ // delegate to _getElementsByTagNameNSRecursive
2286
+ return this._getElementsByTagNameNSRecursive(namespaceURI, localName, new W3CDOMNodeList(this.ownerDocument));
2287
+ };
2288
+
2289
+ /**
2290
+ * @method W3CDOMNode._getElementsByTagNameNSRecursive - implements getElementsByTagName()
2291
+ *
2292
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
2293
+ *
2294
+ * @param namespaceURI : string - the namespace URI of the required node
2295
+ * @param localName : string - the local name of the required node
2296
+ * @param nodeList : W3CDOMNodeList - The accumulating list of matching nodes
2297
+ *
2298
+ * @return : W3CDOMNodeList
2299
+ */
2300
+ W3CDOMNode.prototype._getElementsByTagNameNSRecursive = function W3CDOMNode__getElementsByTagNameNSRecursive(namespaceURI, localName, nodeList) {
2301
+ if (this.nodeType == W3CDOMNode.ELEMENT_NODE || this.nodeType == W3CDOMNode.DOCUMENT_NODE) {
2302
+
2303
+ if (((this.namespaceURI == namespaceURI) || (namespaceURI == "*")) && ((this.localName == localName) || (localName == "*"))) {
2304
+ nodeList._appendChild(this); // add matching node to nodeList
2305
+ }
2306
+
2307
+ // recurse childNodes
2308
+ for(var i = 0; i < this.childNodes.length; i++) {
2309
+ nodeList = this.childNodes.item(i)._getElementsByTagNameNSRecursive(namespaceURI, localName, nodeList);
2310
+ }
2311
+ }
2312
+
2313
+ return nodeList;
2314
+ };
2315
+
2316
+ /**
2317
+ * @method W3CDOMNode._isAncestor - returns true if node is ancestor of this
2318
+ *
2319
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
2320
+ *
2321
+ * @param node : W3CDOMNode - The candidate ancestor node
2322
+ *
2323
+ * @return : boolean
2324
+ */
2325
+ W3CDOMNode.prototype._isAncestor = function W3CDOMNode__isAncestor(node) {
2326
+ // if this node matches, return true,
2327
+ // otherwise recurse up (if there is a parentNode)
2328
+ return ((this == node) || ((this.parentNode) && (this.parentNode._isAncestor(node))));
2329
+ }
2330
+
2331
+ /**
2332
+ * @method W3CDOMNode.importNode - Imports a node from another document to this document.
2333
+ * The returned node has no parent; (parentNode is null).
2334
+ *
2335
+ * @author Jon van Noort (jon@webarcana.com.au)
2336
+ *
2337
+ * @param importedNode : Node - The Node to be imported
2338
+ * @param deep : boolean - If true, recursively clone the subtree under the specified node;
2339
+ * if false, clone only the node itself (and its attributes, if it is an Element).
2340
+ *
2341
+ * @return : W3CDOMNode
2342
+ */
2343
+ W3CDOMNode.prototype.importNode = function W3CDOMNode_importNode(importedNode, deep) {
2344
+ var importNode;
2345
+
2346
+ //there is no need to perform namespace checks since everything has already gone through them
2347
+ //in order to have gotten into the W3CDOM in the first place. The following line
2348
+ //turns namespace checking off in ._isValidNamespace
2349
+ this.getOwnerDocument()._performingImportNodeOperation = true;
2350
+
2351
+ try {
2352
+ if (importedNode.nodeType == W3CDOMNode.ELEMENT_NODE) {
2353
+ if (!this.ownerDocument.implementation.namespaceAware) {
2354
+ // create a local Element (with the name of the importedNode)
2355
+ importNode = this.ownerDocument.createElement(importedNode.tagName);
2356
+
2357
+ // create attributes matching those of the importedNode
2358
+ for(var i = 0; i < importedNode.attributes.length; i++) {
2359
+ importNode.setAttribute(importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
2360
+ }
2361
+ }
2362
+ else {
2363
+ // create a local Element (with the name & namespaceURI of the importedNode)
2364
+ importNode = this.ownerDocument.createElementNS(importedNode.namespaceURI, importedNode.nodeName);
2365
+
2366
+ // create attributes matching those of the importedNode
2367
+ for(var i = 0; i < importedNode.attributes.length; i++) {
2368
+ importNode.setAttributeNS(importedNode.attributes.item(i).namespaceURI, importedNode.attributes.item(i).name, importedNode.attributes.item(i).value);
2369
+ }
2370
+
2371
+ // create namespace definitions matching those of the importedNode
2372
+ for(var i = 0; i < importedNode._namespaces.length; i++) {
2373
+ importNode._namespaces._nodes[i] = this.ownerDocument.createNamespace(importedNode._namespaces.item(i).localName);
2374
+ importNode._namespaces._nodes[i].setValue(importedNode._namespaces.item(i).value);
2375
+ }
2376
+ }
2377
+ }
2378
+ else if (importedNode.nodeType == W3CDOMNode.ATTRIBUTE_NODE) {
2379
+ if (!this.ownerDocument.implementation.namespaceAware) {
2380
+ // create a local Attribute (with the name of the importedAttribute)
2381
+ importNode = this.ownerDocument.createAttribute(importedNode.name);
2382
+ }
2383
+ else {
2384
+ // create a local Attribute (with the name & namespaceURI of the importedAttribute)
2385
+ importNode = this.ownerDocument.createAttributeNS(importedNode.namespaceURI, importedNode.nodeName);
2386
+
2387
+ // create namespace definitions matching those of the importedAttribute
2388
+ for(var i = 0; i < importedNode._namespaces.length; i++) {
2389
+ importNode._namespaces._nodes[i] = this.ownerDocument.createNamespace(importedNode._namespaces.item(i).localName);
2390
+ importNode._namespaces._nodes[i].setValue(importedNode._namespaces.item(i).value);
2391
+ }
2392
+ }
2393
+
2394
+ // set the value of the local Attribute to match that of the importedAttribute
2395
+ importNode.setValue(importedNode.value);
2396
+ }
2397
+ else if (importedNode.nodeType == W3CDOMNode.DOCUMENT_FRAGMENT) {
2398
+ // create a local DocumentFragment
2399
+ importNode = this.ownerDocument.createDocumentFragment();
2400
+ }
2401
+ else if (importedNode.nodeType == W3CDOMNode.NAMESPACE_NODE) {
2402
+ // create a local NamespaceNode (with the same name & value as the importedNode)
2403
+ importNode = this.ownerDocument.createNamespace(importedNode.nodeName);
2404
+ importNode.setValue(importedNode.value);
2405
+ }
2406
+ else if (importedNode.nodeType == W3CDOMNode.TEXT_NODE) {
2407
+ // create a local TextNode (with the same data as the importedNode)
2408
+ importNode = this.ownerDocument.createTextNode(importedNode.data);
2409
+ }
2410
+ else if (importedNode.nodeType == W3CDOMNode.CDATA_SECTION_NODE) {
2411
+ // create a local CDATANode (with the same data as the importedNode)
2412
+ importNode = this.ownerDocument.createCDATASection(importedNode.data);
2413
+ }
2414
+ else if (importedNode.nodeType == W3CDOMNode.PROCESSING_INSTRUCTION_NODE) {
2415
+ // create a local ProcessingInstruction (with the same target & data as the importedNode)
2416
+ importNode = this.ownerDocument.createProcessingInstruction(importedNode.target, importedNode.data);
2417
+ }
2418
+ else if (importedNode.nodeType == W3CDOMNode.COMMENT_NODE) {
2419
+ // create a local Comment (with the same data as the importedNode)
2420
+ importNode = this.ownerDocument.createComment(importedNode.data);
2421
+ }
2422
+ else { // throw Exception if nodeType is not supported
2423
+ throw(new W3CDOMException(W3CDOMException.NOT_SUPPORTED_ERR));
2424
+ }
2425
+
2426
+ if (deep) { // recurse childNodes
2427
+ for(var i = 0; i < importedNode.childNodes.length; i++) {
2428
+ importNode.appendChild(this.ownerDocument.importNode(importedNode.childNodes.item(i), true));
2429
+ }
2430
+ }
2431
+
2432
+ //reset _performingImportNodeOperation
2433
+ this.getOwnerDocument()._performingImportNodeOperation = false;
2434
+ return importNode;
2435
+ }
2436
+ catch (eAny) {
2437
+ //reset _performingImportNodeOperation
2438
+ this.getOwnerDocument()._performingImportNodeOperation = false;
2439
+
2440
+ //re-throw the exception
2441
+ throw eAny;
2442
+ }//djotemp
2443
+ };
2444
+
2445
+ /**
2446
+ * @method W3CDOMNode.escapeString - escape special characters
2447
+ *
2448
+ * @author Jon van Noort (jon@webarcana.com.au)
2449
+ *
2450
+ * @param str : string - The string to be escaped
2451
+ *
2452
+ * @return : string - The escaped string
2453
+ */
2454
+ W3CDOMNode.prototype.__escapeString = function W3CDOMNode__escapeString(str) {
2455
+
2456
+ //the sax processor already has this function. Just wrap it
2457
+ return __escapeString(str);
2458
+ };
2459
+
2460
+ /**
2461
+ * @method W3CDOMNode.unescapeString - unescape special characters
2462
+ *
2463
+ * @author Jon van Noort (jon@webarcana.com.au)
2464
+ *
2465
+ * @param str : string - The string to be unescaped
2466
+ *
2467
+ * @return : string - The unescaped string
2468
+ */
2469
+ W3CDOMNode.prototype.__unescapeString = function W3CDOMNode__unescapeString(str) {
2470
+
2471
+ //the sax processor already has this function. Just wrap it
2472
+ return __unescapeString(str);
2473
+ };
2474
+
2475
+
2476
+
2477
+ /**
2478
+ * @class W3CDOMDocument - The Document interface represents the entire HTML or XML document.
2479
+ * Conceptually, it is the root of the document tree, and provides the primary access to the document's data.
2480
+ *
2481
+ * @extends W3CDOMNode
2482
+ *
2483
+ * @author Jon van Noort (jon@webarcana.com.au)
2484
+ *
2485
+ * @param implementation : W3CDOMImplementation - the creator Implementation
2486
+ */
2487
+ W3CDOMDocument = function(implementation) {
2488
+ this._class = addClass(this._class, "W3CDOMDocument");
2489
+ this.W3CDOMNode = W3CDOMNode;
2490
+ this.W3CDOMNode(this);
2491
+
2492
+ this.doctype = null; // The Document Type Declaration (see DocumentType) associated with this document
2493
+ this.implementation = implementation; // The W3CDOMImplementation object that handles this document.
2494
+ this.documentElement = null; // This is a convenience attribute that allows direct access to the child node that is the root element of the document
2495
+ this.all = new Array(); // The list of all Elements
2496
+
2497
+ this.nodeName = "#document";
2498
+ this.nodeType = W3CDOMNode.DOCUMENT_NODE;
2499
+ this._id = 0;
2500
+ this._lastId = 0;
2501
+ this._parseComplete = false; // initially false, set to true by parser
2502
+
2503
+ this.ownerDocument = this;
2504
+
2505
+ this._performingImportNodeOperation = false;
2506
+ };
2507
+ W3CDOMDocument.prototype = new W3CDOMNode;
2508
+
2509
+ /**
2510
+ * @method W3CDOMDocument.getDoctype - Java style gettor for .doctype
2511
+ *
2512
+ * @author Jon van Noort (jon@webarcana.com.au)
2513
+ *
2514
+ * @return : W3CDOMDocument
2515
+ */
2516
+ W3CDOMDocument.prototype.getDoctype = function W3CDOMDocument_getDoctype() {
2517
+ return this.doctype;
2518
+ };
2519
+
2520
+ /**
2521
+ * @method W3CDOMDocument.getImplementation - Java style gettor for .implementation
2522
+ *
2523
+ * @author Jon van Noort (jon@webarcana.com.au)
2524
+ *
2525
+ * @return : W3CDOMImplementation
2526
+ */
2527
+ W3CDOMDocument.prototype.getImplementation = function W3CDOMDocument_implementation() {
2528
+ return this.implementation;
2529
+ };
2530
+
2531
+ /**
2532
+ * @method W3CDOMDocument.getDocumentElement - Java style gettor for .documentElement
2533
+ *
2534
+ * @author Jon van Noort (jon@webarcana.com.au)
2535
+ *
2536
+ * @return : W3CDOMDocumentElement
2537
+ */
2538
+ W3CDOMDocument.prototype.getDocumentElement = function W3CDOMDocument_getDocumentElement() {
2539
+ return this.documentElement;
2540
+ };
2541
+
2542
+ /**
2543
+ * @method W3CDOMDocument.createElement - Creates an element of the type specified.
2544
+ * Note that the instance returned implements the Element interface,
2545
+ * so attributes can be specified directly on the returned object.
2546
+ *
2547
+ * @author Jon van Noort (jon@webarcana.com.au)
2548
+ *
2549
+ * @param tagName : string - The name of the element type to instantiate.
2550
+ *
2551
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
2552
+ *
2553
+ * @return : W3CDOMElement - The new Element object.
2554
+ */
2555
+ W3CDOMDocument.prototype.createElement = function W3CDOMDocument_createElement(tagName) {
2556
+ // throw Exception if the tagName string contains an illegal character
2557
+ if (this.ownerDocument.implementation.errorChecking && (!this.ownerDocument.implementation._isValidName(tagName))) {
2558
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
2559
+ }
2560
+
2561
+ // create W3CDOMElement specifying 'this' as ownerDocument
2562
+ var node = new W3CDOMElement(this);
2563
+
2564
+ // assign values to properties (and aliases)
2565
+ node.tagName = tagName;
2566
+ node.nodeName = tagName;
2567
+
2568
+ // add Element to 'all' collection
2569
+ this.all[this.all.length] = node;
2570
+
2571
+ return node;
2572
+ };
2573
+
2574
+ /**
2575
+ * @method W3CDOMDocument.createDocumentFragment - CCreates an empty DocumentFragment object.
2576
+ *
2577
+ * @author Jon van Noort (jon@webarcana.com.au)
2578
+ *
2579
+ * @return : W3CDOMDocumentFragment - The new DocumentFragment object
2580
+ */
2581
+ W3CDOMDocument.prototype.createDocumentFragment = function W3CDOMDocument_createDocumentFragment() {
2582
+ // create W3CDOMDocumentFragment specifying 'this' as ownerDocument
2583
+ var node = new W3CDOMDocumentFragment(this);
2584
+
2585
+ return node;
2586
+ };
2587
+
2588
+ /**
2589
+ * @method W3CDOMDocument.createTextNode - Creates a Text node given the specified string.
2590
+ *
2591
+ * @author Jon van Noort (jon@webarcana.com.au)
2592
+ *
2593
+ * @param data : string - The data for the node.
2594
+ *
2595
+ * @return : W3CDOMText - The new Text object.
2596
+ */
2597
+ W3CDOMDocument.prototype.createTextNode = function W3CDOMDocument_createTextNode(data) {
2598
+ // create W3CDOMText specifying 'this' as ownerDocument
2599
+ var node = new W3CDOMText(this);
2600
+
2601
+ // assign values to properties (and aliases)
2602
+ node.data = data;
2603
+ node.nodeValue = data;
2604
+
2605
+ // set initial length
2606
+ node.length = data.length;
2607
+
2608
+ return node;
2609
+ };
2610
+
2611
+ /**
2612
+ * @method W3CDOMDocument.createComment - Creates a Text node given the specified string.
2613
+ *
2614
+ * @author Jon van Noort (jon@webarcana.com.au)
2615
+ *
2616
+ * @param data : string - The data for the node.
2617
+ *
2618
+ * @return : W3CDOMComment - The new Comment object.
2619
+ */
2620
+ W3CDOMDocument.prototype.createComment = function W3CDOMDocument_createComment(data) {
2621
+ // create W3CDOMComment specifying 'this' as ownerDocument
2622
+ var node = new W3CDOMComment(this);
2623
+
2624
+ // assign values to properties (and aliases)
2625
+ node.data = data;
2626
+ node.nodeValue = data;
2627
+
2628
+ // set initial length
2629
+ node.length = data.length;
2630
+
2631
+ return node;
2632
+ };
2633
+
2634
+ /**
2635
+ * @method W3CDOMDocument.createCDATASection - Creates a CDATASection node whose value is the specified string.
2636
+ *
2637
+ * @author Jon van Noort (jon@webarcana.com.au)
2638
+ *
2639
+ * @param data : string - The data for the node.
2640
+ *
2641
+ * @return : W3CDOMCDATASection - The new CDATASection object.
2642
+ */
2643
+ W3CDOMDocument.prototype.createCDATASection = function W3CDOMDocument_createCDATASection(data) {
2644
+ // create W3CDOMCDATASection specifying 'this' as ownerDocument
2645
+ var node = new W3CDOMCDATASection(this);
2646
+
2647
+ // assign values to properties (and aliases)
2648
+ node.data = data;
2649
+ node.nodeValue = data;
2650
+
2651
+ // set initial length
2652
+ node.length = data.length;
2653
+
2654
+ return node;
2655
+ };
2656
+
2657
+ /**
2658
+ * @method W3CDOMDocument.createProcessingInstruction - Creates a ProcessingInstruction node given the specified target and data strings.
2659
+ *
2660
+ * @author Jon van Noort (jon@webarcana.com.au)
2661
+ *
2662
+ * @param target : string - The target part of the processing instruction.
2663
+ * @param data : string - The data for the node.
2664
+ *
2665
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
2666
+ *
2667
+ * @return : W3CDOMProcessingInstruction - The new ProcessingInstruction object.
2668
+ */
2669
+ W3CDOMDocument.prototype.createProcessingInstruction = function W3CDOMDocument_createProcessingInstruction(target, data) {
2670
+ // throw Exception if the target string contains an illegal character
2671
+ if (this.ownerDocument.implementation.errorChecking && (!this.implementation._isValidName(target))) {
2672
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
2673
+ }
2674
+
2675
+ // create W3CDOMProcessingInstruction specifying 'this' as ownerDocument
2676
+ var node = new W3CDOMProcessingInstruction(this);
2677
+
2678
+ // assign values to properties (and aliases)
2679
+ node.target = target;
2680
+ node.nodeName = target;
2681
+ node.data = data;
2682
+ node.nodeValue = data;
2683
+
2684
+ // set initial length
2685
+ node.length = data.length;
2686
+
2687
+ return node;
2688
+ };
2689
+
2690
+ /**
2691
+ * @method W3CDOMDocument.createAttribute - Creates an Attr of the given name
2692
+ *
2693
+ * @author Jon van Noort (jon@webarcana.com.au)
2694
+ *
2695
+ * @param name : string - The name of the attribute.
2696
+ *
2697
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
2698
+ *
2699
+ * @return : W3CDOMAttr - The new Attr object.
2700
+ */
2701
+ W3CDOMDocument.prototype.createAttribute = function W3CDOMDocument_createAttribute(name) {
2702
+ // throw Exception if the name string contains an illegal character
2703
+ if (this.ownerDocument.implementation.errorChecking && (!this.ownerDocument.implementation._isValidName(name))) {
2704
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
2705
+ }
2706
+
2707
+ // create W3CDOMAttr specifying 'this' as ownerDocument
2708
+ var node = new W3CDOMAttr(this);
2709
+
2710
+ // assign values to properties (and aliases)
2711
+ node.name = name;
2712
+ node.nodeName = name;
2713
+
2714
+ return node;
2715
+ };
2716
+
2717
+ /**
2718
+ * @method W3CDOMDocument.createElementNS - Creates an element of the type specified,
2719
+ * within the specified namespace.
2720
+ * Note that the instance returned implements the Element interface,
2721
+ * so attributes can be specified directly on the returned object.
2722
+ *
2723
+ * @author Jon van Noort (jon@webarcana.com.au)
2724
+ *
2725
+ * @param namespaceURI : string - The namespace URI of the element.
2726
+ * @param qualifiedName : string - The qualified name of the element type to instantiate.
2727
+ *
2728
+ * @throws : W3CDOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
2729
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
2730
+ *
2731
+ * @return : W3CDOMElement - The new Element object.
2732
+ */
2733
+ W3CDOMDocument.prototype.createElementNS = function W3CDOMDocument_createElementNS(namespaceURI, qualifiedName) {
2734
+ // test for exceptions
2735
+ if (this.ownerDocument.implementation.errorChecking) {
2736
+ // throw Exception if the Namespace is invalid
2737
+ if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName)) {
2738
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
2739
+ }
2740
+
2741
+ // throw Exception if the qualifiedName string contains an illegal character
2742
+ if (!this.ownerDocument.implementation._isValidName(qualifiedName)) {
2743
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
2744
+ }
2745
+ }
2746
+
2747
+ // create W3CDOMElement specifying 'this' as ownerDocument
2748
+ var node = new W3CDOMElement(this);
2749
+ var qname = this.implementation._parseQName(qualifiedName);
2750
+
2751
+ // assign values to properties (and aliases)
2752
+ node.nodeName = qualifiedName;
2753
+ node.namespaceURI = namespaceURI;
2754
+ node.prefix = qname.prefix;
2755
+ node.localName = qname.localName;
2756
+ node.tagName = qualifiedName;
2757
+
2758
+ // add Element to 'all' collection
2759
+ this.all[this.all.length] = node;
2760
+
2761
+ return node;
2762
+ };
2763
+
2764
+ /**
2765
+ * @method W3CDOMDocument.createAttributeNS - Creates an Attr of the given name
2766
+ * within the specified namespace.
2767
+ *
2768
+ * @author Jon van Noort (jon@webarcana.com.au)
2769
+ *
2770
+ * @param namespaceURI : string - The namespace URI of the attribute.
2771
+ * @param qualifiedName : string - The qualified name of the attribute.
2772
+ *
2773
+ * @throws : W3CDOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
2774
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
2775
+ *
2776
+ * @return : W3CDOMAttr - The new Attr object.
2777
+ */
2778
+ W3CDOMDocument.prototype.createAttributeNS = function W3CDOMDocument_createAttributeNS(namespaceURI, qualifiedName) {
2779
+ // test for exceptions
2780
+ if (this.ownerDocument.implementation.errorChecking) {
2781
+ // throw Exception if the Namespace is invalid
2782
+ if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName, true)) {
2783
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
2784
+ }
2785
+
2786
+ // throw Exception if the qualifiedName string contains an illegal character
2787
+ if (!this.ownerDocument.implementation._isValidName(qualifiedName)) {
2788
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
2789
+ }
2790
+ }
2791
+
2792
+ // create W3CDOMAttr specifying 'this' as ownerDocument
2793
+ var node = new W3CDOMAttr(this);
2794
+ var qname = this.implementation._parseQName(qualifiedName);
2795
+
2796
+ // assign values to properties (and aliases)
2797
+ node.nodeName = qualifiedName
2798
+ node.namespaceURI = namespaceURI
2799
+ node.prefix = qname.prefix;
2800
+ node.localName = qname.localName;
2801
+ node.name = qualifiedName
2802
+ node.nodeValue = "";
2803
+
2804
+ return node;
2805
+ };
2806
+
2807
+ /**
2808
+ * @method W3CDOMDocument.createNamespace - Creates an Namespace of the given name
2809
+ *
2810
+ * @author Jon van Noort (jon@webarcana.com.au)
2811
+ *
2812
+ * @param qualifiedName : string - The qualified name of the attribute.
2813
+ *
2814
+ * @return : W3CDOMNamespace - The new Namespace object.
2815
+ */
2816
+ W3CDOMDocument.prototype.createNamespace = function W3CDOMDocument_createNamespace(qualifiedName) {
2817
+ // create W3CDOMNamespace specifying 'this' as ownerDocument
2818
+ var node = new W3CDOMNamespace(this);
2819
+ var qname = this.implementation._parseQName(qualifiedName);
2820
+
2821
+ // assign values to properties (and aliases)
2822
+ node.nodeName = qualifiedName
2823
+ node.prefix = qname.prefix;
2824
+ node.localName = qname.localName;
2825
+ node.name = qualifiedName
2826
+ node.nodeValue = "";
2827
+
2828
+ return node;
2829
+ };
2830
+
2831
+ /**
2832
+ * @method W3CDOMDocument.getElementById - Return the Element whose ID is given by elementId
2833
+ *
2834
+ * @author Jon van Noort (jon@webarcana.com.au)
2835
+ *
2836
+ * @param elementId : string - The unique ID of the Element
2837
+ *
2838
+ * @return : W3CDOMElement - The requested W3CDOMElement
2839
+ */
2840
+ W3CDOMDocument.prototype.getElementById = function W3CDOMDocument_getElementById(elementId) {
2841
+ // return this._ids[elementId];
2842
+ retNode = null;
2843
+
2844
+ // loop through all Elements in the 'all' collection
2845
+ for (var i=0; i < this.all.length; i++) {
2846
+ var node = this.all[i];
2847
+
2848
+ // if id matches & node is alive (ie, connected (in)directly to the documentElement)
2849
+ if ((node.id == elementId) && (node._isAncestor(node.ownerDocument.documentElement))) {
2850
+ retNode = node;
2851
+ break;
2852
+ }
2853
+ }
2854
+
2855
+ return retNode;
2856
+ };
2857
+
2858
+
2859
+
2860
+ /**
2861
+ * @method W3CDOMDocument._genId - generate a unique internal id
2862
+ *
2863
+ * @author Jon van Noort (jon@webarcana.com.au)
2864
+ *
2865
+ * @return : string - The unique (serial) id
2866
+ */
2867
+ W3CDOMDocument.prototype._genId = function W3CDOMDocument__genId() {
2868
+ this._lastId += 1; // increment lastId (to generate unique id)
2869
+
2870
+ return this._lastId;
2871
+ };
2872
+
2873
+
2874
+ /**
2875
+ * @method W3CDOMDocument._isValidNamespace - test if Namespace is valid
2876
+ * ie, not valid if;
2877
+ * the qualifiedName is malformed, or
2878
+ * the qualifiedName has a prefix and the namespaceURI is null, or
2879
+ * the qualifiedName has a prefix that is "xml" and the namespaceURI is
2880
+ * different from "http://www.w3.org/XML/1998/namespace" [Namespaces].
2881
+ *
2882
+ * @author Jon van Noort (jon@webarcana.com.au), David Joham (djoham@yahoo.com) and Scott Severtson
2883
+ *
2884
+ * @param namespaceURI : string - the namespace URI
2885
+ * @param qualifiedName : string - the QName
2886
+ * @Param isAttribute : boolean - true, if the requesting node is an Attr
2887
+ *
2888
+ * @return : boolean
2889
+ */
2890
+ W3CDOMDocument.prototype._isValidNamespace = function W3CDOMDocument__isValidNamespace(namespaceURI, qualifiedName, isAttribute) {
2891
+
2892
+ if (this._performingImportNodeOperation == true) {
2893
+ //we're doing an importNode operation (or a cloneNode) - in both cases, there
2894
+ //is no need to perform any namespace checking since the nodes have to have been valid
2895
+ //to have gotten into the W3CDOM in the first place
2896
+ return true;
2897
+ }
2898
+
2899
+ var valid = true;
2900
+ // parse QName
2901
+ var qName = this.implementation._parseQName(qualifiedName);
2902
+
2903
+
2904
+ //only check for namespaces if we're finished parsing
2905
+ if (this._parseComplete == true) {
2906
+
2907
+ // if the qualifiedName is malformed
2908
+ if (qName.localName.indexOf(":") > -1 ){
2909
+ valid = false;
2910
+ }
2911
+
2912
+ if ((valid) && (!isAttribute)) {
2913
+ // if the namespaceURI is not null
2914
+ if (!namespaceURI) {
2915
+ valid = false;
2916
+ }
2917
+ }
2918
+
2919
+ // if the qualifiedName has a prefix
2920
+ if ((valid) && (qName.prefix == "")) {
2921
+ valid = false;
2922
+ }
2923
+
2924
+ }
2925
+
2926
+ // if the qualifiedName has a prefix that is "xml" and the namespaceURI is
2927
+ // different from "http://www.w3.org/XML/1998/namespace" [Namespaces].
2928
+ if ((valid) && (qName.prefix == "xml") && (namespaceURI != "http://www.w3.org/XML/1998/namespace")) {
2929
+ valid = false;
2930
+ }
2931
+
2932
+ return valid;
2933
+ }
2934
+
2935
+ /**
2936
+ * @method W3CDOMDocument.toString - Serialize the document into an XML string
2937
+ *
2938
+ * @author David Joham (djoham@yahoo.com)
2939
+ *
2940
+ * @return : string
2941
+ */
2942
+ W3CDOMDocument.prototype.toString = function W3CDOMDocument_toString() {
2943
+ return "" + this.childNodes;
2944
+ } // end function getXML
2945
+
2946
+
2947
+ /**
2948
+ * @class W3CDOMElement - By far the vast majority of objects (apart from text) that authors encounter
2949
+ * when traversing a document are Element nodes.
2950
+ *
2951
+ * @extends W3CDOMNode
2952
+ *
2953
+ * @author Jon van Noort (jon@webarcana.com.au)
2954
+ *
2955
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
2956
+ */
2957
+ W3CDOMElement = function(ownerDocument) {
2958
+ this._class = addClass(this._class, "W3CDOMElement");
2959
+ this.W3CDOMNode = W3CDOMNode;
2960
+ this.W3CDOMNode(ownerDocument);
2961
+
2962
+ this.tagName = ""; // The name of the element.
2963
+ this.id = ""; // the ID of the element
2964
+
2965
+ this.nodeType = W3CDOMNode.ELEMENT_NODE;
2966
+ };
2967
+ W3CDOMElement.prototype = new W3CDOMNode;
2968
+
2969
+ /**
2970
+ * @method W3CDOMElement.getTagName - Java style gettor for .TagName
2971
+ *
2972
+ * @author Jon van Noort (jon@webarcana.com.au)
2973
+ *
2974
+ * @return : string
2975
+ */
2976
+ W3CDOMElement.prototype.getTagName = function W3CDOMElement_getTagName() {
2977
+ return this.tagName;
2978
+ };
2979
+
2980
+ /**
2981
+ * @method W3CDOMElement.getAttribute - Retrieves an attribute value by name
2982
+ *
2983
+ * @author Jon van Noort (jon@webarcana.com.au)
2984
+ *
2985
+ * @param name : string - The name of the attribute to retrieve
2986
+ *
2987
+ * @return : string - The Attr value as a string, or the empty string if that attribute does not have a specified value.
2988
+ */
2989
+ W3CDOMElement.prototype.getAttribute = function W3CDOMElement_getAttribute(name) {
2990
+ var ret = "";
2991
+
2992
+ // if attribute exists, use it
2993
+ var attr = this.attributes.getNamedItem(name);
2994
+
2995
+ if (attr) {
2996
+ ret = attr.value;
2997
+ }
2998
+
2999
+ return ret; // if Attribute exists, return its value, otherwise, return ""
3000
+ };
3001
+
3002
+ /**
3003
+ * @method W3CDOMElement.setAttribute - Retrieves an attribute value by name
3004
+ *
3005
+ * @author Jon van Noort (jon@webarcana.com.au)
3006
+ *
3007
+ * @param name : string - The name of the attribute to create or alter
3008
+ * @param value : string - Value to set in string form
3009
+ *
3010
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
3011
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attribute is readonly.
3012
+ */
3013
+ W3CDOMElement.prototype.setAttribute = function W3CDOMElement_setAttribute(name, value) {
3014
+ // if attribute exists, use it
3015
+ var attr = this.attributes.getNamedItem(name);
3016
+
3017
+ if (!attr) {
3018
+ attr = this.ownerDocument.createAttribute(name); // otherwise create it
3019
+ }
3020
+
3021
+ var value = new String(value);
3022
+
3023
+ // test for exceptions
3024
+ if (this.ownerDocument.implementation.errorChecking) {
3025
+ // throw Exception if Attribute is readonly
3026
+ if (attr._readonly) {
3027
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3028
+ }
3029
+
3030
+ // throw Exception if the value string contains an illegal character
3031
+ if (!this.ownerDocument.implementation._isValidString(value)) {
3032
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
3033
+ }
3034
+ }
3035
+
3036
+ if (this.ownerDocument.implementation._isIdDeclaration(name)) {
3037
+ this.id = value; // cache ID for getElementById()
3038
+ }
3039
+
3040
+ // assign values to properties (and aliases)
3041
+ attr.value = value;
3042
+ attr.nodeValue = value;
3043
+
3044
+ // update .specified
3045
+ if (value.length > 0) {
3046
+ attr.specified = true;
3047
+ }
3048
+ else {
3049
+ attr.specified = false;
3050
+ }
3051
+
3052
+ // add/replace Attribute in NamedNodeMap
3053
+ this.attributes.setNamedItem(attr);
3054
+ };
3055
+
3056
+ /**
3057
+ * @method W3CDOMElement.removeAttribute - Removes an attribute by name
3058
+ *
3059
+ * @author Jon van Noort (jon@webarcana.com.au)
3060
+ *
3061
+ * @param name : string - The name of the attribute to remove
3062
+ *
3063
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
3064
+ */
3065
+ W3CDOMElement.prototype.removeAttribute = function W3CDOMElement_removeAttribute(name) {
3066
+ // delegate to W3CDOMNamedNodeMap.removeNamedItem
3067
+ return this.attributes.removeNamedItem(name);
3068
+ };
3069
+
3070
+ /**
3071
+ * @method W3CDOMElement.getAttributeNode - Retrieves an Attr node by name
3072
+ *
3073
+ * @author Jon van Noort (jon@webarcana.com.au)
3074
+ *
3075
+ * @param name : string - The name of the attribute to remove
3076
+ *
3077
+ * @return : W3CDOMAttr - The Attr node with the specified attribute name or null if there is no such attribute.
3078
+ */
3079
+ W3CDOMElement.prototype.getAttributeNode = function W3CDOMElement_getAttributeNode(name) {
3080
+ // delegate to W3CDOMNamedNodeMap.getNamedItem
3081
+ return this.attributes.getNamedItem(name);
3082
+ };
3083
+
3084
+ /**
3085
+ * @method W3CDOMElement.setAttributeNode - Adds a new attribute
3086
+ * If an attribute with that name is already present in the element, it is replaced by the new one
3087
+ *
3088
+ * @author Jon van Noort (jon@webarcana.com.au)
3089
+ *
3090
+ * @param newAttr : W3CDOMAttr - The attribute node to be attached
3091
+ *
3092
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
3093
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Element is readonly.
3094
+ * @throws : W3CDOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
3095
+ *
3096
+ * @return : W3CDOMAttr - If the newAttr attribute replaces an existing attribute with the same name,
3097
+ * the previously existing Attr node is returned, otherwise null is returned.
3098
+ */
3099
+ W3CDOMElement.prototype.setAttributeNode = function W3CDOMElement_setAttributeNode(newAttr) {
3100
+ // if this Attribute is an ID
3101
+ if (this.ownerDocument.implementation._isIdDeclaration(newAttr.name)) {
3102
+ this.id = newAttr.value; // cache ID for getElementById()
3103
+ }
3104
+
3105
+ // delegate to W3CDOMNamedNodeMap.setNamedItem
3106
+ return this.attributes.setNamedItem(newAttr);
3107
+ };
3108
+
3109
+ /**
3110
+ * @method W3CDOMElement.removeAttributeNode - Removes the specified attribute
3111
+ *
3112
+ * @author Jon van Noort (jon@webarcana.com.au)
3113
+ *
3114
+ * @param oldAttr : W3CDOMAttr - The Attr node to remove from the attribute list
3115
+ *
3116
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Element is readonly.
3117
+ * @throws : W3CDOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
3118
+ *
3119
+ * @return : W3CDOMAttr - The Attr node that was removed.
3120
+ */
3121
+ W3CDOMElement.prototype.removeAttributeNode = function W3CDOMElement_removeAttributeNode(oldAttr) {
3122
+ // throw Exception if Attribute is readonly
3123
+ if (this.ownerDocument.implementation.errorChecking && oldAttr._readonly) {
3124
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3125
+ }
3126
+
3127
+ // get item index
3128
+ var itemIndex = this.attributes._findItemIndex(oldAttr._id);
3129
+
3130
+ // throw Exception if node does not exist in this map
3131
+ if (this.ownerDocument.implementation.errorChecking && (itemIndex < 0)) {
3132
+ throw(new W3CDOMException(W3CDOMException.NOT_FOUND_ERR));
3133
+ }
3134
+
3135
+ return this.attributes._removeChild(itemIndex);
3136
+ };
3137
+
3138
+ /**
3139
+ * @method W3CDOMElement.getAttributeNS - Retrieves an attribute value by namespaceURI and localName
3140
+ *
3141
+ * @author Jon van Noort (jon@webarcana.com.au)
3142
+ *
3143
+ * @param namespaceURI : string - the namespace URI of the required node
3144
+ * @param localName : string - the local name of the required node
3145
+ *
3146
+ * @return : string - The Attr value as a string, or the empty string if that attribute does not have a specified value.
3147
+ */
3148
+ W3CDOMElement.prototype.getAttributeNS = function W3CDOMElement_getAttributeNS(namespaceURI, localName) {
3149
+ var ret = "";
3150
+
3151
+ // delegate to W3CDOMNAmedNodeMap.getNamedItemNS
3152
+ var attr = this.attributes.getNamedItemNS(namespaceURI, localName);
3153
+
3154
+
3155
+ if (attr) {
3156
+ ret = attr.value;
3157
+ }
3158
+
3159
+ return ret; // if Attribute exists, return its value, otherwise return ""
3160
+ };
3161
+
3162
+ /**
3163
+ * @method W3CDOMElement.setAttributeNS - Sets an attribute value by namespaceURI and localName
3164
+ *
3165
+ * @author Jon van Noort (jon@webarcana.com.au)
3166
+ *
3167
+ * @param namespaceURI : string - the namespace URI of the required node
3168
+ * @param qualifiedName : string - the qualified name of the required node
3169
+ * @param value : string - Value to set in string form
3170
+ *
3171
+ * @throws : W3CDOMException - INVALID_CHARACTER_ERR: Raised if the string contains an illegal character
3172
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
3173
+ * @throws : W3CDOMException - NAMESPACE_ERR: Raised if the Namespace is invalid
3174
+ */
3175
+ W3CDOMElement.prototype.setAttributeNS = function W3CDOMElement_setAttributeNS(namespaceURI, qualifiedName, value) {
3176
+ // call W3CDOMNamedNodeMap.getNamedItem
3177
+ var attr = this.attributes.getNamedItem(namespaceURI, qualifiedName);
3178
+
3179
+ if (!attr) { // if Attribute exists, use it
3180
+ // otherwise create it
3181
+ attr = this.ownerDocument.createAttributeNS(namespaceURI, qualifiedName);
3182
+ }
3183
+
3184
+ var value = new String(value);
3185
+
3186
+ // test for exceptions
3187
+ if (this.ownerDocument.implementation.errorChecking) {
3188
+ // throw Exception if Attribute is readonly
3189
+ if (attr._readonly) {
3190
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3191
+ }
3192
+
3193
+ // throw Exception if the Namespace is invalid
3194
+ if (!this.ownerDocument._isValidNamespace(namespaceURI, qualifiedName)) {
3195
+ throw(new W3CDOMException(W3CDOMException.NAMESPACE_ERR));
3196
+ }
3197
+
3198
+ // throw Exception if the value string contains an illegal character
3199
+ if (!this.ownerDocument.implementation._isValidString(value)) {
3200
+ throw(new W3CDOMException(W3CDOMException.INVALID_CHARACTER_ERR));
3201
+ }
3202
+ }
3203
+
3204
+ // if this Attribute is an ID
3205
+ if (this.ownerDocument.implementation._isIdDeclaration(name)) {
3206
+ this.id = value; // cache ID for getElementById()
3207
+ }
3208
+
3209
+ // assign values to properties (and aliases)
3210
+ attr.value = value;
3211
+ attr.nodeValue = value;
3212
+
3213
+ // update .specified
3214
+ if (value.length > 0) {
3215
+ attr.specified = true;
3216
+ }
3217
+ else {
3218
+ attr.specified = false;
3219
+ }
3220
+
3221
+ // delegate to W3CDOMNamedNodeMap.setNamedItem
3222
+ this.attributes.setNamedItemNS(attr);
3223
+ };
3224
+
3225
+ /**
3226
+ * @method W3CDOMElement.removeAttributeNS - Removes an attribute by namespaceURI and localName
3227
+ *
3228
+ * @author Jon van Noort (jon@webarcana.com.au)
3229
+ *
3230
+ * @param namespaceURI : string - the namespace URI of the required node
3231
+ * @param localName : string - the local name of the required node
3232
+ *
3233
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
3234
+ *
3235
+ * @return : W3CDOMAttr
3236
+ */
3237
+ W3CDOMElement.prototype.removeAttributeNS = function W3CDOMElement_removeAttributeNS(namespaceURI, localName) {
3238
+ // delegate to W3CDOMNamedNodeMap.removeNamedItemNS
3239
+ return this.attributes.removeNamedItemNS(namespaceURI, localName);
3240
+ };
3241
+
3242
+ /**
3243
+ * @method W3CDOMElement.getAttributeNodeNS - Retrieves an Attr node by namespaceURI and localName
3244
+ *
3245
+ * @author Jon van Noort (jon@webarcana.com.au)
3246
+ *
3247
+ * @param namespaceURI : string - the namespace URI of the required node
3248
+ * @param localName : string - the local name of the required node
3249
+ *
3250
+ * @return : W3CDOMAttr - The Attr node with the specified attribute name or null if there is no such attribute.
3251
+ */
3252
+ W3CDOMElement.prototype.getAttributeNodeNS = function W3CDOMElement_getAttributeNodeNS(namespaceURI, localName) {
3253
+ // delegate to W3CDOMNamedNodeMap.getNamedItemNS
3254
+ return this.attributes.getNamedItemNS(namespaceURI, localName);
3255
+ };
3256
+
3257
+ /**
3258
+ * @method W3CDOMElement.setAttributeNodeNS - Adds a new attribute
3259
+ * If an attribute with that name is already present in the element, it is replaced by the new one
3260
+ *
3261
+ * @author Jon van Noort (jon@webarcana.com.au)
3262
+ *
3263
+ * @param newAttr : W3CDOMAttr - the attribute node to be attached
3264
+ *
3265
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if the Attrbute is readonly.
3266
+ * @throws : W3CDOMException - WRONG_DOCUMENT_ERR: Raised if arg was created from a different document than the one that created this map.
3267
+ * @throws : W3CDOMException - INUSE_ATTRIBUTE_ERR: Raised if arg is an Attr that is already an attribute of another Element object.
3268
+ * The W3CDOM user must explicitly clone Attr nodes to re-use them in other elements.
3269
+ *
3270
+ * @return : W3CDOMAttr - If the newAttr attribute replaces an existing attribute with the same name,
3271
+ * the previously existing Attr node is returned, otherwise null is returned.
3272
+ */
3273
+ W3CDOMElement.prototype.setAttributeNodeNS = function W3CDOMElement_setAttributeNodeNS(newAttr) {
3274
+ // if this Attribute is an ID
3275
+ if ((newAttr.prefix == "") && this.ownerDocument.implementation._isIdDeclaration(newAttr.name)) {
3276
+ this.id = newAttr.value; // cache ID for getElementById()
3277
+ }
3278
+
3279
+ // delegate to W3CDOMNamedNodeMap.setNamedItemNS
3280
+ return this.attributes.setNamedItemNS(newAttr);
3281
+ };
3282
+
3283
+ /**
3284
+ * @method W3CDOMElement.hasAttribute - Returns true if specified node exists
3285
+ *
3286
+ * @author Jon van Noort (jon@webarcana.com.au)
3287
+ *
3288
+ * @param name : string - the name of the required node
3289
+ *
3290
+ * @return : boolean
3291
+ */
3292
+ W3CDOMElement.prototype.hasAttribute = function W3CDOMElement_hasAttribute(name) {
3293
+ // delegate to W3CDOMNamedNodeMap._hasAttribute
3294
+ return this.attributes._hasAttribute(name);
3295
+ }
3296
+
3297
+ /**
3298
+ * @method W3CDOMElement.hasAttributeNS - Returns true if specified node exists
3299
+ *
3300
+ * @author Jon van Noort (jon@webarcana.com.au)
3301
+ *
3302
+ * @param namespaceURI : string - the namespace URI of the required node
3303
+ * @param localName : string - the local name of the required node
3304
+ *
3305
+ * @return : boolean
3306
+ */
3307
+ W3CDOMElement.prototype.hasAttributeNS = function W3CDOMElement_hasAttributeNS(namespaceURI, localName) {
3308
+ // delegate to W3CDOMNamedNodeMap._hasAttributeNS
3309
+ return this.attributes._hasAttributeNS(namespaceURI, localName);
3310
+ }
3311
+
3312
+ /**
3313
+ * @method W3CDOMElement.toString - Serialize this Element and its children into an XML string
3314
+ *
3315
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
3316
+ *
3317
+ * @return : string
3318
+ */
3319
+ W3CDOMElement.prototype.toString = function W3CDOMElement_toString() {
3320
+ var ret = "";
3321
+
3322
+ // serialize namespace declarations
3323
+ var ns = this._namespaces.toString();
3324
+ if (ns.length > 0) ns = " "+ ns;
3325
+
3326
+ // serialize Attribute declarations
3327
+ var attrs = this.attributes.toString();
3328
+ if (attrs.length > 0) attrs = " "+ attrs;
3329
+
3330
+ // serialize this Element
3331
+ ret += "<" + this.nodeName + ns + attrs +">";
3332
+ ret += this.childNodes.toString();;
3333
+ ret += "</" + this.nodeName+">";
3334
+
3335
+ return ret;
3336
+ }
3337
+
3338
+ /**
3339
+ * @class W3CDOMAttr - The Attr interface represents an attribute in an Element object
3340
+ *
3341
+ * @extends W3CDOMNode
3342
+ *
3343
+ * @author Jon van Noort (jon@webarcana.com.au)
3344
+ *
3345
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3346
+ */
3347
+ W3CDOMAttr = function(ownerDocument) {
3348
+ this._class = addClass(this._class, "W3CDOMAttr");
3349
+ this.W3CDOMNode = W3CDOMNode;
3350
+ this.W3CDOMNode(ownerDocument);
3351
+
3352
+ this.name = ""; // the name of this attribute
3353
+
3354
+ // If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
3355
+ // Note that the implementation is in charge of this attribute, not the user.
3356
+ // If the user changes the value of the attribute (even if it ends up having the same value as the default value)
3357
+ // then the specified flag is automatically flipped to true
3358
+ // (I wish! You will need to use setValue to 'automatically' update specified)
3359
+ this.specified = false;
3360
+
3361
+ this.value = ""; // the value of the attribute is returned as a string
3362
+
3363
+ this.nodeType = W3CDOMNode.ATTRIBUTE_NODE;
3364
+
3365
+ this.ownerElement = null; // set when Attr is added to NamedNodeMap
3366
+
3367
+ // disable childNodes
3368
+ this.childNodes = null;
3369
+ this.attributes = null;
3370
+ };
3371
+ W3CDOMAttr.prototype = new W3CDOMNode;
3372
+
3373
+ /**
3374
+ * @method W3CDOMAttr.getName - Java style gettor for .name
3375
+ *
3376
+ * @author Jon van Noort (jon@webarcana.com.au)
3377
+ *
3378
+ * @return : string
3379
+ */
3380
+ W3CDOMAttr.prototype.getName = function W3CDOMAttr_getName() {
3381
+ return this.nodeName;
3382
+ };
3383
+
3384
+ /**
3385
+ * @method W3CDOMAttr.getSpecified - Java style gettor for .specified
3386
+ *
3387
+ * @author Jon van Noort (jon@webarcana.com.au)
3388
+ *
3389
+ * @return : boolean
3390
+ */
3391
+ W3CDOMAttr.prototype.getSpecified = function W3CDOMAttr_getSpecified() {
3392
+ return this.specified;
3393
+ };
3394
+
3395
+ /**
3396
+ * @method W3CDOMAttr.getValue - Java style gettor for .value
3397
+ *
3398
+ * @author Jon van Noort (jon@webarcana.com.au)
3399
+ *
3400
+ * @return : string
3401
+ */
3402
+ W3CDOMAttr.prototype.getValue = function W3CDOMAttr_getValue() {
3403
+ return this.nodeValue;
3404
+ };
3405
+
3406
+ /**
3407
+ * @method W3CDOMAttr.setValue - Java style settor for .value
3408
+ * alias for W3CDOMAttr.setNodeValue
3409
+ *
3410
+ * @author Jon van Noort (jon@webarcana.com.au)
3411
+ *
3412
+ * @param value : string - the new attribute value
3413
+ *
3414
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
3415
+ */
3416
+ W3CDOMAttr.prototype.setValue = function W3CDOMAttr_setValue(value) {
3417
+ // throw Exception if Attribute is readonly
3418
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3419
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3420
+ }
3421
+
3422
+ // delegate to setNodeValue
3423
+ this.setNodeValue(value);
3424
+ };
3425
+
3426
+ /**
3427
+ * @method W3CDOMAttr.setNodeValue - Java style settor for .nodeValue
3428
+ *
3429
+ * @author Jon van Noort (jon@webarcana.com.au)
3430
+ *
3431
+ * @param value : string - the new attribute value
3432
+ */
3433
+ W3CDOMAttr.prototype.setNodeValue = function W3CDOMAttr_setNodeValue(value) {
3434
+ this.nodeValue = new String(value);
3435
+ this.value = this.nodeValue;
3436
+ this.specified = (this.value.length > 0);
3437
+ };
3438
+
3439
+ /**
3440
+ * @method W3CDOMAttr.toString - Serialize this Attr into an XML string
3441
+ *
3442
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
3443
+ *
3444
+ * @return : string
3445
+ */
3446
+ W3CDOMAttr.prototype.toString = function W3CDOMAttr_toString() {
3447
+ var ret = "";
3448
+
3449
+ // serialize Attribute
3450
+ ret += this.nodeName +"=\""+ this.__escapeString(this.nodeValue) +"\"";
3451
+
3452
+ return ret;
3453
+ }
3454
+
3455
+ W3CDOMAttr.prototype.getOwnerElement = function() {
3456
+
3457
+ return this.ownerElement;
3458
+
3459
+ }
3460
+
3461
+ /**
3462
+ * @class W3CDOMNamespace - The Namespace interface represents an namespace in an Element object
3463
+ *
3464
+ * @extends W3CDOMNode
3465
+ *
3466
+ * @author Jon van Noort (jon@webarcana.com.au)
3467
+ *
3468
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3469
+ */
3470
+ W3CDOMNamespace = function(ownerDocument) {
3471
+ this._class = addClass(this._class, "W3CDOMNamespace");
3472
+ this.W3CDOMNode = W3CDOMNode;
3473
+ this.W3CDOMNode(ownerDocument);
3474
+
3475
+ this.name = ""; // the name of this attribute
3476
+
3477
+ // If this attribute was explicitly given a value in the original document, this is true; otherwise, it is false.
3478
+ // Note that the implementation is in charge of this attribute, not the user.
3479
+ // If the user changes the value of the attribute (even if it ends up having the same value as the default value)
3480
+ // then the specified flag is automatically flipped to true
3481
+ // (I wish! You will need to use _setValue to 'automatically' update specified)
3482
+ this.specified = false;
3483
+
3484
+ this.value = ""; // the value of the attribute is returned as a string
3485
+
3486
+ this.nodeType = W3CDOMNode.NAMESPACE_NODE;
3487
+ };
3488
+ W3CDOMNamespace.prototype = new W3CDOMNode;
3489
+
3490
+ /**
3491
+ * @method W3CDOMNamespace.getValue - Java style gettor for .value
3492
+ *
3493
+ * @author Jon van Noort (jon@webarcana.com.au)
3494
+ *
3495
+ * @return : string
3496
+ */
3497
+ W3CDOMNamespace.prototype.getValue = function W3CDOMNamespace_getValue() {
3498
+ return this.nodeValue;
3499
+ };
3500
+
3501
+ /**
3502
+ * @method W3CDOMNamespace.setValue - utility function to set value (rather than direct assignment to .value)
3503
+ *
3504
+ * @author Jon van Noort (jon@webarcana.com.au)
3505
+ *
3506
+ * @param value : string - the new namespace value
3507
+ */
3508
+ W3CDOMNamespace.prototype.setValue = function W3CDOMNamespace_setValue(value) {
3509
+ // assign values to properties (and aliases)
3510
+ this.nodeValue = new String(value);
3511
+ this.value = this.nodeValue;
3512
+ };
3513
+
3514
+ /**
3515
+ * @method W3CDOMNamespace.toString - Serialize this Attr into an XML string
3516
+ *
3517
+ * @author Jon van Noort (jon@webarcana.com.au)
3518
+ *
3519
+ * @return : string
3520
+ */
3521
+ W3CDOMNamespace.prototype.toString = function W3CDOMNamespace_toString() {
3522
+ var ret = "";
3523
+
3524
+ // serialize Namespace Declaration
3525
+ if (this.nodeName != "") {
3526
+ ret += this.nodeName +"=\""+ this.__escapeString(this.nodeValue) +"\"";
3527
+ }
3528
+ else { // handle default namespace
3529
+ ret += "xmlns=\""+ this.__escapeString(this.nodeValue) +"\"";
3530
+ }
3531
+
3532
+ return ret;
3533
+ }
3534
+
3535
+ /**
3536
+ * @class W3CDOMCharacterData - parent abstract class for W3CDOMText and W3CDOMComment
3537
+ *
3538
+ * @extends W3CDOMNode
3539
+ *
3540
+ * @author Jon van Noort (jon@webarcana.com.au)
3541
+ *
3542
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3543
+ */
3544
+ W3CDOMCharacterData = function(ownerDocument) {
3545
+ this._class = addClass(this._class, "W3CDOMCharacterData");
3546
+ this.W3CDOMNode = W3CDOMNode;
3547
+ this.W3CDOMNode(ownerDocument);
3548
+
3549
+ this.data = "";
3550
+ this.length = 0;
3551
+ };
3552
+ W3CDOMCharacterData.prototype = new W3CDOMNode;
3553
+
3554
+ /**
3555
+ * @method W3CDOMCharacterData.getData - Java style gettor for .data
3556
+ *
3557
+ * @author Jon van Noort (jon@webarcana.com.au)
3558
+ *
3559
+ * @return : string
3560
+ */
3561
+ W3CDOMCharacterData.prototype.getData = function W3CDOMCharacterData_getData() {
3562
+ return this.nodeValue;
3563
+ };
3564
+
3565
+ /**
3566
+ * @method W3CDOMCharacterData.setData - Java style settor for .data
3567
+ * alias for W3CDOMCharacterData.setNodeValue
3568
+ *
3569
+ * @author Jon van Noort (jon@webarcana.com.au)
3570
+ *
3571
+ * @param data : string - the character data
3572
+ *
3573
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
3574
+ */
3575
+ W3CDOMCharacterData.prototype.setData = function W3CDOMCharacterData_setData(data) {
3576
+ // delegate to setNodeValue
3577
+ this.setNodeValue(data);
3578
+ };
3579
+
3580
+ /**
3581
+ * @method W3CDOMCharacterData.setNodeValue - Java style settor for .nodeValue
3582
+ *
3583
+ * @author Jon van Noort (jon@webarcana.com.au)
3584
+ *
3585
+ * @param data : string - the node value
3586
+ *
3587
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Attribute is readonly.
3588
+ */
3589
+ W3CDOMCharacterData.prototype.setNodeValue = function W3CDOMCharacterData_setNodeValue(data) {
3590
+ // throw Exception if Attribute is readonly
3591
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3592
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3593
+ }
3594
+
3595
+ // assign values to properties (and aliases)
3596
+ this.nodeValue = new String(data);
3597
+ this.data = this.nodeValue;
3598
+
3599
+ // update length
3600
+ this.length = this.nodeValue.length;
3601
+ };
3602
+
3603
+ /**
3604
+ * @method W3CDOMCharacterData.getLength - Java style gettor for .length
3605
+ *
3606
+ * @author Jon van Noort (jon@webarcana.com.au)
3607
+ *
3608
+ * @return : string
3609
+ */
3610
+ W3CDOMCharacterData.prototype.getLength = function W3CDOMCharacterData_getLength() {
3611
+ return this.nodeValue.length;
3612
+ };
3613
+
3614
+ /**
3615
+ * @method W3CDOMCharacterData.substringData - Extracts a range of data from the node
3616
+ *
3617
+ * @author Jon van Noort (jon@webarcana.com.au)
3618
+ *
3619
+ * @param offset : int - Start offset of substring to extract
3620
+ * @param count : int - The number of characters to extract
3621
+ *
3622
+ * @throws : W3CDOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
3623
+ *
3624
+ * @return : string - The specified substring.
3625
+ * If the sum of offset and count exceeds the length, then all characters to the end of the data are returned.
3626
+ */
3627
+ W3CDOMCharacterData.prototype.substringData = function W3CDOMCharacterData_substringData(offset, count) {
3628
+ var ret = null;
3629
+
3630
+ if (this.data) {
3631
+ // throw Exception if offset is negative or greater than the data length,
3632
+ // or the count is negative
3633
+ if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
3634
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3635
+ }
3636
+
3637
+ // if count is not specified
3638
+ if (!count) {
3639
+ ret = this.data.substring(offset); // default to 'end of string'
3640
+ }
3641
+ else {
3642
+ ret = this.data.substring(offset, offset + count);
3643
+ }
3644
+ }
3645
+
3646
+ return ret;
3647
+ };
3648
+
3649
+ /**
3650
+ * @method W3CDOMCharacterData.appendData - Append the string to the end of the character data of the node.
3651
+ * Upon success, data provides access to the concatenation of data and the W3CDOMString specified.
3652
+ *
3653
+ * @author Jon van Noort (jon@webarcana.com.au)
3654
+ *
3655
+ * @param arg : string - The string to append
3656
+ *
3657
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
3658
+ */
3659
+ W3CDOMCharacterData.prototype.appendData = function W3CDOMCharacterData_appendData(arg) {
3660
+ // throw Exception if W3CDOMCharacterData is readonly
3661
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3662
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3663
+ }
3664
+
3665
+ // append data
3666
+ this.setData(""+ this.data + arg);
3667
+ };
3668
+
3669
+ /**
3670
+ * @method W3CDOMCharacterData.insertData - Insert a string at the specified character offset.
3671
+ *
3672
+ * @author Jon van Noort (jon@webarcana.com.au)
3673
+ *
3674
+ * @param offset : int - The character offset at which to insert
3675
+ * @param arg : string - The string to insert
3676
+ *
3677
+ * @throws : W3CDOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
3678
+ * or if the specified count is negative.
3679
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
3680
+ */
3681
+ W3CDOMCharacterData.prototype.insertData = function W3CDOMCharacterData_insertData(offset, arg) {
3682
+ // throw Exception if W3CDOMCharacterData is readonly
3683
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3684
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3685
+ }
3686
+
3687
+ if (this.data) {
3688
+ // throw Exception if offset is negative or greater than the data length,
3689
+ if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length))) {
3690
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3691
+ }
3692
+
3693
+ // insert data
3694
+ this.setData(this.data.substring(0, offset).concat(arg, this.data.substring(offset)));
3695
+ }
3696
+ else {
3697
+ // throw Exception if offset is negative or greater than the data length,
3698
+ if (this.ownerDocument.implementation.errorChecking && (offset != 0)) {
3699
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3700
+ }
3701
+
3702
+ // set data
3703
+ this.setData(arg);
3704
+ }
3705
+ };
3706
+
3707
+ /**
3708
+ * @method W3CDOMCharacterData.deleteData - Remove a range of characters from the node.
3709
+ * Upon success, data and length reflect the change
3710
+ *
3711
+ * @author Jon van Noort (jon@webarcana.com.au)
3712
+ *
3713
+ * @param offset : int - The offset from which to remove characters
3714
+ * @param count : int - The number of characters to delete.
3715
+ * If the sum of offset and count exceeds length then all characters from offset to the end of the data are deleted
3716
+ *
3717
+ * @throws : W3CDOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
3718
+ * or if the specified count is negative.
3719
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
3720
+ */
3721
+ W3CDOMCharacterData.prototype.deleteData = function W3CDOMCharacterData_deleteData(offset, count) {
3722
+ // throw Exception if W3CDOMCharacterData is readonly
3723
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3724
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3725
+ }
3726
+
3727
+ if (this.data) {
3728
+ // throw Exception if offset is negative or greater than the data length,
3729
+ if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
3730
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3731
+ }
3732
+
3733
+ // delete data
3734
+ if(!count || (offset + count) > this.data.length) {
3735
+ this.setData(this.data.substring(0, offset));
3736
+ }
3737
+ else {
3738
+ this.setData(this.data.substring(0, offset).concat(this.data.substring(offset + count)));
3739
+ }
3740
+ }
3741
+ };
3742
+
3743
+ /**
3744
+ * @method W3CDOMCharacterData.replaceData - Replace the characters starting at the specified character offset with the specified string
3745
+ *
3746
+ * @author Jon van Noort (jon@webarcana.com.au)
3747
+ *
3748
+ * @param offset : int - The offset from which to start replacing
3749
+ * @param count : int - The number of characters to replace.
3750
+ * If the sum of offset and count exceeds length, then all characters to the end of the data are replaced
3751
+ * @param arg : string - The string with which the range must be replaced
3752
+ *
3753
+ * @throws : W3CDOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
3754
+ * or if the specified count is negative.
3755
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this CharacterData is readonly.
3756
+ */
3757
+ W3CDOMCharacterData.prototype.replaceData = function W3CDOMCharacterData_replaceData(offset, count, arg) {
3758
+ // throw Exception if W3CDOMCharacterData is readonly
3759
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
3760
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3761
+ }
3762
+
3763
+ if (this.data) {
3764
+ // throw Exception if offset is negative or greater than the data length,
3765
+ if (this.ownerDocument.implementation.errorChecking && ((offset < 0) || (offset > this.data.length) || (count < 0))) {
3766
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3767
+ }
3768
+
3769
+ // replace data
3770
+ this.setData(this.data.substring(0, offset).concat(arg, this.data.substring(offset + count)));
3771
+ }
3772
+ else {
3773
+ // set data
3774
+ this.setData(arg);
3775
+ }
3776
+ };
3777
+
3778
+ /**
3779
+ * @class W3CDOMText - The Text interface represents the textual content (termed character data in XML) of an Element or Attr.
3780
+ * If there is no markup inside an element's content, the text is contained in a single object implementing the Text interface
3781
+ * that is the only child of the element. If there is markup, it is parsed into a list of elements and Text nodes that form the
3782
+ * list of children of the element.
3783
+ *
3784
+ * @extends W3CDOMCharacterData
3785
+ *
3786
+ * @author Jon van Noort (jon@webarcana.com.au)
3787
+ *
3788
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3789
+ */
3790
+ W3CDOMText = function(ownerDocument) {
3791
+ this._class = addClass(this._class, "W3CDOMText");
3792
+ this.W3CDOMCharacterData = W3CDOMCharacterData;
3793
+ this.W3CDOMCharacterData(ownerDocument);
3794
+
3795
+ this.nodeName = "#text";
3796
+ this.nodeType = W3CDOMNode.TEXT_NODE;
3797
+ };
3798
+ W3CDOMText.prototype = new W3CDOMCharacterData;
3799
+
3800
+ /**
3801
+ * @method W3CDOMText.splitText - Breaks this Text node into two Text nodes at the specified offset,
3802
+ * keeping both in the tree as siblings. This node then only contains all the content up to the offset point.
3803
+ * And a new Text node, which is inserted as the next sibling of this node, contains all the content at and after the offset point.
3804
+ *
3805
+ * @author Jon van Noort (jon@webarcana.com.au)
3806
+ *
3807
+ * @param offset : int - The offset at which to split, starting from 0.
3808
+ *
3809
+ * @throws : W3CDOMException - INDEX_SIZE_ERR: Raised if specified offset is negative or greater than the number of 16-bit units in data,
3810
+ * @throws : W3CDOMException - NO_MODIFICATION_ALLOWED_ERR: Raised if this Text is readonly.
3811
+ *
3812
+ * @return : W3CDOMText - The new Text node
3813
+ */
3814
+ W3CDOMText.prototype.splitText = function W3CDOMText_splitText(offset) {
3815
+ var data, inode;
3816
+
3817
+ // test for exceptions
3818
+ if (this.ownerDocument.implementation.errorChecking) {
3819
+ // throw Exception if Node is readonly
3820
+ if (this._readonly) {
3821
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3822
+ }
3823
+
3824
+ // throw Exception if offset is negative or greater than the data length,
3825
+ if ((offset < 0) || (offset > this.data.length)) {
3826
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3827
+ }
3828
+ }
3829
+
3830
+ if (this.parentNode) {
3831
+ // get remaining string (after offset)
3832
+ data = this.substringData(offset);
3833
+
3834
+ // create new TextNode with remaining string
3835
+ inode = this.ownerDocument.createTextNode(data);
3836
+
3837
+ // attach new TextNode
3838
+ if (this.nextSibling) {
3839
+ this.parentNode.insertBefore(inode, this.nextSibling);
3840
+ }
3841
+ else {
3842
+ this.parentNode.appendChild(inode);
3843
+ }
3844
+
3845
+ // remove remaining string from original TextNode
3846
+ this.deleteData(offset);
3847
+ }
3848
+
3849
+ return inode;
3850
+ };
3851
+
3852
+ /**
3853
+ * @method W3CDOMText.toString - Serialize this Text into an XML string
3854
+ *
3855
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
3856
+ *
3857
+ * @return : string
3858
+ */
3859
+ W3CDOMText.prototype.toString = function W3CDOMText_toString() {
3860
+ return this.__escapeString(""+ this.nodeValue);
3861
+ }
3862
+
3863
+ /**
3864
+ * @class W3CDOMCDATASection - CDATA sections are used to escape blocks of text containing characters that would otherwise be regarded as markup.
3865
+ * The only delimiter that is recognized in a CDATA section is the "\]\]\>" string that ends the CDATA section
3866
+ *
3867
+ * @extends W3CDOMCharacterData
3868
+ *
3869
+ * @author Jon van Noort (jon@webarcana.com.au)
3870
+ *
3871
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3872
+ */
3873
+ W3CDOMCDATASection = function(ownerDocument) {
3874
+ this._class = addClass(this._class, "W3CDOMCDATASection");
3875
+ this.W3CDOMCharacterData = W3CDOMCharacterData;
3876
+ this.W3CDOMCharacterData(ownerDocument);
3877
+
3878
+ this.nodeName = "#cdata-section";
3879
+ this.nodeType = W3CDOMNode.CDATA_SECTION_NODE;
3880
+ };
3881
+ W3CDOMCDATASection.prototype = new W3CDOMCharacterData;
3882
+
3883
+ /**
3884
+ * @method W3CDOMCDATASection.splitText - Breaks this CDATASection node into two CDATASection nodes at the specified offset,
3885
+ * keeping both in the tree as siblings. This node then only contains all the content up to the offset point.
3886
+ * And a new CDATASection node, which is inserted as the next sibling of this node, contains all the content at and after the offset point.
3887
+ *
3888
+ * @author Jon van Noort (jon@webarcana.com.au)
3889
+ *
3890
+ * @param offset : int - The offset at which to split, starting from 0.
3891
+ *
3892
+ * @return : W3CDOMCDATASection - The new CDATASection node
3893
+ */
3894
+ W3CDOMCDATASection.prototype.splitText = function W3CDOMCDATASection_splitText(offset) {
3895
+ var data, inode;
3896
+
3897
+ // test for exceptions
3898
+ if (this.ownerDocument.implementation.errorChecking) {
3899
+ // throw Exception if Node is readonly
3900
+ if (this._readonly) {
3901
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
3902
+ }
3903
+
3904
+ // throw Exception if offset is negative or greater than the data length,
3905
+ if ((offset < 0) || (offset > this.data.length)) {
3906
+ throw(new W3CDOMException(W3CDOMException.INDEX_SIZE_ERR));
3907
+ }
3908
+ }
3909
+
3910
+ if(this.parentNode) {
3911
+ // get remaining string (after offset)
3912
+ data = this.substringData(offset);
3913
+
3914
+ // create new CDATANode with remaining string
3915
+ inode = this.ownerDocument.createCDATASection(data);
3916
+
3917
+ // attach new CDATANode
3918
+ if (this.nextSibling) {
3919
+ this.parentNode.insertBefore(inode, this.nextSibling);
3920
+ }
3921
+ else {
3922
+ this.parentNode.appendChild(inode);
3923
+ }
3924
+
3925
+ // remove remaining string from original CDATANode
3926
+ this.deleteData(offset);
3927
+ }
3928
+
3929
+ return inode;
3930
+ };
3931
+
3932
+ /**
3933
+ * @method W3CDOMCDATASection.toString - Serialize this CDATASection into an XML string
3934
+ *
3935
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
3936
+ *
3937
+ * @return : string
3938
+ */
3939
+ W3CDOMCDATASection.prototype.toString = function W3CDOMCDATASection_toString() {
3940
+ var ret = "";
3941
+ //do NOT unescape the nodeValue string in CDATA sections!
3942
+ ret += "<![CDATA[" + this.nodeValue + "\]\]\>";
3943
+
3944
+ return ret;
3945
+ }
3946
+
3947
+ /**
3948
+ * @class W3CDOMComment - This represents the content of a comment, i.e., all the characters between the starting '<!--' and ending '-->'
3949
+ *
3950
+ * @extends W3CDOMCharacterData
3951
+ *
3952
+ * @author Jon van Noort (jon@webarcana.com.au)
3953
+ *
3954
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3955
+ */
3956
+ W3CDOMComment = function(ownerDocument) {
3957
+ this._class = addClass(this._class, "W3CDOMComment");
3958
+ this.W3CDOMCharacterData = W3CDOMCharacterData;
3959
+ this.W3CDOMCharacterData(ownerDocument);
3960
+
3961
+ this.nodeName = "#comment";
3962
+ this.nodeType = W3CDOMNode.COMMENT_NODE;
3963
+ };
3964
+ W3CDOMComment.prototype = new W3CDOMCharacterData;
3965
+
3966
+ /**
3967
+ * @method W3CDOMComment.toString - Serialize this Comment into an XML string
3968
+ *
3969
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
3970
+ *
3971
+ * @return : string
3972
+ */
3973
+ W3CDOMComment.prototype.toString = function W3CDOMComment_toString() {
3974
+ var ret = "";
3975
+
3976
+ ret += "<!--" + this.nodeValue + "-->";
3977
+
3978
+ return ret;
3979
+ }
3980
+
3981
+ /**
3982
+ * @class W3CDOMProcessingInstruction - The ProcessingInstruction interface represents a "processing instruction",
3983
+ * used in XML as a way to keep processor-specific information in the text of the document
3984
+ *
3985
+ * @extends W3CDOMNode
3986
+ *
3987
+ * @author Jon van Noort (jon@webarcana.com.au)
3988
+ *
3989
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
3990
+ */
3991
+ W3CDOMProcessingInstruction = function(ownerDocument) {
3992
+ this._class = addClass(this._class, "W3CDOMProcessingInstruction");
3993
+ this.W3CDOMNode = W3CDOMNode;
3994
+ this.W3CDOMNode(ownerDocument);
3995
+
3996
+ // The target of this processing instruction.
3997
+ // XML defines this as being the first token following the markup that begins the processing instruction.
3998
+ this.target = "";
3999
+
4000
+ // The content of this processing instruction.
4001
+ // This is from the first non white space character after the target to the character immediately preceding the ?>
4002
+ this.data = "";
4003
+
4004
+ this.nodeType = W3CDOMNode.PROCESSING_INSTRUCTION_NODE;
4005
+ };
4006
+ W3CDOMProcessingInstruction.prototype = new W3CDOMNode;
4007
+
4008
+ /**
4009
+ * @method W3CDOMProcessingInstruction.getTarget - Java style gettor for .target
4010
+ *
4011
+ * @author Jon van Noort (jon@webarcana.com.au)
4012
+ *
4013
+ * @return : string
4014
+ */
4015
+ W3CDOMProcessingInstruction.prototype.getTarget = function W3CDOMProcessingInstruction_getTarget() {
4016
+ return this.nodeName;
4017
+ };
4018
+
4019
+ /**
4020
+ * @method W3CDOMProcessingInstruction.getData - Java style gettor for .data
4021
+ *
4022
+ * @author Jon van Noort (jon@webarcana.com.au)
4023
+ *
4024
+ * @return : string
4025
+ */
4026
+ W3CDOMProcessingInstruction.prototype.getData = function W3CDOMProcessingInstruction_getData() {
4027
+ return this.nodeValue;
4028
+ };
4029
+
4030
+ /**
4031
+ * @method W3CDOMProcessingInstruction.setData - Java style settor for .data
4032
+ * alias for W3CDOMProcessingInstruction.setNodeValue
4033
+ *
4034
+ * @author Jon van Noort (jon@webarcana.com.au)
4035
+ *
4036
+ * @param data : string - The new data of this processing instruction.
4037
+ */
4038
+ W3CDOMProcessingInstruction.prototype.setData = function W3CDOMProcessingInstruction_setData(data) {
4039
+ // delegate to setNodeValue
4040
+ this.setNodeValue(data);
4041
+ };
4042
+
4043
+ /**
4044
+ * @method W3CDOMProcessingInstruction.setNodeValue - Java style settor for .nodeValue
4045
+ *
4046
+ * @author Jon van Noort (jon@webarcana.com.au)
4047
+ *
4048
+ * @param data : string - The new data of this processing instruction.
4049
+ */
4050
+ W3CDOMProcessingInstruction.prototype.setNodeValue = function W3CDOMProcessingInstruction_setNodeValue(data) {
4051
+ // throw Exception if W3CDOMNode is readonly
4052
+ if (this.ownerDocument.implementation.errorChecking && this._readonly) {
4053
+ throw(new W3CDOMException(W3CDOMException.NO_MODIFICATION_ALLOWED_ERR));
4054
+ }
4055
+
4056
+ // assign values to properties (and aliases)
4057
+ this.nodeValue = new String(data);
4058
+ this.data = this.nodeValue;
4059
+ };
4060
+
4061
+ /**
4062
+ * @method W3CDOMProcessingInstruction.toString - Serialize this ProcessingInstruction into an XML string
4063
+ *
4064
+ * @author Jon van Noort (jon@webarcana.com.au) and David Joham (djoham@yahoo.com)
4065
+ *
4066
+ * @return : string
4067
+ */
4068
+ W3CDOMProcessingInstruction.prototype.toString = function W3CDOMProcessingInstruction_toString() {
4069
+ var ret = "";
4070
+
4071
+ ret += "<?" + this.nodeName +" "+ this.nodeValue + " ?>";
4072
+
4073
+ return ret;
4074
+ }
4075
+
4076
+ /**
4077
+ * @class W3CDOMDocumentFragment - DocumentFragment is a "lightweight" or "minimal" Document object.
4078
+ *
4079
+ * @extends W3CDOMNode
4080
+ *
4081
+ * @author Jon van Noort (jon@webarcana.com.au)
4082
+ *
4083
+ * @param ownerDocument : W3CDOMDocument - The Document object associated with this node.
4084
+ */
4085
+ W3CDOMDocumentFragment = function(ownerDocument) {
4086
+ this._class = addClass(this._class, "W3CDOMDocumentFragment");
4087
+ this.W3CDOMNode = W3CDOMNode;
4088
+ this.W3CDOMNode(ownerDocument);
4089
+
4090
+ this.nodeName = "#document-fragment";
4091
+ this.nodeType = W3CDOMNode.DOCUMENT_FRAGMENT_NODE;
4092
+ };
4093
+ W3CDOMDocumentFragment.prototype = new W3CDOMNode;
4094
+
4095
+ /**
4096
+ * @method W3CDOMDocumentFragment.toString - Serialize this DocumentFragment into an XML string
4097
+ *
4098
+ * @author David Joham (djoham@yahoo.com)
4099
+ *
4100
+ * @return : string
4101
+ */
4102
+ W3CDOMDocumentFragment.prototype.toString = function W3CDOMDocumentFragment_toString() {
4103
+ var xml = "";
4104
+ var intCount = this.getChildNodes().getLength();
4105
+
4106
+ // create string concatenating the serialized ChildNodes
4107
+ for (intLoop = 0; intLoop < intCount; intLoop++) {
4108
+ xml += this.getChildNodes().item(intLoop).toString();
4109
+ }
4110
+
4111
+ return xml;
4112
+ }
4113
+
4114
+ ///////////////////////
4115
+ // NOT IMPLEMENTED //
4116
+ ///////////////////////
4117
+ W3CDOMDocumentType = function() { alert("W3CDOMDocumentType.constructor(): Not Implemented" ); };
4118
+ W3CDOMEntity = function() { alert("W3CDOMEntity.constructor(): Not Implemented" ); };
4119
+ W3CDOMEntityReference = function() { alert("W3CDOMEntityReference.constructor(): Not Implemented"); };
4120
+ W3CDOMNotation = function() { alert("W3CDOMNotation.constructor(): Not Implemented" ); };
4121
+
4122
+
4123
+ Strings = new Object()
4124
+ Strings.WHITESPACE = " \t\n\r";
4125
+ Strings.QUOTES = "\"'";
4126
+
4127
+ Strings.isEmpty = function Strings_isEmpty(strD) {
4128
+ return (strD == null) || (strD.length == 0);
4129
+ };
4130
+ Strings.indexOfNonWhitespace = function Strings_indexOfNonWhitespace(strD, iB, iE) {
4131
+ if(Strings.isEmpty(strD)) return -1;
4132
+ iB = iB || 0;
4133
+ iE = iE || strD.length;
4134
+
4135
+ for(var i = iB; i < iE; i++)
4136
+ if(Strings.WHITESPACE.indexOf(strD.charAt(i)) == -1) {
4137
+ return i;
4138
+ }
4139
+ return -1;
4140
+ };
4141
+ Strings.lastIndexOfNonWhitespace = function Strings_lastIndexOfNonWhitespace(strD, iB, iE) {
4142
+ if(Strings.isEmpty(strD)) return -1;
4143
+ iB = iB || 0;
4144
+ iE = iE || strD.length;
4145
+
4146
+ for(var i = iE - 1; i >= iB; i--)
4147
+ if(Strings.WHITESPACE.indexOf(strD.charAt(i)) == -1)
4148
+ return i;
4149
+ return -1;
4150
+ };
4151
+ Strings.indexOfWhitespace = function Strings_indexOfWhitespace(strD, iB, iE) {
4152
+ if(Strings.isEmpty(strD)) return -1;
4153
+ iB = iB || 0;
4154
+ iE = iE || strD.length;
4155
+
4156
+ for(var i = iB; i < iE; i++)
4157
+ if(Strings.WHITESPACE.indexOf(strD.charAt(i)) != -1)
4158
+ return i;
4159
+ return -1;
4160
+ };
4161
+ Strings.replace = function Strings_replace(strD, iB, iE, strF, strR) {
4162
+ if(Strings.isEmpty(strD)) return "";
4163
+ iB = iB || 0;
4164
+ iE = iE || strD.length;
4165
+
4166
+ return strD.substring(iB, iE).split(strF).join(strR);
4167
+ };
4168
+ Strings.getLineNumber = function Strings_getLineNumber(strD, iP) {
4169
+ if(Strings.isEmpty(strD)) return -1;
4170
+ iP = iP || strD.length;
4171
+
4172
+ return strD.substring(0, iP).split("\n").length
4173
+ };
4174
+ Strings.getColumnNumber = function Strings_getColumnNumber(strD, iP) {
4175
+ if(Strings.isEmpty(strD)) return -1;
4176
+ iP = iP || strD.length;
4177
+
4178
+ var arrD = strD.substring(0, iP).split("\n");
4179
+ var strLine = arrD[arrD.length - 1];
4180
+ arrD.length--;
4181
+ var iLinePos = arrD.join("\n").length;
4182
+
4183
+ return iP - iLinePos;
4184
+ };
4185
+
4186
+
4187
+ StringBuffer = function() {this._a=new Array();};
4188
+ StringBuffer.prototype.append = function StringBuffer_append(d){this._a[this._a.length]=d;};
4189
+ StringBuffer.prototype.toString = function StringBuffer_toString(){return this._a.join("");};