rhack 1.2.1 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +13 -5
  2. data/README.md +21 -9
  3. data/ext/curb/curb.c +977 -977
  4. data/ext/curb/curb.h +52 -52
  5. data/ext/curb/curb_config.h +270 -270
  6. data/ext/curb/curb_easy.c +3437 -3434
  7. data/ext/curb/curb_easy.h +94 -94
  8. data/ext/curb/curb_errors.c +647 -647
  9. data/ext/curb/curb_errors.h +129 -129
  10. data/ext/curb/curb_macros.h +162 -162
  11. data/ext/curb/curb_multi.c +704 -702
  12. data/ext/curb/curb_multi.h +26 -26
  13. data/ext/curb/curb_postfield.c +523 -523
  14. data/ext/curb/curb_postfield.h +40 -40
  15. data/ext/curb/curb_upload.c +80 -80
  16. data/ext/curb/curb_upload.h +30 -30
  17. data/ext/curb-original/curb.c +977 -977
  18. data/ext/curb-original/curb.h +52 -52
  19. data/ext/curb-original/curb_config.h +238 -238
  20. data/ext/curb-original/curb_easy.c +3404 -3404
  21. data/ext/curb-original/curb_easy.h +90 -90
  22. data/ext/curb-original/curb_errors.c +647 -647
  23. data/ext/curb-original/curb_errors.h +129 -129
  24. data/ext/curb-original/curb_macros.h +159 -159
  25. data/ext/curb-original/curb_multi.c +633 -633
  26. data/ext/curb-original/curb_multi.h +26 -26
  27. data/ext/curb-original/curb_postfield.c +523 -523
  28. data/ext/curb-original/curb_postfield.h +40 -40
  29. data/ext/curb-original/curb_upload.c +80 -80
  30. data/ext/curb-original/curb_upload.h +30 -30
  31. data/lib/rhack/clients/base.rb +61 -10
  32. data/lib/rhack/clients/oauth.rb +4 -4
  33. data/lib/rhack/curl/easy.rb +1 -0
  34. data/lib/rhack/curl/global.rb +2 -0
  35. data/lib/rhack/curl/response.rb +4 -2
  36. data/lib/rhack/frame.rb +70 -32
  37. data/lib/rhack/js/browser/env.js +697 -697
  38. data/lib/rhack/js/browser/jquery.js +7180 -7180
  39. data/lib/rhack/js/browser/xmlsax.js +1564 -1564
  40. data/lib/rhack/js/browser/xmlw3cdom_1.js +1443 -1443
  41. data/lib/rhack/js/browser/xmlw3cdom_2.js +2744 -2744
  42. data/lib/rhack/page.rb +227 -68
  43. data/lib/rhack/scout.rb +52 -26
  44. data/lib/rhack/scout_squad.rb +10 -2
  45. data/lib/rhack/version.rb +1 -1
  46. data/rhack.gemspec +1 -1
  47. metadata +17 -17
@@ -1,1444 +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;
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
1444
  };