rhack 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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
+ };