envjs 0.1.7 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (187) hide show
  1. data/.jslintrbrc +29 -0
  2. data/.project +17 -0
  3. data/CHANGELOG.rdoc +3 -0
  4. data/DTD/xhtml-lat1.ent +196 -0
  5. data/DTD/xhtml-special.ent +80 -0
  6. data/DTD/xhtml-symbol.ent +237 -0
  7. data/DTD/xhtml.soc +14 -0
  8. data/DTD/xhtml1-frameset.dtd +1235 -0
  9. data/DTD/xhtml1-strict.dtd +978 -0
  10. data/DTD/xhtml1-transitional.dtd +1201 -0
  11. data/DTD/xhtml1.dcl +192 -0
  12. data/Makefile +7 -0
  13. data/Manifest.txt +287 -0
  14. data/{README → README.rdoc} +24 -3
  15. data/Rakefile +196 -0
  16. data/Wakefile +24 -0
  17. data/build.properties +9 -0
  18. data/build.xml +247 -0
  19. data/gm/jquery.js +6002 -0
  20. data/gm/mainx.js +2648 -0
  21. data/gm/sensx.js +135 -0
  22. data/gm/t.js +6 -0
  23. data/gm/x.html +76 -0
  24. data/htmlparser/BrowserTreeBuilder.java +456 -0
  25. data/htmlparser/README +34 -0
  26. data/htmlparser/build.sh +38 -0
  27. data/jsl/jsl +0 -0
  28. data/jsl/jsl.default.conf +129 -0
  29. data/jsl/jsl.exe +0 -0
  30. data/lib/envjs.rb +2 -0
  31. data/lib/envjs/env.js +22 -3
  32. data/lib/envjs/event_loop.js +2 -0
  33. data/lib/envjs/static.js +155 -21
  34. data/licenses/GPL-LICENSE.txt +278 -0
  35. data/licenses/MIT-LICENSE.txt +20 -0
  36. data/src/base64.js +80 -0
  37. data/src/build.js +6 -0
  38. data/src/cruft/bad.html +24 -0
  39. data/src/cruft/dom.js +606 -0
  40. data/src/cruft/element.js +297 -0
  41. data/src/cruft/good.html +30 -0
  42. data/src/cruft/good.js +32 -0
  43. data/src/cruft/internal.js +81 -0
  44. data/src/cruft/parser.js +458 -0
  45. data/src/css/properties.js +293 -0
  46. data/src/css/rule.js +22 -0
  47. data/src/css/sizzle.js +717 -0
  48. data/src/css/stylesheet.js +52 -0
  49. data/src/dom/attr.js +55 -0
  50. data/src/dom/cdatasection.js +31 -0
  51. data/src/dom/characterdata.js +119 -0
  52. data/src/dom/comment.js +30 -0
  53. data/src/dom/doctype.js +9 -0
  54. data/src/dom/document.js +553 -0
  55. data/src/dom/dom.js +134 -0
  56. data/src/dom/element.js +217 -0
  57. data/src/dom/entities.js +273 -0
  58. data/src/dom/exception.js +28 -0
  59. data/src/dom/fragment.js +37 -0
  60. data/src/dom/implementation.js +602 -0
  61. data/src/dom/instruction.js +51 -0
  62. data/src/dom/namednodemap.js +374 -0
  63. data/src/dom/namespace.js +50 -0
  64. data/src/dom/node.js +618 -0
  65. data/src/dom/nodelist.js +195 -0
  66. data/src/dom/parser.js +1207 -0
  67. data/src/dom/text.js +73 -0
  68. data/src/event/event.js +39 -0
  69. data/src/event/mouseevent.js +4 -0
  70. data/src/event/uievent.js +8 -0
  71. data/src/html/a.js +110 -0
  72. data/src/html/anchor.js +80 -0
  73. data/src/html/area.js +57 -0
  74. data/src/html/base.js +26 -0
  75. data/src/html/blockquote-q.js +19 -0
  76. data/src/html/body.js +19 -0
  77. data/src/html/button.js +21 -0
  78. data/src/html/canvas.js +14 -0
  79. data/src/html/col-colgroup.js +49 -0
  80. data/src/html/collection.js +72 -0
  81. data/src/html/cookie.js +151 -0
  82. data/src/html/del-ins.js +25 -0
  83. data/src/html/div.js +28 -0
  84. data/src/html/document.js +359 -0
  85. data/src/html/element.js +380 -0
  86. data/src/html/fieldset.js +19 -0
  87. data/src/html/form.js +484 -0
  88. data/src/html/frame.js +89 -0
  89. data/src/html/frameset.js +25 -0
  90. data/src/html/head.js +44 -0
  91. data/src/html/html.js +0 -0
  92. data/src/html/htmlparser.js +340 -0
  93. data/src/html/iframe.js +26 -0
  94. data/src/html/image.js +0 -0
  95. data/src/html/img.js +62 -0
  96. data/src/html/input-elements.js +307 -0
  97. data/src/html/input.js +65 -0
  98. data/src/html/label.js +26 -0
  99. data/src/html/legend.js +19 -0
  100. data/src/html/link.js +82 -0
  101. data/src/html/map.js +22 -0
  102. data/src/html/meta.js +37 -0
  103. data/src/html/object.js +89 -0
  104. data/src/html/optgroup.js +25 -0
  105. data/src/html/option.js +97 -0
  106. data/src/html/param.js +38 -0
  107. data/src/html/script.js +122 -0
  108. data/src/html/select.js +129 -0
  109. data/src/html/style.js +31 -0
  110. data/src/html/table.js +199 -0
  111. data/src/html/tbody-thead-tfoot.js +91 -0
  112. data/src/html/td-th.js +18 -0
  113. data/src/html/textarea.js +25 -0
  114. data/src/html/title.js +20 -0
  115. data/src/html/tr.js +114 -0
  116. data/src/intro.js +141 -0
  117. data/src/outro.js +70 -0
  118. data/src/parser/html5.detailed.js +10762 -0
  119. data/src/parser/html5.min.js +503 -0
  120. data/src/parser/html5.pretty.js +10815 -0
  121. data/src/parser/intro.js +42 -0
  122. data/src/parser/outro.js +9 -0
  123. data/src/platform/core.js +323 -0
  124. data/src/platform/johnson.js +479 -0
  125. data/src/platform/rhino.js +327 -0
  126. data/src/platform/static/intro.js +41 -0
  127. data/src/platform/static/outro.js +30 -0
  128. data/src/profile/aop.js +238 -0
  129. data/src/profile/profile.js +402 -0
  130. data/src/serializer/xml.js +21 -0
  131. data/src/svg/animatedstring.js +25 -0
  132. data/src/svg/document.js +25 -0
  133. data/src/svg/element.js +22 -0
  134. data/src/svg/locatable.js +17 -0
  135. data/src/svg/rect.js +18 -0
  136. data/src/svg/rectelement.js +24 -0
  137. data/src/svg/stylable.js +49 -0
  138. data/src/svg/svgelement.js +22 -0
  139. data/src/svg/transformable.js +15 -0
  140. data/src/window/css.js +15 -0
  141. data/src/window/dialog.js +16 -0
  142. data/src/window/document.js +28 -0
  143. data/src/window/event.js +262 -0
  144. data/src/window/history.js +62 -0
  145. data/src/window/location.js +138 -0
  146. data/src/window/navigator.js +48 -0
  147. data/src/window/screen.js +53 -0
  148. data/src/window/timer.js +21 -0
  149. data/src/window/window.js +284 -0
  150. data/src/window/xhr.js +127 -0
  151. data/src/xpath/expression.js +49 -0
  152. data/src/xpath/implementation.js +2482 -0
  153. data/src/xpath/result.js +67 -0
  154. data/src/xpath/util.js +551 -0
  155. data/src/xpath/xmltoken.js +149 -0
  156. data/src/xslt/COPYING +34 -0
  157. data/src/xslt/ajaxslt-0.8.1/AUTHORS +1 -0
  158. data/src/xslt/ajaxslt-0.8.1/ChangeLog +136 -0
  159. data/src/xslt/ajaxslt-0.8.1/Makefile +49 -0
  160. data/src/xslt/ajaxslt-0.8.1/README +102 -0
  161. data/src/xslt/ajaxslt-0.8.1/TODO +15 -0
  162. data/src/xslt/ajaxslt-0.8.1/dom.js +566 -0
  163. data/src/xslt/ajaxslt-0.8.1/dom_unittest.html +24 -0
  164. data/src/xslt/ajaxslt-0.8.1/dom_unittest.js +131 -0
  165. data/src/xslt/ajaxslt-0.8.1/simplelog.js +79 -0
  166. data/src/xslt/ajaxslt-0.8.1/test/xpath.html +18 -0
  167. data/src/xslt/ajaxslt-0.8.1/test/xpath_script.js +45 -0
  168. data/src/xslt/ajaxslt-0.8.1/test/xslt.html +58 -0
  169. data/src/xslt/ajaxslt-0.8.1/test/xslt_script.js +33 -0
  170. data/src/xslt/ajaxslt-0.8.1/unittestsuite.html +26 -0
  171. data/src/xslt/ajaxslt-0.8.1/xmltoken.js +149 -0
  172. data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.html +18 -0
  173. data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.js +811 -0
  174. data/src/xslt/ajaxslt-0.8.1/xpath_unittest.html +39 -0
  175. data/src/xslt/ajaxslt-0.8.1/xpath_unittest.js +557 -0
  176. data/src/xslt/ajaxslt-0.8.1/xpathdebug.js +234 -0
  177. data/src/xslt/ajaxslt-0.8.1/xslt_unittest.html +138 -0
  178. data/src/xslt/ajaxslt-0.8.1/xslt_unittest.js +68 -0
  179. data/src/xslt/implementation.js +625 -0
  180. data/src/xslt/processor.js +37 -0
  181. data/src/xslt/util.js +449 -0
  182. data/test/foo.html +8 -0
  183. data/test/foo.js +40 -0
  184. data/test/jquery.js +6002 -0
  185. data/test/x.js +1 -0
  186. data/test/y.js +1 -0
  187. metadata +245 -14
