webr 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/README.md +4 -0
  2. data/Rakefile +19 -0
  3. data/app/webr.rb +57 -0
  4. data/bin/webr +6 -0
  5. data/ext/jasmine/lib/jasmine.js +2423 -0
  6. data/ext/jsdom/lib/jsdom.js +70 -0
  7. data/ext/jsdom/lib/jsdom/browser/domtohtml.js +198 -0
  8. data/ext/jsdom/lib/jsdom/browser/htmlencoding.js +381 -0
  9. data/ext/jsdom/lib/jsdom/browser/htmltodom.js +151 -0
  10. data/ext/jsdom/lib/jsdom/browser/index.js +484 -0
  11. data/ext/jsdom/lib/jsdom/level1/core.js +1610 -0
  12. data/ext/jsdom/lib/jsdom/level2/core.js +406 -0
  13. data/ext/jsdom/lib/jsdom/level2/events.js +358 -0
  14. data/ext/jsdom/lib/jsdom/level2/html.js +1424 -0
  15. data/ext/jsdom/lib/jsdom/level2/index.js +7 -0
  16. data/ext/jsdom/lib/jsdom/level2/languages/javascript.js +17 -0
  17. data/ext/jsdom/lib/jsdom/level3/core.js +514 -0
  18. data/ext/jsdom/lib/jsdom/level3/events.js +296 -0
  19. data/ext/jsdom/lib/jsdom/level3/html.js +5 -0
  20. data/ext/jsdom/lib/jsdom/level3/index.js +7 -0
  21. data/ext/node-htmlparser/lib/node-htmlparser.js +769 -0
  22. data/ext/node-htmlparser/lib/node-htmlparser.min.js +22 -0
  23. data/ext/request/request.js +116 -0
  24. data/js/jasmine-start.js +10 -0
  25. data/js/webr.js +97 -0
  26. data/jspec/jasmine_spec.js +23 -0
  27. data/lib/webr.rb +17 -0
  28. data/lib/webr/browser.rb +44 -0
  29. data/lib/webr/jasmine.rb +6 -0
  30. data/lib/webr/jasmine/browser.rb +15 -0
  31. data/lib/webr/jasmine/reporter.rb +16 -0
  32. data/lib/webr/jasmine/reporter/base.rb +40 -0
  33. data/lib/webr/jasmine/reporter/console.rb +79 -0
  34. data/lib/webr/jasmine/reporter/html.rb +179 -0
  35. data/lib/webr/portal.rb +19 -0
  36. data/lib/webr/runtime.rb +23 -0
  37. data/lib/webr/version.rb +3 -0
  38. data/spec/data/plain.html +13 -0
  39. data/spec/data/script-embedded.html +17 -0
  40. data/spec/data/script-external-onload.html +11 -0
  41. data/spec/data/script-external-onload.js +11 -0
  42. data/spec/data/script-external.html +11 -0
  43. data/spec/data/script-external.js +1 -0
  44. data/spec/data/script-jquery-1.4.2.html +12 -0
  45. data/spec/data/script-jquery-1.4.3.html +12 -0
  46. data/spec/data/script-jquery.js +3 -0
  47. data/spec/lib/webr/browser_spec.rb +133 -0
  48. data/spec/lib/webr/jasmine/browser_spec.rb +22 -0
  49. data/spec/lib/webr/jasmine/reporter/html_spec.rb +15 -0
  50. data/spec/spec_helper.rb +4 -0
  51. data/tasks/spec.rake +16 -0
  52. data/webr.gemspec +30 -0
  53. metadata +207 -0
