4 * Copyright(c) 2006-2007, Ext JS, LLC.
6 * Originally Released Under LGPL - original licence link has changed is not relivant.
9 * <script type="text/javascript">
14 * @extends Roo.Element
15 * An extended {@link Roo.Element} object that supports a shadow and shim, constrain to viewport and
16 * automatic maintaining of shadow/shim positions.
17 * @cfg {Boolean} shim False to disable the iframe shim in browsers which need one (defaults to true)
18 * @cfg {String/Boolean} shadow True to create a shadow element with default class "x-layer-shadow", or
19 * you can pass a string with a CSS class name. False turns off the shadow.
20 * @cfg {Object} dh DomHelper object config to create element with (defaults to {tag: "div", cls: "x-layer"}).
21 * @cfg {Boolean} constrain False to disable constrain to viewport (defaults to true)
22 * @cfg {String} cls CSS class to add to the element
23 * @cfg {Number} zindex Starting z-index (defaults to 11000)
24 * @cfg {Number} shadowOffset Number of pixels to offset the shadow (defaults to 3)
26 * @param {Object} config An object with config options.
27 * @param {String/HTMLElement} existingEl (optional) Uses an existing DOM element. If the element is not found it creates it.
30 Roo.Layer = function(config, existingEl){
31 config = config || {};
32 var dh = Roo.DomHelper;
33 var cp = config.parentEl, pel = cp ? Roo.getDom(cp) : document.body;
35 this.dom = Roo.getDom(existingEl);
38 var o = config.dh || {tag: "div", cls: "x-layer"};
39 this.dom = dh.append(pel, o);
42 this.addClass(config.cls);
44 this.constrain = config.constrain !== false;
45 this.visibilityMode = Roo.Element.VISIBILITY;
47 this.id = this.dom.id = config.id;
49 this.id = Roo.id(this.dom);
51 this.zindex = config.zindex || this.getZIndex();
52 this.position("absolute", this.zindex);
54 this.shadowOffset = config.shadowOffset || 4;
55 this.shadow = new Roo.Shadow({
56 offset : this.shadowOffset,
60 this.shadowOffset = 0;
62 this.useShim = config.shim !== false && Roo.useShims;
63 this.useDisplay = config.useDisplay;
67 var supr = Roo.Element.prototype;
69 // shims are shared among layer to keep from having 100 iframes
72 Roo.extend(Roo.Layer, Roo.Element, {
74 getZIndex : function(){
75 return this.zindex || parseInt(this.getStyle("z-index"), 10) || 11000;
85 var shim = shims.shift();
87 shim = this.createShim();
88 shim.enableDisplayMode('block');
89 shim.dom.style.display = 'none';
90 shim.dom.style.visibility = 'visible';
92 var pn = this.dom.parentNode;
93 if(shim.dom.parentNode != pn){
94 pn.insertBefore(shim.dom, this.dom);
96 shim.setStyle('z-index', this.getZIndex()-2);
101 hideShim : function(){
103 this.shim.setDisplayed(false);
104 shims.push(this.shim);
109 disableShadow : function(){
111 this.shadowDisabled = true;
113 this.lastShadowOffset = this.shadowOffset;
114 this.shadowOffset = 0;
118 enableShadow : function(show){
120 this.shadowDisabled = false;
121 this.shadowOffset = this.lastShadowOffset;
122 delete this.lastShadowOffset;
130 // this code can execute repeatedly in milliseconds (i.e. during a drag) so
131 // code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)
132 sync : function(doShow){
133 var sw = this.shadow;
134 if(!this.updating && this.isVisible() && (sw || this.useShim)){
135 var sh = this.getShim();
137 var w = this.getWidth(),
138 h = this.getHeight();
140 var l = this.getLeft(true),
141 t = this.getTop(true);
143 if(sw && !this.shadowDisabled){
144 if(doShow && !sw.isVisible()){
147 sw.realign(l, t, w, h);
153 // fit the shim behind the shadow, so it is shimmed too
154 var a = sw.adjusts, s = sh.dom.style;
155 s.left = (Math.min(l, l+a.l))+"px";
156 s.top = (Math.min(t, t+a.t))+"px";
157 s.width = (w+a.w)+"px";
158 s.height = (h+a.h)+"px";
172 destroy : function(){
177 this.removeAllListeners();
178 var pn = this.dom.parentNode;
180 pn.removeChild(this.dom);
182 Roo.Element.uncache(this.id);
190 beginUpdate : function(){
191 this.updating = true;
195 endUpdate : function(){
196 this.updating = false;
201 hideUnders : function(negOffset){
209 constrainXY : function(){
211 var vw = Roo.lib.Dom.getViewWidth(),
212 vh = Roo.lib.Dom.getViewHeight();
213 var s = Roo.get(document).getScroll();
215 var xy = this.getXY();
216 var x = xy[0], y = xy[1];
217 var w = this.dom.offsetWidth+this.shadowOffset, h = this.dom.offsetHeight+this.shadowOffset;
218 // only move it if it needs it
220 // first validate right/bottom
221 if((x + w) > vw+s.left){
222 x = vw - w - this.shadowOffset;
225 if((y + h) > vh+s.top){
226 y = vh - h - this.shadowOffset;
229 // then make sure top/left isn't negative
240 var ay = this.avoidY;
241 if(y <= ay && (y+h) >= ay){
247 supr.setXY.call(this, xy);
253 isVisible : function(){
258 showAction : function(){
259 this.visible = true; // track visibility to prevent getStyle calls
260 if(this.useDisplay === true){
261 this.setDisplayed("");
262 }else if(this.lastXY){
263 supr.setXY.call(this, this.lastXY);
264 }else if(this.lastLT){
265 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
270 hideAction : function(){
271 this.visible = false;
272 if(this.useDisplay === true){
273 this.setDisplayed(false);
275 this.setLeftTop(-10000,-10000);
279 // overridden Element method
280 setVisible : function(v, a, d, c, e){
290 }.createDelegate(this);
291 supr.setVisible.call(this, true, true, d, cb, e);
294 this.hideUnders(true);
303 }.createDelegate(this);
305 supr.setVisible.call(this, v, a, d, cb, e);
314 storeXY : function(xy){
319 storeLeftTop : function(left, top){
321 this.lastLT = [left, top];
325 beforeFx : function(){
327 return Roo.Layer.superclass.beforeFx.apply(this, arguments);
331 afterFx : function(){
332 Roo.Layer.superclass.afterFx.apply(this, arguments);
333 this.sync(this.isVisible());
337 beforeAction : function(){
338 if(!this.updating && this.shadow){
343 // overridden Element method
344 setLeft : function(left){
345 this.storeLeftTop(left, this.getTop(true));
346 supr.setLeft.apply(this, arguments);
350 setTop : function(top){
351 this.storeLeftTop(this.getLeft(true), top);
352 supr.setTop.apply(this, arguments);
356 setLeftTop : function(left, top){
357 this.storeLeftTop(left, top);
358 supr.setLeftTop.apply(this, arguments);
362 setXY : function(xy, a, d, c, e){
366 var cb = this.createCB(c);
367 supr.setXY.call(this, xy, a, d, cb, e);
374 createCB : function(c){
385 // overridden Element method
386 setX : function(x, a, d, c, e){
387 this.setXY([x, this.getY()], a, d, c, e);
390 // overridden Element method
391 setY : function(y, a, d, c, e){
392 this.setXY([this.getX(), y], a, d, c, e);
395 // overridden Element method
396 setSize : function(w, h, a, d, c, e){
398 var cb = this.createCB(c);
399 supr.setSize.call(this, w, h, a, d, cb, e);
405 // overridden Element method
406 setWidth : function(w, a, d, c, e){
408 var cb = this.createCB(c);
409 supr.setWidth.call(this, w, a, d, cb, e);
415 // overridden Element method
416 setHeight : function(h, a, d, c, e){
418 var cb = this.createCB(c);
419 supr.setHeight.call(this, h, a, d, cb, e);
425 // overridden Element method
426 setBounds : function(x, y, w, h, a, d, c, e){
428 var cb = this.createCB(c);
430 this.storeXY([x, y]);
431 supr.setXY.call(this, [x, y]);
432 supr.setSize.call(this, w, h, a, d, cb, e);
435 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
441 * Sets the z-index of this layer and adjusts any shadow and shim z-indexes. The layer z-index is automatically
442 * incremented by two more than the value passed in so that it always shows above any shadow or shim (the shadow
443 * element, if any, will be assigned z-index + 1, and the shim element, if any, will be assigned the unmodified z-index).
444 * @param {Number} zindex The new z-index to set
445 * @return {this} The Layer
447 setZIndex : function(zindex){
448 this.zindex = zindex;
449 this.setStyle("z-index", zindex + 2);
451 this.shadow.setZIndex(zindex + 1);
454 this.shim.setStyle("z-index", zindex);