webr 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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,151 @@
1
+ var HTMLDecode = require('./htmlencoding').HTMLDecode;
2
+
3
+ var HtmlToDom = function(parser){
4
+
5
+ if(parser && parser.write) {
6
+ // sax parser
7
+ this.appendHtmlToElement = function(html, element){
8
+
9
+ var currentElement = element, currentLevel = 0;
10
+
11
+ parser.onerror = function (e) {};
12
+
13
+ parser.ontext = function (t) {
14
+ var ownerDocument = currentElement.ownerDocument || currentElement;
15
+ var newText = ownerDocument.createTextNode(t);
16
+ currentElement.appendChild(newText);
17
+ };
18
+
19
+ parser.onopentag = function (node) {
20
+ var nodeName = node.name.toLowerCase(),
21
+ document = currentElement.ownerDocument || currentElement,
22
+ newElement = document.createElement(nodeName),
23
+ i = 0,
24
+ length = (node.attributes && node.attributes.length) ?
25
+ node.attributes.length :
26
+ 0;
27
+
28
+ for (i in node.attributes)
29
+ {
30
+ if (node.attributes.hasOwnProperty(i)) {
31
+ newElement.setAttribute(i, node.attributes[i]);
32
+ }
33
+ }
34
+
35
+ for (var i=0; i<node.attributes.length; i++) {
36
+ newElement.setAttribute(i, node.attributes.item(i));
37
+ }
38
+ currentElement.appendChild(newElement);
39
+ currentElement = newElement;
40
+ };
41
+
42
+ parser.onclosetag = function(node) {
43
+ currentElement = currentElement.parentNode;
44
+ }
45
+
46
+ parser.write(html).close();
47
+
48
+ return element;
49
+ }
50
+
51
+ } else if(parser && (parser.ParseHtml || parser.DefaultHandler)) {
52
+
53
+ // Forgiving HTML parser
54
+
55
+ if(parser.ParseHtml){
56
+ // davglass/node-htmlparser
57
+ } else if(parser.DefaultHandler){
58
+ // tautologistics/node-htmlparser
59
+ parser.ParseHtml = function(rawHtml){
60
+ var handler = new this.DefaultHandler();
61
+ var parser = new this.Parser(handler);
62
+ parser.parseComplete(rawHtml);
63
+ return handler.dom;
64
+ }
65
+ }
66
+
67
+ this.appendHtmlToElement = function(html, element){
68
+
69
+ if (typeof html !== 'string') {
70
+ html +='';
71
+ }
72
+
73
+ var parsed = parser.ParseHtml(html);
74
+
75
+ for (var i = 0; i < parsed.length; i++) {
76
+ setChild.call(element, parsed[i]);
77
+ }
78
+
79
+ return element;
80
+
81
+ }
82
+
83
+ } else if(parser && parser.moduleName == 'HTML5') { /* HTML5 parser */
84
+ this.appendHtmlToElement = function(html, element) {
85
+ if(typeof html !== 'string') html += '';
86
+ var p = new parser.Parser({document: element.ownerDocument});
87
+ p.parse_fragment(html, element);
88
+ element.appendChild(p.fragment);
89
+ }
90
+ } else {
91
+
92
+ this.appendHtmlToElement = function(){
93
+ var sys = require('sys');
94
+ sys.puts('');
95
+ sys.puts('###########################################################');
96
+ sys.puts('# WARNING: No HTML parser could be found.');
97
+ sys.puts('# Element.innerHTML setter support has been disabled');
98
+ sys.puts('# Element.innerHTML getter support will still function');
99
+ sys.puts('# Download: http://github.com/tautologistics/node-htmlparser');
100
+ sys.puts('###########################################################');
101
+ sys.puts('');
102
+
103
+ }
104
+
105
+ }
106
+ }
107
+
108
+ // utility function for forgiving parser
109
+ var setChild = function(node) {
110
+
111
+ var newNode, currentDocument = this._ownerDocument || this;
112
+
113
+ if (node.type == 'tag' || node.type == 'script' || node.type == 'style') {
114
+ try{
115
+ newNode = currentDocument.createElement(node.name);
116
+ }catch (err) {
117
+ //console.log("raw: "+node.raw);
118
+ }
119
+ }
120
+ if (node.type == 'text') {
121
+ newNode = currentDocument.createTextNode(HTMLDecode(node.data));
122
+ }
123
+ if (node.type == 'comment') {
124
+ newNode = currentDocument.createComment(node.data);
125
+ }
126
+ if (node.attribs && newNode) {
127
+ for (var c in node.attribs) {
128
+ // catchin errors here helps with improperly escaped attributes
129
+ // but properly fixing this should (can only?) be done in the htmlparser itself
130
+ try{
131
+ newNode.setAttribute(c.toLowerCase(), HTMLDecode(node.attribs[c]));
132
+ }catch(err) {
133
+ //console.log("raw: "+node.raw);
134
+ //console.log(node.attribs);
135
+ //console.log("offender: "+node.attribs[c]);
136
+ }
137
+ }
138
+ }
139
+ if (node.children && newNode) {
140
+ for (var c = 0; c < node.children.length; c++) {
141
+ setChild.call(newNode, node.children[c]);
142
+ }
143
+ }
144
+ if (newNode) {
145
+ return this.appendChild(newNode);
146
+ } else {
147
+ return null;
148
+ }
149
+ };
150
+
151
+ exports.HtmlToDom = HtmlToDom;
@@ -0,0 +1,484 @@
1
+ var sys = require('sys'),
2
+ http = require('http'),
3
+ url = require('url'),
4
+ HtmlToDom = require('./htmltodom').HtmlToDom,
5
+ domToHtml = require('./domtohtml').domToHtml,
6
+ htmlencoding = require('./htmlencoding'),
7
+ HTMLEncode = htmlencoding.HTMLEncode,
8
+ HTMLDecode = htmlencoding.HTMLDecode,
9
+ _console = {
10
+ log: console.log,
11
+ info: console.info,
12
+ warn: console.warn,
13
+ error: console.error
14
+ };
15
+
16
+ exports.windowAugmentation = function(dom, options) {
17
+ options = options || {};
18
+ var window = exports.createWindow(dom, options),
19
+ setupDoc = (typeof options.document === 'undefined');
20
+
21
+ if (setupDoc) {
22
+ browser = browserAugmentation(dom, options),
23
+ options.document = new (browser.Document)();
24
+ }
25
+
26
+ window.document = options.document;
27
+
28
+ if (options.document.childNodes.length === 0) {
29
+ window.document.appendChild(
30
+ window.document.createElement("html")
31
+ );
32
+ var head = window.document.createElement('head');
33
+ window.document.documentElement.appendChild(head);
34
+ head.appendChild(
35
+ window.document.createElement('title')
36
+ );
37
+ window.document.documentElement.appendChild(
38
+ window.document.createElement('body')
39
+ );
40
+ }
41
+
42
+ if (!window.document.addEventListener) {
43
+ window.document.addEventListener = function() {};
44
+ }
45
+
46
+ window.console = _console;
47
+ window.document.compareDocumentPosition = function() {};
48
+ window.document.documentElement.style = {};
49
+ window.document.documentElement.hasAttribute = true;
50
+ return window;
51
+ }
52
+
53
+ exports.createWindow = function(dom, options) {
54
+ options = options || {};
55
+ var document,
56
+ window = {
57
+ get document() { return document },
58
+ set document(doc) {
59
+ document = doc;
60
+ if (document) {
61
+ document.defaultView = window;
62
+ document.parentWindow = window;
63
+ }
64
+ },
65
+ setTimeout: setTimeout,
66
+ setInterval: setInterval,
67
+ clearInterval: clearInterval,
68
+ clearTimeout: clearTimeout,
69
+ name: 'nodejs',
70
+ innerWidth: 1024,
71
+ innerHeight: 768,
72
+ length: 1,
73
+ outerWidth: 1024,
74
+ outerHeight: 768,
75
+ pageXOffset: 0,
76
+ pageYOffset: 0,
77
+ screenX: 0,
78
+ screenY: 0,
79
+ screenLeft: 0,
80
+ screenTop: 0,
81
+ scrollX: 0,
82
+ scrollY: 0,
83
+ scrollTop: 0,
84
+ scrollLeft: 0
85
+ };
86
+
87
+ window.frames = [window];
88
+ window.contentWindow = window;
89
+ window.addEventListener2 = function(type, fn, capture) {
90
+ fn.apply(window);
91
+ };
92
+
93
+ window.getComputedStyle = function(node) {
94
+ var s = node.style,
95
+ cs = {};
96
+
97
+ for (var n in s) {
98
+ cs[n] = s[n];
99
+ }
100
+ cs.__proto__ = {
101
+ getPropertyValue: function(name) {
102
+ return node.style[name];
103
+ }
104
+ };
105
+ return cs;
106
+ };
107
+ window.addEventListener = function() {};
108
+
109
+ window.alert = function () {};
110
+ window.blur = function () {};
111
+ window.close = function () {};
112
+ window.confirm = function () {};
113
+ window.createPopup = function () {};
114
+ window.focus = function () {};
115
+ window.moveBy = function () {};
116
+ window.moveTo = function () {};
117
+ window.open = function () {};
118
+ window.print = function () {};
119
+ window.prompt = function () {};
120
+ window.resizeBy = function () {};
121
+ window.resizeTo = function () {};
122
+ window.scroll = function () {};
123
+ window.scrollBy = function () {};
124
+ window.scrollTo = function () {};
125
+
126
+ // Author: Swizec
127
+ // some scripts expect a proper window.location; try parsing it from options.url
128
+ if (options.url) {
129
+ var host = options.url.split("://", 2)[1].split("/", 1)[0];
130
+ window.location = { href: options.url,
131
+ hash: (options.url.indexOf('#') > -1) ? "#"+options.url.split("#", 2)[1] : '',
132
+ host: host,
133
+ hostname: host.split(":", 2)[0],
134
+ pathname: (function () {
135
+ var path = options.url.split("://", 2)[1].split("/", 2)[1];
136
+ return (path) ? path.split('#', 2)[0] : '';
137
+ })(),
138
+ port: (host.split(":", 2)[1]) ? host.split(":", 2)[1] : 80,
139
+ protocol: options.url.split("://", 2)[0]+":",
140
+ search: (options.url.indexOf('?') > -1) ? "?"+options.url.split("?", 2)[1] : '',
141
+ // TODO: find a way to actually implement these
142
+ reload: function () {},
143
+ replace: function () {}
144
+ }
145
+ }else {
146
+ window.location = { href: __filename };
147
+ }
148
+
149
+ window.navigator = {
150
+ userAgent: 'Node.js (' + process.platform + '; U; rv:' + process.version + ')',
151
+ appName: 'Node.js jsDom',
152
+ platform: process.platform,
153
+ appVersion: process.version
154
+ };
155
+
156
+ window.window = window;
157
+ window.self = window;
158
+
159
+ window.close = function() {
160
+ var len = document._nodes.length, i, el;
161
+ for (i = 0; i < len; i++) {
162
+ el = document._nodes[i];
163
+ document._nodes[i] = null;
164
+ if (el.parentNode) {
165
+ el.parentNode.removeChild(el);
166
+ }
167
+ }
168
+ delete document._attributes._parentNode;
169
+ delete document._ownerDocument;
170
+ delete document._children[0]._parentNode;
171
+ delete document._children[0]._ownerDocument;
172
+ delete document.defaultView;
173
+ delete document.contentWindow;
174
+ delete document.contentDocument;
175
+ delete document.parentWindow;
176
+ delete document._documentElement;
177
+
178
+ delete window.self;
179
+ delete window.window;
180
+ delete window.contentWindow;
181
+ delete window.document;
182
+ len = window.frames.length;
183
+ for (i = 0; i < len; i++) {
184
+ if (window !== window.frames[i]) {
185
+ window.frames[i].close();
186
+ }
187
+ delete window.frames[i];
188
+ }
189
+ };
190
+
191
+ return window;
192
+ };
193
+
194
+ var htmlparser = null; //Caching for HTMLParser require. HUGE performace boost.
195
+ /**
196
+ * 5000 iterations
197
+ * Without cache: ~1800+ms
198
+ * With cache: ~80ms
199
+ */
200
+
201
+ var browserAugmentation = exports.browserAugmentation = function(dom, options) {
202
+
203
+ if(!options) options = {};
204
+
205
+ // set up html parser - use a provided one or try and load from library
206
+
207
+ var htmltodom;
208
+
209
+ if(options.parser) {
210
+ htmltodom = new HtmlToDom(options.parser);
211
+ } else {
212
+ try {
213
+ if (!htmlparser) {//Only require once
214
+ htmlparser = require('htmlparser');
215
+ }
216
+ htmltodom = new HtmlToDom(htmlparser);
217
+ } catch(e) {
218
+ try {
219
+ htmlparser = require('node-htmlparser/lib/node-htmlparser');
220
+ htmltodom = new HtmlToDom(htmlparser);
221
+ } catch(e) {
222
+ htmltodom = new HtmlToDom();
223
+ }
224
+ }
225
+ }
226
+
227
+ /***************************************
228
+ * Browser Augmentation *
229
+ ***************************************/
230
+
231
+
232
+ if (!dom.Node.prototype.__proto__.addEventListener) {
233
+ dom.Node.prototype.addEventListener = function(){};
234
+ }
235
+
236
+
237
+ dom.Element.prototype.getElementsByClassName = function(className) {
238
+
239
+ function filterByClassName(child) {
240
+ if (!child) {
241
+ return false;
242
+ }
243
+
244
+ if (child.nodeType &&
245
+ child.nodeType === dom.Node.prototype.ENTITY_REFERENCE_NODE)
246
+ {
247
+ child = child._entity;
248
+ }
249
+
250
+ var classString = child.className;
251
+ if (classString) {
252
+ var s = classString.split(" ");
253
+ for (var i=0; i<s.length; i++) {
254
+ if (s[i] === className) {
255
+ return true;
256
+ }
257
+ }
258
+ }
259
+ return false;
260
+ }
261
+
262
+ var disableLiveLists = this.ownerDocument &&
263
+ this.ownerDocument.implementation &&
264
+ this.ownerDocument.implementation.hasFeature("DisableLiveLists");
265
+
266
+ return new dom.NodeList(dom.mapper(this, filterByClassName), !disableLiveLists);
267
+ };
268
+
269
+ dom.Document.prototype.__defineSetter__("title",function(value) {
270
+ this.getElementsByTagName('title')[0].innerHTML = value;
271
+ return value;
272
+ });
273
+
274
+ dom.Document.prototype.__defineGetter__("title",function() {
275
+ // Swizec - sometimes there is no title
276
+ var elements = this.getElementsByTagName('title');
277
+ return (elements.length > 0) ? elements[0].innerHTML : '';
278
+ });
279
+
280
+ dom.Element.prototype.__defineGetter__('sourceIndex', function() {
281
+ /*
282
+ * According to QuirksMode:
283
+ * Get the sourceIndex of element x. This is also the index number for
284
+ * the element in the document.getElementsByTagName('*') array.
285
+ * http://www.quirksmode.org/dom/w3c_core.html#t77
286
+ */
287
+ var items = this.ownerDocument.getElementsByTagName('*'),
288
+ len = items.length;
289
+
290
+ for (var i = 0; i < len; i++) {
291
+ if (items[i] === this) {
292
+ return i;
293
+ }
294
+ }
295
+ });
296
+
297
+ dom.Document.prototype.__defineGetter__('outerHTML', function() {
298
+ var html = domToHtml(this.documentElement);
299
+ if (this.doctype) {
300
+ html = this.doctype.toString() + '\n' + html;
301
+ }
302
+ return html;
303
+ });
304
+
305
+ dom.Element.prototype.__defineGetter__('outerHTML', function() {
306
+ return domToHtml(this);
307
+ });
308
+
309
+ dom.Element.prototype.__defineGetter__('innerHTML', function() {
310
+ return domToHtml(this.childNodes, true);
311
+ });
312
+ dom.Element.prototype.__defineSetter__('doctype', function() {
313
+ throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR);
314
+ });
315
+ dom.Element.prototype.__defineGetter__('doctype', function() {
316
+ var r = null;
317
+ if (this.nodeName == '#document') {
318
+ if (this._doctype) {
319
+ r = this._doctype;
320
+ }
321
+ }
322
+ return r;
323
+ });
324
+
325
+ dom.Element.prototype.__defineSetter__('innerHTML', function(html) {
326
+ //Check for lib first
327
+
328
+ if (html === null) {
329
+ return null;
330
+ }
331
+
332
+ //Clear the children first:
333
+ for (var i = this.childNodes.length-1; i >= 0; i--) {
334
+ if (this.childNodes[i].parentNode) {
335
+ this.childNodes[i].parentNode.removeChild(this.childNodes[i]);
336
+ }
337
+ }
338
+ if (this.nodeName === '#document') {
339
+ parseDocType(this, html);
340
+ }
341
+ var nodes = htmltodom.appendHtmlToElement(html, this);
342
+ return html;
343
+ });
344
+
345
+ var DOC_HTML5 = /<!doctype html>/is,
346
+ DOC_TYPE = /<!DOCTYPE (\w.*)">/is;
347
+
348
+ var parseDocType = function(doc, html) {
349
+ var publicID = '',
350
+ systemID = '',
351
+ fullDT = '',
352
+ name = 'HTML',
353
+ set = true,
354
+ html5DT = html.match(DOC_HTML5),
355
+ dt = html.match(DOC_TYPE);
356
+
357
+ //Default, No doctype === null
358
+ doc._doctype = null;
359
+
360
+ if (html5DT && html5DT[0]) { //Handle the HTML shorty doctype
361
+ fullDT = html5DT[0];
362
+
363
+ } else if (dt && dt[1]) { //Parse the doctype
364
+ fullDT = dt[0];
365
+ dt = dt[1].split(' "');
366
+ var _id1 = dt.pop().replace(/"/g, ''),
367
+ _id2 = dt.pop().replace(/"/g, '');
368
+
369
+ if (_id1.indexOf('-//') !== -1) {
370
+ publicID = _id1;
371
+ }
372
+ if (_id2.indexOf('-//') !== -1) {
373
+ publicID = _id2;
374
+ }
375
+ if (_id1.indexOf('://') !== -1) {
376
+ systemID = _id1;
377
+ }
378
+ if (_id2.indexOf('://') !== -1) {
379
+ systemID = _id2;
380
+ }
381
+ if (dt.length) {
382
+ dt = dt[0].split(' ');
383
+ name = dt[0].toUpperCase();
384
+ }
385
+ } else {
386
+ //No DocType found
387
+ return;
388
+ }
389
+ doc._doctype = new dom.DOMImplementation().createDocumentType(name, publicID, systemID);
390
+ doc._doctype._ownerDocument = doc;
391
+ doc._doctype._fullDT = fullDT;
392
+ doc._doctype.toString = function() {
393
+ return this._fullDT;
394
+ };
395
+ }
396
+
397
+ dom.Document.prototype.__defineGetter__("body", function() {
398
+ return this.getElementsByTagName("body").item(0);
399
+ });
400
+
401
+ dom.Document.prototype.__defineGetter__("head", function() {
402
+ return this.getElementsByTagName("head").item(0);
403
+ });
404
+
405
+ // Author: Swizec
406
+ // styleSheets is an interface to all of the css on a page
407
+ // some scripts like readability.js expect this to exist
408
+ dom.Document.prototype.__defineGetter__("styleSheets", function () {
409
+ var styles = new Array(),
410
+ nodes1 = this.getElementsByTagName("style"),
411
+ nodes2 = (this.head) ? this.head.getElementsByTagName("link") : [],
412
+ node;
413
+
414
+ function StyleSheet(node) {
415
+ this.cssText = node.textContent;
416
+ this.disabled = false;
417
+ this.href = (node.attributes['href']) ? node.attributes['href'] : '';
418
+ this.media = (node.attributes['media']) ? node.attributes['media'] : 'screen';
419
+ this.title = node.attributes['title'];
420
+ this.type = node.attributes['type'];
421
+ }
422
+
423
+ for (var i=0; i < nodes1.length; i++ ) {
424
+ node = nodes1.item(i);
425
+ styles.push(new StyleSheet(node));
426
+ }
427
+
428
+ for (var i=0; i< nodes2.length; i++ ) {
429
+ node = nodes2.item(i);
430
+ if (node.attributes['rel'] == 'stylesheet') {
431
+ styles.push(new StyleSheet(node));
432
+ }
433
+ }
434
+
435
+ return styles;
436
+ });
437
+
438
+ dom.Document.prototype.console = _console;
439
+
440
+ dom.Element.prototype.__defineGetter__('nodeName', function(val) {
441
+ return this._nodeName.toUpperCase();
442
+ });
443
+
444
+ dom.Element.prototype.__defineGetter__('tagName', function(val) {
445
+ var t = this._tagName.toUpperCase();
446
+ //Document should not return a tagName
447
+ if (this.nodeName === '#document') {
448
+ t = null;
449
+ }
450
+ return t;
451
+ });
452
+
453
+ dom.Element.prototype.scrollTop = 0;
454
+ dom.Element.prototype.scrollLeft = 0;
455
+
456
+
457
+ dom.Element.prototype.__defineGetter__('text', function() {
458
+ if (this.attributes.getNamedItem('value')) {
459
+ return this.value;
460
+ } else {
461
+ return this.innerHTML;
462
+ }
463
+ });
464
+
465
+ dom.Element.prototype.__defineGetter__('textContent', function() {
466
+ var stripHTML = /<\S[^><]*>/g;
467
+ var out = this.innerHTML;
468
+ //Remove all the HTML
469
+ out = out.replace(stripHTML, '');
470
+ //Now decode the encoded text content
471
+ out = HTMLDecode(out);
472
+ return out;
473
+ });
474
+ dom.Element.prototype.__defineSetter__('textContent', function(txt) {
475
+ //Un encode all the entities
476
+ txt = HTMLEncode(txt);
477
+ //Set the content
478
+ this.innerHTML = txt;
479
+ return txt;
480
+ });
481
+
482
+
483
+ return dom;
484
+ }