rhack 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. data/.gemtest +0 -0
  2. data/CURB-LICENSE +51 -0
  3. data/Gemfile +4 -0
  4. data/History.txt +4 -0
  5. data/LICENSE +51 -0
  6. data/License.txt +17 -0
  7. data/Manifest.txt +61 -0
  8. data/README.txt +12 -0
  9. data/Rakefile +34 -0
  10. data/ext/curb-original/curb.c +977 -0
  11. data/ext/curb-original/curb.h +52 -0
  12. data/ext/curb-original/curb_config.h +235 -0
  13. data/ext/curb-original/curb_easy.c +3455 -0
  14. data/ext/curb-original/curb_easy.h +90 -0
  15. data/ext/curb-original/curb_errors.c +647 -0
  16. data/ext/curb-original/curb_errors.h +129 -0
  17. data/ext/curb-original/curb_macros.h +159 -0
  18. data/ext/curb-original/curb_multi.c +704 -0
  19. data/ext/curb-original/curb_multi.h +26 -0
  20. data/ext/curb-original/curb_postfield.c +523 -0
  21. data/ext/curb-original/curb_postfield.h +40 -0
  22. data/ext/curb-original/curb_upload.c +80 -0
  23. data/ext/curb-original/curb_upload.h +30 -0
  24. data/ext/curb/Makefile +157 -0
  25. data/ext/curb/curb.c +977 -0
  26. data/ext/curb/curb.h +52 -0
  27. data/ext/curb/curb_config.h +235 -0
  28. data/ext/curb/curb_easy.c +3430 -0
  29. data/ext/curb/curb_easy.h +94 -0
  30. data/ext/curb/curb_errors.c +647 -0
  31. data/ext/curb/curb_errors.h +129 -0
  32. data/ext/curb/curb_macros.h +159 -0
  33. data/ext/curb/curb_multi.c +710 -0
  34. data/ext/curb/curb_multi.h +26 -0
  35. data/ext/curb/curb_postfield.c +523 -0
  36. data/ext/curb/curb_postfield.h +40 -0
  37. data/ext/curb/curb_upload.c +80 -0
  38. data/ext/curb/curb_upload.h +30 -0
  39. data/ext/curb/extconf.rb +399 -0
  40. data/lib/cache.rb +44 -0
  41. data/lib/curl-global.rb +151 -0
  42. data/lib/extensions/browser/env.js +697 -0
  43. data/lib/extensions/browser/jquery.js +7180 -0
  44. data/lib/extensions/browser/xmlsax.js +1564 -0
  45. data/lib/extensions/browser/xmlw3cdom_1.js +1444 -0
  46. data/lib/extensions/browser/xmlw3cdom_2.js +2744 -0
  47. data/lib/extensions/curb.rb +125 -0
  48. data/lib/extensions/declarative.rb +153 -0
  49. data/lib/extensions/johnson.rb +63 -0
  50. data/lib/frame.rb +766 -0
  51. data/lib/init.rb +36 -0
  52. data/lib/rhack.rb +16 -0
  53. data/lib/rhack.yml.template +19 -0
  54. data/lib/rhack/proxy/checker.rb +226 -0
  55. data/lib/rhack/proxy/list.rb +196 -0
  56. data/lib/rhack/services.rb +445 -0
  57. data/lib/rhack_in.rb +2 -0
  58. data/lib/scout.rb +591 -0
  59. data/lib/words.rb +37 -0
  60. data/test/test_frame.rb +107 -0
  61. data/test/test_rhack.rb +5 -0
  62. data/test/test_scout.rb +53 -0
  63. metadata +195 -0
@@ -0,0 +1,1444 @@
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
+ };