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