<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>The source code</title> <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" /> <script type="text/javascript" src="../resources/prettify/prettify.js"></script> <style type="text/css"> .highlight { display: block; background-color: #ddd; } </style> <script type="text/javascript"> function highlight() { document.getElementById(location.hash.replace(/#/, "")).className = "highlight"; } </script> </head> <body onload="prettyPrint(); highlight();"> <pre class="prettyprint lang-js"><span id='Ext-LoadMask'>/** </span> * A modal, floating Component which may be shown above a specified {@link Ext.Component Component} while loading data. * When shown, the configured owning Component will be covered with a modality mask, and the LoadMask's {@link #msg} will be * displayed centered, accompanied by a spinner image. * * If the {@link #store} config option is specified, the masking will be automatically shown and then hidden synchronized with * the Store's loading process. * * Because this is a floating Component, its z-index will be managed by the global {@link Ext.WindowManager ZIndexManager} * object, and upon show, it will place itsef at the top of the hierarchy. * * Example usage: * * // Basic mask: * var myMask = new Ext.LoadMask(myPanel, {msg:"Please wait..."}); * myMask.show(); */ Ext.define('Ext.LoadMask', { extend: 'Ext.Component', alias: 'widget.loadmask', /* Begin Definitions */ mixins: { floating: 'Ext.util.Floating', bindable: 'Ext.util.Bindable' }, uses: ['Ext.data.StoreManager'], /* End Definitions */ <span id='Ext-LoadMask-cfg-store'> /** </span> * @cfg {Ext.data.Store} store * Optional Store to which the mask is bound. The mask is displayed when a load request is issued, and * hidden on either load success, or load fail. */ //<locale> <span id='Ext-LoadMask-cfg-msg'> /** </span> * @cfg {String} [msg="Loading..."] * The text to display in a centered loading message box. */ msg : 'Loading...', //</locale> <span id='Ext-LoadMask-cfg-msgCls'> /** </span> * @cfg {String} [msgCls="x-mask-loading"] * The CSS class to apply to the loading message element. */ msgCls : Ext.baseCSSPrefix + 'mask-loading', <span id='Ext-LoadMask-cfg-maskCls'> /** </span> * @cfg {String} [maskCls="x-mask"] * The CSS class to apply to the mask element */ maskCls: Ext.baseCSSPrefix + 'mask', <span id='Ext-LoadMask-cfg-useMsg'> /** </span> * @cfg {Boolean} [useMsg=true] * Whether or not to use a loading message class or simply mask the bound element. */ useMsg: true, <span id='Ext-LoadMask-cfg-useTargetEl'> /** </span> * @cfg {Boolean} [useTargetEl=false] * True to mask the {@link Ext.Component#getTargetEl targetEl} of the bound Component. By default, * the {@link Ext.Component#getEl el} will be masked. */ useTargetEl: false, baseCls: Ext.baseCSSPrefix + 'mask-msg', childEls: [ 'msgEl' ], renderTpl: '<div id="{id}-msgEl" style="position:relative" class="{[values.$comp.msgCls]}"></div>', // Private. Obviously, it's floating. floating: { shadow: 'frame' }, // Private. Masks are not focusable focusOnToFront: false, // When we put the load mask to the front of it's owner, we generally don't want to also bring the owning // component to the front. bringParentToFront: false, <span id='Ext-LoadMask-method-constructor'> /** </span> * Creates new LoadMask. * @param {Ext.Component} comp The Component you wish to mask. The the mask will be automatically sized * upon Component resize, and the message box will be kept centered.</p> * @param {Object} [config] The config object */ constructor : function(comp, config) { var me = this; // Element support to be deprecated if (!comp.isComponent) { //<debug> if (Ext.isDefined(Ext.global.console)) { Ext.global.console.warn('Ext.LoadMask: LoadMask for elements has been deprecated, use Ext.dom.Element.mask & Ext.dom.Element.unmask'); } //</debug> comp = Ext.get(comp); this.isElement = true; } me.ownerCt = comp; if (!this.isElement) { me.bindComponent(comp); } me.callParent([config]); if (me.store) { me.bindStore(me.store, true); } }, bindComponent: function(comp){ var me = this, listeners = { scope: this, resize: me.sizeMask, added: me.onComponentAdded, removed: me.onComponentRemoved }, hierarchyEventSource = Ext.container.Container.hierarchyEventSource; if (comp.floating) { listeners.move = me.sizeMask; me.activeOwner = comp; } else if (comp.ownerCt) { me.onComponentAdded(comp.ownerCt); } else { // if the target comp is non-floating and under a floating comp don't bring the load mask to the front of the stack me.preventBringToFront = true; } me.mon(comp, listeners); // subscribe to the observer that manages the hierarchy me.mon(hierarchyEventSource, { show: me.onContainerShow, hide: me.onContainerHide, expand: me.onContainerExpand, collapse: me.onContainerCollapse, scope: me }); }, onComponentAdded: function(owner){ var me = this; delete me.activeOwner; me.floatParent = owner; if (!owner.floating) { owner = owner.up('[floating]'); } if (owner) { me.activeOwner = owner; me.mon(owner, 'move', me.sizeMask, me); } owner = me.floatParent.ownerCt; if (me.rendered && me.isVisible() && owner) { me.floatOwner = owner; me.mon(owner, 'afterlayout', me.sizeMask, me, {single: true}); } }, onComponentRemoved: function(owner){ var me = this, activeOwner = me.activeOwner, floatOwner = me.floatOwner; if (activeOwner) { me.mun(activeOwner, 'move', me.sizeMask, me); } if (floatOwner) { me.mun(floatOwner, 'afterlayout', me.sizeMask, me); } delete me.activeOwner; delete me.floatOwner; }, afterRender: function() { this.callParent(arguments); this.container = this.floatParent.getContentTarget(); }, onContainerShow: function(container){ if (this.isActiveContainer(container)) { this.onComponentShow(); } }, onContainerHide: function(container){ if (this.isActiveContainer(container)) { this.onComponentHide(); } }, onContainerExpand: function(container){ if (this.isActiveContainer(container)) { this.onComponentShow(); } }, onContainerCollapse: function(container){ if (this.isActiveContainer(container)) { this.onComponentHide(); } }, isActiveContainer: function(container){ return this.isDescendantOf(container); }, onComponentHide: function(){ var me = this; if (me.rendered && me.isVisible()) { me.hide(); me.showNext = true; } }, onComponentShow: function(){ if (this.showNext) { this.show(); } delete this.showNext; }, <span id='Ext-LoadMask-method-sizeMask'> /** </span> * @private * Called when this LoadMask's Component is resized. The toFront method rebases and resizes the modal mask. */ sizeMask: function() { var me = this, target; if (me.rendered && me.isVisible()) { me.center(); target = me.getMaskTarget(); me.getMaskEl().show().setSize(target.getSize()).alignTo(target, 'tl-tl'); } }, <span id='Ext-LoadMask-method-bindStore'> /** </span> * Changes the data store bound to this LoadMask. * @param {Ext.data.Store} store The store to bind to this LoadMask */ bindStore : function(store, initial) { var me = this; me.mixins.bindable.bindStore.apply(me, arguments); store = me.store; if (store && store.isLoading()) { me.onBeforeLoad(); } }, getStoreListeners: function(){ return { beforeload: this.onBeforeLoad, load: this.onLoad, exception: this.onLoad, // Fired when a range is requested for rendering that is not in the cache cachemiss: this.onBeforeLoad, // Fired when a range for rendering which was previously missing from the cache is loaded cachefilled: this.onLoad }; }, onDisable : function() { this.callParent(arguments); if (this.loading) { this.onLoad(); } }, getOwner: function(){ return this.ownerCt || this.floatParent; }, getMaskTarget: function(){ var owner = this.getOwner(); return this.useTargetEl ? owner.getTargetEl() : owner.getEl(); }, // private onBeforeLoad : function() { var me = this, owner = me.getOwner(), origin; if (!me.disabled) { me.loading = true; // If the owning Component has not been layed out, defer so that the ZIndexManager // gets to read its layed out size when sizing the modal mask if (owner.componentLayoutCounter) { me.maybeShow(); } else { // The code below is a 'run-once' interceptor. origin = owner.afterComponentLayout; owner.afterComponentLayout = function() { owner.afterComponentLayout = origin; origin.apply(owner, arguments); me.maybeShow(); }; } } }, maybeShow: function(){ var me = this, owner = me.getOwner(); if (!owner.isVisible(true)) { me.showNext = true; } else if (me.loading && owner.rendered) { me.show(); } }, getMaskEl: function(){ var me = this; return me.maskEl || (me.maskEl = me.el.insertSibling({ cls: me.maskCls, style: { zIndex: me.el.getStyle('zIndex') - 2 } }, 'before')); }, onShow: function() { var me = this, msgEl = me.msgEl; me.callParent(arguments); me.loading = true; if (me.useMsg) { msgEl.show().update(me.msg); } else { msgEl.parent().hide(); } }, hide: function(){ // Element support to be deprecated if (this.isElement) { this.ownerCt.unmask(); this.fireEvent('hide', this); return; } delete this.showNext; return this.callParent(arguments); }, onHide: function(){ this.callParent(); this.getMaskEl().hide(); }, show: function(){ // Element support to be deprecated if (this.isElement) { this.ownerCt.mask(this.useMsg ? this.msg : '', this.msgCls); this.fireEvent('show', this); return; } return this.callParent(arguments); }, afterShow: function() { this.callParent(arguments); this.sizeMask(); }, setZIndex: function(index) { var me = this, owner = me.activeOwner; if (owner) { // it seems silly to add 1 to have it subtracted in the call below, // but this allows the x-mask el to have the correct z-index (same as the component) // so instead of directly changing the zIndexStack just get the z-index of the owner comp index = parseInt(owner.el.getStyle('zIndex'), 10) + 1; } me.getMaskEl().setStyle('zIndex', index - 1); return me.mixins.floating.setZIndex.apply(me, arguments); }, // private onLoad : function() { this.loading = false; this.hide(); }, onDestroy: function(){ var me = this; if (me.isElement) { me.ownerCt.unmask(); } Ext.destroy(me.maskEl); me.callParent(); } }); </pre> </body> </html>