4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5 <title>The source code</title>
6 <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7 <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8 <style type="text/css">
9 .highlight { display: block; background-color: #ddd; }
11 <script type="text/javascript">
12 function highlight() {
13 document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
17 <body onload="prettyPrint(); highlight();">
18 <pre class="prettyprint lang-js"><span id='Ext-ZIndexManager'>/**
19 </span> * @class Ext.ZIndexManager
20 * <p>A class that manages a group of {@link Ext.Component#floating} Components and provides z-order management,
21 * and Component activation behavior, including masking below the active (topmost) Component.</p>
22 * <p>{@link Ext.Component#floating Floating} Components which are rendered directly into the document (such as {@link Ext.window.Window Window}s) which are
23 * {@link Ext.Component#show show}n are managed by a {@link Ext.WindowManager global instance}.</p>
24 * <p>{@link Ext.Component#floating Floating} Components which are descendants of {@link Ext.Component#floating floating} <i>Containers</i>
25 * (for example a {@link Ext.view.BoundList BoundList} within an {@link Ext.window.Window Window}, or a {@link Ext.menu.Menu Menu}),
26 * are managed by a ZIndexManager owned by that floating Container. Therefore ComboBox dropdowns within Windows will have managed z-indices
27 * guaranteed to be correct, relative to the Window.</p>
29 Ext.define('Ext.ZIndexManager', {
31 alternateClassName: 'Ext.WindowGroup',
37 constructor: function(container) {
46 // This is the ZIndexManager for an Ext.container.Container, base its zseed on the zIndex of the Container's element
47 if (container.isContainer) {
48 container.on('resize', me._onContainerResize, me);
49 me.zseed = Ext.Number.from(container.getEl().getStyle('zIndex'), me.getNextZSeed());
50 // The containing element we will be dealing with (eg masking) is the content target
51 me.targetEl = container.getTargetEl();
52 me.container = container;
54 // This is the ZIndexManager for a DOM element
56 Ext.EventManager.onWindowResize(me._onContainerResize, me);
57 me.zseed = me.getNextZSeed();
58 me.targetEl = Ext.get(container);
61 // No container passed means we are the global WindowManager. Our target is the doc body.
62 // DOM must be ready to collect that ref.
64 Ext.EventManager.onWindowResize(me._onContainerResize, me);
65 me.zseed = me.getNextZSeed();
66 Ext.onDocumentReady(function() {
67 me.targetEl = Ext.getBody();
72 getNextZSeed: function() {
73 return (Ext.ZIndexManager.zBase += 10000);
76 setBase: function(baseZIndex) {
77 this.zseed = baseZIndex;
78 return this.assignZIndices();
82 assignZIndices: function() {
83 var a = this.zIndexStack,
89 for (; i < len; i++) {
91 if (comp && !comp.hidden) {
93 // Setting the zIndex of a Component returns the topmost zIndex consumed by
95 // If it's just a plain floating Component such as a BoundList, then the
96 // return value is the passed value plus 10, ready for the next item.
97 // If a floating *Container* has its zIndex set, it re-orders its managed
98 // floating children, starting from that new base, and returns a value 10000 above
99 // the highest zIndex which it allocates.
100 zIndex = comp.setZIndex(zIndex);
103 this._activateLast();
108 _setActiveChild: function(comp) {
109 if (comp !== this.front) {
112 this.front.setActive(false, comp);
116 comp.setActive(true);
118 this._showModalMask(comp);
125 _activateLast: function(justHidden) {
127 lastActivated = false,
130 // Go down through the z-index stack.
131 // Activate the next visible one down.
132 // Keep going down to find the next visible modal one to shift the modal mask down under
133 for (i = this.zIndexStack.length-1; i >= 0; --i) {
134 comp = this.zIndexStack[i];
136 if (!lastActivated) {
137 this._setActiveChild(comp);
138 lastActivated = true;
141 // Move any modal mask down to just under the next modal floater down the stack
143 this._showModalMask(comp);
149 // none to activate, so there must be no modal mask.
150 // And clear the currently active property
151 this._hideModalMask();
152 if (!lastActivated) {
153 this._setActiveChild(null);
157 _showModalMask: function(comp) {
158 var zIndex = comp.el.getStyle('zIndex') - 4,
159 maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : Ext.get(comp.getEl().dom.parentNode),
164 Ext.global.console && Ext.global.console.warn && Ext.global.console.warn('mask target could not be found. Mask cannot be shown');
169 parentBox = maskTarget.getBox();
172 this.mask = Ext.getBody().createChild({
173 cls: Ext.baseCSSPrefix + 'mask'
175 this.mask.setVisibilityMode(Ext.Element.DISPLAY);
176 this.mask.on('click', this._onMaskClick, this);
178 if (maskTarget.dom === document.body) {
179 parentBox.height = Ext.Element.getViewHeight();
181 maskTarget.addCls(Ext.baseCSSPrefix + 'body-masked');
182 this.mask.setBox(parentBox);
183 this.mask.setStyle('zIndex', zIndex);
187 _hideModalMask: function() {
188 if (this.mask && this.mask.dom.parentNode) {
189 Ext.get(this.mask.dom.parentNode).removeCls(Ext.baseCSSPrefix + 'body-masked');
194 _onMaskClick: function() {
200 _onContainerResize: function() {
201 if (this.mask && this.mask.isVisible()) {
202 this.mask.setSize(Ext.get(this.mask.dom.parentNode).getViewSize(true));
206 <span id='Ext-ZIndexManager-method-register'> /**
207 </span> * <p>Registers a floating {@link Ext.Component} with this ZIndexManager. This should not
208 * need to be called under normal circumstances. Floating Components (such as Windows, BoundLists and Menus) are automatically registered
209 * with a {@link Ext.Component#zIndexManager zIndexManager} at render time.</p>
210 * <p>Where this may be useful is moving Windows between two ZIndexManagers. For example,
211 * to bring the Ext.MessageBox dialog under the same manager as the Desktop's
212 * ZIndexManager in the desktop sample app:</p><code><pre>
213 MyDesktop.getDesktop().getManager().register(Ext.MessageBox);
214 </pre></code>
215 * @param {Ext.Component} comp The Component to register.
217 register : function(comp) {
218 if (comp.zIndexManager) {
219 comp.zIndexManager.unregister(comp);
221 comp.zIndexManager = this;
223 this.list[comp.id] = comp;
224 this.zIndexStack.push(comp);
225 comp.on('hide', this._activateLast, this);
228 <span id='Ext-ZIndexManager-method-unregister'> /**
229 </span> * <p>Unregisters a {@link Ext.Component} from this ZIndexManager. This should not
230 * need to be called. Components are automatically unregistered upon destruction.
231 * See {@link #register}.</p>
232 * @param {Ext.Component} comp The Component to unregister.
234 unregister : function(comp) {
235 delete comp.zIndexManager;
236 if (this.list && this.list[comp.id]) {
237 delete this.list[comp.id];
238 comp.un('hide', this._activateLast);
239 Ext.Array.remove(this.zIndexStack, comp);
241 // Destruction requires that the topmost visible floater be activated. Same as hiding.
242 this._activateLast(comp);
246 <span id='Ext-ZIndexManager-method-get'> /**
247 </span> * Gets a registered Component by id.
248 * @param {String/Object} id The id of the Component or a {@link Ext.Component} instance
249 * @return {Ext.Component}
252 return typeof id == "object" ? id : this.list[id];
255 <span id='Ext-ZIndexManager-method-bringToFront'> /**
256 </span> * Brings the specified Component to the front of any other active Components in this ZIndexManager.
257 * @param {String/Object} comp The id of the Component or a {@link Ext.Component} instance
258 * @return {Boolean} True if the dialog was brought to the front, else false
259 * if it was already in front
261 bringToFront : function(comp) {
262 comp = this.get(comp);
263 if (comp !== this.front) {
264 Ext.Array.remove(this.zIndexStack, comp);
265 this.zIndexStack.push(comp);
266 this.assignZIndices();
270 this._showModalMask(comp);
275 <span id='Ext-ZIndexManager-method-sendToBack'> /**
276 </span> * Sends the specified Component to the back of other active Components in this ZIndexManager.
277 * @param {String/Object} comp The id of the Component or a {@link Ext.Component} instance
278 * @return {Ext.Component} The Component
280 sendToBack : function(comp) {
281 comp = this.get(comp);
282 Ext.Array.remove(this.zIndexStack, comp);
283 this.zIndexStack.unshift(comp);
284 this.assignZIndices();
288 <span id='Ext-ZIndexManager-method-hideAll'> /**
289 </span> * Hides all Components managed by this ZIndexManager.
291 hideAll : function() {
292 for (var id in this.list) {
293 if (this.list[id].isComponent && this.list[id].isVisible()) {
294 this.list[id].hide();
299 <span id='Ext-ZIndexManager-method-hide'> /**
301 * Temporarily hides all currently visible managed Components. This is for when
302 * dragging a Window which may manage a set of floating descendants in its ZIndexManager;
303 * they should all be hidden just for the duration of the drag.
307 ln = this.zIndexStack.length,
310 this.tempHidden = [];
311 for (; i < ln; i++) {
312 comp = this.zIndexStack[i];
313 if (comp.isVisible()) {
314 this.tempHidden.push(comp);
320 <span id='Ext-ZIndexManager-method-show'> /**
322 * Restores temporarily hidden managed Components to visibility.
326 ln = this.tempHidden.length,
331 for (; i < ln; i++) {
332 comp = this.tempHidden[i];
336 comp.setPosition(x, y);
338 delete this.tempHidden;
341 <span id='Ext-ZIndexManager-method-getActive'> /**
342 </span> * Gets the currently-active Component in this ZIndexManager.
343 * @return {Ext.Component} The active Component
345 getActive : function() {
349 <span id='Ext-ZIndexManager-method-getBy'> /**
350 </span> * Returns zero or more Components in this ZIndexManager using the custom search function passed to this method.
351 * The function should accept a single {@link Ext.Component} reference as its only argument and should
352 * return true if the Component matches the search criteria, otherwise it should return false.
353 * @param {Function} fn The search function
354 * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the Component being tested.
355 * that gets passed to the function if not specified)
356 * @return {Array} An array of zero or more matching windows
358 getBy : function(fn, scope) {
361 len = this.zIndexStack.length,
364 for (; i < len; i++) {
365 comp = this.zIndexStack[i];
366 if (fn.call(scope||comp, comp) !== false) {
373 <span id='Ext-ZIndexManager-method-each'> /**
374 </span> * Executes the specified function once for every Component in this ZIndexManager, passing each
375 * Component as the only parameter. Returning false from the function will stop the iteration.
376 * @param {Function} fn The function to execute for each item
377 * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function is executed. Defaults to the current Component in the iteration.
379 each : function(fn, scope) {
381 for (var id in this.list) {
382 comp = this.list[id];
383 if (comp.isComponent && fn.call(scope || comp, comp) === false) {
389 <span id='Ext-ZIndexManager-method-eachBottomUp'> /**
390 </span> * Executes the specified function once for every Component in this ZIndexManager, passing each
391 * Component as the only parameter. Returning false from the function will stop the iteration.
392 * The components are passed to the function starting at the bottom and proceeding to the top.
393 * @param {Function} fn The function to execute for each item
394 * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function
395 * is executed. Defaults to the current Component in the iteration.
397 eachBottomUp: function (fn, scope) {
399 stack = this.zIndexStack,
402 for (i = 0, n = stack.length ; i < n; i++) {
404 if (comp.isComponent && fn.call(scope || comp, comp) === false) {
410 <span id='Ext-ZIndexManager-method-eachTopDown'> /**
411 </span> * Executes the specified function once for every Component in this ZIndexManager, passing each
412 * Component as the only parameter. Returning false from the function will stop the iteration.
413 * The components are passed to the function starting at the top and proceeding to the bottom.
414 * @param {Function} fn The function to execute for each item
415 * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the function
416 * is executed. Defaults to the current Component in the iteration.
418 eachTopDown: function (fn, scope) {
420 stack = this.zIndexStack,
423 for (i = stack.length ; i-- > 0; ) {
425 if (comp.isComponent && fn.call(scope || comp, comp) === false) {
431 destroy: function() {
432 this.each(function(c) {
435 delete this.zIndexStack;
437 delete this.container;
438 delete this.targetEl;
441 <span id='Ext-WindowManager'> /**
442 </span> * @class Ext.WindowManager
443 * @extends Ext.ZIndexManager
444 * <p>The default global floating Component group that is available automatically.</p>
445 * <p>This manages instances of floating Components which were rendered programatically without
446 * being added to a {@link Ext.container.Container Container}, and for floating Components which were added into non-floating Containers.</p>
447 * <p><i>Floating</i> Containers create their own instance of ZIndexManager, and floating Components added at any depth below
448 * there are managed by that ZIndexManager.</p>
451 Ext.WindowManager = Ext.WindowMgr = new this();