envjs 0.1.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.jslintrbrc +29 -0
- data/.project +17 -0
- data/CHANGELOG.rdoc +3 -0
- data/DTD/xhtml-lat1.ent +196 -0
- data/DTD/xhtml-special.ent +80 -0
- data/DTD/xhtml-symbol.ent +237 -0
- data/DTD/xhtml.soc +14 -0
- data/DTD/xhtml1-frameset.dtd +1235 -0
- data/DTD/xhtml1-strict.dtd +978 -0
- data/DTD/xhtml1-transitional.dtd +1201 -0
- data/DTD/xhtml1.dcl +192 -0
- data/Makefile +7 -0
- data/Manifest.txt +287 -0
- data/{README → README.rdoc} +24 -3
- data/Rakefile +196 -0
- data/Wakefile +24 -0
- data/build.properties +9 -0
- data/build.xml +247 -0
- data/gm/jquery.js +6002 -0
- data/gm/mainx.js +2648 -0
- data/gm/sensx.js +135 -0
- data/gm/t.js +6 -0
- data/gm/x.html +76 -0
- data/htmlparser/BrowserTreeBuilder.java +456 -0
- data/htmlparser/README +34 -0
- data/htmlparser/build.sh +38 -0
- data/jsl/jsl +0 -0
- data/jsl/jsl.default.conf +129 -0
- data/jsl/jsl.exe +0 -0
- data/lib/envjs.rb +2 -0
- data/lib/envjs/env.js +22 -3
- data/lib/envjs/event_loop.js +2 -0
- data/lib/envjs/static.js +155 -21
- data/licenses/GPL-LICENSE.txt +278 -0
- data/licenses/MIT-LICENSE.txt +20 -0
- data/src/base64.js +80 -0
- data/src/build.js +6 -0
- data/src/cruft/bad.html +24 -0
- data/src/cruft/dom.js +606 -0
- data/src/cruft/element.js +297 -0
- data/src/cruft/good.html +30 -0
- data/src/cruft/good.js +32 -0
- data/src/cruft/internal.js +81 -0
- data/src/cruft/parser.js +458 -0
- data/src/css/properties.js +293 -0
- data/src/css/rule.js +22 -0
- data/src/css/sizzle.js +717 -0
- data/src/css/stylesheet.js +52 -0
- data/src/dom/attr.js +55 -0
- data/src/dom/cdatasection.js +31 -0
- data/src/dom/characterdata.js +119 -0
- data/src/dom/comment.js +30 -0
- data/src/dom/doctype.js +9 -0
- data/src/dom/document.js +553 -0
- data/src/dom/dom.js +134 -0
- data/src/dom/element.js +217 -0
- data/src/dom/entities.js +273 -0
- data/src/dom/exception.js +28 -0
- data/src/dom/fragment.js +37 -0
- data/src/dom/implementation.js +602 -0
- data/src/dom/instruction.js +51 -0
- data/src/dom/namednodemap.js +374 -0
- data/src/dom/namespace.js +50 -0
- data/src/dom/node.js +618 -0
- data/src/dom/nodelist.js +195 -0
- data/src/dom/parser.js +1207 -0
- data/src/dom/text.js +73 -0
- data/src/event/event.js +39 -0
- data/src/event/mouseevent.js +4 -0
- data/src/event/uievent.js +8 -0
- data/src/html/a.js +110 -0
- data/src/html/anchor.js +80 -0
- data/src/html/area.js +57 -0
- data/src/html/base.js +26 -0
- data/src/html/blockquote-q.js +19 -0
- data/src/html/body.js +19 -0
- data/src/html/button.js +21 -0
- data/src/html/canvas.js +14 -0
- data/src/html/col-colgroup.js +49 -0
- data/src/html/collection.js +72 -0
- data/src/html/cookie.js +151 -0
- data/src/html/del-ins.js +25 -0
- data/src/html/div.js +28 -0
- data/src/html/document.js +359 -0
- data/src/html/element.js +380 -0
- data/src/html/fieldset.js +19 -0
- data/src/html/form.js +484 -0
- data/src/html/frame.js +89 -0
- data/src/html/frameset.js +25 -0
- data/src/html/head.js +44 -0
- data/src/html/html.js +0 -0
- data/src/html/htmlparser.js +340 -0
- data/src/html/iframe.js +26 -0
- data/src/html/image.js +0 -0
- data/src/html/img.js +62 -0
- data/src/html/input-elements.js +307 -0
- data/src/html/input.js +65 -0
- data/src/html/label.js +26 -0
- data/src/html/legend.js +19 -0
- data/src/html/link.js +82 -0
- data/src/html/map.js +22 -0
- data/src/html/meta.js +37 -0
- data/src/html/object.js +89 -0
- data/src/html/optgroup.js +25 -0
- data/src/html/option.js +97 -0
- data/src/html/param.js +38 -0
- data/src/html/script.js +122 -0
- data/src/html/select.js +129 -0
- data/src/html/style.js +31 -0
- data/src/html/table.js +199 -0
- data/src/html/tbody-thead-tfoot.js +91 -0
- data/src/html/td-th.js +18 -0
- data/src/html/textarea.js +25 -0
- data/src/html/title.js +20 -0
- data/src/html/tr.js +114 -0
- data/src/intro.js +141 -0
- data/src/outro.js +70 -0
- data/src/parser/html5.detailed.js +10762 -0
- data/src/parser/html5.min.js +503 -0
- data/src/parser/html5.pretty.js +10815 -0
- data/src/parser/intro.js +42 -0
- data/src/parser/outro.js +9 -0
- data/src/platform/core.js +323 -0
- data/src/platform/johnson.js +479 -0
- data/src/platform/rhino.js +327 -0
- data/src/platform/static/intro.js +41 -0
- data/src/platform/static/outro.js +30 -0
- data/src/profile/aop.js +238 -0
- data/src/profile/profile.js +402 -0
- data/src/serializer/xml.js +21 -0
- data/src/svg/animatedstring.js +25 -0
- data/src/svg/document.js +25 -0
- data/src/svg/element.js +22 -0
- data/src/svg/locatable.js +17 -0
- data/src/svg/rect.js +18 -0
- data/src/svg/rectelement.js +24 -0
- data/src/svg/stylable.js +49 -0
- data/src/svg/svgelement.js +22 -0
- data/src/svg/transformable.js +15 -0
- data/src/window/css.js +15 -0
- data/src/window/dialog.js +16 -0
- data/src/window/document.js +28 -0
- data/src/window/event.js +262 -0
- data/src/window/history.js +62 -0
- data/src/window/location.js +138 -0
- data/src/window/navigator.js +48 -0
- data/src/window/screen.js +53 -0
- data/src/window/timer.js +21 -0
- data/src/window/window.js +284 -0
- data/src/window/xhr.js +127 -0
- data/src/xpath/expression.js +49 -0
- data/src/xpath/implementation.js +2482 -0
- data/src/xpath/result.js +67 -0
- data/src/xpath/util.js +551 -0
- data/src/xpath/xmltoken.js +149 -0
- data/src/xslt/COPYING +34 -0
- data/src/xslt/ajaxslt-0.8.1/AUTHORS +1 -0
- data/src/xslt/ajaxslt-0.8.1/ChangeLog +136 -0
- data/src/xslt/ajaxslt-0.8.1/Makefile +49 -0
- data/src/xslt/ajaxslt-0.8.1/README +102 -0
- data/src/xslt/ajaxslt-0.8.1/TODO +15 -0
- data/src/xslt/ajaxslt-0.8.1/dom.js +566 -0
- data/src/xslt/ajaxslt-0.8.1/dom_unittest.html +24 -0
- data/src/xslt/ajaxslt-0.8.1/dom_unittest.js +131 -0
- data/src/xslt/ajaxslt-0.8.1/simplelog.js +79 -0
- data/src/xslt/ajaxslt-0.8.1/test/xpath.html +18 -0
- data/src/xslt/ajaxslt-0.8.1/test/xpath_script.js +45 -0
- data/src/xslt/ajaxslt-0.8.1/test/xslt.html +58 -0
- data/src/xslt/ajaxslt-0.8.1/test/xslt_script.js +33 -0
- data/src/xslt/ajaxslt-0.8.1/unittestsuite.html +26 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken.js +149 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.html +18 -0
- data/src/xslt/ajaxslt-0.8.1/xmltoken_unittest.js +811 -0
- data/src/xslt/ajaxslt-0.8.1/xpath_unittest.html +39 -0
- data/src/xslt/ajaxslt-0.8.1/xpath_unittest.js +557 -0
- data/src/xslt/ajaxslt-0.8.1/xpathdebug.js +234 -0
- data/src/xslt/ajaxslt-0.8.1/xslt_unittest.html +138 -0
- data/src/xslt/ajaxslt-0.8.1/xslt_unittest.js +68 -0
- data/src/xslt/implementation.js +625 -0
- data/src/xslt/processor.js +37 -0
- data/src/xslt/util.js +449 -0
- data/test/foo.html +8 -0
- data/test/foo.js +40 -0
- data/test/jquery.js +6002 -0
- data/test/x.js +1 -0
- data/test/y.js +1 -0
- metadata +245 -14
data/src/html/element.js
ADDED
@@ -0,0 +1,380 @@
|
|
1
|
+
$debug("Defining HTMLElement");
|
2
|
+
/*
|
3
|
+
* HTMLElement - DOM Level 2
|
4
|
+
*/
|
5
|
+
var HTMLElement = function(ownerDocument) {
|
6
|
+
this.DOMElement = DOMElement;
|
7
|
+
this.DOMElement(ownerDocument);
|
8
|
+
|
9
|
+
this.$css2props = null;
|
10
|
+
};
|
11
|
+
HTMLElement.prototype = new DOMElement;
|
12
|
+
__extend__(HTMLElement.prototype, {
|
13
|
+
|
14
|
+
get className() {
|
15
|
+
return this.getAttribute("class")||'';
|
16
|
+
},
|
17
|
+
set className(value) {
|
18
|
+
return this.setAttribute("class",trim(value));
|
19
|
+
|
20
|
+
},
|
21
|
+
get dir() {
|
22
|
+
return this.getAttribute("dir")||"ltr";
|
23
|
+
|
24
|
+
},
|
25
|
+
set dir(val) {
|
26
|
+
return this.setAttribute("dir",val);
|
27
|
+
|
28
|
+
},
|
29
|
+
get id(){
|
30
|
+
return this.getAttribute('id');
|
31
|
+
|
32
|
+
},
|
33
|
+
set id(id){
|
34
|
+
this.setAttribute('id', id);
|
35
|
+
|
36
|
+
},
|
37
|
+
get innerHTML(){
|
38
|
+
return this.childNodes.xml;
|
39
|
+
|
40
|
+
},
|
41
|
+
set innerHTML(html){
|
42
|
+
//Should be replaced with HTMLPARSER usage
|
43
|
+
//$debug('SETTING INNER HTML ('+this+'+'+html.substring(0,64));
|
44
|
+
var doc = new HTMLDocument(this.ownerDocument.implementation,
|
45
|
+
this.ownerDocument._parentWindow,
|
46
|
+
"");
|
47
|
+
// print("innerHTML",html);
|
48
|
+
// try { throw new Error; } catch(e) { print(e.stack); }
|
49
|
+
var docstring = '<html><head></head><body>'+
|
50
|
+
'<envjs_1234567890 xmlns="envjs_1234567890">'
|
51
|
+
+html+
|
52
|
+
'</envjs_1234567890>'+
|
53
|
+
'</body></html>';
|
54
|
+
doc.in_inner_html = true;
|
55
|
+
this.ownerDocument._parentWindow.parseHtmlDocument(docstring,doc,null,null,true);
|
56
|
+
var parent = doc.body.childNodes[0];
|
57
|
+
while(this.firstChild != null){
|
58
|
+
this.removeChild( this.firstChild );
|
59
|
+
}
|
60
|
+
var importedNode;
|
61
|
+
|
62
|
+
var pn = this;
|
63
|
+
while(pn.parentNode) {
|
64
|
+
pn = pn.parentNode;
|
65
|
+
}
|
66
|
+
// print(this,pn,this.ownerDocument);
|
67
|
+
try{
|
68
|
+
if (pn === this.ownerDocument) {
|
69
|
+
this.ownerDocument.in_inner_html = true;
|
70
|
+
// print("yup");
|
71
|
+
}
|
72
|
+
while(parent.firstChild != null){
|
73
|
+
importedNode = this.importNode(
|
74
|
+
parent.removeChild( parent.firstChild ), true);
|
75
|
+
this.appendChild( importedNode );
|
76
|
+
}
|
77
|
+
} finally {
|
78
|
+
if (pn === this.ownerDocument) {
|
79
|
+
// print("nope");
|
80
|
+
this.ownerDocument.in_inner_html = false;
|
81
|
+
}
|
82
|
+
}
|
83
|
+
//Mark for garbage collection
|
84
|
+
doc = null;
|
85
|
+
},
|
86
|
+
get innerText(){
|
87
|
+
return __recursivelyGatherText__(this);
|
88
|
+
},
|
89
|
+
set innerText(newText){
|
90
|
+
while(this.firstChild != null){
|
91
|
+
this.removeChild( this.firstChild );
|
92
|
+
}
|
93
|
+
var text = this.ownerDocument.createTextNode(newText);
|
94
|
+
this.appendChild(text);
|
95
|
+
},
|
96
|
+
get lang() {
|
97
|
+
return this.getAttribute("lang");
|
98
|
+
|
99
|
+
},
|
100
|
+
set lang(val) {
|
101
|
+
return this.setAttribute("lang",val);
|
102
|
+
|
103
|
+
},
|
104
|
+
get offsetHeight(){
|
105
|
+
return Number(this.style["height"].replace("px",""));
|
106
|
+
},
|
107
|
+
get offsetWidth(){
|
108
|
+
return Number(this.style["width"].replace("px",""));
|
109
|
+
},
|
110
|
+
offsetLeft: 0,
|
111
|
+
offsetRight: 0,
|
112
|
+
get offsetParent(){
|
113
|
+
/* TODO */
|
114
|
+
return;
|
115
|
+
},
|
116
|
+
set offsetParent(element){
|
117
|
+
/* TODO */
|
118
|
+
return;
|
119
|
+
},
|
120
|
+
scrollHeight: 0,
|
121
|
+
scrollWidth: 0,
|
122
|
+
scrollLeft: 0,
|
123
|
+
scrollRight: 0,
|
124
|
+
get style(){
|
125
|
+
if(this.$css2props === null){
|
126
|
+
this.$css2props = new CSS2Properties(this);
|
127
|
+
}
|
128
|
+
return this.$css2props;
|
129
|
+
},
|
130
|
+
set style(values){
|
131
|
+
__updateCss2Props__(this, values);
|
132
|
+
},
|
133
|
+
setAttribute: function (name, value) {
|
134
|
+
DOMElement.prototype.setAttribute.apply(this,[name, value]);
|
135
|
+
if (name === "style") {
|
136
|
+
__updateCss2Props__(this, value);
|
137
|
+
}
|
138
|
+
},
|
139
|
+
get title() {
|
140
|
+
return this.getAttribute("title");
|
141
|
+
|
142
|
+
},
|
143
|
+
set title(value) {
|
144
|
+
return this.setAttribute("title", value);
|
145
|
+
|
146
|
+
},
|
147
|
+
get tabIndex(){
|
148
|
+
var ti = this.getAttribute('tabindex');
|
149
|
+
if(ti!==null)
|
150
|
+
return Number(ti);
|
151
|
+
else
|
152
|
+
return 0;
|
153
|
+
},
|
154
|
+
set tabIndex(value){
|
155
|
+
if(value===undefined||value===null)
|
156
|
+
value = 0;
|
157
|
+
this.setAttribute('tabindex',Number(value));
|
158
|
+
},
|
159
|
+
//Not in the specs but I'll leave it here for now.
|
160
|
+
get outerHTML(){
|
161
|
+
return this.xml;
|
162
|
+
|
163
|
+
},
|
164
|
+
scrollIntoView: function(){
|
165
|
+
/*TODO*/
|
166
|
+
return;
|
167
|
+
|
168
|
+
},
|
169
|
+
|
170
|
+
onclick: function(event){
|
171
|
+
return __eval__(this.getAttribute('onclick')||'', this);
|
172
|
+
},
|
173
|
+
|
174
|
+
|
175
|
+
ondblclick: function(event){
|
176
|
+
return __eval__(this.getAttribute('ondblclick')||'', this);
|
177
|
+
},
|
178
|
+
onkeydown: function(event){
|
179
|
+
return __eval__(this.getAttribute('onkeydown')||'', this);
|
180
|
+
},
|
181
|
+
onkeypress: function(event){
|
182
|
+
return __eval__(this.getAttribute('onkeypress')||'', this);
|
183
|
+
},
|
184
|
+
onkeyup: function(event){
|
185
|
+
return __eval__(this.getAttribute('onkeyup')||'', this);
|
186
|
+
},
|
187
|
+
onmousedown: function(event){
|
188
|
+
return __eval__(this.getAttribute('onmousedown')||'', this);
|
189
|
+
},
|
190
|
+
onmousemove: function(event){
|
191
|
+
return __eval__(this.getAttribute('onmousemove')||'', this);
|
192
|
+
},
|
193
|
+
onmouseout: function(event){
|
194
|
+
return __eval__(this.getAttribute('onmouseout')||'', this);
|
195
|
+
},
|
196
|
+
onmouseover: function(event){
|
197
|
+
return __eval__(this.getAttribute('onmouseover')||'', this);
|
198
|
+
},
|
199
|
+
onmouseup: function(event){
|
200
|
+
return __eval__(this.getAttribute('onmouseup')||'', this);
|
201
|
+
},
|
202
|
+
|
203
|
+
appendChild: function( newChild, refChild ) {
|
204
|
+
var rv = DOMElement.prototype.appendChild.apply(this, arguments);
|
205
|
+
var node = newChild;
|
206
|
+
var pn = this;
|
207
|
+
while(pn.parentNode) {
|
208
|
+
pn = pn.parentNode;
|
209
|
+
}
|
210
|
+
if(pn === node.ownerDocument) {
|
211
|
+
__exec_script_tags__(newChild);
|
212
|
+
}
|
213
|
+
return rv;
|
214
|
+
}
|
215
|
+
});
|
216
|
+
|
217
|
+
var __exec_script_tags__ = function(node) {
|
218
|
+
var $env = __ownerDocument__(node)._parentWindow.$envx;
|
219
|
+
var doc = __ownerDocument__(node);
|
220
|
+
var type = ( node.type === null ) ? "text/javascript" : node.type;
|
221
|
+
// print("check exec",node,node.ownerDocument.in_inner_html);
|
222
|
+
// print(node,node.childNodes.length);
|
223
|
+
if(node.nodeName.toLowerCase() == 'script' && type == "text/javascript"){
|
224
|
+
// print("check",node,node.src,node.text,node.ownerDocument.in_inner_html,doc.parentWindow,node.executed);
|
225
|
+
if (node.ownerDocument.in_inner_html) {
|
226
|
+
//print("ignore",node);
|
227
|
+
node.executed = true;
|
228
|
+
} else if (doc.parentWindow &&
|
229
|
+
!node.ownerDocument.in_inner_html &&
|
230
|
+
!node.executed && (
|
231
|
+
(node.src && !node.src.match(/^\s*$/)) ||
|
232
|
+
(node.text && !node.text.match(/^\s*$/))
|
233
|
+
) ) {
|
234
|
+
node.executed = true;
|
235
|
+
//p.replaceEntities = true;
|
236
|
+
//print("exec",node);
|
237
|
+
var okay = $env.loadLocalScript(node, null);
|
238
|
+
// only fire event if we actually had something to load
|
239
|
+
if (node.src && node.src.length > 0){
|
240
|
+
var event = doc.createEvent();
|
241
|
+
event.initEvent( okay ? "load" : "error", false, false );
|
242
|
+
node.dispatchEvent( event, false );
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
for(var i=0; i < node.childNodes.length; i++) {
|
247
|
+
__exec_script_tags__(node.childNodes[i]);
|
248
|
+
}
|
249
|
+
};
|
250
|
+
|
251
|
+
var __recursivelyGatherText__ = function(aNode) {
|
252
|
+
var accumulateText = "";
|
253
|
+
var idx; var n;
|
254
|
+
for (idx=0;idx < aNode.childNodes.length;idx++){
|
255
|
+
n = aNode.childNodes.item(idx);
|
256
|
+
if(n.nodeType == DOMNode.TEXT_NODE)
|
257
|
+
accumulateText += n.data;
|
258
|
+
else
|
259
|
+
accumulateText += __recursivelyGatherText__(n);
|
260
|
+
}
|
261
|
+
|
262
|
+
return accumulateText;
|
263
|
+
};
|
264
|
+
|
265
|
+
var __eval__ = function(script,node){
|
266
|
+
if (script == "")
|
267
|
+
return undefined;
|
268
|
+
try {
|
269
|
+
var scope = node;
|
270
|
+
var __scopes__ = [];
|
271
|
+
var original = script;
|
272
|
+
if(scope) {
|
273
|
+
// script = "(function(){return eval(original)}).call(__scopes__[0])";
|
274
|
+
script = "return (function(){"+original+"}).call(__scopes__[0])";
|
275
|
+
while(scope) {
|
276
|
+
__scopes__.push(scope);
|
277
|
+
scope = scope.parentNode;
|
278
|
+
script = "with(__scopes__["+(__scopes__.length-1)+"] ){"+script+"};";
|
279
|
+
}
|
280
|
+
}
|
281
|
+
script = "function(original,__scopes__){"+script+"}";
|
282
|
+
// print("scripta",script);
|
283
|
+
// print("scriptb",original);
|
284
|
+
var original_script_window = $master.first_script_window;
|
285
|
+
if ( !$master.first_script_window ) {
|
286
|
+
// $master.first_script_window = window;
|
287
|
+
}
|
288
|
+
// FIX!!!
|
289
|
+
var $inner = node.ownerDocument._parentWindow["$inner"];
|
290
|
+
var result = $master.evaluate(script,$inner)(original,__scopes__);
|
291
|
+
// $master.first_script_window = original_script_window;
|
292
|
+
return result;
|
293
|
+
}catch(e){
|
294
|
+
$warn("Exception during on* event eval: "+e);
|
295
|
+
throw e;
|
296
|
+
}
|
297
|
+
};
|
298
|
+
|
299
|
+
var __updateCss2Props__ = function(elem, values){
|
300
|
+
if(elem.$css2props === null){
|
301
|
+
elem.$css2props = new CSS2Properties(elem);
|
302
|
+
}
|
303
|
+
__cssTextToStyles__(elem.$css2props, values);
|
304
|
+
};
|
305
|
+
|
306
|
+
var __registerEventAttrs__ = function(elm){
|
307
|
+
if(elm.hasAttribute('onclick')){
|
308
|
+
elm.addEventListener('click', elm.onclick );
|
309
|
+
}
|
310
|
+
if(elm.hasAttribute('ondblclick')){
|
311
|
+
elm.addEventListener('dblclick', elm.onclick );
|
312
|
+
}
|
313
|
+
if(elm.hasAttribute('onkeydown')){
|
314
|
+
elm.addEventListener('keydown', elm.onclick );
|
315
|
+
}
|
316
|
+
if(elm.hasAttribute('onkeypress')){
|
317
|
+
elm.addEventListener('keypress', elm.onclick );
|
318
|
+
}
|
319
|
+
if(elm.hasAttribute('onkeyup')){
|
320
|
+
elm.addEventListener('keyup', elm.onclick );
|
321
|
+
}
|
322
|
+
if(elm.hasAttribute('onmousedown')){
|
323
|
+
elm.addEventListener('mousedown', elm.onclick );
|
324
|
+
}
|
325
|
+
if(elm.hasAttribute('onmousemove')){
|
326
|
+
elm.addEventListener('mousemove', elm.onclick );
|
327
|
+
}
|
328
|
+
if(elm.hasAttribute('onmouseout')){
|
329
|
+
elm.addEventListener('mouseout', elm.onclick );
|
330
|
+
}
|
331
|
+
if(elm.hasAttribute('onmouseover')){
|
332
|
+
elm.addEventListener('mouseover', elm.onclick );
|
333
|
+
}
|
334
|
+
if(elm.hasAttribute('onmouseup')){
|
335
|
+
elm.addEventListener('mouseup', elm.onclick );
|
336
|
+
}
|
337
|
+
return elm;
|
338
|
+
};
|
339
|
+
|
340
|
+
// non-ECMA function, but no other way for click events to enter env.js
|
341
|
+
var __click__ = function(element){
|
342
|
+
var event = new Event({
|
343
|
+
target:element,
|
344
|
+
currentTarget:element
|
345
|
+
});
|
346
|
+
event.initEvent("click");
|
347
|
+
element.dispatchEvent(event);
|
348
|
+
};
|
349
|
+
var __submit__ = function(element){
|
350
|
+
var event = new Event({
|
351
|
+
target:element,
|
352
|
+
currentTarget:element
|
353
|
+
});
|
354
|
+
event.initEvent("submit");
|
355
|
+
element.dispatchEvent(event);
|
356
|
+
};
|
357
|
+
var __focus__ = function(element){
|
358
|
+
var event = new Event({
|
359
|
+
target:element,
|
360
|
+
currentTarget:element
|
361
|
+
});
|
362
|
+
event.initEvent("focus");
|
363
|
+
element.dispatchEvent(event);
|
364
|
+
};
|
365
|
+
var __blur__ = function(element){
|
366
|
+
var event = new Event({
|
367
|
+
target:element,
|
368
|
+
currentTarget:element
|
369
|
+
});
|
370
|
+
event.initEvent("blur");
|
371
|
+
element.dispatchEvent(event);
|
372
|
+
};
|
373
|
+
|
374
|
+
// $w.HTMLElement = HTMLElement;
|
375
|
+
|
376
|
+
// Local Variables:
|
377
|
+
// espresso-indent-level:4
|
378
|
+
// c-basic-offset:4
|
379
|
+
// tab-width:4
|
380
|
+
// End:
|
@@ -0,0 +1,19 @@
|
|
1
|
+
$debug("Defining HTMLFieldSetElement");
|
2
|
+
/*
|
3
|
+
* HTMLFieldSetElement - DOM Level 2
|
4
|
+
*/
|
5
|
+
var HTMLFieldSetElement = function(ownerDocument) {
|
6
|
+
this.HTMLLegendElement = HTMLLegendElement;
|
7
|
+
this.HTMLLegendElement(ownerDocument);
|
8
|
+
};
|
9
|
+
HTMLFieldSetElement.prototype = new HTMLLegendElement;
|
10
|
+
__extend__(HTMLFieldSetElement.prototype, {
|
11
|
+
get margin(){
|
12
|
+
return this.getAttribute('margin');
|
13
|
+
},
|
14
|
+
set margin(value){
|
15
|
+
this.setAttribute('margin',value);
|
16
|
+
}
|
17
|
+
});
|
18
|
+
|
19
|
+
// $w.HTMLFieldSetElement = HTMLFieldSetElement;
|
data/src/html/form.js
ADDED
@@ -0,0 +1,484 @@
|
|
1
|
+
$debug("Defining HTMLFormElement");
|
2
|
+
/*
|
3
|
+
* HTMLFormElement - DOM Level 2
|
4
|
+
*/
|
5
|
+
var HTMLFormElement = function(ownerDocument){
|
6
|
+
this.HTMLElement = HTMLElement;
|
7
|
+
this.HTMLElement(ownerDocument);
|
8
|
+
};
|
9
|
+
HTMLFormElement.prototype = new HTMLElement;
|
10
|
+
__extend__(HTMLFormElement.prototype,{
|
11
|
+
get acceptCharset(){
|
12
|
+
return this.getAttribute('accept-charset');
|
13
|
+
|
14
|
+
},
|
15
|
+
set acceptCharset(acceptCharset){
|
16
|
+
this.setAttribute('accept-charset', acceptCharset);
|
17
|
+
|
18
|
+
},
|
19
|
+
get action(){
|
20
|
+
return this.getAttribute('action');
|
21
|
+
|
22
|
+
},
|
23
|
+
set action(action){
|
24
|
+
this.setAttribute('action', action);
|
25
|
+
|
26
|
+
},
|
27
|
+
get elements() {
|
28
|
+
return this.getElementsByTagName("*");
|
29
|
+
|
30
|
+
},
|
31
|
+
get enctype(){
|
32
|
+
return this.getAttribute('enctype');
|
33
|
+
|
34
|
+
},
|
35
|
+
set enctype(enctype){
|
36
|
+
this.setAttribute('enctype', enctype);
|
37
|
+
|
38
|
+
},
|
39
|
+
get length() {
|
40
|
+
return this.elements.length;
|
41
|
+
|
42
|
+
},
|
43
|
+
get method(){
|
44
|
+
return this.getAttribute('method');
|
45
|
+
|
46
|
+
},
|
47
|
+
set method(action){
|
48
|
+
this.setAttribute('method', action);
|
49
|
+
|
50
|
+
},
|
51
|
+
get name() {
|
52
|
+
return this.getAttribute("name");
|
53
|
+
|
54
|
+
},
|
55
|
+
set name(val) {
|
56
|
+
return this.setAttribute("name",val);
|
57
|
+
|
58
|
+
},
|
59
|
+
get target() {
|
60
|
+
return this.getAttribute("target");
|
61
|
+
|
62
|
+
},
|
63
|
+
set target(val) {
|
64
|
+
return this.setAttribute("target",val);
|
65
|
+
|
66
|
+
},
|
67
|
+
submit:function(){
|
68
|
+
__submit__(this);
|
69
|
+
|
70
|
+
},
|
71
|
+
reset:function(){
|
72
|
+
__reset__(this);
|
73
|
+
|
74
|
+
},
|
75
|
+
onsubmit:function(){
|
76
|
+
var v;
|
77
|
+
if ((v = __eval__(this.getAttribute('onsubmit')||'', this)) != false) {
|
78
|
+
// this.submit();
|
79
|
+
}
|
80
|
+
return v;
|
81
|
+
},
|
82
|
+
onreset:function(){
|
83
|
+
var v;
|
84
|
+
if ((v = __eval__(this.getAttribute('onreset')||'', this)) != false) {
|
85
|
+
this.reset();
|
86
|
+
}
|
87
|
+
return v;
|
88
|
+
}
|
89
|
+
});
|
90
|
+
|
91
|
+
// $w.HTMLFormElement = HTMLFormElement;
|
92
|
+
|
93
|
+
/**
|
94
|
+
* Form Submissions
|
95
|
+
*
|
96
|
+
* This code is borrow largely from jquery.params and jquery.form.js
|
97
|
+
*
|
98
|
+
* formToArray() gathers form element data into an array of objects that can
|
99
|
+
* be passed to any of the following ajax functions: $.get, $.post, or load.
|
100
|
+
* Each object in the array has both a 'name' and 'value' property. An example of
|
101
|
+
* an array for a simple login form might be:
|
102
|
+
*
|
103
|
+
* [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
|
104
|
+
*
|
105
|
+
* It is this array that is passed to pre-submit callback functions provided to the
|
106
|
+
* ajaxSubmit() and ajaxForm() methods.
|
107
|
+
*
|
108
|
+
* The semantic argument can be used to force form serialization in semantic order.
|
109
|
+
* This is normally true anyway, unless the form contains input elements of type='image'.
|
110
|
+
* If your form must be submitted with name/value pairs in semantic order and your form
|
111
|
+
* contains an input of type='image" then pass true for this arg, otherwise pass false
|
112
|
+
* (or nothing) to avoid the overhead for this logic.
|
113
|
+
*
|
114
|
+
*
|
115
|
+
* @name formToArray
|
116
|
+
* @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
|
117
|
+
* @type Array<Object>
|
118
|
+
*/
|
119
|
+
var __formToArray__ = function(form, semantic, boundary) {
|
120
|
+
var array = [],
|
121
|
+
elements = semantic ? form.getElementsByTagName('*') : form.elements,
|
122
|
+
element,
|
123
|
+
i,j,imax, jmax,
|
124
|
+
name,
|
125
|
+
value;
|
126
|
+
|
127
|
+
if (!elements)
|
128
|
+
return array;
|
129
|
+
|
130
|
+
imax = elements.length;
|
131
|
+
for(i=0; i < imax; i++) {
|
132
|
+
element = elements[i];
|
133
|
+
name = element.name;
|
134
|
+
if (!name)
|
135
|
+
continue;
|
136
|
+
|
137
|
+
if (semantic && form.clk && element.type == "image") {
|
138
|
+
// handle image inputs on the fly when semantic == true
|
139
|
+
if(!element.disabled && form.clk == element) {
|
140
|
+
if (form.clk_x) {
|
141
|
+
array.push({
|
142
|
+
name: name+'.x',
|
143
|
+
value: form.clk_x
|
144
|
+
});
|
145
|
+
}
|
146
|
+
if (form.clk_y) {
|
147
|
+
array.push({
|
148
|
+
name: name+'.y',
|
149
|
+
value: form.clk_y
|
150
|
+
});
|
151
|
+
}
|
152
|
+
}
|
153
|
+
continue;
|
154
|
+
}
|
155
|
+
|
156
|
+
value = __fieldValue__(element, true);
|
157
|
+
if (value && value.constructor == Array) {
|
158
|
+
jmax = value.length;
|
159
|
+
for(j=0; j < jmax; j++){
|
160
|
+
// FIX: handle uploads with the same name
|
161
|
+
array.push({name: name, value: value[j]});
|
162
|
+
}
|
163
|
+
} else if (value !== null && typeof value != 'undefined'){
|
164
|
+
array.push({name: name, value: value});
|
165
|
+
if(element.type == "file") {
|
166
|
+
var v = array[array.length-1];
|
167
|
+
v.filename = element.value || null;
|
168
|
+
}
|
169
|
+
}
|
170
|
+
}
|
171
|
+
|
172
|
+
if (!semantic && form.clk) {
|
173
|
+
// input type=='image' are not found in elements array! handle them here
|
174
|
+
elements = form.getElementsByTagName("input");
|
175
|
+
imax = imax=elements.length;
|
176
|
+
for(i=0; i < imax; i++) {
|
177
|
+
element = elements[i];
|
178
|
+
name = element.name;
|
179
|
+
if(name && !element.disabled && element.type == "image" && form.clk == element)
|
180
|
+
if (form.clk_x)
|
181
|
+
array.push({name: name+'.x', value: form.clk_x});
|
182
|
+
if (form.clk_y)
|
183
|
+
array.push({name: name+'.y', value: form.clk_y});
|
184
|
+
}
|
185
|
+
}
|
186
|
+
return array;
|
187
|
+
};
|
188
|
+
|
189
|
+
|
190
|
+
/**
|
191
|
+
* Serializes form data into a 'submittable' string. This method will return a string
|
192
|
+
* in the format: name1=value1&name2=value2
|
193
|
+
*
|
194
|
+
* The semantic argument can be used to force form serialization in semantic order.
|
195
|
+
* If your form must be submitted with name/value pairs in semantic order then pass
|
196
|
+
* true for this arg, otherwise pass false (or nothing) to avoid the overhead for
|
197
|
+
* this logic (which can be significant for very large forms).
|
198
|
+
*
|
199
|
+
*
|
200
|
+
* @name formSerialize
|
201
|
+
* @param semantic true if serialization must maintain strict semantic ordering of elements (slower)
|
202
|
+
* @type String
|
203
|
+
*/
|
204
|
+
var __formSerialize__ = function(form, semantic,boundary) {
|
205
|
+
//hand off to param for proper encoding
|
206
|
+
v = __param__(__formToArray__(form, semantic,boundary),boundary);
|
207
|
+
// print("v",v);
|
208
|
+
return v;
|
209
|
+
};
|
210
|
+
this.__formSerialize__ = __formSerialize__;
|
211
|
+
|
212
|
+
/**
|
213
|
+
* Serializes all field elements inputs Array into a query string.
|
214
|
+
* This method will return a string in the format: name1=value1&name2=value2
|
215
|
+
*
|
216
|
+
* The successful argument controls whether or not serialization is limited to
|
217
|
+
* 'successful' controls (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
|
218
|
+
* The default value of the successful argument is true.
|
219
|
+
*
|
220
|
+
*
|
221
|
+
* @name fieldSerialize
|
222
|
+
* @param successful true if only successful controls should be serialized (default is true)
|
223
|
+
* @type String
|
224
|
+
*/
|
225
|
+
var __fieldSerialize__ = function(inputs, successful) {
|
226
|
+
var array = [],
|
227
|
+
input,
|
228
|
+
name,
|
229
|
+
value,
|
230
|
+
i,j, imax, jmax;
|
231
|
+
|
232
|
+
imax = inputs.length;
|
233
|
+
for(i=0; i<imax; i++){
|
234
|
+
input = inputs[i];
|
235
|
+
name = input.name;
|
236
|
+
if (!name)
|
237
|
+
return;
|
238
|
+
value = __fieldValue__(input, successful);
|
239
|
+
if (value && value.constructor == Array) {
|
240
|
+
jmax = value.length;
|
241
|
+
for (j=0; j < max; j++){
|
242
|
+
array.push({
|
243
|
+
name: name,
|
244
|
+
value: value[j]
|
245
|
+
});
|
246
|
+
}
|
247
|
+
}else if (value !== null && typeof value != 'undefined'){
|
248
|
+
array.push({
|
249
|
+
name: input.name,
|
250
|
+
value: value
|
251
|
+
});
|
252
|
+
}
|
253
|
+
};
|
254
|
+
//hand off for proper encoding
|
255
|
+
return __param__(array);
|
256
|
+
};
|
257
|
+
|
258
|
+
|
259
|
+
/**
|
260
|
+
* Returns the value(s) of the element in the matched set. For example, consider the following form:
|
261
|
+
*
|
262
|
+
*
|
263
|
+
* The successful argument controls whether or not the field element must be 'successful'
|
264
|
+
* (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
|
265
|
+
* The default value of the successful argument is true. If this value is false the value(s)
|
266
|
+
* for each element is returned.
|
267
|
+
*
|
268
|
+
* Note: This method *always* returns an array. If no valid value can be determined the
|
269
|
+
* array will be empty, otherwise it will contain one or more values.
|
270
|
+
*
|
271
|
+
*
|
272
|
+
* @name fieldValue
|
273
|
+
* @param Boolean successful true if only the values for successful controls
|
274
|
+
* should be returned (default is true)
|
275
|
+
* @type Array<String>
|
276
|
+
*/
|
277
|
+
var __fieldValues__ = function(inputs, successful) {
|
278
|
+
var i,
|
279
|
+
imax = inputs.length,
|
280
|
+
element,
|
281
|
+
values = [],
|
282
|
+
value;
|
283
|
+
for (i=0; i < imax; i++) {
|
284
|
+
element = inputs[i];
|
285
|
+
value = __fieldValue__(element, successful);
|
286
|
+
if (value === null || typeof value == 'undefined' ||
|
287
|
+
(value.constructor == Array && !value.length))
|
288
|
+
continue;
|
289
|
+
value.constructor == Array ?
|
290
|
+
Array.prototype.push(values, value) :
|
291
|
+
values.push(value);
|
292
|
+
}
|
293
|
+
return values;
|
294
|
+
};
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Returns the value of the field element.
|
298
|
+
*
|
299
|
+
* The successful argument controls whether or not the field element must be 'successful'
|
300
|
+
* (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
|
301
|
+
* The default value of the successful argument is true. If the given element is not
|
302
|
+
* successful and the successful arg is not false then the returned value will be null.
|
303
|
+
*
|
304
|
+
* Note: If the successful flag is true (default) but the element is not successful, the return will be null
|
305
|
+
* Note: The value returned for a successful select-multiple element will always be an array.
|
306
|
+
* Note: If the element has no value the return value will be undefined.
|
307
|
+
*
|
308
|
+
* @name fieldValue
|
309
|
+
* @param Element el The DOM element for which the value will be returned
|
310
|
+
* @param Boolean successful true if value returned must be for a successful controls (default is true)
|
311
|
+
* @type String or Array<String> or null or undefined
|
312
|
+
*/
|
313
|
+
var __fieldValue__ = function(element, successful) {
|
314
|
+
var name = element.name,
|
315
|
+
type = element.type,
|
316
|
+
tag = element.tagName.toLowerCase(),
|
317
|
+
index,
|
318
|
+
array,
|
319
|
+
options,
|
320
|
+
option,
|
321
|
+
one,
|
322
|
+
i, imax,
|
323
|
+
value;
|
324
|
+
if (typeof successful == 'undefined') successful = true;
|
325
|
+
|
326
|
+
// NOTE: changed to default to first selected: could do this when building the DOM?
|
327
|
+
// Probably, but a little unclear ...
|
328
|
+
|
329
|
+
if (successful && (!name || element.disabled || type == 'reset' || type == 'button' ||
|
330
|
+
(type == 'checkbox' || type == 'radio') && !element.checked ||
|
331
|
+
(type == 'submit' || type == 'image') &&
|
332
|
+
element.form && element.form.clk != element || (false && tag == 'select' &&
|
333
|
+
element.selectedIndex == -1)))
|
334
|
+
return null;
|
335
|
+
|
336
|
+
if (tag == 'select') {
|
337
|
+
index = element.selectedIndex;
|
338
|
+
// print("i",index);
|
339
|
+
if (index < 0)
|
340
|
+
// return null;
|
341
|
+
index = 0;
|
342
|
+
array = [];
|
343
|
+
options = element.options;
|
344
|
+
one = (type == 'select-one');
|
345
|
+
imax = (one ? index+1 : options.length);
|
346
|
+
i = (one ? index : 0);
|
347
|
+
for( i; i < imax; i++) {
|
348
|
+
option = options[i];
|
349
|
+
if (option && option.selected) {
|
350
|
+
value = option.value;
|
351
|
+
if (one)
|
352
|
+
return value;
|
353
|
+
array.push(value);
|
354
|
+
}
|
355
|
+
}
|
356
|
+
if (array.length === 0) {
|
357
|
+
if (element.options[0]) {
|
358
|
+
array.push( element.options[0].value );
|
359
|
+
}
|
360
|
+
}
|
361
|
+
return array;
|
362
|
+
}
|
363
|
+
|
364
|
+
// print("**",tag,type,element.value,element.innerText);
|
365
|
+
|
366
|
+
if (type == "file") {
|
367
|
+
return Ruby.File.basename(element.value);
|
368
|
+
}
|
369
|
+
|
370
|
+
if (tag == "textarea") {
|
371
|
+
return element.innerText;
|
372
|
+
}
|
373
|
+
|
374
|
+
return element.value;
|
375
|
+
};
|
376
|
+
|
377
|
+
|
378
|
+
/**
|
379
|
+
* Clears the form data. Takes the following actions on the form's input fields:
|
380
|
+
* - input text fields will have their 'value' property set to the empty string
|
381
|
+
* - select elements will have their 'selectedIndex' property set to -1
|
382
|
+
* - checkbox and radio inputs will have their 'checked' property set to false
|
383
|
+
* - inputs of type submit, button, reset, and hidden will *not* be effected
|
384
|
+
* - button elements will *not* be effected
|
385
|
+
*
|
386
|
+
*
|
387
|
+
* @name clearForm
|
388
|
+
*/
|
389
|
+
var __clearForm__ = function(form) {
|
390
|
+
var i,
|
391
|
+
j, jmax,
|
392
|
+
elements,
|
393
|
+
resetable = ['input','select','textarea'];
|
394
|
+
for(i=0; i<resetable.lenth; i++){
|
395
|
+
elements = form.getElementsByTagName(resetable[i]);
|
396
|
+
jmax = elements.length;
|
397
|
+
for(j=0;j<jmax;j++){
|
398
|
+
__clearField__(elements[j]);
|
399
|
+
}
|
400
|
+
}
|
401
|
+
};
|
402
|
+
|
403
|
+
/**
|
404
|
+
* Clears the selected form element. Takes the following actions on the element:
|
405
|
+
* - input text fields will have their 'value' property set to the empty string
|
406
|
+
* - select elements will have their 'selectedIndex' property set to -1
|
407
|
+
* - checkbox and radio inputs will have their 'checked' property set to false
|
408
|
+
* - inputs of type submit, button, reset, and hidden will *not* be effected
|
409
|
+
* - button elements will *not* be effected
|
410
|
+
*
|
411
|
+
* @name clearFields
|
412
|
+
*/
|
413
|
+
var __clearField__ = function(element) {
|
414
|
+
var type = element.type,
|
415
|
+
tag = element.tagName.toLowerCase();
|
416
|
+
if (type == 'text' || type == 'password' || tag == 'textarea')
|
417
|
+
element.value = '';
|
418
|
+
else if (type == 'checkbox' || type == 'radio')
|
419
|
+
element.checked = false;
|
420
|
+
else if (tag == 'select')
|
421
|
+
element.selectedIndex = -1;
|
422
|
+
};
|
423
|
+
|
424
|
+
|
425
|
+
// Serialize an array of key/values into a query string
|
426
|
+
var __param__= function( array, boundary ) {
|
427
|
+
var serialized = [];
|
428
|
+
if(boundary) {
|
429
|
+
for(i=0; i<array.length; i++){
|
430
|
+
if (array[i].filename === null) {
|
431
|
+
continue;
|
432
|
+
}
|
433
|
+
serialized.push( "--"+boundary + "\r\n" );
|
434
|
+
var fn = array[i].filename ? '; filename="'+array[i].value+'"' : "";
|
435
|
+
if (fn) {
|
436
|
+
var mime_type = "text/plain";
|
437
|
+
var transfer_encoding;
|
438
|
+
if (array[i].filename.match(/\.jpe?g$/)) {
|
439
|
+
mime_type = "image/jpeg";
|
440
|
+
transfer_encoding = "base64";
|
441
|
+
}
|
442
|
+
var content;
|
443
|
+
if (transfer_encoding === "base64") {
|
444
|
+
Ruby.require("base64");
|
445
|
+
content = Ruby.eval("lambda { |fn| Base64.encode64(File.read(fn)) }").call(array[i].filename);
|
446
|
+
} else {
|
447
|
+
content = Ruby.File.read(array[i].filename);
|
448
|
+
}
|
449
|
+
// FIX: better mime types
|
450
|
+
array[i].value = [ "Content-Type: "+mime_type ];
|
451
|
+
if(transfer_encoding) {
|
452
|
+
array[i].value.push("Content-Transfer-Encoding: "+transfer_encoding);
|
453
|
+
}
|
454
|
+
array[i].value.push("Content-Length: "+content.length);
|
455
|
+
array[i].value.push("");
|
456
|
+
array[i].value.push(content);
|
457
|
+
array[i].value = array[i].value.join("\r\n");
|
458
|
+
}
|
459
|
+
serialized.push('Content-Disposition: form-data; name="'+array[i].name+'"'+fn+'\r\n');
|
460
|
+
serialized.push(array[i].value);
|
461
|
+
serialized.push( "\r\n" );
|
462
|
+
}
|
463
|
+
serialized.push( "--"+boundary + "--\r\n" );
|
464
|
+
var v = serialized.join("");
|
465
|
+
// print("vvvv",v);
|
466
|
+
return v;
|
467
|
+
} else {
|
468
|
+
// Serialize the key/values
|
469
|
+
for(i=0; i<array.length; i++){
|
470
|
+
serialized[ serialized.length ] =
|
471
|
+
encodeURIComponent(array[i].name) + '=' +
|
472
|
+
encodeURIComponent(array[i].value);
|
473
|
+
}
|
474
|
+
|
475
|
+
// Return the resulting serialization
|
476
|
+
return serialized.join("&").replace(/%20/g, "+");
|
477
|
+
}
|
478
|
+
};
|
479
|
+
|
480
|
+
// Local Variables:
|
481
|
+
// espresso-indent-level:4
|
482
|
+
// c-basic-offset:4
|
483
|
+
// tab-width:4
|
484
|
+
// End:
|