Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / docs / source / prototype-bridge.html
1 <html>
2 <head>
3   <title>The source code</title>
4     <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
5     <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
6 </head>
7 <body  onload="prettyPrint();">
8     <pre class="prettyprint lang-js">/*!
9  * Ext JS Library 3.0.3
10  * Copyright(c) 2006-2009 Ext JS, LLC
11  * licensing@extjs.com
12  * http://www.extjs.com/license
13  */
14 (function(){
15
16 var libFlyweight,
17     version = Prototype.Version.split('.'),
18     mouseEnterSupported = (parseInt(version[0]) >= 2) || (parseInt(version[1]) >= 7) || (parseInt(version[2]) >= 1),
19     mouseCache = {},
20     elContains = function(parent, child) {
21        if(parent && parent.firstChild){  
22          while(child) {
23             if(child === parent) {
24                 return true;
25             }
26             child = child.parentNode;               
27             if(child && (child.nodeType != 1)) {
28                 child = null;
29             }
30           }
31         }
32         return false;
33     },
34     checkRelatedTarget = function(e) {
35         return !elContains(e.currentTarget, pub.getRelatedTarget(e));
36     };
37
38 Ext.lib.Dom = {
39     getViewWidth : function(full){
40         return full ? this.getDocumentWidth() : this.getViewportWidth();
41     },
42
43     getViewHeight : function(full){
44         return full ? this.getDocumentHeight() : this.getViewportHeight();
45     },
46
47     getDocumentHeight: function() { // missing from prototype?
48         var scrollHeight = (document.compatMode != "CSS1Compat") ? document.body.scrollHeight : document.documentElement.scrollHeight;
49         return Math.max(scrollHeight, this.getViewportHeight());
50     },
51
52     getDocumentWidth: function() { // missing from prototype?
53         var scrollWidth = (document.compatMode != "CSS1Compat") ? document.body.scrollWidth : document.documentElement.scrollWidth;
54         return Math.max(scrollWidth, this.getViewportWidth());
55     },
56
57     getViewportHeight: function() { // missing from prototype?
58         var height = self.innerHeight;
59         var mode = document.compatMode;
60
61         if ( (mode || Ext.isIE) && !Ext.isOpera ) {
62             height = (mode == "CSS1Compat") ?
63                     document.documentElement.clientHeight : // Standards
64                     document.body.clientHeight; // Quirks
65         }
66
67         return height;
68     },
69
70     getViewportWidth: function() { // missing from prototype?
71         var width = self.innerWidth;  // Safari
72         var mode = document.compatMode;
73
74         if (mode || Ext.isIE) { // IE, Gecko, Opera
75             width = (mode == "CSS1Compat") ?
76                     document.documentElement.clientWidth : // Standards
77                     document.body.clientWidth; // Quirks
78         }
79         return width;
80     },
81
82     isAncestor : function(p, c){ // missing from prototype?
83         var ret = false;
84             
85         p = Ext.getDom(p);
86         c = Ext.getDom(c);
87         if (p && c) {
88             if (p.contains) {
89                 return p.contains(c);
90             } else if (p.compareDocumentPosition) {
91                 return !!(p.compareDocumentPosition(c) & 16);
92             } else {
93                 while (c = c.parentNode) {
94                     ret = c == p || ret;                        
95                 }
96             }               
97         }   
98         return ret;
99     },
100
101     getRegion : function(el){
102         return Ext.lib.Region.getRegion(el);
103     },
104
105     getY : function(el){
106         return this.getXY(el)[1];
107     },
108
109     getX : function(el){
110         return this.getXY(el)[0];
111     },
112
113     getXY : function(el){ // this initially used Position.cumulativeOffset but it is not accurate enough
114         var p, pe, b, scroll, bd = (document.body || document.documentElement);
115         el = Ext.getDom(el);
116
117         if(el == bd){
118             return [0, 0];
119         }
120
121         if (el.getBoundingClientRect) {
122             b = el.getBoundingClientRect();
123             scroll = fly(document).getScroll();
124             return [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)];
125         }
126         var x = 0, y = 0;
127
128         p = el;
129
130         var hasAbsolute = fly(el).getStyle("position") == "absolute";
131
132         while (p) {
133
134             x += p.offsetLeft;
135             y += p.offsetTop;
136
137             if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
138                 hasAbsolute = true;
139             }
140
141             if (Ext.isGecko) {
142                 pe = fly(p);
143
144                 var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
145                 var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
146
147
148                 x += bl;
149                 y += bt;
150
151
152                 if (p != el && pe.getStyle('overflow') != 'visible') {
153                     x += bl;
154                     y += bt;
155                 }
156             }
157             p = p.offsetParent;
158         }
159
160         if (Ext.isSafari && hasAbsolute) {
161             x -= bd.offsetLeft;
162             y -= bd.offsetTop;
163         }
164
165         if (Ext.isGecko && !hasAbsolute) {
166             var dbd = fly(bd);
167             x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
168             y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
169         }
170
171         p = el.parentNode;
172         while (p && p != bd) {
173             if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
174                 x -= p.scrollLeft;
175                 y -= p.scrollTop;
176             }
177             p = p.parentNode;
178         }
179         return [x, y];
180     },
181
182     setXY : function(el, xy){ // this initially used Position.cumulativeOffset but it is not accurate enough
183         el = Ext.fly(el, '_setXY');
184         el.position();
185         var pts = el.translatePoints(xy);
186         if(xy[0] !== false){
187             el.dom.style.left = pts.left + "px";
188         }
189         if(xy[1] !== false){
190             el.dom.style.top = pts.top + "px";
191         }
192     },
193
194     setX : function(el, x){
195         this.setXY(el, [x, false]);
196     },
197
198     setY : function(el, y){
199         this.setXY(el, [false, y]);
200     }
201 };
202
203 Ext.lib.Event = {
204     getPageX : function(e){
205         return Event.pointerX(e.browserEvent || e);
206     },
207
208     getPageY : function(e){
209         return Event.pointerY(e.browserEvent || e);
210     },
211
212     getXY : function(e){
213         e = e.browserEvent || e;
214         return [Event.pointerX(e), Event.pointerY(e)];
215     },
216
217     getTarget : function(e){
218         return Event.element(e.browserEvent || e);
219     },
220
221     resolveTextNode: Ext.isGecko ? function(node){
222         if(!node){
223             return;
224         }
225         var s = HTMLElement.prototype.toString.call(node);
226         if(s == '[xpconnect wrapped native prototype]' || s == '[object XULElement]'){
227             return;
228         }
229         return node.nodeType == 3 ? node.parentNode : node;
230     } : function(node){
231         return node && node.nodeType == 3 ? node.parentNode : node;
232     },
233
234     getRelatedTarget: function(ev) { // missing from prototype?
235         ev = ev.browserEvent || ev;
236         var t = ev.relatedTarget;
237         if (!t) {
238             if (ev.type == "mouseout") {
239                 t = ev.toElement;
240             } else if (ev.type == "mouseover") {
241                 t = ev.fromElement;
242             }
243         }
244
245         return this.resolveTextNode(t);
246     },
247
248     on : function(el, eventName, fn){
249         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
250             var item = mouseCache[el.id] || (mouseCache[el.id] = {});
251             item[eventName] = fn;
252             fn = fn.createInterceptor(checkRelatedTarget);
253             eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
254         }
255         Event.observe(el, eventName, fn, false);
256     },
257
258     un : function(el, eventName, fn){
259         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
260             var item = mouseCache[el.id], 
261                 ev = item && item[eventName];
262
263             if(ev){
264                 fn = ev.fn;
265                 delete item[eventName];
266                 eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
267             }
268         }
269         Event.stopObserving(el, eventName, fn, false);
270     },
271
272     purgeElement : function(el){
273         // no equiv?
274     },
275
276     preventDefault : function(e){   // missing from prototype?
277         e = e.browserEvent || e;
278         if(e.preventDefault) {
279             e.preventDefault();
280         } else {
281             e.returnValue = false;
282         }
283     },
284
285     stopPropagation : function(e){   // missing from prototype?
286         e = e.browserEvent || e;
287         if(e.stopPropagation) {
288             e.stopPropagation();
289         } else {
290             e.cancelBubble = true;
291         }
292     },
293
294     stopEvent : function(e){
295         Event.stop(e.browserEvent || e);
296     },
297
298     onAvailable : function(id, fn, scope){  // no equiv
299         var start = new Date(), iid;
300         var f = function(){
301             if(start.getElapsed() > 10000){
302                 clearInterval(iid);
303             }
304             var el = document.getElementById(id);
305             if(el){
306                 clearInterval(iid);
307                 fn.call(scope||window, el);
308             }
309         };
310         iid = setInterval(f, 50);
311     }
312 };
313
314 Ext.lib.Ajax = function(){
315     var createSuccess = function(cb){
316          return cb.success ? function(xhr){
317             cb.success.call(cb.scope||window, createResponse(cb, xhr));
318          } : Ext.emptyFn;
319     };
320     var createFailure = function(cb){
321          return cb.failure ? function(xhr){
322             cb.failure.call(cb.scope||window, createResponse(cb, xhr));
323          } : Ext.emptyFn;
324     };
325     var createResponse = function(cb, xhr){
326         var headerObj = {},
327             headerStr,              
328             t,
329             s;
330
331         try {
332             headerStr = xhr.getAllResponseHeaders();   
333             Ext.each(headerStr.replace(/\r\n/g, '\n').split('\n'), function(v){
334                 t = v.indexOf(':');
335                 if(t >= 0){
336                     s = v.substr(0, t).toLowerCase();
337                     if(v.charAt(t + 1) == ' '){
338                         ++t;
339                     }
340                     headerObj[s] = v.substr(t + 1);
341                 }
342             });
343         } catch(e) {}
344         
345         return {
346             responseText: xhr.responseText,
347             responseXML : xhr.responseXML,
348             argument: cb.argument,
349             status: xhr.status,
350             statusText: xhr.statusText,
351             getResponseHeader : function(header){return headerObj[header.toLowerCase()];},
352             getAllResponseHeaders : function(){return headerStr}
353         };
354     };
355     return {
356         request : function(method, uri, cb, data, options){
357             var o = {
358                 method: method,
359                 parameters: data || '',
360                 timeout: cb.timeout,
361                 onSuccess: createSuccess(cb),
362                 onFailure: createFailure(cb)
363             };
364             if(options){
365                 var hs = options.headers;
366                 if(hs){
367                     o.requestHeaders = hs;
368                 }
369                 if(options.xmlData){
370                     method = (method ? method : (options.method ? options.method : 'POST'));
371                     if (!hs || !hs['Content-Type']){
372                         o.contentType = 'text/xml';
373                     }
374                     o.postBody = options.xmlData;
375                     delete o.parameters;
376                 }
377                 if(options.jsonData){
378                     method = (method ? method : (options.method ? options.method : 'POST'));
379                     if (!hs || !hs['Content-Type']){
380                         o.contentType = 'application/json';
381                     }
382                     o.postBody = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
383                     delete o.parameters;
384                 }
385             }
386             new Ajax.Request(uri, o);
387         },
388
389         formRequest : function(form, uri, cb, data, isUpload, sslUri){
390             new Ajax.Request(uri, {
391                 method: Ext.getDom(form).method ||'POST',
392                 parameters: Form.serialize(form)+(data?'&'+data:''),
393                 timeout: cb.timeout,
394                 onSuccess: createSuccess(cb),
395                 onFailure: createFailure(cb)
396             });
397         },
398
399         isCallInProgress : function(trans){
400             return false;
401         },
402
403         abort : function(trans){
404             return false;
405         },
406         
407         serializeForm : function(form){
408             return Form.serialize(form.dom||form);
409         }
410     };
411 }();
412
413
414 Ext.lib.Anim = function(){
415     
416     var easings = {
417         easeOut: function(pos) {
418             return 1-Math.pow(1-pos,2);
419         },
420         easeIn: function(pos) {
421             return 1-Math.pow(1-pos,2);
422         }
423     };
424     var createAnim = function(cb, scope){
425         return {
426             stop : function(skipToLast){
427                 this.effect.cancel();
428             },
429
430             isAnimated : function(){
431                 return this.effect.state == 'running';
432             },
433
434             proxyCallback : function(){
435                 Ext.callback(cb, scope);
436             }
437         };
438     };
439     return {
440         scroll : function(el, args, duration, easing, cb, scope){
441             // not supported so scroll immediately?
442             var anim = createAnim(cb, scope);
443             el = Ext.getDom(el);
444             if(typeof args.scroll.to[0] == 'number'){
445                 el.scrollLeft = args.scroll.to[0];
446             }
447             if(typeof args.scroll.to[1] == 'number'){
448                 el.scrollTop = args.scroll.to[1];
449             }
450             anim.proxyCallback();
451             return anim;
452         },
453
454         motion : function(el, args, duration, easing, cb, scope){
455             return this.run(el, args, duration, easing, cb, scope);
456         },
457
458         color : function(el, args, duration, easing, cb, scope){
459             return this.run(el, args, duration, easing, cb, scope);
460         },
461
462         run : function(el, args, duration, easing, cb, scope, type){
463             var o = {};
464             for(var k in args){
465                 switch(k){   // scriptaculous doesn't support, so convert these
466                     case 'points':
467                         var by, pts, e = Ext.fly(el, '_animrun');
468                         e.position();
469                         if(by = args.points.by){
470                             var xy = e.getXY();
471                             pts = e.translatePoints([xy[0]+by[0], xy[1]+by[1]]);
472                         }else{
473                             pts = e.translatePoints(args.points.to);
474                         }
475                         o.left = pts.left+'px';
476                         o.top = pts.top+'px';
477                     break;
478                     case 'width':
479                         o.width = args.width.to+'px';
480                     break;
481                     case 'height':
482                         o.height = args.height.to+'px';
483                     break;
484                     case 'opacity':
485                         o.opacity = String(args.opacity.to);
486                     break;
487                     default:
488                         o[k] = String(args[k].to);
489                     break;
490                 }
491             }
492             var anim = createAnim(cb, scope);
493             anim.effect = new Effect.Morph(Ext.id(el), {
494                 duration: duration,
495                 afterFinish: anim.proxyCallback,
496                 transition: easings[easing] || Effect.Transitions.linear,
497                 style: o
498             });
499             return anim;
500         }
501     };
502 }();
503
504
505 // all lib flyweight calls use their own flyweight to prevent collisions with developer flyweights
506 function fly(el){
507     if(!libFlyweight){
508         libFlyweight = new Ext.Element.Flyweight();
509     }
510     libFlyweight.dom = el;
511     return libFlyweight;
512 }
513     
514 Ext.lib.Region = function(t, r, b, l) {
515     this.top = t;
516     this[1] = t;
517     this.right = r;
518     this.bottom = b;
519     this.left = l;
520     this[0] = l;
521 };
522
523 Ext.lib.Region.prototype = {
524     contains : function(region) {
525         return ( region.left   >= this.left   &&
526                  region.right  <= this.right  &&
527                  region.top    >= this.top    &&
528                  region.bottom <= this.bottom    );
529
530     },
531
532     getArea : function() {
533         return ( (this.bottom - this.top) * (this.right - this.left) );
534     },
535
536     intersect : function(region) {
537         var t = Math.max( this.top,    region.top    );
538         var r = Math.min( this.right,  region.right  );
539         var b = Math.min( this.bottom, region.bottom );
540         var l = Math.max( this.left,   region.left   );
541
542         if (b >= t && r >= l) {
543             return new Ext.lib.Region(t, r, b, l);
544         } else {
545             return null;
546         }
547     },
548     union : function(region) {
549         var t = Math.min( this.top,    region.top    );
550         var r = Math.max( this.right,  region.right  );
551         var b = Math.max( this.bottom, region.bottom );
552         var l = Math.min( this.left,   region.left   );
553
554         return new Ext.lib.Region(t, r, b, l);
555     },
556
557     constrainTo : function(r) {
558             this.top = this.top.constrain(r.top, r.bottom);
559             this.bottom = this.bottom.constrain(r.top, r.bottom);
560             this.left = this.left.constrain(r.left, r.right);
561             this.right = this.right.constrain(r.left, r.right);
562             return this;
563     },
564
565     adjust : function(t, l, b, r){
566         this.top += t;
567         this.left += l;
568         this.right += r;
569         this.bottom += b;
570         return this;
571     }
572 };
573
574 Ext.lib.Region.getRegion = function(el) {
575     var p = Ext.lib.Dom.getXY(el);
576
577     var t = p[1];
578     var r = p[0] + el.offsetWidth;
579     var b = p[1] + el.offsetHeight;
580     var l = p[0];
581
582     return new Ext.lib.Region(t, r, b, l);
583 };
584
585 Ext.lib.Point = function(x, y) {
586    if (Ext.isArray(x)) {
587       y = x[1];
588       x = x[0];
589    }
590     this.x = this.right = this.left = this[0] = x;
591     this.y = this.top = this.bottom = this[1] = y;
592 };
593
594 Ext.lib.Point.prototype = new Ext.lib.Region();
595
596
597 // prevent IE leaks
598 if(Ext.isIE) {
599     function fnCleanUp() {
600         var p = Function.prototype;
601         delete p.createSequence;
602         delete p.defer;
603         delete p.createDelegate;
604         delete p.createCallback;
605         delete p.createInterceptor;
606
607         window.detachEvent("onunload", fnCleanUp);
608     }
609     window.attachEvent("onunload", fnCleanUp);
610 }
611 })();</pre>
612 </body>
613 </html>