Upgrade to ExtJS 3.0.0 - Released 07/06/2009
[extjs.git] / src / adapter / yui-bridge.js
1 /*!
2  * Ext JS Library 3.0.0
3  * Copyright(c) 2006-2009 Ext JS, LLC
4  * licensing@extjs.com
5  * http://www.extjs.com/license
6  */
7 if(typeof YAHOO == "undefined"){
8     throw "Unable to load Ext, core YUI utilities (yahoo, dom, event) not found.";
9 }
10
11 (function(){
12     var E = YAHOO.util.Event,
13         D = YAHOO.util.Dom,
14         CN = YAHOO.util.Connect,
15         ES = YAHOO.util.Easing,
16         A = YAHOO.util.Anim,
17         libFlyweight,
18         version = YAHOO.env.getVersion('yahoo').version.split('.'),
19         mouseEnterSupported = parseInt(version[0]) >= 3,
20         mouseCache = {},
21         isXUL = Ext.isGecko ? function(node){
22             return Object.prototype.toString.call(node) == '[object XULElement]';
23         } : function(){
24         }, isTextNode = Ext.isGecko ? function(node){
25             try{
26                 return node.nodeType == 3;
27             }catch (e){
28                 return false;
29             }
30         } : function(node){
31             return node.nodeType == 3;
32         }, elContains = function(parent, child){
33             if(parent && parent.firstChild){
34                 while(child){
35                     if(child === parent){
36                         return true;
37                     }
38                     try{
39                         child = child.parentNode;
40                     }catch (e){
41                         return false;
42                     }
43                     if(child && (child.nodeType != 1)){
44                         child = null;
45                     }
46                 }
47             }
48             return false;
49         }, checkRelatedTarget = function(e){
50             var related = Ext.lib.Event.getRelatedTarget(e);
51             return !(isXUL(related) || elContains(e.currentTarget, related));
52         };
53
54 Ext.lib.Dom = {
55     getViewWidth : function(full){
56         return full ? D.getDocumentWidth() : D.getViewportWidth();
57     },
58
59     getViewHeight : function(full){
60         return full ? D.getDocumentHeight() : D.getViewportHeight();
61     },
62
63     isAncestor : function(haystack, needle){
64         return D.isAncestor(haystack, needle);
65     },
66
67     getRegion : function(el){
68         return D.getRegion(el);
69     },
70
71     getY : function(el){
72         return this.getXY(el)[1];
73     },
74
75     getX : function(el){
76         return this.getXY(el)[0];
77     },
78
79     // original version based on YahooUI getXY
80     // this version fixes several issues in Safari and FF
81     // and boosts performance by removing the batch overhead, repetitive dom lookups and array index calls
82     getXY : function(el){
83         var p, pe, b, scroll, bd = (document.body || document.documentElement);
84         el = Ext.getDom(el);
85
86         if(el == bd){
87             return [0, 0];
88         }
89
90         if (el.getBoundingClientRect) {
91             b = el.getBoundingClientRect();
92             scroll = fly(document).getScroll();
93             return [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)];
94         }
95         var x = 0, y = 0;
96
97         p = el;
98
99         var hasAbsolute = fly(el).getStyle("position") == "absolute";
100
101         while (p) {
102
103             x += p.offsetLeft;
104             y += p.offsetTop;
105
106             if (!hasAbsolute && fly(p).getStyle("position") == "absolute") {
107                 hasAbsolute = true;
108             }
109
110             if (Ext.isGecko) {
111                 pe = fly(p);
112
113                 var bt = parseInt(pe.getStyle("borderTopWidth"), 10) || 0;
114                 var bl = parseInt(pe.getStyle("borderLeftWidth"), 10) || 0;
115
116
117                 x += bl;
118                 y += bt;
119
120
121                 if (p != el && pe.getStyle('overflow') != 'visible') {
122                     x += bl;
123                     y += bt;
124                 }
125             }
126             p = p.offsetParent;
127         }
128
129         if (Ext.isSafari && hasAbsolute) {
130             x -= bd.offsetLeft;
131             y -= bd.offsetTop;
132         }
133
134         if (Ext.isGecko && !hasAbsolute) {
135             var dbd = fly(bd);
136             x += parseInt(dbd.getStyle("borderLeftWidth"), 10) || 0;
137             y += parseInt(dbd.getStyle("borderTopWidth"), 10) || 0;
138         }
139
140         p = el.parentNode;
141         while (p && p != bd) {
142             if (!Ext.isOpera || (p.tagName != 'TR' && fly(p).getStyle("display") != "inline")) {
143                 x -= p.scrollLeft;
144                 y -= p.scrollTop;
145             }
146             p = p.parentNode;
147         }
148         return [x, y];
149     },
150
151     setXY : function(el, xy){
152         el = Ext.fly(el, '_setXY');
153         el.position();
154         var pts = el.translatePoints(xy);
155         if(xy[0] !== false){
156             el.dom.style.left = pts.left + "px";
157         }
158         if(xy[1] !== false){
159             el.dom.style.top = pts.top + "px";
160         }
161     },
162
163     setX : function(el, x){
164         this.setXY(el, [x, false]);
165     },
166
167     setY : function(el, y){
168         this.setXY(el, [false, y]);
169     }
170 };
171
172 Ext.lib.Event = {
173     getPageX : function(e){
174         return E.getPageX(e.browserEvent || e);
175     },
176
177     getPageY : function(e){
178         return E.getPageY(e.browserEvent || e);
179     },
180
181     getXY : function(e){
182         return E.getXY(e.browserEvent || e);
183     },
184
185     getTarget : function(e){
186         return E.getTarget(e.browserEvent || e);
187     },
188
189     getRelatedTarget : function(e){
190         return E.getRelatedTarget(e.browserEvent || e);
191     },
192
193     on : function(el, eventName, fn, scope, override){
194         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
195             var item = mouseCache[el.id] || (mouseCache[el.id] = {});
196             item[eventName] = fn;
197             fn = fn.createInterceptor(checkRelatedTarget);
198             eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
199         }
200         E.on(el, eventName, fn, scope, override);
201     },
202
203     un : function(el, eventName, fn){
204         if((eventName == 'mouseenter' || eventName == 'mouseleave') && !mouseEnterSupported){
205             var item = mouseCache[el.id], 
206                 ev = item && item[eventName];
207
208             if(ev){
209                 fn = ev.fn;
210                 delete item[eventName];
211                 eventName = (eventName == 'mouseenter') ? 'mouseover' : 'mouseout';
212             }
213         }
214         E.removeListener(el, eventName, fn);;
215     },
216
217     purgeElement : function(el){
218         E.purgeElement(el);
219     },
220
221     preventDefault : function(e){
222         E.preventDefault(e.browserEvent || e);
223     },
224
225     stopPropagation : function(e){
226         E.stopPropagation(e.browserEvent || e);
227     },
228
229     stopEvent : function(e){
230         E.stopEvent(e.browserEvent || e);
231     },
232
233     onAvailable : function(el, fn, scope, override){
234         return E.onAvailable(el, fn, scope, override);
235     }
236 };
237
238 Ext.lib.Ajax = {
239     request : function(method, uri, cb, data, options){
240         if(options){
241             var hs = options.headers;
242             if(hs){
243                 for(var h in hs){
244                     if(hs.hasOwnProperty(h)){
245                         CN.initHeader(h, hs[h], false);
246                     }
247                 }
248             }
249             if(options.xmlData){
250                 if (!hs || !hs['Content-Type']){
251                     CN.initHeader('Content-Type', 'text/xml', false);
252                 }
253                 method = (method ? method : (options.method ? options.method : 'POST'));
254                 data = options.xmlData;
255             }else if(options.jsonData){
256                 if (!hs || !hs['Content-Type']){
257                     CN.initHeader('Content-Type', 'application/json', false);
258                 }
259                 method = (method ? method : (options.method ? options.method : 'POST'));
260                 data = typeof options.jsonData == 'object' ? Ext.encode(options.jsonData) : options.jsonData;
261             }
262         }
263         return CN.asyncRequest(method, uri, cb, data);
264     },
265
266     formRequest : function(form, uri, cb, data, isUpload, sslUri){
267         CN.setForm(form, isUpload, sslUri);
268         return CN.asyncRequest(Ext.getDom(form).method ||'POST', uri, cb, data);
269     },
270
271     isCallInProgress : function(trans){
272         return CN.isCallInProgress(trans);
273     },
274
275     abort : function(trans){
276         return CN.abort(trans);
277     },
278
279     serializeForm : function(form){
280         var d = CN.setForm(form.dom || form);
281         CN.resetFormState();
282         return d;
283     }
284 };
285
286 Ext.lib.Region = YAHOO.util.Region;
287 Ext.lib.Point = YAHOO.util.Point;
288
289
290 Ext.lib.Anim = {
291     scroll : function(el, args, duration, easing, cb, scope){
292         this.run(el, args, duration, easing, cb, scope, YAHOO.util.Scroll);
293     },
294
295     motion : function(el, args, duration, easing, cb, scope){
296         this.run(el, args, duration, easing, cb, scope, YAHOO.util.Motion);
297     },
298
299     color : function(el, args, duration, easing, cb, scope){
300         this.run(el, args, duration, easing, cb, scope, YAHOO.util.ColorAnim);
301     },
302
303     run : function(el, args, duration, easing, cb, scope, type){
304         type = type || YAHOO.util.Anim;
305         if(typeof easing == "string"){
306             easing = YAHOO.util.Easing[easing];
307         }
308         var anim = new type(el, args, duration, easing);
309         anim.animateX(function(){
310             Ext.callback(cb, scope);
311         });
312         return anim;
313     }
314 };
315
316 // all lib flyweight calls use their own flyweight to prevent collisions with developer flyweights
317 function fly(el){
318     if(!libFlyweight){
319         libFlyweight = new Ext.Element.Flyweight();
320     }
321     libFlyweight.dom = el;
322     return libFlyweight;
323 }
324
325 // prevent IE leaks
326 if(Ext.isIE) {
327     function fnCleanUp() {
328         var p = Function.prototype;
329         delete p.createSequence;
330         delete p.defer;
331         delete p.createDelegate;
332         delete p.createCallback;
333         delete p.createInterceptor;
334
335         window.detachEvent("onunload", fnCleanUp);
336     }
337     window.attachEvent("onunload", fnCleanUp);
338 }
339 // various overrides
340
341 // add ability for callbacks with animations
342 if(YAHOO.util.Anim){
343     YAHOO.util.Anim.prototype.animateX = function(callback, scope){
344         var f = function(){
345             this.onComplete.unsubscribe(f);
346             if(typeof callback == "function"){
347                 callback.call(scope || this, this);
348             }
349         };
350         this.onComplete.subscribe(f, this, true);
351         this.animate();
352     };
353 }
354
355 if(YAHOO.util.DragDrop && Ext.dd.DragDrop){
356     YAHOO.util.DragDrop.defaultPadding = Ext.dd.DragDrop.defaultPadding;
357     YAHOO.util.DragDrop.constrainTo = Ext.dd.DragDrop.constrainTo;
358 }
359
360 YAHOO.util.Dom.getXY = function(el) {
361     var f = function(el) {
362         return Ext.lib.Dom.getXY(el);
363     };
364     return YAHOO.util.Dom.batch(el, f, YAHOO.util.Dom, true);
365 };
366
367
368 // workaround for Safari anim duration speed problems
369 if(YAHOO.util.AnimMgr){
370     YAHOO.util.AnimMgr.fps = 1000;
371 }
372
373 YAHOO.util.Region.prototype.adjust = function(t, l, b, r){
374     this.top += t;
375     this.left += l;
376     this.right += r;
377     this.bottom += b;
378     return this;
379 };
380     
381 YAHOO.util.Region.prototype.constrainTo = function(r) {
382     this.top = this.top.constrain(r.top, r.bottom);
383     this.bottom = this.bottom.constrain(r.top, r.bottom);
384     this.left = this.left.constrain(r.left, r.right);
385     this.right = this.right.constrain(r.left, r.right);
386     return this;
387 };
388
389
390 })();