@@ -0,0 +1,297 @@
1
+ /*
2
+ * HTMLElement - DOM Level 2
3
+ */
4
+ $w.__defineGetter__("HTMLElement", function(){
5
+ return function(){
6
+ throw new Error("Object cannot be created in this context");
7
+ };
8
+ });
9
+
10
+ var Element = function(node){
11
+ var $dom = node,
12
+ $id = createGUID();
13
+
14
+ $w.__defineGetter__("Element", function(){
15
+ var $dom, $id;
16
+ return function(elem){
17
+ $dom = elem;
18
+ $id = createGUID();
19
+ __extend__(this, new DOMNode($dom));
20
+
21
+ // A lot of the methods defined below belong in HTML specific
22
+ // subclasses. This is already unwieldy since most of these
23
+ //methods are meant for general xml consumption
24
+ __extend__(this, {
25
+ get nodeName(){
26
+ return this.tagName;
27
+ },
28
+ get tagName(){
29
+ return $dom.getTagName().toUpperCase();
30
+ },
31
+ toString: function(){
32
+ return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
33
+ },
34
+ get outerHTML(){
35
+ var ret = "<" + this.tagName, attr = this.attributes;
36
+
37
+ for ( var i in attr )
38
+ ret += " " + i + "='" + attr[i] + "'";
39
+
40
+ if ( this.childNodes.length || this.nodeName == "SCRIPT" )
41
+ ret += ">" + this.childNodes.outerHTML +
42
+ "</" + this.tagName + ">";
43
+ else
44
+ ret += "/>";
45
+
46
+ return ret;
47
+ },
48
+
49
+ get attributes(){
50
+ var attr = {}, attrs = $dom.getAttributes();
51
+ for ( var i = 0; i < attrs.getLength(); i++ ){
52
+ attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
53
+ }return attr;
54
+ },
55
+
56
+ get innerHTML(){
57
+ return this.childNodes.outerHTML;
58
+ },
59
+ set innerHTML(html){
60
+ html = html.replace(/<\/?([A-Z]+)/g, function(m){
61
+ return m.toLowerCase();
62
+ }).replace(/&nbsp;/g, " ");
63
+
64
+ var dom = new DOMParser().parseFromString("<wrap>" + html + "</wrap>");
65
+ var nodes = this.ownerDocument.importNode( dom.documentElement, true ).childNodes;
66
+
67
+ while (this.firstChild){
68
+ this.removeChild( this.firstChild );
69
+ }
70
+
71
+ for ( var i = 0; i < nodes.length; i++ )
72
+ this.appendChild( nodes[i] );
73
+ },
74
+
75
+ get textContent(){
76
+ function nav(nodes){
77
+ var str = "";
78
+ for ( var i = 0; i < nodes.length; i++ ){
79
+ if ( nodes[i].nodeType == 3 ){
80
+ str += nodes[i].nodeValue;
81
+ }else if ( nodes[i].nodeType == 1 ){
82
+ str += nav(nodes[i].childNodes);
83
+ }
84
+ } return str;
85
+ } return nav(this.childNodes);
86
+ },
87
+ set textContent(text){
88
+ while (this.firstChild)
89
+ this.removeChild( this.firstChild );
90
+ this.appendChild( this.ownerDocument.createTextNode(text));
91
+ },
92
+
93
+ style: {},
94
+ clientHeight: 0,
95
+ clientWidth: 0,
96
+ offsetHeight: 0,
97
+ offsetWidth: 0,
98
+
99
+ get disabled() {
100
+ var val = this.getAttribute("disabled");
101
+ return val != "false" && !!val;
102
+ },
103
+ set disabled(val) { return this.setAttribute("disabled",val); },
104
+
105
+ get checked() {
106
+ var val = this.getAttribute("checked");
107
+ return val != "false" && !!val;
108
+ },
109
+ set checked(val) { return this.setAttribute("checked",val); },
110
+
111
+ get selected() {
112
+ if ( !this._selectDone ) {
113
+ this._selectDone = true;
114
+
115
+ if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
116
+ var opt = this.parentNode.getElementsByTagName("option");
117
+
118
+ if ( this == opt[0] ) {
119
+ var select = true;
120
+
121
+ for ( var i = 1; i < opt.length; i++ ){
122
+ if ( opt[i].selected ) {
123
+ select = false;
124
+ break;
125
+ }
126
+ }
127
+ if ( select ){ this.selected = true; }
128
+ }
129
+ }
130
+ }
131
+
132
+ var val = this.getAttribute("selected");
133
+ return val != "false" && !!val;
134
+ },
135
+ set selected(val) { return this.setAttribute("selected",val); },
136
+
137
+ get className() { return this.getAttribute("class") || ""; },
138
+ set className(val) {
139
+ return this.setAttribute("class",
140
+ val.replace(/(^\s*|\s*$)/g,""));
141
+ },
142
+
143
+ get type() { return this.getAttribute("type") || ""; },
144
+ set type(val) { return this.setAttribute("type",val); },
145
+
146
+ get defaultValue() { return this.getAttribute("defaultValue") || ""; },
147
+ set defaultValue(val) { return this.setAttribute("defaultValue",val); },
148
+
149
+ get value() { return this.getAttribute("value") || ""; },
150
+ set value(val) { return this.setAttribute("value",val); },
151
+
152
+ get src() { return this.getAttribute("src") || ""; },
153
+ set src(val) { return this.setAttribute("src",val); },
154
+
155
+ get id() { return this.getAttribute("id") || ""; },
156
+ set id(val) { return this.setAttribute("id",val); },
157
+
158
+ getAttribute: function(name){
159
+ return $dom.hasAttribute(name) ?
160
+ new String( $dom.getAttribute(name) ) :
161
+ null;
162
+ },
163
+ setAttribute: function(name,value){
164
+ $dom.setAttribute(name,value);
165
+ },
166
+ removeAttribute: function(name){
167
+ $dom.removeAttribute(name);
168
+ },
169
+
170
+ get childNodes(){
171
+ return new DOMNodeList( $dom.getChildNodes() );
172
+ },
173
+ get firstChild(){
174
+ return makeNode( $dom.getFirstChild() );
175
+ },
176
+ get lastChild(){
177
+ return makeNode( $dom.getLastChild() );
178
+ },
179
+ appendChild: function(node){
180
+ //Because the dom implementation is private in scope now,
181
+ //we will need to fix these to use some innerHtml etc
182
+ //if required
183
+ $dom.appendChild( $nodeImplCache[node.__guid__] );
184
+ },
185
+ insertBefore: function(node,before){
186
+ $dom.insertBefore( $nodeImplCache[node.__guid__], before ? $nodeImplCache[before.__guid__] : before );
187
+
188
+ execScripts( node );
189
+
190
+ function execScripts( node ) {
191
+ if ( node.nodeName == "SCRIPT" ) {
192
+ if ( !node.getAttribute("src") ) {
193
+ eval.call( window, node.textContent );
194
+ }
195
+ } else {
196
+ var scripts = node.getElementsByTagName("script");
197
+ for ( var i = 0; i < scripts.length; i++ ) {
198
+ execScripts( node );
199
+ }
200
+ }
201
+ }
202
+ },
203
+ removeChild: function(node){
204
+ $dom.removeChild( $nodeImplCache[node.__guid__] );
205
+ },
206
+
207
+ getElementsByTagName: function(name){
208
+ // why can't we just do ?:
209
+ //var elems = $dom.getElementsByTagName(name), ret = [];
210
+ var elems = $dom.getElementsByTagName("*"), ret = [];
211
+ ret.item = function(i){ return this[i]; };
212
+ ret.getLength = function(){ return this.length; };
213
+ for ( var i = 0; i < elems.length; i++ ) {
214
+ var elem = elems.item(i);
215
+ if ( elem.getAttribute("name") == name )
216
+ ret.push( elem );
217
+ }return new DOMNodeList( ret );
218
+ },
219
+
220
+ addEventListener: window.addEventListener,
221
+ removeEventListener: window.removeEventListener,
222
+ dispatchEvent: window.dispatchEvent,
223
+
224
+ click: function(){
225
+ var event = document.createEvent();
226
+ event.initEvent("click");
227
+ this.dispatchEvent(event);
228
+ },
229
+ submit: function(){
230
+ var event = document.createEvent();
231
+ event.initEvent("submit");
232
+ this.dispatchEvent(event);
233
+ },
234
+ focus: function(){
235
+ var event = document.createEvent();
236
+ event.initEvent("focus");
237
+ this.dispatchEvent(event);
238
+ },
239
+ blur: function(){
240
+ var event = document.createEvent();
241
+ event.initEvent("blur");
242
+ this.dispatchEvent(event);
243
+ },
244
+ get contentWindow(){
245
+ return this.nodeName == "IFRAME" ? {
246
+ document: this.contentDocument
247
+ } : null;
248
+ },
249
+ get contentDocument(){
250
+ if ( this.nodeName == "IFRAME" ) {
251
+ if ( !this._doc )
252
+ this._doc = HTMLtoDOM("<html><head><title></title></head><body></body></html>");
253
+ return this._doc;
254
+ } else { return null; }
255
+ },
256
+ get __guid__(){return $id;}
257
+ });
258
+
259
+ //All this constructor stuff belond in the HTML subclasses
260
+ //and even more generally in the HTML specific element
261
+ //subclass otherwise its going to become a mess
262
+ this.style = {
263
+ get opacity(){ return this._opacity; },
264
+ set opacity(val){ this._opacity = val + ""; }
265
+ };
266
+
267
+ // Load CSS info
268
+ var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
269
+ for ( var i = 0; i < styles.length; i++ ) {
270
+ var style = styles[i].split(/\s*:\s*/);
271
+ if ( style.length == 2 )
272
+ this.style[ style[0] ] = style[1];
273
+ }
274
+
275
+ if ( this.nodeName == "FORM" ) {
276
+ this.__defineGetter__("elements", function(){
277
+ return this.getElementsByTagName("*");
278
+ });
279
+ this.__defineGetter__("length", function(){
280
+ var elems = this.elements;
281
+ for ( var i = 0; i < elems.length; i++ ) {
282
+ this[i] = elems[i];
283
+ }
284
+ return elems.length;
285
+ });
286
+ }
287
+
288
+ if ( this.nodeName == "SELECT" ) {
289
+ this.__defineGetter__("options", function(){
290
+ return this.getElementsByTagName("option");
291
+ });
292
+ }
293
+
294
+ this.defaultValue = this.value;
295
+ return this;
296
+ };
297
+ });
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
2
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
3
+ <html lang="en" xml:lang='en' xmlns="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta name="generator" content=
6
+ "HTML Tidy for Mac OS X (vers 1st July 2004), see www.w3.org" />
7
+ <title>Hello World</title>
8
+ <meta content="en-us" http-equiv="Content-Language" />
9
+ <meta content="text/html; charset=us-ascii" http-equiv=
10
+ "Content-Type" />
11
+ <script type='text/javascript'>
12
+ //<![CDATA[
13
+ document.write("<script>");
14
+ document.write("var foo = \'hello world\'");
15
+ document.write("<\/script>");
16
+ //]]>
17
+ </script>
18
+ </head>
19
+ <body>
20
+ <h1>hello world!</h1>
21
+ <div><!-- note div not closed properly -->
22
+ <ul>
23
+ <li>item 1</li>
24
+ <li>item 2</li>
25
+ <li>item 3 <a href='another/page.html'>link</a> to another
26
+ page!</li>
27
+ </ul>
28
+ </div>
29
+ </body>
30
+ </html>
data/src/cruft/good.js ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "html":{
3
+ "$xmlns" : "http://www.w3.org/1999/xhtml",
4
+ "$xmlns$xml": "http://www.w3.org/XML/1998/namespace",
5
+ "$lang" : "en",
6
+ "$xml$lang" : "en",
7
+ "head":{
8
+ "meta":{
9
+ "$name" : "generator",
10
+ "$content" : "HTML Tidy for Mac OS X (vers 1st July 2004), see www.w3.org"
11
+ },
12
+ "title":"Hello World",
13
+ "meta":[null,null],
14
+ "script":{
15
+ "$type" : "text/javascript",
16
+ '$':["// document.write(\"<script>\"); document.write(\"var foo = \\'hello world\\'\"); document.write(\"<\\/script>\"); //"]
17
+ }
18
+ },
19
+ "body":{
20
+ "h1":"hello world!",
21
+ "div":{
22
+ "ul":{
23
+ "li":["item 1","item 2",{
24
+ "a":{
25
+ "$href" : "another/page.html",
26
+ '$':["link"]
27
+ }
28
+ }]
29
+ }
30
+ }
31
+ }
32
+ }}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * @author thatcher
3
+ */
4
+ //html passed to env external filter 1 (html to xml)
5
+ <html lang="en" xml:lang='en'>
6
+ <head>
7
+ <title>Hello World</title>
8
+ <meta content="en-us"
9
+ http-equiv="Content-Language"/>
10
+ <meta content="text/html; charset=utf-8"
11
+ http-equiv="Content-Type"/>
12
+ <script type='text/javascript'>
13
+ document.write("<script>");
14
+ document.write("var foo = \'hello world\'");
15
+ document.write("</script>");
16
+ </script>
17
+ </head>
18
+ <body>
19
+ <h1>hello world!</h1>
20
+ <div><!-- note div not closed properly -->
21
+ <ul>
22
+ <li>item 1</li>
23
+ <li>item 2</li>
24
+ <li>item 3 <a href='another/page.html'>link</a> to another page!</li>
25
+ </ul>
26
+ <div>
27
+ </body>
28
+ </html>
29
+
30
+ //xml passed to env external filter 2 (xml to javascript)
31
+ <html lang="en" xml:lang='en'>
32
+ <head>
33
+ <title>Hello World</title>
34
+ <meta content="en-us"
35
+ http-equiv="Content-Language"/>
36
+ <meta content="text/html; charset=utf-8"
37
+ http-equiv="Content-Type"/>
38
+ <script type='text/javascript'>
39
+ document.write("<script>");
40
+ document.write("var foo = \'hello world\'");
41
+ document.write("</script>");
42
+ </script>
43
+ </head>
44
+ <body>
45
+ <h1>hello world!</h1>
46
+ <div>
47
+ <ul>
48
+ <li>item 1</li>
49
+ <li>item 2</li>
50
+ <li>item 3 <a href='another/page.html'>link</a> to another page!</li>
51
+ </ul>
52
+ </div>
53
+ </body>
54
+ </html>
55
+
56
+ //Result passed to env internal parser
57
+ _={html:{ lang:'en', xml$lang:'en', $:[
58
+ {head:{$:[
59
+ {title:{$:['Hello World']}},
60
+ {meta:{ content:'en-us', 'http-equiv':'Content-Language'}},
61
+ {meta:{ content:'text/html; charset=utf-8', 'http-equiv':'Content-Type'}},
62
+ {script:{ type:'text/javascript', $:['\
63
+ document.write("<script>");\
64
+ document.write("var foo = \'hello world\'");\
65
+ document.write("</script>");\
66
+ ']}},
67
+ {body:{$:[
68
+ {h1:{$:['hello world!']}},
69
+ {div:{ clazz:'abc def ghi', $:[
70
+ {p:{$:['my name is chris thatcher']}},
71
+ {ul:{$:[
72
+ {li:{$:['item 1']}},
73
+ {li:{$:['item 2']}},
74
+ {li:{$:[
75
+ 'item 3 has ',{a:{href:'another/page.html', $:['link']}}, 'to another page!'
76
+ ]}}
77
+ ]}}
78
+ ]}}
79
+ ]}}
80
+ ]}}
81
+ ]}};
@@ -0,0 +1,458 @@
1
+ /*
2
+ originally from http://www.senocular.com/index.php?id=1.289
3
+
4
+ SUPPORTED
5
+ - ID selectors
6
+ - Class selectors
7
+ - Multiple class definitions (i.e. LI.red.level)
8
+ - Tag selectors
9
+ - Selector groups
10
+ - Child selectors
11
+ - descendants
12
+ - Adjacent selectors
13
+ - Attribute selectors
14
+ LIMITED SUPPORT
15
+ - Psuedo classes/elements (Must specify in element get properties method), only first pseudo identifier recognized
16
+ NOT SUPPORTED
17
+ - @import
18
+ - Specificity / ! important (would need to check order of definition, determine doc location of LINK vs STYLE tags and parse in order)
19
+ - - current order assumption: STYLE, LINK, INLINE (last with most precedence, parsed last)
20
+ - Inherited properties (TODO? - if so, need to define those properties inherited)
21
+
22
+ -------------------
23
+
24
+ // TODO:
25
+ // NEED TO CHECK COMBINATOR
26
+
27
+ // TESTING
28
+
29
+ // CHECK FOR NULL/EMPTY STRING PARSING
30
+
31
+ */
32
+ Object.prototype.toString = function(s, t){
33
+ var looped = false;
34
+ var str;
35
+ if (t == undefined) t = "\t";
36
+ else t += "\t";
37
+ if (s == undefined) s = "Object: {";
38
+ else s += "{";
39
+ for (var p in this){
40
+ if (!this.hasOwnProperty(p) || !this[p]) continue;
41
+ s += "\n"+t;
42
+ if (!looped) looped = true
43
+ if (this[p] instanceof Array) s += p+": ["+this[p]+"]";
44
+ else if (typeof this[p] == "object") s += this[p].toString(p+": ", t);
45
+ else if (typeof this[p] == "function") s += p+": (function)";
46
+ else if (typeof this[p] == "string"){
47
+ str = String(this[p]);
48
+ str = str.replace(/\r/g,"\\r");
49
+ str = str.replace(/\n/g,"\\n");
50
+ str = str.replace(/\t/g,"\\t");
51
+ s += p+": \""+str+"\"";
52
+ }else s += p+": "+this[p];
53
+ }
54
+ return s+"\n"+t.slice(0,-1)+"}";
55
+ };
56
+
57
+ CSSParser.DELIM1 = "##DELIM1##";
58
+ CSSParser.DELIM2 = "##DELIM2##";
59
+ CSSParser.combine = function(target, copyFrom){
60
+ for(var p in copyFrom) target[p] = copyFrom[p];
61
+ }
62
+ CSSParser.trim = function(str){
63
+ return str.replace(/^\s*|\s*$/g,"");
64
+ }
65
+ CSSParser.whiteSpaceToSpaces = function(str){
66
+ return str.replace(/\s+/g," ");
67
+ }
68
+ CSSParser.removeComments = function(str){
69
+ str = str.replace(/<!--/g,"");
70
+ str = str.replace(/-->/g,"");
71
+ return str.replace(/\/\*(\r|\n|.)*\*\//g,"");
72
+ }
73
+ CSSParser.arrayContains = function(ary, value){
74
+ var i, len = ary.length;
75
+ for (i=0; i<len; i++){
76
+ if (ary[i] == value) return true;
77
+ }
78
+ return false;
79
+ }
80
+ CSSParser.arrayContains = function(ary, value){
81
+ var i, len = ary.length;
82
+ for (i=0; i<len; i++){
83
+ if (ary[i] == value) return true;
84
+ }
85
+ return false;
86
+ }
87
+ CSSParser.arrayContainsEach = function(haystack_ary, needles_ary){
88
+ var n, nlen = needles_ary.length;
89
+ var h, hlen = haystack_ary.length;
90
+ var match = false;
91
+ for (n=0; n<nlen; n++){
92
+ match = false;
93
+ for (h=0; h<hlen; h++){
94
+ if (haystack_ary[h] == needles_ary[n]) match = true;
95
+ }
96
+ if (!match) return false;
97
+ }
98
+ return true;
99
+ }
100
+
101
+
102
+ function CSSParser(style_str, dom){
103
+ this.data = "";
104
+ this.styles = new Array();
105
+
106
+ if (style_str && typeof style_str == "object"){
107
+ dom = style_str;
108
+ style_str = "all";
109
+ }else if (!dom) dom = dw.getDocumentDOM();
110
+ switch(style_str){
111
+ case "*":
112
+ case "all":
113
+ case "document":
114
+ style_str = CSSParser.getEmbeddedCSSStyle(dom);
115
+ style_str += CSSParser.getLinkedCSSStyle(dom);
116
+ break;
117
+ case "styles":
118
+ style_str = CSSParser.getEmbeddedCSSStyle(dom);
119
+ break;
120
+ case "links":
121
+ style_str = CSSParser.getLinkedCSSStyle(dom);
122
+ break;
123
+ }
124
+
125
+ this.parseData(style_str);
126
+ }
127
+ CSSParser.prototype.parseData = function(style_str){
128
+ if (!style_str) style_str = "";
129
+ this.data = style_str;
130
+ style_str = CSSParser.trim(CSSParser.removeComments(style_str));
131
+ // TODO: @import ?
132
+ var blocks = style_str.split("}");
133
+ blocks.pop();
134
+ var i, len = blocks.length;
135
+ var definition_block, properties;
136
+ for (i=0; i<len; i++){
137
+ definition_block = blocks[i].split("{");
138
+ this.styles.push(new CSSStyleGroup(definition_block[0], definition_block[1]));
139
+ }
140
+ }
141
+ function CSSStyleGroup(style_str, properties_str){
142
+ this.data = style_str;
143
+ this.selectors = new Array();
144
+
145
+ this.parseData(style_str, properties_str);
146
+ }
147
+ CSSStyleGroup.prototype.parseData = function(style_str, properties_str){
148
+ this.selectors = style_str.split(",");
149
+ var i, len = this.selectors.length;
150
+ for (i=0; i<len; i++){
151
+ this.selectors[i] = new CSSSelectorDefinition(this.selectors[i], properties_str);
152
+ }
153
+ }
154
+ CSSStyleGroup.prototype.match = function(elem, pseudo){
155
+ var i, len = this.selectors.length;
156
+ for (i=0; i<len; i++){
157
+ if (this.selectors[i].match(elem, pseudo)) return this.selectors[i].properties;
158
+ }
159
+ return false;
160
+ }
161
+
162
+ function CSSSelectorDefinition(selector_str, properties_str){
163
+ this.data = "";
164
+ this.singleSelectors = new Array();
165
+ this.properties = new CSSProperties(properties_str);
166
+
167
+ if (selector_str) this.parseData(selector_str);
168
+ }
169
+ CSSSelectorDefinition.prototype.parseData = function(selector_str){
170
+ selector_str = CSSParser.trim(selector_str);
171
+ selector_str = CSSParser.whiteSpaceToSpaces(selector_str);
172
+ selector_str = selector_str.replace(/\s*\+\s*/g,"+");
173
+ selector_str = selector_str.replace(/\s*>\s*/g,">");
174
+ this.data = selector_str;
175
+ selector_str = selector_str.replace(/ /g,CSSParser.DELIM1 + " " + CSSParser.DELIM1);
176
+ selector_str = selector_str.replace(/\+/g,CSSParser.DELIM1 + "+" + CSSParser.DELIM1);
177
+ selector_str = selector_str.replace(/>/g,CSSParser.DELIM1 + ">" + CSSParser.DELIM1);
178
+ var sels = selector_str.split(CSSParser.DELIM1);
179
+ var i, len = sels.length;
180
+ var sel_comb = null;
181
+ for (i=0; i<len; i+=2){
182
+ if (i) sel_comb = sels[i-1];
183
+ this.singleSelectors.push(new CSSSingleSelector(sels[i], sel_comb));
184
+ }
185
+ }
186
+ CSSSelectorDefinition.prototype.match = function(element, pseudo){
187
+ // go backwards, starting from right of selector definition
188
+ var index = this.singleSelectors.length-1;
189
+ var compare_elem = element;
190
+ var selector = this.singleSelectors[index];
191
+
192
+ if (!selector.match(compare_elem, pseudo)) return false;
193
+ while (compare_elem && index >= 0){
194
+ switch (selector.combinator){
195
+ case " ":
196
+ index--;
197
+ selector = this.singleSelectors[index];
198
+ do {
199
+ compare_elem = compare_elem.parentNode;
200
+ } while(compare_elem && !selector.match(compare_elem, pseudo));
201
+ if (!compare_elem) return false;
202
+ break;
203
+ case ">":
204
+ index--;
205
+ selector = this.singleSelectors[index];
206
+ compare_elem = compare_elem.parentNode;
207
+ if (!selector.match(compare_elem, pseudo)) return false;
208
+ break;
209
+ case "+":
210
+ index--;
211
+ selector = this.singleSelectors[index];
212
+ compare_elem = CSSParser.previousSibling(compare_elem);
213
+ if (!selector.match(compare_elem, pseudo)) return false;
214
+ break;
215
+ default:
216
+ // assume first selector in definition chain, therefore comparison complete
217
+ if (!index) return this.properties;
218
+ else return false;
219
+ }
220
+ if (pseudo) pseudo = null; // only used when compare_elem == element
221
+ }
222
+ return false;
223
+ }
224
+
225
+ /*
226
+ CSSSelectorDefinition.prototype.match = function(elem, pseudo){
227
+ var i = this.singleSelectors.length;
228
+ // go backwards, starting from right of selector definition
229
+ var compare = elem;
230
+ while (i--){
231
+ // TODO:
232
+ // NEED TO CHECK COMBINATOR MATCHES HERE?
233
+ // ----------------------------------------------------------------------------------------------------------------------------------
234
+ // CSSParser.previousSibling
235
+ if (this.singleSelectors[i].match(elem, pseudo)) return this.properties;
236
+ }
237
+ return false;
238
+ }
239
+ */
240
+
241
+ function CSSSingleSelector(selector_str, selector_comb){
242
+ this.data = selector_str;
243
+ this.combinator = selector_comb; //:String; either " ", ">", or "+"; can be null/undefined
244
+ this.type = "*"; //:String; <E>
245
+ this.classes = "*"; //:Array; E.name
246
+ this.id = "*"; //:String; E#name
247
+ this.pseudoclass = "*"; //:String; E:link
248
+ this.attributes = "*"; //:CSSAttributeSelector; E[attribute], E[attribute=value]
249
+
250
+ this.parseData(selector_str);
251
+ }
252
+ CSSSingleSelector.prototype.parseData = function(selector_str){
253
+ var pcs;
254
+ if (selector_str.indexOf(":") != -1){
255
+ pcs = selector_str.split(":");
256
+ selector_str = pcs[0];
257
+ this.pseudoclass = pcs[1];
258
+ }
259
+ if (selector_str.indexOf("[") != -1){
260
+ pcs = [selector_str.indexOf("["), selector_str.lastIndexOf("]")];
261
+ this.attributes = new CSSAttributeSelector(selector_str.substring(pcs[0], pcs[1]+1));
262
+ selector_str = selector_str.substring(0, pcs[0]) + selector_str.substring(pcs[1]+1);
263
+ }
264
+ if (selector_str.indexOf("#") != -1){
265
+ pcs = selector_str.split("#");
266
+ selector_str = pcs[0];
267
+ this.id = pcs[1];
268
+ }
269
+ if (selector_str.indexOf(".") != -1){
270
+ pcs = selector_str.indexOf(".");
271
+ this.classes = new CSSClassSelector(selector_str.substring(pcs+1));
272
+ selector_str = selector_str.substring(0, pcs);
273
+ }
274
+ if (selector_str) this.type = selector_str.toLowerCase();
275
+ }
276
+
277
+ CSSSingleSelector.prototype.match = function(element, pseudo){
278
+ if (element.nodeType == Node.TEXT_NODE) element = element.parentNode;
279
+ if (!element || element.nodeType != Node.ELEMENT_NODE) return false;
280
+ if (this.type != "*" && element.tagName.toLowerCase() != this.type) return false;
281
+ if (this.id != "*" && element.getAttribute("id") != this.id) return false;
282
+ if (pseudo && pseudo != this.pseudoclass) return false;
283
+ if (this.classes != "*" && !CSSParser.arrayContainsEach(CSSParser.getElementAttributeList(element, "class"), this.classes)) return false;
284
+ if (this.attributes != "*" && !this.attributes.match(element)) return false;
285
+ return true;
286
+ }
287
+
288
+ function CSSAttributeSelector(attrib_str){
289
+ this.attributeNames = new Array();
290
+ this.attributeValues = new Array();
291
+ this.attributeContains = new Array();
292
+ this.attributeBegins = new Array();
293
+
294
+ this.parseData(attrib_str);
295
+ }
296
+ CSSAttributeSelector.prototype.parseData = function(attrib_str){
297
+ var attr_ary = attrib_str.match(/\[[^\]]*\]/g);
298
+ var i, len = attr_ary.length;
299
+ var attr;
300
+ for (i=0; i<len; i++){
301
+ attr = attr_ary[i].slice(1,-1).split("=");
302
+ if (attr.length == 1){
303
+ this.attributeNames.push(new CSSAttribute(attr[0], null));
304
+ }else if (attr[0].charAt(attr[0].length-1) == "~"){
305
+ this.attributeContains.push(new CSSAttribute(attr[0].slice(0,-1), attr[1].slice(1,-1)));
306
+ }else if (attr[0].charAt(attr[0].length-1) == "|"){
307
+ this.attributeBegins.push(new CSSAttribute(attr[0].slice(0,-1), attr[1].slice(1,-1)));
308
+ }else{
309
+ this.attributeValues.push(new CSSAttribute(attr[0], attr[1].slice(1,-1)));
310
+ }
311
+ }
312
+ }
313
+ CSSAttributeSelector.prototype.match = function(elem){
314
+ if (this.attributeNames.length && !this.matchNames(elem)) return false;
315
+ if (this.attributeValues.length && !this.matchValues(elem)) return false;
316
+ if (this.attributeContains.length && !this.matchContains(elem)) return false;
317
+ if (this.attributeBegins.length && !this.matchBegins(elem)) return false;
318
+ return true;
319
+ }
320
+ CSSAttributeSelector.prototype.matchNames = function(elem){
321
+ var i, len = this.attributeNames.length;
322
+ for (i=0; i<len; i++){
323
+ if (elem.getAttribute(this.attributeNames[i].name) == undefined) return false;
324
+ }
325
+ return true;
326
+ }
327
+ CSSAttributeSelector.prototype.matchValues = function(elem){
328
+ var i, len = this.attributeValues.length;
329
+ for (i=0; i<len; i++){
330
+ alert([this.attributeValues[i].name, this.attributeValues[i].value])
331
+ if (elem.getAttribute(this.attributeValues[i].name) != this.attributeValues[i].value) return false;
332
+ }
333
+ return true;
334
+ }
335
+ CSSAttributeSelector.prototype.matchContains = function(elem){
336
+ var i, len = this.attributeContains.length;
337
+ var attrib, re;
338
+ for (i=0; i<len; i++){
339
+ attrib = elem.getAttribute(this.attributeContains[i].name);
340
+ if (attrib == undefined) return false;
341
+ re = new RegExp("(^| )"+this.attributeContains[i].value+"( |$)", "g");
342
+ if (!attrib.match(re)) return false;
343
+ }
344
+ return true;
345
+ }
346
+ CSSAttributeSelector.prototype.matchBegins = function(elem){
347
+ var i, len = this.attributeBegins.length;
348
+ var attrib;
349
+ for (i=0; i<len; i++){
350
+ attrib = elem.getAttribute(this.attributeBegins[i].name);
351
+ if (attrib == undefined) return false;
352
+ if (attrib == this.attributeBegins[i].value || attrib.indexOf(this.attributeBegins[i].value + "-") != 0){
353
+ // allows for exact match or exact match upto first "-" in separated list
354
+ return false;
355
+ }
356
+ }
357
+ return true;
358
+ }
359
+
360
+ function CSSAttribute(name, value){
361
+ this.name = name;
362
+ this.value = value;
363
+ }
364
+ function CSSClassSelector(class_str){
365
+ this.values = new Array();
366
+
367
+ this.parseData(class_str);
368
+ }
369
+ CSSClassSelector.prototype.parseData = function(class_str){
370
+ this.values = class_str.split(".");
371
+ }
372
+
373
+ function CSSProperties(properties_str){
374
+ this.values = new Object();
375
+
376
+ this.parseData(properties_str);
377
+ }
378
+ CSSProperties.prototype.parseData = function(properties_str){
379
+ if (!properties_str) return;
380
+ var property_block = properties_str.split(";");
381
+ var i, len = property_block.length;
382
+ var property, value_block;
383
+ for (i=0; i<len; i++){
384
+ property = CSSParser.trim(property_block[i]);
385
+ if (property){
386
+ value_block = property.split(":");
387
+ this.values[CSSParser.trim(value_block[0].toLowerCase())] = CSSParser.trim(value_block[1]);
388
+ }
389
+ }
390
+ }
391
+
392
+
393
+ CSSParser.getLinkedCSSStyle = function(dom){
394
+ var links = dom.getElementsByTagName("LINK");
395
+ var style_str = "";
396
+ if (links.length){
397
+ var contents;
398
+ var i, len = links.length;
399
+ for (i=0; i<len; i++){
400
+ if (links[i].rel == "stylesheet" && links[i].href){
401
+ contents = DWfile.read(dom.URL.substr(0, dom.URL.lastIndexOf("/")+1) + links[i].getAttribute("href"));
402
+ if (contents) style_str += contents;
403
+ }
404
+ }
405
+ }
406
+ return (style_str == "") ? "" : style_str;
407
+ }
408
+ CSSParser.getEmbeddedCSSStyle = function(dom){
409
+ var styles = dom.getElementsByTagName("STYLE");
410
+ var style_str = "";
411
+ if (styles.length){
412
+ var i, len = styles.length;
413
+ for (i=0; i<len; i++) style_str += styles[i].innerHTML;
414
+ }
415
+ return (style_str == "") ? "" : style_str;
416
+ }
417
+ CSSParser.getInlineCSSStyle = function(element){
418
+ return (element.style == undefined) ? "" : element.style;
419
+ }
420
+
421
+ CSSParser.previousSibling = function(element){
422
+ var par = element.parentNode;
423
+ if (!par || !par.hasChildNodes()) return false;
424
+ var sib = false;
425
+ var i, len = par.childNodes.length;
426
+ for (i=0; i<len; i++){
427
+ if (par.childNodes[i] == element) return sib;
428
+ sib = par.childNodes[i];
429
+ }
430
+ return false;
431
+ }
432
+
433
+ CSSParser.getElementAttributeList = function(elem, attrib){
434
+ var attrib_list = new Array();
435
+ var attrib = elem.getAttribute(attrib);
436
+ if (!attrib) return attrib_list;
437
+ attrib = CSSParser.whiteSpaceToSpaces(attrib);
438
+ attrib_list = attrib.split(" ");
439
+ return attrib_list;
440
+ }
441
+
442
+
443
+ // -------------------------------------------
444
+ // PUBLIC INTERFACE
445
+ // -------------------------------------------
446
+ // new Parser(dom), new Parser("all" [, dom]), new Parser("style{prop:value;}" [, dom])
447
+ CSSParser.prototype.getElementProperties = function(elem, pseudo){
448
+ var i, len = this.styles.length;
449
+ var properties = new CSSProperties(elem.getAttribute("style"));
450
+ var match_props;
451
+ for (i=0; i<len; i++){
452
+ match_props = this.styles[i].match(elem, pseudo);
453
+ if (match_props){
454
+ CSSParser.combine(properties.values, match_props.values);
455
+ }
456
+ }
457
+ return properties.values;
458
+ }