@@ -0,0 +1,1610 @@
1
+ /*
2
+ ServerJS Javascript DOM Level 1
3
+ */
4
+ var core = {
5
+
6
+ mapper: function(parent, filter, recursive) {
7
+ return function() {
8
+ return core.mapDOMNodes(parent, recursive !== false, filter);
9
+ };
10
+ },
11
+
12
+ // Returns Array
13
+ mapDOMNodes : function(parent, recursive, callback) {
14
+
15
+ var results = [], result, child, i;
16
+ // mark children readonly
17
+ if (parent.childNodes) {
18
+ for (i=0;i<parent.childNodes.length;i++)
19
+ {
20
+ child = parent.childNodes.item(i);
21
+ if (callback(child)) {
22
+ results.push(child);
23
+ }
24
+
25
+ if (recursive) {
26
+ results = results.concat(core.mapDOMNodes(child, true, callback));
27
+ }
28
+ }
29
+ }
30
+ return results;
31
+ },
32
+
33
+ markTreeReadonly : function(el) {
34
+ el._readonly = true;
35
+
36
+ // mark children readonly
37
+ if (el.children) {
38
+ for (var i=0;i<el.children.length;i++) {
39
+ core.markTreeReadonly(el.children.item(i));
40
+ }
41
+ }
42
+
43
+ // also mark attributes and their children read-only
44
+ if (el.attributes) {
45
+ for (var i=0;i<el.attributes.length;i++) {
46
+ core.markTreeReadonly(el.attributes.item(i));
47
+ }
48
+ }
49
+ }
50
+ };
51
+ var sys = require("sys");
52
+
53
+ // ExceptionCode
54
+ var INDEX_SIZE_ERR = core.INDEX_SIZE_ERR = 1;
55
+ var DOMSTRING_SIZE_ERR = core.DOMSTRING_SIZE_ERR = 2;
56
+ var HIERARCHY_REQUEST_ERR = core.HIERARCHY_REQUEST_ERR = 3;
57
+ var WRONG_DOCUMENT_ERR = core.WRONG_DOCUMENT_ERR = 4;
58
+ var INVALID_CHARACTER_ERR = core.INVALID_CHARACTER_ERR = 5;
59
+ var NO_DATA_ALLOWED_ERR = core.NO_DATA_ALLOWED_ERR = 6;
60
+ var NO_MODIFICATION_ALLOWED_ERR = core.NO_MODIFICATION_ALLOWED_ERR = 7;
61
+ var NOT_FOUND_ERR = core.NOT_FOUND_ERR = 8;
62
+ var NOT_SUPPORTED_ERR = core.NOT_SUPPORTED_ERR = 9;
63
+ var INUSE_ATTRIBUTE_ERR = core.INUSE_ATTRIBUTE_ERR = 10;
64
+
65
+ core.exceptionMessages = {
66
+ INDEX_SIZE_ERR : "Index size error",
67
+ DOMSTRING_SIZE_ERR : "DOMString size error",
68
+ HIERARCHY_REQUEST_ERR : "Heirarchy request error",
69
+ WRONG_DOCUMENT_ERR : "Wrong document",
70
+ INVALID_CHARACTER_ERR : "Invalid character",
71
+ NO_DATA_ALLOWED_ERR : "No data allowed",
72
+ NO_MODIFICATION_ALLOWED_ERR : "No modification allowed",
73
+ NOT_FOUND_ERR : "Not found",
74
+ NOT_SUPPORTED_ERR : "Not supported",
75
+ INUSE_ATTRIBUTE_ERR : "Attribute in use"
76
+ }
77
+
78
+ core.DOMException = function(code, message) {
79
+ this._code = code;
80
+ Error.call(this, core.exceptionMessages[code]);
81
+ this.message = core.exceptionMessages[code];
82
+ if(message) this.message = this.message + ": " + message;
83
+ if(Error.captureStackTrace) Error.captureStackTrace(this, core.DOMException);
84
+ };
85
+
86
+ core.DOMException.prototype = {
87
+ get code() { return this._code;},
88
+ INDEX_SIZE_ERR : INDEX_SIZE_ERR,
89
+ DOMSTRING_SIZE_ERR : DOMSTRING_SIZE_ERR,
90
+ HIERARCHY_REQUEST_ERR : HIERARCHY_REQUEST_ERR,
91
+ WRONG_DOCUMENT_ERR : WRONG_DOCUMENT_ERR,
92
+ INVALID_CHARACTER_ERR : INVALID_CHARACTER_ERR,
93
+ NO_DATA_ALLOWED_ERR : NO_DATA_ALLOWED_ERR,
94
+ NO_MODIFICATION_ALLOWED_ERR : NO_MODIFICATION_ALLOWED_ERR,
95
+ NOT_FOUND_ERR : NOT_FOUND_ERR,
96
+ NOT_SUPPORTED_ERR : NOT_SUPPORTED_ERR,
97
+ INUSE_ATTRIBUTE_ERR : INUSE_ATTRIBUTE_ERR
98
+ };
99
+
100
+ core.DOMException.prototype.__proto__ = Error.prototype;
101
+
102
+ core.NodeList = function(query, live) {
103
+ this._query = query;
104
+ this.update();
105
+ };
106
+ core.NodeList.prototype = {
107
+ update: function() {
108
+ for (var i = 0; i < this._length; i++) {
109
+ this[i] = undefined;
110
+ }
111
+ var nodes = this._snapshot = this._query();
112
+ this._length = nodes.length;
113
+ for (var i = 0; i < nodes.length; i++) {
114
+ this[i] = nodes[i];
115
+ }
116
+ return nodes;
117
+ },
118
+ toArray: function() {
119
+ return this.update();
120
+ },
121
+ get length() {
122
+ this.update();
123
+ return this._length;
124
+ },
125
+ item: function(index) {
126
+ this.update();
127
+ return this[index] || null;
128
+ },
129
+ toString: function() {
130
+ return '[ jsdom NodeList ]: contains ' + this.length + ' items';
131
+ }
132
+ };
133
+
134
+ core.DOMImplementation = function(document, /* Object */ features) {
135
+ this._ownerDocument = document;
136
+
137
+ if (features) {
138
+ this._features = features;
139
+ }
140
+ };
141
+
142
+ core.DOMImplementation.prototype = {
143
+ _features : {},
144
+ get ownerDocument() { return this._ownerDocument;},
145
+ hasFeature: function(/* string */ feature, /* string */ version) {
146
+ for (var i in this._features) {
147
+ if (this._features.hasOwnProperty(i) &&
148
+ i.toLowerCase() === feature.toLowerCase())
149
+ {
150
+ if (!version) {
151
+ return true;
152
+ }
153
+ var versions = this._features[i];
154
+
155
+ if (typeof versions === 'string' && versions === version) {
156
+ return true;
157
+ } else {
158
+ var j=0, l=versions.length;
159
+ for (j; j<l; j++)
160
+ {
161
+ if (versions[j] === version) {
162
+ return true;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ }
168
+ return false;
169
+ }
170
+ };
171
+
172
+ core.Node = function (ownerDocument) {
173
+ var childArray = this._childArray = [];
174
+ this._children = new core.NodeList(function() { return childArray });
175
+ this._nodeValue = null;
176
+ this._parentNode = null;
177
+ this._ownerDocument = ownerDocument;
178
+ this._attributes = new core.AttrNodeMap(this.ownerDocument, this);
179
+ this._nodeName = null;
180
+ this._readonly = false;
181
+ this.style = {
182
+ position: 'static'
183
+ };
184
+ };
185
+ core.Node.prototype = {
186
+ get ELEMENT_NODE() { return 1;},
187
+ get ATTRIBUTE_NODE() { return 2;},
188
+ get TEXT_NODE() { return 3;},
189
+ get CDATA_SECTION_NODE() { return 4;},
190
+ get ENTITY_REFERENCE_NODE() { return 5;},
191
+ get ENTITY_NODE() { return 6;},
192
+ get PROCESSING_INSTRUCTION_NODE() { return 7;},
193
+ get COMMENT_NODE() { return 8;},
194
+ get DOCUMENT_NODE() { return 9;},
195
+ get DOCUMENT_TYPE_NODE() { return 10;},
196
+ get DOCUMENT_FRAGMENT_NODE() { return 11;},
197
+ get NOTATION_NODE() { return 12;},
198
+
199
+ get children() { return this._children;},
200
+ get nodeValue() { return this._nodeValue;},
201
+ set nodeValue(value) {
202
+ // readonly
203
+ if (this.readonly === true) {
204
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR, 'Attempting to modify a read-only node');
205
+ }
206
+
207
+ this._nodeValue = value;
208
+ },
209
+ get parentNode() { return this._parentNode;},
210
+
211
+ get nodeName() {
212
+ var name = this._nodeName || this._tagName;
213
+ if (this.nodeType === this.ELEMENT_NODE &&
214
+ this.ownerDocument &&
215
+ this.ownerDocument.doctype &&
216
+ this.ownerDocument.doctype.name.indexOf("html") !== -1)
217
+ {
218
+ return name.toUpperCase();
219
+ }
220
+ return name;
221
+ },
222
+ set nodeName() { throw new core.DOMException();},
223
+ get attributes() { return this._attributes;},
224
+ get firstChild() {
225
+ return this._childArray.length > 0 ? this._childArray[0] : null;
226
+ },
227
+ set firstChild() { throw new core.DOMException();},
228
+ get ownerDocument() { return this._ownerDocument;},
229
+ get readonly() { return this._readonly;},
230
+
231
+ get lastChild() {
232
+ var len = this._childArray.length;
233
+ return len > 0 ? this._childArray[len -1] : null;
234
+ },
235
+ set lastChild() { throw new core.DOMException();},
236
+
237
+ get childNodes() { return this._children;},
238
+ set childNodes() { throw new core.DOMException();},
239
+
240
+ get nextSibling() {
241
+ // find this node's index in the parentNode, add one and call it a day
242
+ var index = 0;
243
+
244
+ if (!this._parentNode ||
245
+ !this._parentNode.childNodes ||
246
+ !this._parentNode.childNodes.length ||
247
+ this._parentNode.childNodes.length < 2)
248
+ {
249
+ return null;
250
+ }
251
+
252
+ var currentNode;
253
+ var index = 0;
254
+
255
+ while ((currentNode = this._parentNode.childNodes[index])) {
256
+ index++;
257
+ if (currentNode === this) { break;}
258
+ }
259
+
260
+ // TODO: there is some subtle weirdness here.
261
+ if (this._parentNode.childNodes.item(index) === this) {
262
+ index++;
263
+ }
264
+
265
+ // Swizec - some scripts hang here because null is not returned
266
+ if (index > this._parentNode.childNodes.length) {
267
+ return null;
268
+ }
269
+
270
+ return this._parentNode.childNodes.item(index) || null;
271
+ },
272
+ set nextSibling() { throw new core.DOMException();},
273
+
274
+ get previousSibling() {
275
+ // find this node's index in the parentNode, add one and call it a day
276
+ var index = 0;
277
+
278
+ if (!this._parentNode ||
279
+ !this._parentNode.childNodes ||
280
+ !this._parentNode.childNodes.length ||
281
+ this._parentNode.childNodes.length < 1)
282
+ {
283
+ return null;
284
+ }
285
+
286
+ var currentNode;
287
+ while ((currentNode = this._parentNode.childNodes[index])) {
288
+ if (currentNode === this) {
289
+ break;
290
+ }
291
+ index++;
292
+ }
293
+
294
+ return this._parentNode.childNodes[index-1] || null;
295
+ },
296
+ set previousSibling() { throw new core.DOMException();},
297
+
298
+ /* returns Node */
299
+ insertBefore : function(/* Node */ newChild, /* Node*/ refChild){
300
+
301
+ // readonly
302
+ if (this.readonly === true) {
303
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR, 'Attempting to modify a read-only node');
304
+ }
305
+
306
+ if (newChild.nodeType && newChild.nodeType === this.ATTRIBUTE_NODE) {
307
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
308
+ }
309
+
310
+ if (newChild.ownerDocument !== this.ownerDocument) {
311
+ throw new core.DOMException(WRONG_DOCUMENT_ERR);
312
+ }
313
+
314
+ var found = false;
315
+
316
+ // if the newChild is already in the tree elsewhere, remove it first
317
+ if (newChild._parentNode) {
318
+ newChild._parentNode.removeChild(newChild);
319
+ }
320
+
321
+ // if refChild is null, add to the end of the list
322
+ if (refChild === null) {
323
+ return this.appendChild(newChild);
324
+ }
325
+
326
+ for (var i=0;i<this._childArray.length;i++) {
327
+ if (this._childArray[i] === refChild) {
328
+ var current = this;
329
+ // search for parents matching the newChild
330
+ while ((current = current._parentNode))
331
+ {
332
+ if (current === newChild) {
333
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
334
+ }
335
+ }
336
+
337
+ // fragments are merged into the element
338
+ if (newChild.nodeType === this.DOCUMENT_FRAGMENT_NODE) {
339
+ var tmpNode;
340
+ while (newChild.children.length > 0) {
341
+ tmpNode = newChild.removeChild(newChild.firstChild);
342
+ this.insertBefore(tmpNode, refChild);
343
+ }
344
+
345
+ } else {
346
+ this._childArray.splice(i,0,newChild);
347
+ newChild._parentNode = this;
348
+ }
349
+ found = true;
350
+ break;
351
+ }
352
+ }
353
+
354
+ if (!found) {
355
+ throw new core.DOMException(NOT_FOUND_ERR);
356
+ } else {
357
+ return newChild;
358
+ }
359
+ }, // raises(DOMException);
360
+
361
+ /* returns Node */
362
+ replaceChild : function(/* Node */ newChild, /* Node */ oldChild){
363
+
364
+ // readonly
365
+ if (this.readonly === true) {
366
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR, 'Attempting to modify a read-only node');
367
+ }
368
+
369
+ if (newChild.nodeType === this.ATTRIBUTE_NODE) {
370
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
371
+ }
372
+
373
+ // moving elements across documents
374
+ if (newChild.ownerDocument !== this.ownerDocument) {
375
+ throw new core.DOMException(WRONG_DOCUMENT_ERR);
376
+ }
377
+
378
+ for (var i=0;i<this._childArray.length;i++)
379
+ {
380
+ if (this._childArray[i] === oldChild) {
381
+ var current = this;
382
+ // search for parents matching the newChild
383
+ while ((current = current._parentNode)) {
384
+ if (current === newChild) {
385
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
386
+ }
387
+ }
388
+
389
+ this._childArray.splice(i,1);
390
+
391
+ if (newChild.parentNode && newChild.parentNode.removeChild) {
392
+ newChild.parentNode.removeChild(newChild);
393
+ }
394
+ newChild._parentNode = this;
395
+
396
+ // insert the new child at this location
397
+ if (newChild.nodeType === this.DOCUMENT_FRAGMENT_NODE) {
398
+ var child;
399
+ for (var j = 0;j<newChild.children.length;j++) {
400
+ child = newChild.children.item(j);
401
+ this._childArray.splice(i+j,0, child);
402
+ }
403
+ } else {
404
+ this._childArray.splice(i,0, newChild);
405
+ }
406
+
407
+ return oldChild;
408
+ }
409
+ }
410
+ throw new core.DOMException(NOT_FOUND_ERR);
411
+ }, //raises(DOMException);
412
+
413
+ /* returns Node */
414
+ removeChild : function(/* Node */ oldChild){
415
+
416
+ // readonly
417
+ if (this.readonly === true) {
418
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
419
+ }
420
+
421
+ var found = false, child;
422
+ for (var i=0;i<this._childArray.length;i++) {
423
+ if (this._childArray[i] === oldChild) {
424
+ found=true;
425
+ child = this._childArray[i];
426
+ this._childArray.splice(i,1);
427
+ oldChild._parentNode = null;
428
+
429
+ if (child.id) {
430
+ if (child._ownerDocument._ids) {
431
+ child._ownerDocument._ids[child.id] = null;
432
+ delete child._ownerDocument._ids[child.id];
433
+ }
434
+ }
435
+
436
+ if (this.nodeType === this.DOCUMENT_NODE) {
437
+ if (this._documentElement === oldChild) {
438
+ this._documentElement = null;// force a recalculation
439
+ }
440
+ }
441
+
442
+ return oldChild;
443
+ }
444
+ }
445
+
446
+ // node was not found.
447
+ throw new core.DOMException(NOT_FOUND_ERR);
448
+ }, // raises(DOMException);
449
+
450
+ /* returns Node */
451
+ appendChild : function(/* Node */ newChild){
452
+ // readonly
453
+ if (this.readonly === true) {
454
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
455
+ }
456
+
457
+ if (newChild.nodeType === this.ATTRIBUTE_NODE) {
458
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
459
+ }
460
+
461
+ // avoid recursion
462
+ var cur = this;
463
+ do {
464
+ if (cur === newChild) {
465
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
466
+ }
467
+ } while ((cur = cur._parentNode))
468
+
469
+ // only elements created with this.ownerDocument can be added here
470
+ if (newChild.ownerDocument &&
471
+ this.ownerDocument &&
472
+ newChild.ownerDocument !== this.ownerDocument) {
473
+
474
+ throw new core.DOMException(WRONG_DOCUMENT_ERR);
475
+ }
476
+
477
+ try {
478
+ this.removeChild(newChild);
479
+ } catch (e) { /* do nothing */ }
480
+
481
+ // fragments are merged into the element
482
+ if (newChild.nodeType === this.DOCUMENT_FRAGMENT_NODE) {
483
+
484
+ var transfer = [];
485
+ var length = newChild.children.length;
486
+ var i = length-1;
487
+ var tmpNode;
488
+ var child;
489
+ // remove backwards so that item indexes stay stable while nodes are removed
490
+ for (;i> -1;i--)
491
+ {
492
+ transfer.unshift(newChild.removeChild(newChild.children.item(i)));
493
+ }
494
+ for (i=0;i<transfer.length;i++)
495
+ {
496
+ this.appendChild(transfer[i]);
497
+ }
498
+
499
+ } else {
500
+ if (newChild && newChild.parentNode) {
501
+ try {
502
+ newChild.parentNode.removeChild(newChild);
503
+ } catch (e) {}
504
+ }
505
+
506
+ // Attach the parent node.
507
+ newChild._parentNode = this;
508
+ this._childArray.push(newChild);
509
+
510
+ if (newChild.id) {
511
+ if (!this._ownerDocument._ids) {
512
+ this._ownerDocument._ids = {};
513
+ }
514
+ this._ownerDocument._ids[newChild.id] = newChild;
515
+ }
516
+ }
517
+
518
+ return newChild;
519
+ }, // raises(DOMException);
520
+
521
+ /* returns boolean */
522
+ hasChildNodes : function() {
523
+ return this.childNodes.length > 0;
524
+ },
525
+
526
+ /* returns Node */
527
+ cloneNode : function(/* bool */ deep) {
528
+
529
+ var object = null;
530
+
531
+ var attrCopy = function(src, dest) {
532
+ if (src.attributes && src.attributes.length) {
533
+ for (var i=0;i<src.attributes.length;i++)
534
+ {
535
+ dest.setAttribute(src.attributes.item(i).nodeName,
536
+ src.attributes.item(i).nodeValue);
537
+ }
538
+ }
539
+ return dest;
540
+ };
541
+
542
+ switch (this.nodeType) {
543
+
544
+ case this.ELEMENT_NODE:
545
+ object = attrCopy(this,this.ownerDocument.createElement(this.tagName));
546
+ break;
547
+
548
+ case this.TEXT_NODE:
549
+ object = attrCopy(this,this.ownerDocument.createTextNode(this.tagName));
550
+ object.nodeValue = this.nodeValue;
551
+ break;
552
+ case this.CDATA_SECTION_NODE:
553
+ object = this.ownerDocument.createCDATASection(this.tagName);
554
+ object.nodeValue = this.nodeValue;
555
+ break;
556
+ case this.ENTITY_REFERENCE_NODE:
557
+ var ref = this.ownerDocument.createEntityReference(this._entity.name);
558
+ object = attrCopy(this, ref);
559
+ object.nodeValue = this.nodeValue;
560
+ break;
561
+ case this.ATTRIBUTE_NODE:
562
+ object = this.ownerDocument.createAttribute(this.name);
563
+ break;
564
+ case this.ENTITY_NODE:
565
+ var entity = this.ownerDocument.createEntityNode(this._entity.name);
566
+ object = attrCopy(this, entity);
567
+ object.nodeValue = this.nodeValue;
568
+ break;
569
+ case this.PROCESSING_INSTRUCTION_NODE:
570
+ var pi = this.ownerDocument.createProcessingInstruction(this._target,
571
+ this._data);
572
+ object = attrCopy(this, pi);
573
+ object.nodeValue = this.nodeValue;
574
+ break;
575
+ case this.COMMENT_NODE:
576
+ object = this.ownerDocument.createComment(this.tagName);
577
+ object.nodeValue = this.nodeValue;
578
+ break;
579
+ case this.DOCUMENT_NODE:
580
+ object = attrCopy(this, new core.Document());
581
+ // TODO: clone the doctype/entities/notations/etc?
582
+ break;
583
+ case this.DOCUMENT_TYPE_NODE:
584
+ object = attrCopy(this, new core.DocumentType());
585
+ object.nodeValue = this.nodeValue;
586
+ break;
587
+ case this.DOCUMENT_FRAGMENT_NODE:
588
+ object = this.ownerDocument.createDocumentFragment();
589
+ break;
590
+ case this.NOTATION_NODE:
591
+ object = this.ownerDocument.createNotationNode(this._name,
592
+ this._publicId,
593
+ this._systemId);
594
+ object = attrCopy(this,object);
595
+ object.nodeValue = this.nodeValue;
596
+ break;
597
+ default:
598
+ throw new core.DOMException(NOT_FOUND_ERR);
599
+ break;
600
+ }
601
+
602
+ if (deep || this.nodeType === this.ATTRIBUTE_NODE) {
603
+ var clone = null;
604
+ for (var i=0;i<this.children.length;i++)
605
+ {
606
+ clone = this.children.item(i).cloneNode(true);
607
+ if (!clone) {
608
+ debug(this.children.item(i).nodeType);
609
+ }
610
+ if (clone.nodeType === this.ATTRIBUTE_NODE) {
611
+ object.setAttributeNode(clone);
612
+ } else {
613
+ object.appendChild(clone);
614
+ }
615
+ }
616
+ }
617
+
618
+ return object;
619
+ },
620
+
621
+ /* returns void */
622
+ normalize: function() {
623
+ var prevChild, child, attr,i;
624
+
625
+ if (this._attributes && this._attributes.length) {
626
+ for (i=0;i<this._attributes.length;i++)
627
+ {
628
+ if (attr = this._attributes.item(i).normalize) {
629
+ attr = this._attributes.item(i).normalize();
630
+ }
631
+ }
632
+ }
633
+
634
+ for (i=0;i<this._childArray.length;i++)
635
+ {
636
+ child = this._childArray[i];
637
+
638
+ if (child.normalize) {
639
+ child.normalize();
640
+ }
641
+
642
+ if (i>0) {
643
+ prevChild = this._childArray[i-1];
644
+
645
+ if (child.nodeType === this.TEXT_NODE &&
646
+ prevChild.nodeType === this.TEXT_NODE)
647
+ {
648
+
649
+ // remove the child and decrement i
650
+ prevChild.appendData(child.value);
651
+
652
+ this.removeChild(child);
653
+ i--;
654
+ }
655
+ }
656
+ }
657
+ },
658
+
659
+ toString: function() {
660
+ var id = '';
661
+ if (this.id) {
662
+ id = '#' + this.id;
663
+ }
664
+ if (this.className) {
665
+ id += '.' + this.className;
666
+ }
667
+ return '[ ' + this.tagName + id + ' ]';
668
+ }
669
+ };
670
+
671
+
672
+ core.NamedNodeMap = function(document) {
673
+ this._nodes = {};
674
+ this._length = 0;
675
+ this._ownerDocument = document;
676
+ this._readonly = false;
677
+ };
678
+ core.NamedNodeMap.prototype = {
679
+ get readonly() { return this._readonly;},
680
+ get ownerDocument() { this._ownerDocument;},
681
+ get length() {
682
+ var count = 0;
683
+ for (var i in this._nodes) {
684
+ count++;
685
+ }
686
+ this._length = count;
687
+ return this._length;
688
+ },
689
+
690
+ exists : function(name) {
691
+ return (this._nodes[name] || this._nodes[name] === null) ? true : false;
692
+ },
693
+
694
+ /* returns Node */
695
+ getNamedItem: function(/* string */ name) {
696
+ return this._nodes[name] || null;
697
+ },
698
+
699
+ /* returns Node */
700
+ setNamedItem: function(/* Node */ arg) {
701
+
702
+ // readonly
703
+ if (this._readonly === true) {
704
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
705
+ }
706
+
707
+ // arg is from a different document
708
+ if (arg && arg._ownerDocument !== this._ownerDocument) {
709
+ throw new core.DOMException(WRONG_DOCUMENT_ERR);
710
+ }
711
+
712
+ // if this argument is already in use..
713
+ if (arg && arg._parentNode) {
714
+ throw new core.DOMException(INUSE_ATTRIBUTE_ERR);
715
+ }
716
+
717
+ var ret;
718
+ if (!this._nodes[arg.name] || this._nodes[arg.name] === null) {
719
+ this._length++;
720
+ ret = null;
721
+ } else {
722
+ ret = this._nodes[arg.name];
723
+ }
724
+ arg._parentNode = this;
725
+ arg._specified = true;
726
+ this._nodes[arg.name] = arg;
727
+ return ret;
728
+ }, // raises: function(DOMException) {},
729
+
730
+ /* returns Node */
731
+ removeNamedItem: function(/* string */ name) {
732
+
733
+ // readonly
734
+ if (this.readonly === true) {
735
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
736
+ }
737
+
738
+ if (!this._nodes.hasOwnProperty(name)) {
739
+ throw new core.DOMException(NOT_FOUND_ERR);
740
+ }
741
+
742
+ var prev = this._nodes[name] || null;
743
+ this._nodes[name] = null;
744
+ delete this._nodes[name];
745
+
746
+ this._length--;
747
+ return prev;
748
+ }, // raises: function(DOMException) {},
749
+
750
+ /* returns Node */
751
+ item: function(/* int */ index) {
752
+ var current = 0;
753
+ for (var member in this._nodes) {
754
+ if (this._nodes.hasOwnProperty(member)) {
755
+ if (current === index && this._nodes[member]) {
756
+ return this._nodes[member];
757
+ }
758
+ current++;
759
+ }
760
+ }
761
+ return null;
762
+ }
763
+ };
764
+
765
+ core.AttrNodeMap = function(document, parentNode) {
766
+ core.NamedNodeMap.call(this,document);
767
+ this._parentNode = parentNode;
768
+
769
+ };
770
+ core.AttrNodeMap.prototype = {
771
+ get parentNode() { return this._parentNode;},
772
+
773
+ /* returns Node */
774
+ removeNamedItem: function(/* string */ name) {
775
+
776
+ var prev = core.NamedNodeMap.prototype.removeNamedItem.call(this, name);
777
+ var doc = this._ownerDocument;
778
+
779
+ // set default value if available
780
+ if (doc && doc.doctype && doc.doctype.name.toLowerCase() !== "html") {
781
+ var defaultValue = false;
782
+ var elem = doc.doctype._attributes.getNamedItem(this.parentNode.nodeName);
783
+ var defaultValue = elem.attributes.getNamedItem(name);
784
+
785
+ if (defaultValue) {
786
+ var attr = doc.createAttribute(name);
787
+ attr.value = defaultValue.value;
788
+ attr._specified = false;
789
+ this._nodes[name] = attr;
790
+ this._length++;
791
+ }
792
+ }
793
+ return prev;
794
+ }, // raises: function(DOMException) {},
795
+ };
796
+ core.AttrNodeMap.prototype.__proto__ = core.NamedNodeMap.prototype;
797
+
798
+ core.NotationNodeMap = function(document) {
799
+ core.NamedNodeMap.call(this,document);
800
+ this._readonly = false;
801
+ for (var i=1;i<arguments.length;i++) {
802
+ this.setNamedItem(arguments[i]);
803
+ }
804
+ this._readonly = true;
805
+ };
806
+ core.NotationNodeMap.prototype = {};
807
+ core.NotationNodeMap.prototype.__proto__ = core.NamedNodeMap.prototype;
808
+
809
+ core.EntityNodeMap = function(document) {
810
+ core.NamedNodeMap.call(this,document);
811
+ this._readonly = false;
812
+ for (var i=1;i<arguments.length;i++) {
813
+ this.setNamedItem(arguments[i]);
814
+ }
815
+ this._readonly = true;
816
+ };
817
+ core.EntityNodeMap.prototype = {};
818
+ core.EntityNodeMap.prototype.__proto__ = core.NamedNodeMap.prototype;
819
+
820
+
821
+ core.Element = function (document, tagName) {
822
+ this._attributes = null;
823
+ this._ownerDocument = document;
824
+ core.Node.call(this, document);
825
+ this._nodeName = tagName;
826
+ this._nodeType = this.ELEMENT_NODE;
827
+ this._tagName = tagName;
828
+
829
+ };
830
+
831
+ core.Element.prototype = {
832
+
833
+ get nodeValue() { return null;},
834
+ set nodeValue(value) { /* do nothing */ },
835
+ get tagName() {
836
+ if (this.nodeType === this.ELEMENT_NODE &&
837
+ this.ownerDocument &&
838
+ this.ownerDocument.doctype &&
839
+ this.ownerDocument.doctype.name.indexOf("html") !== -1)
840
+ {
841
+ return this.nodeName.toUpperCase();
842
+ }
843
+ return this.nodeName;
844
+ },
845
+ get nodeType() { return this._nodeType;},
846
+ get attributes() {
847
+ // Author: Swizec
848
+ // some scripts expect access to attributes by index
849
+ for(var i=0; i<this._attributes.length; i++) {
850
+ this._attributes[i] = this._attributes.item(i);
851
+ }
852
+ return this._attributes;
853
+ },
854
+
855
+ get name() { return this.nodeName;},
856
+ /* returns string */
857
+ getAttribute: function(/* string */ name) {
858
+ var attribute = this._attributes.getNamedItem(name);
859
+ if (attribute) {
860
+ return attribute.value;
861
+ }
862
+ return "";
863
+ },
864
+
865
+ /* returns string */
866
+ setAttribute: function(/* string */ name, /* string */ value) {
867
+
868
+ // readonly
869
+ if (this.readonly === true) {
870
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
871
+ }
872
+
873
+ if (this._attributes === null) {
874
+ this._attributes = new core.AttrNodeMap(this.ownerDocument, this);
875
+ }
876
+
877
+ if (this.ownerDocument) {
878
+ var attr = this.ownerDocument.createAttribute(name);
879
+ attr.value = value;
880
+
881
+ if (this.attributes.exists(name)) {
882
+ this._attributes.removeNamedItem(name);
883
+ }
884
+ this._attributes.setNamedItem(attr);
885
+ }
886
+ if (name === 'id') {
887
+ if (!this._ownerDocument._ids) {
888
+ this._ownerDocument._ids = {};
889
+ }
890
+ this._ownerDocument._ids[value] = this;
891
+ }
892
+ return value;
893
+ }, //raises: function(DOMException) {},
894
+
895
+ /* returns string */
896
+ removeAttribute: function(/* string */ name) {
897
+
898
+ // readonly
899
+ if (this.readonly === true) {
900
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
901
+ }
902
+
903
+ if (!this._attributes.exists(name)) {
904
+ return name;
905
+ }
906
+
907
+ this._attributes.removeNamedItem(name);
908
+ return name;
909
+ }, // raises: function(DOMException) {},
910
+
911
+ /* returns Attr */
912
+ getAttributeNode: function(/* string */ name) {
913
+ if (!this._attributes.exists(name)) {
914
+ return null;
915
+ }
916
+
917
+ return this._attributes.getNamedItem(name);
918
+ },
919
+
920
+ /* returns Attr */
921
+ setAttributeNode: function(/* Attr */ newAttr) {
922
+
923
+ // readonly
924
+ if (this.readonly === true) {
925
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
926
+ }
927
+
928
+ if (this._attributes === null) {
929
+ this._attributes = new core.AttrNodeMap(this.ownerDocument, this);
930
+ }
931
+
932
+ // only attributes created with this.ownerDocument can be added here
933
+ if (newAttr.ownerDocument !== this.ownerDocument) {
934
+ throw new core.DOMException(WRONG_DOCUMENT_ERR);
935
+ }
936
+
937
+ var prevNode = this._attributes.getNamedItem(newAttr.name);
938
+ if (prevNode) {
939
+ prevNode._parentNode = null;
940
+ }
941
+
942
+ this._attributes.setNamedItem(newAttr);
943
+
944
+ return (prevNode && prevNode.specified) ? prevNode : null;
945
+ }, // raises: function(DOMException) {},
946
+
947
+ /* returns Attr */
948
+ removeAttributeNode: function(/* Attr */ oldAttr) {
949
+
950
+ // readonly
951
+ if (this.readonly === true) {
952
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
953
+ }
954
+
955
+ var existingAttr = this._attributes.getNamedItem(oldAttr.name);
956
+
957
+ if (this._attributes && existingAttr === oldAttr) {
958
+ this._attributes.removeNamedItem(oldAttr.name);
959
+ return oldAttr;
960
+ }
961
+ throw new core.DOMException(NOT_FOUND_ERR);
962
+ }, //raises: function(DOMException) {},
963
+
964
+ /* returns NodeList */
965
+ getElementsByTagName: function(/* string */ name) {
966
+ function filterByTagName(child) {
967
+ if (child.nodeType && child.nodeType ===
968
+ core.Node.prototype.ENTITY_REFERENCE_NODE)
969
+ {
970
+ child = child._entity;
971
+ }
972
+
973
+ if (child.nodeName && child.nodeType === core.Node.prototype.ELEMENT_NODE)
974
+ {
975
+ if (name === "*") {
976
+ return true;
977
+
978
+ // case insensitivity for html
979
+ } else if (child.ownerDocument && child.ownerDocument.doctype &&
980
+ child.ownerDocument.doctype.name === "html" &&
981
+ child.nodeName.toLowerCase() === name.toLowerCase())
982
+ {
983
+ return true;
984
+ } else if (child.nodeName.toLowerCase() === name.toLowerCase()) {
985
+ return true;
986
+ }
987
+ }
988
+ return false;
989
+ }
990
+
991
+ var disableLiveLists = this.ownerDocument &&
992
+ this.ownerDocument.implementation &&
993
+ this.ownerDocument.implementation.hasFeature("DisableLiveLists");
994
+
995
+ return new core.NodeList(core.mapper(this, filterByTagName), !disableLiveLists);
996
+ },
997
+ };
998
+ core.Element.prototype.__proto__ = core.Node.prototype;
999
+
1000
+ core.DocumentFragment = function(document) {
1001
+ core.Element.call(this, document, "#document-fragment");
1002
+ this._nodeType = this.DOCUMENT_FRAGMENT_NODE;
1003
+ };
1004
+ core.DocumentFragment.prototype = {
1005
+ get nodeValue() { return null;},
1006
+ set nodeValue() { /* do nothing */ },
1007
+ get attributes() { return null;}
1008
+ };
1009
+ core.DocumentFragment.prototype.__proto__ = core.Element.prototype;
1010
+
1011
+ core.ProcessingInstruction = function (document, target, data) {
1012
+ this._ownerDocument = document;
1013
+ core.Node.call(this, document);
1014
+ this._nodeName = target;
1015
+ this._tagName = target;
1016
+ this._target = target;
1017
+ this._nodeValue = data;
1018
+ }
1019
+ core.ProcessingInstruction.prototype = {
1020
+ get target() { return this._target;},
1021
+ set target(value) { throw new core.DOMException(1);},
1022
+ get nodeType() { return this.PROCESSING_INSTRUCTION_NODE;},
1023
+ get nodeValue() { return this._nodeValue;},
1024
+ set nodeValue(value) { this._nodeValue = value},
1025
+ get data() { return this._nodeValue;},
1026
+ set data() { throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);},
1027
+ get attributes() { return null;}
1028
+
1029
+ };
1030
+ core.ProcessingInstruction.prototype.__proto__ = core.Node.prototype;
1031
+
1032
+ core.Document = function(name, doctype, implementation, /* string */contentType)
1033
+ {
1034
+ core.Element.call(this, "#document");
1035
+ this._nodeName = this._tagName = "#document";
1036
+ this._contentType = contentType || "text/xml";
1037
+ this._doctype = doctype;
1038
+ this._implementation = implementation || new core.DOMImplementation();
1039
+ this._documentElement = null;
1040
+ this._ids = {};
1041
+ this._ownerDocument = this;
1042
+ this._readonly = false;
1043
+ };
1044
+
1045
+
1046
+ var tagRegEx = /[^\w:\d_-]+/i;
1047
+ var entRegEx = /[^\w\d_\-&;]+/;
1048
+
1049
+ core.Document.prototype = {
1050
+ _elementBuilders : {},
1051
+ _defaultElementBuilder: function(document, tagName) {
1052
+ return new core.Element(document, tagName);
1053
+ },
1054
+ _nodes: null,
1055
+ get contentType() { return this._contentType;},
1056
+ get doctype() { return this._doctype || null;},
1057
+ set doctype(doctype) { this._doctype = doctype;},
1058
+ get documentElement() {
1059
+ if (this._documentElement) {
1060
+ return this._documentElement;
1061
+ } else {
1062
+ var children = this._childArray, len = this._childArray.length, i=0;
1063
+ for (i;i<len;i++) {
1064
+ if (children[i].nodeType === this.ELEMENT_NODE) {
1065
+ this._documentElement = children[i];
1066
+ return children[i];
1067
+ }
1068
+ }
1069
+ return null;
1070
+ }
1071
+ },
1072
+
1073
+ get implementation() { return this._implementation;},
1074
+ set implementation(implementation) { this._implementation = implementation;},
1075
+ get nodeType() { return this.DOCUMENT_NODE;},
1076
+ get nodeName() {
1077
+ if (this.nodeType === this.ELEMENT_NODE &&
1078
+ this.ownerDocument &&
1079
+ this.ownerDocument.doctype &&
1080
+ this.ownerDocument.doctype.name.indexOf("html") !== -1)
1081
+ {
1082
+ return this._nodeName.toUpperCase();
1083
+ }
1084
+ return this._nodeName;
1085
+ },
1086
+ get attributes() { return null;},
1087
+ get ownerDocument() { return null;},
1088
+ get readonly() { return this._readonly;},
1089
+ /* returns Element */
1090
+ createElement: function(/* string */ tagName) {
1091
+ var c = [], lower = tagName.toLowerCase(), element;
1092
+
1093
+ if (!tagName || !tagName.match || (c = tagName.match(tagRegEx))) {
1094
+ throw new core.DOMException(INVALID_CHARACTER_ERR, 'Invalid character in tag name: ' + c.pop());
1095
+ }
1096
+
1097
+ element = (this._elementBuilders[lower] || this._defaultElementBuilder)(this, tagName);
1098
+
1099
+ // Check for and introduce default elements
1100
+ if (this.doctype && this.doctype._attributes && this.doctype.name.toLowerCase() !== "html") {
1101
+ var attrElement = this.doctype._attributes.getNamedItem(tagName);
1102
+ if (attrElement && attrElement.children) {
1103
+
1104
+ attrs = attrElement.attributes;
1105
+ var attr, len = attrs.length;
1106
+ for (var i = 0; i < len; i++) {
1107
+ attr = this.createAttribute(attrs.item(i).name);
1108
+ attr.value = attrs.item(i).value;
1109
+ element.setAttributeNode(attr);
1110
+ attr._specified = false;
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ if (!this._nodes) {
1116
+ this._nodes = [];
1117
+ }
1118
+ this._nodes.push(this);
1119
+
1120
+ return element;
1121
+ }, //raises: function(DOMException) {},
1122
+
1123
+ /* returns DocumentFragment */
1124
+ createDocumentFragment: function() {
1125
+ return new core.DocumentFragment(this);
1126
+ },
1127
+
1128
+ /* returns Text */
1129
+ createTextNode: function(/* string */ data) {
1130
+ return new core.Text(this,data);
1131
+ },
1132
+
1133
+ /* returns Comment */
1134
+ createComment: function(/* string */ data) {
1135
+ return new core.Comment(this,data);
1136
+ },
1137
+
1138
+ /* returns CDATASection */
1139
+ createCDATASection: function(/* string */ data) {
1140
+ if (this.doctype && this.doctype.name === "html") {
1141
+ throw new core.DOMException(NOT_SUPPORTED_ERR);
1142
+ }
1143
+
1144
+ return new core.CDATASection(this,data);
1145
+ }, // raises: function(DOMException) {},
1146
+
1147
+ /* returns ProcessingInstruction */
1148
+ createProcessingInstruction: function(/* string */ target,/* string */ data) {
1149
+
1150
+ if (this.doctype && this.doctype.name === "html") {
1151
+ throw new core.DOMException(NOT_SUPPORTED_ERR);
1152
+ }
1153
+
1154
+ if (target.match(tagRegEx) || !target || !target.length) {
1155
+ throw new core.DOMException(INVALID_CHARACTER_ERR);
1156
+ }
1157
+
1158
+ return new core.ProcessingInstruction(this, target, data);
1159
+ }, // raises: function(DOMException) {},
1160
+
1161
+ /* returns Attr */
1162
+ createAttribute: function(/* string */ name) {
1163
+ if (!name || !name.length || name.match(/[^\w:\d_\.-]+/) ) {
1164
+ throw new core.DOMException(INVALID_CHARACTER_ERR, "attribute name: " + name);
1165
+ }
1166
+ return new core.Attr(this, name,false);
1167
+ }, // raises: function(DOMException) {},
1168
+
1169
+ /* returns EntityReference */
1170
+ createEntityReference: function(/* string */ name) {
1171
+
1172
+ if (this.doctype && this.doctype.name === "html") {
1173
+ throw new core.DOMException(NOT_SUPPORTED_ERR);
1174
+ }
1175
+
1176
+ name = name.replace(/[&;]/g,"");
1177
+ if (!name || !name.length) {
1178
+ throw new core.DOMException(INVALID_CHARACTER_ERR);
1179
+ }
1180
+
1181
+ if (name.match(tagRegEx)) {
1182
+ throw new core.DOMException(INVALID_CHARACTER_ERR);
1183
+ }
1184
+
1185
+ var entity = this._doctype.entities.getNamedItem(name);
1186
+
1187
+ if (!entity) {
1188
+ throw new core.DOMException(NOT_SUPPORTED_ERR);
1189
+ }
1190
+ return new core.EntityReference(this, entity);
1191
+ }, //raises: function(DOMException) {},
1192
+
1193
+ /* returns Entity */
1194
+ createEntityNode : function(/* string */ name)
1195
+ {
1196
+
1197
+ if (name.match(entRegEx) || !name || !name.length) {
1198
+ throw new core.DOMException(INVALID_CHARACTER_ERR);
1199
+ }
1200
+
1201
+ var ret = new core.Entity(this, name);
1202
+ ret._readonly = false;// TODO: fix me please.
1203
+
1204
+ for (var i=1;i<arguments.length;i++)
1205
+ {
1206
+ ret.appendChild(arguments[i]);
1207
+ }
1208
+
1209
+ core.markTreeReadonly(ret);
1210
+
1211
+ return ret;
1212
+ },
1213
+
1214
+ /* returns Notation */
1215
+ createNotationNode : function(/* string */ name,/* string */ publicId,/* string */ systemId)
1216
+ {
1217
+
1218
+ if (name.match(entRegEx) || !name || !name.length) {
1219
+ throw new core.DOMException(INVALID_CHARACTER_ERR);
1220
+ }
1221
+
1222
+ var ret = new core.Notation(this, name, publicId, systemId);
1223
+ ret._readonly = false;// TODO: fix me please.
1224
+
1225
+ for (var i=3;i<arguments.length;i++)
1226
+ {
1227
+ ret.appendChild(arguments[i]);
1228
+ }
1229
+
1230
+ core.markTreeReadonly(ret);
1231
+
1232
+ return ret;
1233
+ },
1234
+
1235
+
1236
+ /* returns Node */
1237
+ appendChild: function(/* Node */ newChild){
1238
+
1239
+ // readonly
1240
+ if (this.readonly === true) {
1241
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1242
+ }
1243
+
1244
+ if (newChild.nodeType === this.ATTRIBUTE_NODE) {
1245
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
1246
+ }
1247
+
1248
+ this._childArray.push(newChild);
1249
+
1250
+ // Attach the parent node.
1251
+ newChild._parentNode = this;
1252
+ return newChild;
1253
+ } // raises(DOMException);
1254
+ };
1255
+ core.Document.prototype.__proto__ = core.Element.prototype;
1256
+
1257
+ core.CharacterData = function(document, value) {
1258
+ core.Node.call(this, document);
1259
+ this._nodeValue = value || "";
1260
+ };
1261
+ core.CharacterData.prototype = {
1262
+
1263
+ get data() { return this._nodeValue;},
1264
+ set data(data) {
1265
+
1266
+ // readonly
1267
+ if (this.readonly === true) {
1268
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1269
+ }
1270
+
1271
+ this._nodeValue = data;
1272
+ },
1273
+
1274
+ /* returns int */
1275
+ get length() { return this._nodeValue.length || 0;},
1276
+
1277
+ /* returns string */
1278
+ substringData: function(/* int */ offset, /* int */ count) {
1279
+
1280
+ if (count < 0 || offset < 0 || offset > this._nodeValue.length) {
1281
+ throw new core.DOMException(INDEX_SIZE_ERR);
1282
+ }
1283
+
1284
+ return (this._nodeValue.length < offset + count) ?
1285
+ this._nodeValue.substring(offset) :
1286
+ this._nodeValue.substring(offset, offset+count);
1287
+
1288
+ }, // raises: function(DOMException) {},
1289
+
1290
+ /* returns string */
1291
+ appendData: function(/* string */ arg) {
1292
+
1293
+ // readonly
1294
+ if (this.readonly === true) {
1295
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1296
+ }
1297
+
1298
+ this._nodeValue+=arg;
1299
+ return this._nodeValue;
1300
+ }, // raises: function(DOMException) {},
1301
+
1302
+ /* returns string */
1303
+ insertData: function(/* int */ offset, /* string */ arg) {
1304
+
1305
+ // readonly
1306
+ if (this.readonly === true) {
1307
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1308
+ }
1309
+
1310
+ if (offset < 0 || offset > this._nodeValue.length) {
1311
+ throw new core.DOMException(INDEX_SIZE_ERR);
1312
+ }
1313
+
1314
+ var start = this._nodeValue.substring(0,offset);
1315
+ var end = this._nodeValue.substring(offset);
1316
+
1317
+ this._nodeValue = start + arg + end;
1318
+
1319
+ }, //raises: function(DOMException) {},
1320
+
1321
+ /* returns void */
1322
+ deleteData: function(/* int */ offset, /* int */ count) {
1323
+
1324
+ // readonly
1325
+ if (this.readonly === true) {
1326
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1327
+ }
1328
+
1329
+ if (offset < 0 ||
1330
+ offset > this._nodeValue.length ||
1331
+ count < 0)
1332
+ {
1333
+ throw new core.DOMException(INDEX_SIZE_ERR);
1334
+ }
1335
+
1336
+ var start = this._nodeValue.substring(0,offset);
1337
+
1338
+ this._nodeValue = (offset+count<this._nodeValue.length) ?
1339
+ start + this._nodeValue.substring(offset+count) :
1340
+ start;
1341
+ }, // raises: function(DOMException) {},
1342
+
1343
+ /* returns void */
1344
+ replaceData: function(/* int */ offset, /* int */ count, /* string */ arg) {
1345
+
1346
+ // readonly
1347
+ if (this.readonly === true) {
1348
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1349
+ }
1350
+
1351
+ count = (offset+count > this._nodeValue.length) ?
1352
+ this.nodeValue.length-offset :
1353
+ count;
1354
+
1355
+ if (offset < 0 ||
1356
+ offset > this._nodeValue.length ||
1357
+ count < 0 /*||
1358
+ offset+count > this._nodeValue.length*/)
1359
+ {
1360
+ throw new core.DOMException(INDEX_SIZE_ERR);
1361
+ }
1362
+
1363
+ var start = this._nodeValue.substring(0,offset);
1364
+ var end = this._nodeValue.substring(offset+count);
1365
+
1366
+ this._nodeValue = start + arg + end;
1367
+ } // raises: function(DOMException) {},
1368
+ };
1369
+ core.CharacterData.prototype.__proto__ = core.Node.prototype;
1370
+
1371
+
1372
+ core.Attr = function(document, name, value) {
1373
+ core.Node.call(this, document);
1374
+ this._nodeValue = value;
1375
+ this._name = name;
1376
+ this._specified = (value) ? true : false;
1377
+ this._tagName = name;
1378
+ this._nodeName = name;
1379
+ };
1380
+ core.Attr.prototype = {
1381
+ get nodeType() { return this.ATTRIBUTE_NODE;},
1382
+ get nodeValue() {
1383
+ var val = '';
1384
+ this._childArray.forEach(function(child) {
1385
+ if (child.nodeType === core.Node.prototype.ENTITY_REFERENCE_NODE) {
1386
+ val += child.childNodes.toArray().reduce(function(prev, c) {
1387
+ return prev += (c.nodeValue || c);
1388
+ }, '');
1389
+ } else {
1390
+ val += child.nodeValue;
1391
+ }
1392
+ });
1393
+ return val;
1394
+ },
1395
+ set nodeValue(value) {
1396
+ // readonly
1397
+ if (this._readonly) {
1398
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1399
+ }
1400
+
1401
+ this._childArray.length = 0;
1402
+ this._childArray.push(this.ownerDocument.createTextNode(value));
1403
+ this._specified = true;
1404
+ this._nodeValue = value;
1405
+ },
1406
+ get name() { return this._name;},
1407
+ get specified() { return this._specified;},
1408
+ get value() {
1409
+ return this.nodeValue;
1410
+ },
1411
+ set value(value) {
1412
+ this.nodeValue = value;
1413
+ },
1414
+ get parentNode() { return null;},
1415
+ get attributes() { return null;},
1416
+
1417
+ insertBefore : function(/* Node */ newChild, /* Node*/ refChild){
1418
+ if (newChild.nodeType === this.CDATA_SECTION_NODE ||
1419
+ newChild.nodeType === this.ELEMENT_NODE)
1420
+ {
1421
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
1422
+ }
1423
+
1424
+ return core.Node.prototype.insertBefore.call(this, newChild, refChild);
1425
+ },
1426
+
1427
+ appendChild : function(/* Node */ arg) {
1428
+
1429
+ if (arg.nodeType === this.CDATA_SECTION_NODE ||
1430
+ arg.nodeType === this.ELEMENT_NODE)
1431
+ {
1432
+ throw new core.DOMException(HIERARCHY_REQUEST_ERR);
1433
+ }
1434
+
1435
+ return core.Node.prototype.appendChild.call(this, arg);
1436
+ }
1437
+
1438
+ };
1439
+ core.Attr.prototype.__proto__ = core.Node.prototype;
1440
+
1441
+ core.Text = function(document, text, readonly) {
1442
+ core.CharacterData.call(this, document, text);
1443
+ this._nodeName = "#text";
1444
+ this._readonly = readonly ? true : false
1445
+ };
1446
+ core.Text.prototype = {
1447
+
1448
+ get attributes() { return null;},
1449
+ get nodeType() { return this.TEXT_NODE;},
1450
+ get value() { return this._nodeValue;},
1451
+ set value(value) { this.nodeValue = value;},
1452
+
1453
+ /* returns Text */
1454
+ splitText: function(offset) {
1455
+
1456
+ // readonly
1457
+ if (this._readonly) {
1458
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
1459
+ }
1460
+
1461
+ if (offset < 0 || offset > this._nodeValue.length) {
1462
+ throw new core.DOMException(INDEX_SIZE_ERR);
1463
+ }
1464
+
1465
+ var newText = this._nodeValue.substring(offset);
1466
+ this._nodeValue = this._nodeValue.substring(0, offset);
1467
+ var newNode = this.ownerDocument.createTextNode(newText);
1468
+ this._parentNode.appendChild(newNode);
1469
+ return newNode;
1470
+ }, //raises: function(DOMException) {},
1471
+ toString: function() {
1472
+ return this.nodeName;
1473
+ }
1474
+ };
1475
+ core.Text.prototype.__proto__ = core.CharacterData.prototype
1476
+
1477
+
1478
+ core.Comment = function(document, text) {
1479
+ core.Text.call(this, document, text);
1480
+ this._nodeName = "#comment";
1481
+ this._tagName = "#comment";
1482
+ };
1483
+ core.Comment.prototype = {
1484
+ get nodeType() { return this.COMMENT_NODE;}
1485
+ };
1486
+ core.Comment.prototype.__proto__ = core.Text.prototype
1487
+
1488
+
1489
+ core.CDATASection = function(document, value) {
1490
+ core.Text.call(this, document, value);
1491
+ this._nodeName = "#cdata-section";
1492
+ };
1493
+ core.CDATASection.prototype = {
1494
+ get nodeType() { return this.CDATA_SECTION_NODE;}
1495
+ };
1496
+ core.CDATASection.prototype.__proto__ = core.Text.prototype
1497
+
1498
+ core.DocumentType = function(document, name, entities, notations, attributes) {
1499
+ core.Node.call(this, document);
1500
+ this._name = name;
1501
+ this._tagName = name;
1502
+ this._nodeName = name;
1503
+ this._entities = entities || new core.EntityNodeMap(document);
1504
+ this._notations = notations || new core.NotationNodeMap(document);
1505
+
1506
+ core.markTreeReadonly(this._notations);
1507
+
1508
+ this._attributes = attributes || new core.NamedNodeMap(document);
1509
+ };
1510
+ core.DocumentType.prototype = {
1511
+ get nodeValue() { return null;},
1512
+ set nodeValue() { /* do nothing */ },
1513
+
1514
+ get nodeType() { return this.DOCUMENT_TYPE_NODE;},
1515
+ get name() { return this._name;},
1516
+ get entities() { return this._entities;},
1517
+ get notations() { return this._notations;},
1518
+ get attributes() { return null;}
1519
+ };
1520
+ core.DocumentType.prototype.__proto__ = core.Node.prototype;
1521
+
1522
+
1523
+ core.Notation = function(document, name, publicId, systemId){
1524
+ core.Node.call(this, document);
1525
+ this._name = name;
1526
+ this._nodeName = name;
1527
+ this._nodeType = this.NOTATION_NODE;
1528
+ this._publicId = publicId || null;
1529
+ this._systemId = systemId || null;
1530
+ this._nodeValue = null;
1531
+ };
1532
+ core.Notation.prototype = {
1533
+ get publicId() { return this._publicId;},
1534
+ get systemId() { return this._systemId;},
1535
+ get name() { return this._name || this._nodeName;},
1536
+ get attributes() { /* as per spec */ return null;},
1537
+ set nodeValue() { /* intentionally left blank */ },
1538
+ get nodeValue() { return this._nodeValue;},
1539
+ get nodeType() { return this.NOTATION_NODE;}
1540
+ };
1541
+ core.Notation.prototype.__proto__ = core.Node.prototype;
1542
+
1543
+
1544
+ core.Entity = function(document, name) {
1545
+ core.Node.call(this, document);
1546
+ this._name = name;
1547
+ this._nodeName = name;
1548
+ this._tagName = name;
1549
+ this._publicId = null;
1550
+ this._systemId = null;
1551
+ this._notationName = null;
1552
+ this._nodeType = this.ENTITY_NODE;
1553
+ this._readonly = true;
1554
+ };
1555
+ core.Entity.prototype = {
1556
+ get nodeValue() { return null;},
1557
+ set nodeValue() {
1558
+ // readonly
1559
+ if (this.readonly === true) {
1560
+ // TODO: is this needed?
1561
+ // throw new DOMException(NO_MODIFICATION_ALLOWED_ERR);
1562
+ }
1563
+ /* do nothing */
1564
+ },
1565
+ get name() { return this._name },
1566
+ get publicId() { return this._publicId;},
1567
+ get systemId() { return this._systemId;},
1568
+
1569
+ set publicId(publicId) { this._publicId = publicId;},
1570
+ set systemId(systemId) { this._systemId = systemId;},
1571
+ set notationName(notationName) { this._notationName = notationName;},
1572
+
1573
+ get notationName() { return this._notationName;},
1574
+ get nodeType() { return this.ENTITY_NODE;},
1575
+ get attributes() { return null;},
1576
+
1577
+ };
1578
+ core.Entity.prototype.__proto__ = core.Node.prototype;
1579
+
1580
+
1581
+ core.EntityReference = function(document, entity) {
1582
+ core.Node.call(this, document);
1583
+ this._entity = entity;
1584
+ this._nodeName = entity.name;
1585
+ this._readonly = true;
1586
+ };
1587
+ core.EntityReference.prototype = {
1588
+ get nodeType() { return this.ENTITY_REFERENCE_NODE;},
1589
+ get nodeValue() { return this._entity.nodeValue;},
1590
+ set nodeValue() {
1591
+ // readonly
1592
+ if (this.readonly === true) {
1593
+ // TODO: is this needed?
1594
+ //throw new DOMException(NO_MODIFICATION_ALLOWED_ERR);
1595
+ }
1596
+
1597
+ /* do nothing */
1598
+ },
1599
+ get attributes() { return null;},
1600
+
1601
+ // Proxy to the entity
1602
+ get nodeName() { return this._entity.nodeName;},
1603
+ get firstChild() { return this._entity.firstChild || null;},
1604
+ get childNodes() { return this._entity.childNodes;},
1605
+ get lastChild() { return this._entity.lastChild || null;},
1606
+
1607
+ };
1608
+ core.EntityReference.prototype.__proto__ = core.Node.prototype;
1609
+
1610
+ exports.dom = { "level1" : { "core" : core }};