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,70 @@
1
+
2
+ var dom = exports.dom = require("./jsdom/level3/index").dom;
3
+ exports.defaultLevel = dom.level3.html;
4
+ exports.browserAugmentation = require("./jsdom/browser/index").browserAugmentation;
5
+ exports.windowAugmentation = require("./jsdom/browser/index").windowAugmentation;
6
+
7
+ var createWindow = exports.createWindow = require("./jsdom/browser/index").createWindow;
8
+
9
+ exports.jsdom = function (html, level, options) {
10
+ level = level || exports.defaultLevel;
11
+ var browser = exports.browserAugmentation(level, (options || {})),
12
+ Document = browser.HTMLDocument || browser.Document;
13
+ doc = new Document();
14
+
15
+ if (options && options.url) {
16
+ doc.URL = options.url;
17
+ }
18
+
19
+ // Author: Swizec
20
+ // remove IE's expressions and expose what applies to us
21
+ if (html) {
22
+ html = html.replace(/<!--\[if .*\![(]*IE[)]*\]>(.+)<\!\[endif\]-->/gi, "$1");
23
+ }
24
+
25
+ doc.innerHTML = html || "<html><head></head><body></body></html>";
26
+
27
+ doc.createWindow = function(url) {
28
+ var window = exports.windowAugmentation(level, { document: doc, url: url });
29
+ if (window &&
30
+ window.document &&
31
+ window.document.createWindow)
32
+ {
33
+ delete window.document.createWindow;
34
+ }
35
+ return window;
36
+ }
37
+ return doc;
38
+ }
39
+
40
+ exports.jQueryify = function (window /* path [optional], callback */) {
41
+
42
+ if (!window || !window.document) { return; }
43
+
44
+ var args = Array.prototype.slice.call(arguments),
45
+ callback = (typeof(args[args.length - 1]) === 'function') && args.pop(),
46
+ path = undefined,
47
+ jQueryTag = window.document.createElement("script");
48
+
49
+ if (args.length > 1 && typeof(args[1] === 'string')) {
50
+ path = args[1];
51
+ }
52
+
53
+ if (path) {
54
+ path = !path.match(/^(file|http|https):/) ? 'file://' + path : path;
55
+ } else {
56
+ path = 'http://code.jquery.com/jquery-latest.js';
57
+ }
58
+
59
+ jQueryTag.src = path;
60
+
61
+ jQueryTag.onload = function() {
62
+ if (this.readyState === 'complete') {
63
+ if (callback) {
64
+ callback(window, window.jQuery);
65
+ }
66
+ }
67
+ };
68
+
69
+ return window;
70
+ };
@@ -0,0 +1,198 @@
1
+ //Make configurable from docType??
2
+ //Set in option
3
+ var isXHTML = false;
4
+
5
+ //List from node-htmlparser
6
+ var singleTags = {
7
+ area: 1,
8
+ base: 1,
9
+ basefont: 1,
10
+ br: 1,
11
+ col: 1,
12
+ frame: 1,
13
+ hr: 1,
14
+ img: 1,
15
+ input: 1,
16
+ isindex: 1,
17
+ link: 1,
18
+ meta: 1,
19
+ param: 1,
20
+ embed: 1
21
+ };
22
+
23
+ var singleTagsRegExp = (function() {
24
+ var tags = [];
25
+ for (var i in singleTags) {
26
+ tags.push(i);
27
+ }
28
+ return new RegExp('<' + tags.join('|<'), 'i');
29
+ })();
30
+
31
+ var uncanon = function(str, letter) {
32
+ return '-' + letter.toLowerCase();
33
+ };
34
+
35
+ var HTMLEncode = require('./htmlencoding').HTMLEncode;
36
+
37
+ var styleIgnore = {
38
+ top: 1,
39
+ left: 1
40
+ };
41
+
42
+ var stringifyElement = function(element) {
43
+ //sys.puts('Stringify HTML for: ' + element);
44
+ var tagName = element.tagName.toLowerCase(),
45
+ ret = {
46
+ start: "<" + tagName,
47
+ end:''
48
+ }, attributes = [], i,
49
+ attribute = null;
50
+
51
+ //sys.puts('Checking Attributes: ' + element._attributes.length);
52
+ //sys.puts(sys.inspect(element));
53
+ if (element.attributes.length) {
54
+ ret.start += " ";
55
+ for (i = 0; i<element.attributes.length; i++) {
56
+ attribute = element.attributes.item(i);
57
+ attributes.push(attribute.name + '="' +
58
+ HTMLEncode(attribute.nodeValue) + '"');
59
+ }
60
+ //sys.puts('attributes: ' + sys.inspect(attributes));
61
+ }
62
+ ret.start += attributes.join(" ");
63
+ if (element.style) {
64
+ var styleAttrs = [];
65
+ for (var i in element.style) {
66
+ if (!styleIgnore[i]) {
67
+ var use = true;
68
+ //sys.puts('Style: ' + i + ' :: ' + element.style[i] );
69
+ if (i === 'position' && element.style[i] === 'static') {
70
+ use = false;
71
+ }
72
+ if (element.style[i] === '') {
73
+ use = false;
74
+ }
75
+ if (use) {
76
+ styleAttrs.push(i.replace(/([A-Z])/g, uncanon) + ': ' +
77
+ HTMLEncode(element.style[i]));
78
+ }
79
+ }
80
+ }
81
+ if (styleAttrs.length) {
82
+ ret.start += ' style="' + styleAttrs.join('; ') + '"';
83
+ }
84
+ }
85
+
86
+ if (singleTags[tagName]) {
87
+ if (isXHTML) {
88
+ ret.start += "/";
89
+ }
90
+ ret.start += ">";
91
+ ret.end = '';
92
+ } else {
93
+ ret.start += ">";
94
+ ret.end = "</" + tagName + ">";
95
+ }
96
+
97
+ return ret;
98
+ };
99
+
100
+ var formatHTML = function(html) {
101
+ var formatted = '',
102
+ pad = 0;
103
+
104
+ html = html.replace(/(<(\/?\w+).*?>)(?=<(?!\/\2))/gi, '$1\r\n');
105
+ html.split('\r\n').forEach(function(node, index) {
106
+ var indent = 0, padding = '', i;
107
+
108
+ if (node.match( /.+<\/\w[^>]*>$/ )) {
109
+ indent = 0;
110
+ } else if (node.match( /^<\/\w/ )) {
111
+ if (pad != 0) {
112
+ pad -= 1;
113
+ }
114
+ } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
115
+ if (!singleTagsRegExp.exec(node)) {
116
+ indent = 1;
117
+ }
118
+ } else {
119
+ indent = 0;
120
+ }
121
+
122
+ for (i = 0; i < pad; i++) {
123
+ padding += ' ';
124
+ }
125
+
126
+ formatted += padding + node + '\r\n';
127
+ pad += indent;
128
+ });
129
+
130
+ return formatted;
131
+ };
132
+
133
+ var generateHtmlRecursive = function(element, rawText) {
134
+ //sys.puts('Generating HTML for: ' + element);
135
+
136
+ var ret = "";
137
+ if (element) {
138
+ if (element.nodeType &&
139
+ element.nodeType === element.ENTITY_REFERENCE_NODE)
140
+ {
141
+ element = element._entity;
142
+ }
143
+
144
+ rawText = rawText ||
145
+ element.parentNode &&
146
+ element.parentNode.nodeName &&
147
+ element.parentNode.nodeName.toUpperCase() === 'SCRIPT';
148
+
149
+ switch (element.nodeType) {
150
+ case element.ELEMENT_NODE:
151
+ var current = stringifyElement(element);
152
+ ret += current.start;
153
+
154
+ if (element.childNodes.length > 0) {
155
+ for (var i=0; i<element.childNodes.length; i++) {
156
+ ret += generateHtmlRecursive(element.childNodes.item(i), rawText);
157
+ }
158
+ } else {
159
+ ret += rawText ? element.nodeValue : HTMLEncode(element.nodeValue);
160
+ }
161
+ ret += current.end;
162
+ break;
163
+ case element.TEXT_NODE:
164
+ ret += rawText ? element.nodeValue : HTMLEncode(element.nodeValue);
165
+ break;
166
+ case element.COMMENT_NODE:
167
+ ret += '<!--' + element.nodeValue + '-->';
168
+ break;
169
+ case element.DOCUMENT_NODE:
170
+ ret += generateHtmlRecursive(element.documentElement, rawText);
171
+ break;
172
+ }
173
+ }
174
+ //require('sys').puts(require('sys').inspect(ret));
175
+ return ret;
176
+ };
177
+
178
+ exports.domToHtml = function(dom, noformat) {
179
+
180
+ var ret = "";
181
+ if(dom.item){
182
+ // node list
183
+ var length = dom.length;
184
+ for (var i=0; i<length; i++) {
185
+ ret += generateHtmlRecursive(dom.item(i));
186
+ }
187
+
188
+ } else {
189
+ // single node
190
+ ret = generateHtmlRecursive(dom);
191
+ }
192
+ if (noformat) {
193
+ return ret;
194
+ } else {
195
+ return formatHTML(ret);
196
+ }
197
+
198
+ };
@@ -0,0 +1,381 @@
1
+
2
+ /* {{{ Encoding Methods borrowed from PHP.js
3
+ http://phpjs.org/pages/license/#MIT
4
+
5
+ * More info at: http://phpjs.org
6
+ *
7
+ * This is version: 3.09
8
+ * php.js is copyright 2010 Kevin van Zonneveld.
9
+ *
10
+ * Portions copyright Brett Zamir (http://brett-zamir.me), Kevin van Zonneveld
11
+ * (http://kevin.vanzonneveld.net), Onno Marsman, Theriault, Michael White
12
+ * (http://getsprink.com), Waldo Malqui Silva, Paulo Ricardo F. Santos, Jack,
13
+ * Jonas Raoni Soares Silva (http://www.jsfromhell.com), Philip Peterson,
14
+ * Legaev Andrey, Ates Goral (http://magnetiq.com), Alex, Ratheous, Martijn
15
+ * Wieringa, Nate, Philippe Baumann, lmeyrick
16
+ * (https://sourceforge.net/projects/bcmath-js/), Enrique Gonzalez,
17
+ * Webtoolkit.info (http://www.webtoolkit.info/), Jani Hartikainen, travc, Ole
18
+ * Vrijenhoek, Ash Searle (http://hexmen.com/blog/), Carlos R. L. Rodrigues
19
+ * (http://www.jsfromhell.com), d3x,
20
+ * http://stackoverflow.com/questions/57803/how-to-convert-decimal-to-hex-in-javascript,
21
+ * pilus, stag019, WebDevHobo (http://webdevhobo.blogspot.com/), Michael
22
+ * Grier, Erkekjetter, T.Wild, Andrea Giammarchi
23
+ * (http://webreflection.blogspot.com), marrtins, GeekFG
24
+ * (http://geekfg.blogspot.com), Johnny Mast (http://www.phpvrouwen.nl),
25
+ * gorthaur, Michael White, majak, Steve Hilder, Oleg Eremeev, Martin
26
+ * (http://www.erlenwiese.de/), gettimeofday, Joris, Steven Levithan
27
+ * (http://blog.stevenlevithan.com), Tim de Koning (http://www.kingsquare.nl),
28
+ * KELAN, Arpad Ray (mailto:arpad@php.net), Breaking Par Consulting Inc
29
+ * (http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256CFB006C45F7),
30
+ * Josh Fraser
31
+ * (http://onlineaspect.com/2007/06/08/auto-detect-a-time-zone-with-javascript/),
32
+ * Chris, Marc Palau, Public Domain (http://www.json.org/json2.js), saulius,
33
+ * Aman Gupta, Pellentesque Malesuada, Mailfaker (http://www.weedem.fr/), Caio
34
+ * Ariede (http://caioariede.com), Thunder.m, Alfonso Jimenez
35
+ * (http://www.alfonsojimenez.com), AJ, mdsjack (http://www.mdsjack.bo.it),
36
+ * Lars Fischer, Kankrelune (http://www.webfaktory.info/), Felix Geisendoerfer
37
+ * (http://www.debuggable.com/felix), Tyler Akins (http://rumkin.com), Mirek
38
+ * Slugen, Robin, Karol Kowalski, Paul Smith, Sakimori, David, noname, Marco,
39
+ * Douglas Crockford (http://javascript.crockford.com), Scott Cariss,
40
+ * class_exists, marc andreu, Steve Clay, Francois, nobbler, David James,
41
+ * Arno, madipta, Fox, mktime, ger, Nathan, felix, Frank Forte, Slawomir
42
+ * Kaniecki, john (http://www.jd-tech.net), Nick Kolosov (http://sammy.ru),
43
+ * Mateusz "loonquawl" Zalega, ReverseSyntax, nord_ua, T. Wild, Thiago Mata
44
+ * (http://thiagomata.blog.com), Linuxworld, lmeyrick
45
+ * (https://sourceforge.net/projects/bcmath-js/this.), Jon Hohle, Pyerre,
46
+ * MeEtc (http://yass.meetcweb.com), Peter-Paul Koch
47
+ * (http://www.quirksmode.org/js/beat.html), T0bsn, Soren Hansen, djmix,
48
+ * Lincoln Ramsay, Sanjoy Roy, sankai, Denny Wardhana, 0m3r, Subhasis Deb,
49
+ * Bayron Guevara, paulo kuong, duncan, Gilbert, Brad Touesnard, Tim Wiel,
50
+ * Marc Jansen, Francesco, Stoyan Kyosev (http://www.svest.org/), J A R, Paul,
51
+ * Ole Vrijenhoek (http://www.nervous.nl/), Raphael (Ao RUDLER), kenneth, Hyam
52
+ * Singer (http://www.impact-computing.com/), LH, JB, JT, Thomas Beaucourt
53
+ * (http://www.webapp.fr), David Randall, Bryan Elliott, date, Ozh, Eugene
54
+ * Bulkin (http://doubleaw.com/), Der Simon
55
+ * (http://innerdom.sourceforge.net/), echo is bad, XoraX
56
+ * (http://www.xorax.info), Matt Bradley, Itsacon (http://www.itsacon.net/),
57
+ * Saulo Vallory, Kristof Coomans (SCK-CEN Belgian Nucleair Research Centre),
58
+ * Pierre-Luc Paour, Kirk Strobeck, Martin Pool, Christoph, Daniel Esteban,
59
+ * Artur Tchernychev, Wagner B. Soares, Valentina De Rosa, strftime, Jason
60
+ * Wong (http://carrot.org/), Brant Messenger
61
+ * (http://www.brantmessenger.com/), Rick Waldron, Bug?, Anton Ongson, Simon
62
+ * Willison (http://simonwillison.net), Marco van Oort, Gabriel Paderni, Blues
63
+ * (http://tech.bluesmoon.info/), Luke Godfrey, rezna, Mick@el, Tomasz
64
+ * Wesolowski, Eric Nagel, Pul, Bobby Drake, uestla, Alan C, Ulrich, Yves
65
+ * Sucaet, sowberry, Norman "zEh" Fuchs, hitwork, Zahlii, johnrembo, Nick
66
+ * Callen, ejsanders, Aidan Lister (http://aidanlister.com/), Brian Tafoya
67
+ * (http://www.premasolutions.com/), Philippe Jausions
68
+ * (http://pear.php.net/user/jausions), Rob, Orlando, HKM, metjay, strcasecmp,
69
+ * strcmp, Taras Bogach, jpfle, ChaosNo1, Alexander Ermolaev
70
+ * (http://snippets.dzone.com/user/AlexanderErmolaev), dptr1988, kilops, Le
71
+ * Torbi, James, DxGx, Pedro Tainha (http://www.pedrotainha.com), Philipp
72
+ * Lenssen, penutbutterjelly, FGFEmperor, baris ozdil, Greg Frazier, Alexander
73
+ * M Beedie, Tod Gentille, gabriel paderni, Yannoo, Maximusya, Atli Þór,
74
+ * daniel airton wermann (http://wermann.com.br), jakes, 3D-GRAF, Riddler
75
+ * (http://www.frontierwebdev.com/), T.J. Leahy, Matteo, stensi, Billy, Jalal
76
+ * Berrami, vlado houba, Victor, fearphage
77
+ * (http://http/my.opera.com/fearphage/), Luis Salazar
78
+ * (http://www.freaky-media.com/), FremyCompany, Tim de Koning, taith, Cord,
79
+ * Manish, davook, Benjamin Lupton, Russell Walker (http://www.nbill.co.uk/),
80
+ * Garagoth, Andrej Pavlovic, rem, Dino, Jamie Beck (http://www.terabit.ca/),
81
+ * DtTvB (http://dt.in.th/2008-09-16.string-length-in-bytes.html), Michael,
82
+ * Christian Doebler, setcookie, YUI Library:
83
+ * http://developer.yahoo.com/yui/docs/YAHOO.util.DateLocale.html, Andreas,
84
+ * Blues at http://hacks.bluesmoon.info/strftime/strftime.js, meo, Greenseed,
85
+ * Luke Smith (http://lucassmith.name), Rival, Diogo Resende, Allan Jensen
86
+ * (http://www.winternet.no), Howard Yeend, Kheang Hok Chin
87
+ * (http://www.distantia.ca/), Jay Klehr, Leslie Hoare, mk.keck, Ben Bryan,
88
+ * booeyOH, Amir Habibi (http://www.residence-mixte.com/), Cagri Ekin
89
+ *
90
+ * Dual licensed under the MIT (MIT-LICENSE.txt)
91
+ * and GPL (GPL-LICENSE.txt) licenses.
92
+ *
93
+ * Permission is hereby granted, free of charge, to any person obtaining a
94
+ * copy of this software and associated documentation files (the
95
+ * "Software"), to deal in the Software without restriction, including
96
+ * without limitation the rights to use, copy, modify, merge, publish,
97
+ * distribute, sublicense, and/or sell copies of the Software, and to
98
+ * permit persons to whom the Software is furnished to do so, subject to
99
+ * the following conditions:
100
+ *
101
+ * The above copyright notice and this permission notice shall be included
102
+ * in all copies or substantial portions of the Software.
103
+ *
104
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
105
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
106
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
107
+ * IN NO EVENT SHALL KEVIN VAN ZONNEVELD BE LIABLE FOR ANY CLAIM, DAMAGES
108
+ * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
109
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
110
+ * OTHER DEALINGS IN THE SOFTWARE.
111
+ */
112
+
113
+ var htmlentities = function(string, quote_style) {
114
+ // http://kevin.vanzonneveld.net
115
+ // + original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
116
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
117
+ // + improved by: nobbler
118
+ // + tweaked by: Jack
119
+ // + bugfixed by: Onno Marsman
120
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
121
+ // + bugfixed by: Brett Zamir (http://brett-zamir.me)
122
+ // + input by: Ratheous
123
+ // - depends on: get_html_translation_table
124
+ // * example 1: htmlentities('Kevin & van Zonneveld');
125
+ // * returns 1: 'Kevin &amp; van Zonneveld'
126
+ // * example 2: htmlentities("foo'bar","ENT_QUOTES");
127
+ // * returns 2: 'foo&#039;bar'
128
+
129
+ string = string || "";
130
+
131
+ var hash_map = {}, symbol, tmp_str = '', entity = '';
132
+ tmp_str = string.toString();
133
+
134
+
135
+ if (false === (hash_map = get_html_translation_table('HTML_SPECIALCHARS', quote_style))) {
136
+ return false;
137
+ }
138
+
139
+ hash_map["'"] = '&#039;';
140
+ delete hash_map["&"];
141
+
142
+ tmp_str = tmp_str.split('&#39;').join("'");
143
+ tmp_str = tmp_str.split('&#34;').join('"');
144
+ tmp_str = tmp_str.split('&apos;').join("'");
145
+ tmp_str = tmp_str.split('&quot;').join('"');
146
+
147
+ // amended by ejones - get_html_translation_table no longer translates
148
+ // char codes by default
149
+
150
+ //hash_map["'"] = '&#039;';
151
+ delete hash_map['38']; // &
152
+ tmp_str = tmp_str.split('&').join('&amp;');
153
+ for (symbol in hash_map) {
154
+ tmp_str = tmp_str
155
+ .split(String.fromCharCode(symbol))
156
+ .join(hash_map[symbol]);
157
+ }
158
+
159
+ return tmp_str;
160
+ };
161
+
162
+ var html_entity_decode = function(string, quote_style) {
163
+ // http://kevin.vanzonneveld.net
164
+ // + original by: john (http://www.jd-tech.net)
165
+ // + input by: ger
166
+ // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
167
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
168
+ // + bugfixed by: Onno Marsman
169
+ // + improved by: marc andreu
170
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
171
+ // + input by: Ratheous
172
+ // + bugfixed by: Brett Zamir (http://brett-zamir.me)
173
+ // + input by: Nick Kolosov (http://sammy.ru)
174
+ // + bugfixed by: Fox
175
+ // - depends on: get_html_translation_table
176
+ // * example 1: html_entity_decode('Kevin &amp; van Zonneveld');
177
+ // * returns 1: 'Kevin & van Zonneveld'
178
+ // * example 2: html_entity_decode('&amp;lt;');
179
+ // * returns 2: '&lt;'
180
+
181
+ string = string || "";
182
+
183
+ var hash_map = {}, symbol, tmp_str = '',
184
+ entity = '', entity_to_char_code = {};
185
+ tmp_str = string.toString();
186
+
187
+ if (false === (hash_map = get_html_translation_table('HTML_ENTITIES', quote_style))) {
188
+ return false;
189
+ }
190
+
191
+
192
+ // amended by ejones - more flexible recognition of entities
193
+ for (symbol in hash_map) {
194
+ entity_to_char_code[hash_map[symbol]] = symbol;
195
+ }
196
+
197
+ tmp_str = tmp_str.replace(/&([#a-z0-9]+);/gi, function( ent, ename ) {
198
+ var char = entity_to_char_code[ent];
199
+ if (char == null && ename === 'apos') char = 39;
200
+ if (char == null && ename[0] === '#') {
201
+ if (ename[1].toLowerCase() === 'x') {
202
+ char = parseInt(ename.substring(2), 16);
203
+ } else {
204
+ char = parseInt(ename.substring(1), 10);
205
+ };
206
+ if (isNaN(char)) char = null;
207
+ };
208
+ return char != null ? String.fromCharCode(char) : ent;
209
+ });
210
+
211
+ return tmp_str;
212
+ };
213
+
214
+
215
+ var get_html_translation_table = function(table, quote_style) {
216
+ // http://kevin.vanzonneveld.net
217
+ // + original by: Philip Peterson
218
+ // + revised by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
219
+ // + bugfixed by: noname
220
+ // + bugfixed by: Alex
221
+ // + bugfixed by: Marco
222
+ // + bugfixed by: madipta
223
+ // + improved by: KELAN
224
+ // + improved by: Brett Zamir (http://brett-zamir.me)
225
+ // + bugfixed by: Brett Zamir (http://brett-zamir.me)
226
+ // + input by: Frank Forte
227
+ // + bugfixed by: T.Wild
228
+ // + input by: Ratheous
229
+ // % note: It has been decided that we're not going to add global
230
+ // % note: dependencies to php.js, meaning the constants are not
231
+ // % note: real constants, but strings instead. Integers are also supported if someone
232
+ // % note: chooses to create the constants themselves.
233
+ // * example 1: get_html_translation_table('HTML_SPECIALCHARS');
234
+ // * returns 1: {'"': '&quot;', '&': '&amp;', '<': '&lt;', '>': '&gt;'}
235
+
236
+ var entities = {}, hash_map = {}, decimal = 0, symbol = '';
237
+ var constMappingTable = {}, constMappingQuoteStyle = {};
238
+ var useTable = {}, useQuoteStyle = {};
239
+
240
+ // Translate arguments
241
+ constMappingTable[0] = 'HTML_SPECIALCHARS';
242
+ constMappingTable[1] = 'HTML_ENTITIES';
243
+ constMappingQuoteStyle[0] = 'ENT_NOQUOTES';
244
+ constMappingQuoteStyle[2] = 'ENT_COMPAT';
245
+ constMappingQuoteStyle[3] = 'ENT_QUOTES';
246
+
247
+ useTable = !isNaN(table) ? constMappingTable[table] : table ? table.toUpperCase() : 'HTML_SPECIALCHARS';
248
+ useQuoteStyle = !isNaN(quote_style) ? constMappingQuoteStyle[quote_style] : quote_style ? quote_style.toUpperCase() : 'ENT_QUOTES';
249
+
250
+ if (useTable !== 'HTML_SPECIALCHARS' && useTable !== 'HTML_ENTITIES') {
251
+ throw new Error("Table: "+useTable+' not supported');
252
+ // return false;
253
+ }
254
+
255
+ entities['38'] = '&amp;';
256
+ if (useTable === 'HTML_ENTITIES') {
257
+ entities['160'] = '&nbsp;';
258
+ entities['161'] = '&iexcl;';
259
+ entities['162'] = '&cent;';
260
+ entities['163'] = '&pound;';
261
+ entities['164'] = '&curren;';
262
+ entities['165'] = '&yen;';
263
+ entities['166'] = '&brvbar;';
264
+ entities['167'] = '&sect;';
265
+ entities['168'] = '&uml;';
266
+ entities['169'] = '&copy;';
267
+ entities['170'] = '&ordf;';
268
+ entities['171'] = '&laquo;';
269
+ entities['172'] = '&not;';
270
+ entities['173'] = '&shy;';
271
+ entities['174'] = '&reg;';
272
+ entities['175'] = '&macr;';
273
+ entities['176'] = '&deg;';
274
+ entities['177'] = '&plusmn;';
275
+ entities['178'] = '&sup2;';
276
+ entities['179'] = '&sup3;';
277
+ entities['180'] = '&acute;';
278
+ entities['181'] = '&micro;';
279
+ entities['182'] = '&para;';
280
+ entities['183'] = '&middot;';
281
+ entities['184'] = '&cedil;';
282
+ entities['185'] = '&sup1;';
283
+ entities['186'] = '&ordm;';
284
+ entities['187'] = '&raquo;';
285
+ entities['188'] = '&frac14;';
286
+ entities['189'] = '&frac12;';
287
+ entities['190'] = '&frac34;';
288
+ entities['191'] = '&iquest;';
289
+ entities['192'] = '&Agrave;';
290
+ entities['193'] = '&Aacute;';
291
+ entities['194'] = '&Acirc;';
292
+ entities['195'] = '&Atilde;';
293
+ entities['196'] = '&Auml;';
294
+ entities['197'] = '&Aring;';
295
+ entities['198'] = '&AElig;';
296
+ entities['199'] = '&Ccedil;';
297
+ entities['200'] = '&Egrave;';
298
+ entities['201'] = '&Eacute;';
299
+ entities['202'] = '&Ecirc;';
300
+ entities['203'] = '&Euml;';
301
+ entities['204'] = '&Igrave;';
302
+ entities['205'] = '&Iacute;';
303
+ entities['206'] = '&Icirc;';
304
+ entities['207'] = '&Iuml;';
305
+ entities['208'] = '&ETH;';
306
+ entities['209'] = '&Ntilde;';
307
+ entities['210'] = '&Ograve;';
308
+ entities['211'] = '&Oacute;';
309
+ entities['212'] = '&Ocirc;';
310
+ entities['213'] = '&Otilde;';
311
+ entities['214'] = '&Ouml;';
312
+ entities['215'] = '&times;';
313
+ entities['216'] = '&Oslash;';
314
+ entities['217'] = '&Ugrave;';
315
+ entities['218'] = '&Uacute;';
316
+ entities['219'] = '&Ucirc;';
317
+ entities['220'] = '&Uuml;';
318
+ entities['221'] = '&Yacute;';
319
+ entities['222'] = '&THORN;';
320
+ entities['223'] = '&szlig;';
321
+ entities['224'] = '&agrave;';
322
+ entities['225'] = '&aacute;';
323
+ entities['226'] = '&acirc;';
324
+ entities['227'] = '&atilde;';
325
+ entities['228'] = '&auml;';
326
+ entities['229'] = '&aring;';
327
+ entities['230'] = '&aelig;';
328
+ entities['231'] = '&ccedil;';
329
+ entities['232'] = '&egrave;';
330
+ entities['233'] = '&eacute;';
331
+ entities['234'] = '&ecirc;';
332
+ entities['235'] = '&euml;';
333
+ entities['236'] = '&igrave;';
334
+ entities['237'] = '&iacute;';
335
+ entities['238'] = '&icirc;';
336
+ entities['239'] = '&iuml;';
337
+ entities['240'] = '&eth;';
338
+ entities['241'] = '&ntilde;';
339
+ entities['242'] = '&ograve;';
340
+ entities['243'] = '&oacute;';
341
+ entities['244'] = '&ocirc;';
342
+ entities['245'] = '&otilde;';
343
+ entities['246'] = '&ouml;';
344
+ entities['247'] = '&divide;';
345
+ entities['248'] = '&oslash;';
346
+ entities['249'] = '&ugrave;';
347
+ entities['250'] = '&uacute;';
348
+ entities['251'] = '&ucirc;';
349
+ entities['252'] = '&uuml;';
350
+ entities['253'] = '&yacute;';
351
+ entities['254'] = '&thorn;';
352
+ entities['255'] = '&yuml;';
353
+ }
354
+
355
+ if (useQuoteStyle !== 'ENT_NOQUOTES') {
356
+ entities['34'] = '&quot;';
357
+ }
358
+ if (useQuoteStyle === 'ENT_QUOTES') {
359
+ entities['39'] = '&#39;';
360
+ }
361
+ entities['60'] = '&lt;';
362
+ entities['62'] = '&gt;';
363
+
364
+
365
+
366
+ // removed by ejones - translation now done in encoding/decoding
367
+
368
+ //// ascii decimals to real symbols
369
+ //for (decimal in entities) {
370
+ // symbol = String.fromCharCode(decimal);
371
+ // hash_map[symbol] = entities[decimal];
372
+ //}
373
+
374
+ //return hash_map;
375
+
376
+ return entities;
377
+ };
378
+
379
+ /* }}} */
380
+ exports.HTMLEncode = htmlentities;
381
+ exports.HTMLDecode = html_entity_decode;