<!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-ZIndexManager'>/**
|
</span> * A class that manages a group of {@link Ext.Component#floating} Components and provides z-order management,
|
* and Component activation behavior, including masking below the active (topmost) Component.
|
*
|
* {@link Ext.Component#floating Floating} Components which are rendered directly into the document (such as
|
* {@link Ext.window.Window Window}s) which are {@link Ext.Component#method-show show}n are managed by a
|
* {@link Ext.WindowManager global instance}.
|
*
|
* {@link Ext.Component#floating Floating} Components which are descendants of {@link Ext.Component#floating floating}
|
* *Containers* (for example a {@link Ext.view.BoundList BoundList} within an {@link Ext.window.Window Window},
|
* or a {@link Ext.menu.Menu Menu}), are managed by a ZIndexManager owned by that floating Container. Therefore
|
* ComboBox dropdowns within Windows will have managed z-indices guaranteed to be correct, relative to the Window.
|
*/
|
Ext.define('Ext.ZIndexManager', {
|
alternateClassName: 'Ext.WindowGroup',
|
|
statics: {
|
<span id='Ext-ZIndexManager-property-zBase'> zBase : 9000
|
</span> },
|
|
<span id='Ext-ZIndexManager-method-constructor'> constructor: function(container) {
|
</span> var me = this;
|
|
me.list = {};
|
me.zIndexStack = [];
|
me.front = null;
|
|
if (container) {
|
|
// This is the ZIndexManager for an Ext.container.Container, base its zseed on the zIndex of the Container's element
|
if (container.isContainer) {
|
container.on('resize', me._onContainerResize, me);
|
me.zseed = Ext.Number.from(me.rendered ? container.getEl().getStyle('zIndex') : undefined, me.getNextZSeed());
|
// The containing element we will be dealing with (eg masking) is the content target
|
me.targetEl = container.getTargetEl();
|
me.container = container;
|
}
|
// This is the ZIndexManager for a DOM element
|
else {
|
Ext.EventManager.onWindowResize(me._onContainerResize, me);
|
me.zseed = me.getNextZSeed();
|
me.targetEl = Ext.get(container);
|
}
|
}
|
// No container passed means we are the global WindowManager. Our target is the doc body.
|
// DOM must be ready to collect that ref.
|
else {
|
Ext.EventManager.onWindowResize(me._onContainerResize, me);
|
me.zseed = me.getNextZSeed();
|
Ext.onDocumentReady(function() {
|
me.targetEl = Ext.getBody();
|
});
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-getNextZSeed'> getNextZSeed: function() {
|
</span> return (Ext.ZIndexManager.zBase += 10000);
|
},
|
|
<span id='Ext-ZIndexManager-method-setBase'> setBase: function(baseZIndex) {
|
</span> this.zseed = baseZIndex;
|
var result = this.assignZIndices();
|
this._activateLast();
|
return result;
|
},
|
|
<span id='Ext-ZIndexManager-method-assignZIndices'> // @private
|
</span> assignZIndices: function() {
|
var a = this.zIndexStack,
|
len = a.length,
|
i = 0,
|
zIndex = this.zseed,
|
comp,
|
topModal;
|
|
for (; i < len; i++) {
|
comp = a[i];
|
if (comp && !comp.hidden) {
|
|
// Setting the zIndex of a Component returns the topmost zIndex consumed by
|
// that Component.
|
// If it's just a plain floating Component such as a BoundList, then the
|
// return value is the passed value plus 10, ready for the next item.
|
// If a floating *Container* has its zIndex set, it re-orders its managed
|
// floating children, starting from that new base, and returns a value 10000 above
|
// the highest zIndex which it allocates.
|
zIndex = comp.setZIndex(zIndex);
|
if (comp.modal) {
|
topModal = comp;
|
}
|
}
|
}
|
|
// If we encountered a modal in our reassigment, ensure our modal mask is just below it.
|
if (topModal) {
|
this._showModalMask(topModal)
|
}
|
return zIndex;
|
},
|
|
<span id='Ext-ZIndexManager-method-_setActiveChild'> // @private
|
</span> _setActiveChild: function(comp, oldFront) {
|
var front = this.front,
|
oldPreventFocus = comp.preventFocusOnActivate;
|
|
if (comp !== front) {
|
|
if (front && !front.destroying) {
|
front.setActive(false, comp);
|
}
|
this.front = comp;
|
if (comp && comp != oldFront) {
|
|
// If the previously active comp did not take focus, then do not disturb focus state by focusing the new front
|
comp.preventFocusOnActivate = comp.preventFocusOnActivate || oldFront && (oldFront.preventFocusOnActivate || !oldFront.focusOnToFront);
|
|
comp.setActive(true);
|
|
// If the modal mask was utilized by the outgoing front component, reposition it.
|
if (comp.modal) {
|
this._showModalMask(comp);
|
}
|
|
// Restore the new front's focusing flag
|
comp.preventFocusOnActivate = oldPreventFocus;
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-onComponentHide'> onComponentHide: function(comp){
|
</span> this._activateLast();
|
},
|
|
<span id='Ext-ZIndexManager-method-_activateLast'> // @private
|
</span> _activateLast: function() {
|
var me = this,
|
stack = me.zIndexStack,
|
i = stack.length - 1,
|
comp;
|
|
// Go down through the z-index stack.
|
// Activate the next visible one down.
|
// If that was modal, then we're done
|
for (; i >= 0 && stack[i].hidden; --i);
|
|
// The loop found a visible floater to activate
|
if ((comp = stack[i])) {
|
me._setActiveChild(comp, me.front);
|
if (comp.modal) {
|
return;
|
}
|
}
|
// No other floater to activate, just deactivate the current one
|
else {
|
if (me.front && !me.front.destroying) {
|
me.front.setActive(false);
|
}
|
me.front = null;
|
}
|
|
// If the new top one was not modal, keep going down to find the next visible
|
// modal one to shift the modal mask down under
|
for (; i >= 0; --i) {
|
comp = stack[i];
|
// If we find a visible modal further down the zIndex stack, move the mask to just under it.
|
if (comp.isVisible() && comp.modal) {
|
me._showModalMask(comp);
|
return;
|
}
|
}
|
|
// No visible modal Component was found in the run down the stack.
|
// So hide the modal mask
|
me._hideModalMask();
|
},
|
|
<span id='Ext-ZIndexManager-method-_showModalMask'> _showModalMask: function(comp) {
|
</span> var me = this,
|
zIndex = comp.el.getStyle('zIndex') - 4,
|
maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : comp.container,
|
mask = me.mask,
|
shim = me.maskShim,
|
viewSize;
|
|
if (!mask) {
|
if (Ext.isIE6) {
|
shim = me.maskShim = Ext.getBody().createChild({
|
tag: 'iframe',
|
cls : Ext.baseCSSPrefix + 'shim ' + Ext.baseCSSPrefix + 'mask-shim'
|
});
|
shim.setVisibilityMode(Ext.Element.DISPLAY);
|
}
|
|
// Create the mask at zero size so that it does not affect upcoming target measurements.
|
mask = me.mask = Ext.getBody().createChild({
|
cls: Ext.baseCSSPrefix + 'mask',
|
style: 'height:0;width:0'
|
});
|
mask.setVisibilityMode(Ext.Element.DISPLAY);
|
mask.on('click', me._onMaskClick, me);
|
}
|
|
mask.maskTarget = maskTarget;
|
viewSize = me.getMaskBox();
|
|
if (shim) {
|
shim.setStyle('zIndex', zIndex);
|
shim.show();
|
shim.setBox(viewSize);
|
}
|
mask.setStyle('zIndex', zIndex);
|
|
// setting mask box before showing it in an IE7 strict iframe within a quirks page
|
// can cause body scrolling [EXTJSIV-6219]
|
mask.show();
|
mask.setBox(viewSize);
|
},
|
|
<span id='Ext-ZIndexManager-method-_hideModalMask'> _hideModalMask: function() {
|
</span> var mask = this.mask,
|
maskShim = this.maskShim;
|
|
if (mask && mask.isVisible()) {
|
mask.maskTarget = undefined;
|
mask.hide();
|
if (maskShim) {
|
maskShim.hide();
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-_onMaskClick'> _onMaskClick: function() {
|
</span> if (this.front) {
|
this.front.focus();
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-getMaskBox'> getMaskBox: function(){
|
</span> var maskTarget = this.mask.maskTarget;
|
if (maskTarget.dom === document.body) {
|
return {
|
height: Math.max(document.body.scrollHeight, Ext.dom.Element.getDocumentHeight()),
|
width: Math.max(document.body.scrollWidth, document.documentElement.clientWidth),
|
x: 0,
|
y: 0
|
};
|
} else {
|
return maskTarget.getBox();
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-_onContainerResize'> _onContainerResize: function() {
|
</span> var me = this,
|
mask = me.mask,
|
maskShim = me.maskShim,
|
viewSize;
|
|
if (mask && mask.isVisible()) {
|
|
// At the new container size, the mask might be *causing* the scrollbar, so to find the valid
|
// client size to mask, we must temporarily unmask the parent node.
|
mask.hide();
|
if (maskShim) {
|
maskShim.hide();
|
}
|
|
viewSize = me.getMaskBox();
|
if (maskShim) {
|
maskShim.setSize(viewSize);
|
maskShim.show();
|
}
|
mask.setSize(viewSize);
|
mask.show();
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-register'> /**
|
</span> * Registers a floating {@link Ext.Component} with this ZIndexManager. This should not
|
* need to be called under normal circumstances. Floating Components (such as Windows,
|
* BoundLists and Menus) are automatically registered with a
|
* {@link Ext.Component#zIndexManager zIndexManager} at render time.
|
*
|
* Where this may be useful is moving Windows between two ZIndexManagers. For example,
|
* to bring the Ext.MessageBox dialog under the same manager as the Desktop's
|
* ZIndexManager in the desktop sample app:
|
*
|
* MyDesktop.getDesktop().getManager().register(Ext.MessageBox);
|
*
|
* @param {Ext.Component} comp The Component to register.
|
*/
|
register : function(comp) {
|
var me = this,
|
compAfterHide = comp.afterHide;
|
|
if (comp.zIndexManager) {
|
comp.zIndexManager.unregister(comp);
|
}
|
comp.zIndexManager = me;
|
|
me.list[comp.id] = comp;
|
me.zIndexStack.push(comp);
|
|
// Hook into Component's afterHide processing
|
comp.afterHide = function() {
|
compAfterHide.apply(comp, arguments);
|
me.onComponentHide(comp);
|
};
|
},
|
|
<span id='Ext-ZIndexManager-method-unregister'> /**
|
</span> * Unregisters a {@link Ext.Component} from this ZIndexManager. This should not
|
* need to be called. Components are automatically unregistered upon destruction.
|
* See {@link #register}.
|
* @param {Ext.Component} comp The Component to unregister.
|
*/
|
unregister : function(comp) {
|
var me = this,
|
list = me.list;
|
|
delete comp.zIndexManager;
|
if (list && list[comp.id]) {
|
delete list[comp.id];
|
|
// Relinquish control of Component's afterHide processing
|
delete comp.afterHide;
|
Ext.Array.remove(me.zIndexStack, comp);
|
|
// Destruction requires that the topmost visible floater be activated. Same as hiding.
|
me._activateLast();
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-get'> /**
|
</span> * Gets a registered Component by id.
|
* @param {String/Object} id The id of the Component or a {@link Ext.Component} instance
|
* @return {Ext.Component}
|
*/
|
get : function(id) {
|
return id.isComponent ? id : this.list[id];
|
},
|
|
<span id='Ext-ZIndexManager-method-bringToFront'> /**
|
</span> * Brings the specified Component to the front of any other active Components in this ZIndexManager.
|
* @param {String/Object} comp The id of the Component or a {@link Ext.Component} instance
|
* @return {Boolean} True if the dialog was brought to the front, else false
|
* if it was already in front
|
*/
|
bringToFront : function(comp, preventFocus) {
|
var me = this,
|
result = false,
|
zIndexStack = me.zIndexStack;
|
|
comp = me.get(comp);
|
if (comp !== me.front) {
|
Ext.Array.remove(zIndexStack, comp);
|
if (comp.preventBringToFront) {
|
// this takes care of cases where a load mask should be displayed under a floated component
|
zIndexStack.unshift(comp);
|
} else {
|
// the default behavior is to push onto the stack
|
zIndexStack.push(comp);
|
}
|
|
me.assignZIndices();
|
|
// Activate new topmost
|
if (!preventFocus) {
|
me._activateLast();
|
}
|
result = true;
|
me.front = comp;
|
|
// If new topmost is modal, ensure the mask is there
|
if (comp.modal) {
|
me._showModalMask(comp);
|
}
|
}
|
return result;
|
},
|
|
<span id='Ext-ZIndexManager-method-sendToBack'> /**
|
</span> * Sends the specified Component to the back of other active Components in this ZIndexManager.
|
* @param {String/Object} comp The id of the Component or a {@link Ext.Component} instance
|
* @return {Ext.Component} The Component
|
*/
|
sendToBack : function(comp) {
|
var me = this;
|
|
comp = me.get(comp);
|
Ext.Array.remove(me.zIndexStack, comp);
|
me.zIndexStack.unshift(comp);
|
me.assignZIndices();
|
this._activateLast();
|
return comp;
|
},
|
|
<span id='Ext-ZIndexManager-method-hideAll'> /**
|
</span> * Hides all Components managed by this ZIndexManager.
|
*/
|
hideAll : function() {
|
var list = this.list,
|
item,
|
id;
|
|
for (id in list) {
|
if (list.hasOwnProperty(id)) {
|
item = list[id];
|
if (item.isComponent && item.isVisible()) {
|
item.hide();
|
}
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-hide'> /**
|
</span> * @private
|
* Temporarily hides all currently visible managed Components. This is for when
|
* dragging a Window which may manage a set of floating descendants in its ZIndexManager;
|
* they should all be hidden just for the duration of the drag.
|
*/
|
hide: function() {
|
var i = 0,
|
stack = this.zIndexStack,
|
len = stack.length,
|
comp;
|
|
this.tempHidden = [];
|
for (; i < len; i++) {
|
comp = stack[i];
|
if (comp.isVisible()) {
|
this.tempHidden.push(comp);
|
comp.el.hide();
|
comp.hidden = true;
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-show'> /**
|
</span> * @private
|
* Restores temporarily hidden managed Components to visibility.
|
*/
|
show: function() {
|
var i = 0,
|
tempHidden = this.tempHidden,
|
len = tempHidden ? tempHidden.length : 0,
|
comp;
|
|
for (; i < len; i++) {
|
comp = tempHidden[i];
|
comp.el.show();
|
comp.hidden = false;
|
comp.setPosition(comp.x, comp.y);
|
}
|
delete this.tempHidden;
|
},
|
|
<span id='Ext-ZIndexManager-method-getActive'> /**
|
</span> * Gets the currently-active Component in this ZIndexManager.
|
* @return {Ext.Component} The active Component
|
*/
|
getActive : function() {
|
return this.front;
|
},
|
|
<span id='Ext-ZIndexManager-method-getBy'> /**
|
</span> * Returns zero or more Components in this ZIndexManager using the custom search function passed to this method.
|
* The function should accept a single {@link Ext.Component} reference as its only argument and should
|
* return true if the Component matches the search criteria, otherwise it should return false.
|
* @param {Function} fn The search function
|
* @param {Object} [scope] The scope (this reference) in which the function is executed.
|
* Defaults to the Component being tested. That gets passed to the function if not specified.
|
* @return {Array} An array of zero or more matching windows
|
*/
|
getBy : function(fn, scope) {
|
var r = [],
|
i = 0,
|
stack = this.zIndexStack,
|
len = stack.length,
|
comp;
|
|
for (; i < len; i++) {
|
comp = stack[i];
|
if (fn.call(scope||comp, comp) !== false) {
|
r.push(comp);
|
}
|
}
|
return r;
|
},
|
|
<span id='Ext-ZIndexManager-method-each'> /**
|
</span> * Executes the specified function once for every Component in this ZIndexManager, passing each
|
* Component as the only parameter. Returning false from the function will stop the iteration.
|
* @param {Function} fn The function to execute for each item
|
* @param {Object} [scope] The scope (this reference) in which the function
|
* is executed. Defaults to the current Component in the iteration.
|
*/
|
each : function(fn, scope) {
|
var list = this.list,
|
id,
|
comp;
|
|
for (id in list) {
|
if (list.hasOwnProperty(id)) {
|
comp = list[id];
|
if (comp.isComponent && fn.call(scope || comp, comp) === false) {
|
return;
|
}
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-eachBottomUp'> /**
|
</span> * Executes the specified function once for every Component in this ZIndexManager, passing each
|
* Component as the only parameter. Returning false from the function will stop the iteration.
|
* The components are passed to the function starting at the bottom and proceeding to the top.
|
* @param {Function} fn The function to execute for each item
|
* @param {Object} scope (optional) The scope (this reference) in which the function
|
* is executed. Defaults to the current Component in the iteration.
|
*/
|
eachBottomUp: function (fn, scope) {
|
var stack = this.zIndexStack,
|
i = 0,
|
len = stack.length,
|
comp;
|
|
for (; i < len; i++) {
|
comp = stack[i];
|
if (comp.isComponent && fn.call(scope || comp, comp) === false) {
|
return;
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-eachTopDown'> /**
|
</span> * Executes the specified function once for every Component in this ZIndexManager, passing each
|
* Component as the only parameter. Returning false from the function will stop the iteration.
|
* The components are passed to the function starting at the top and proceeding to the bottom.
|
* @param {Function} fn The function to execute for each item
|
* @param {Object} [scope] The scope (this reference) in which the function
|
* is executed. Defaults to the current Component in the iteration.
|
*/
|
eachTopDown: function (fn, scope) {
|
var stack = this.zIndexStack,
|
i = stack.length,
|
comp;
|
|
for (; i-- > 0; ) {
|
comp = stack[i];
|
if (comp.isComponent && fn.call(scope || comp, comp) === false) {
|
return;
|
}
|
}
|
},
|
|
<span id='Ext-ZIndexManager-method-destroy'> destroy: function() {
|
</span> var me = this,
|
list = me.list,
|
comp,
|
id;
|
|
for (id in list) {
|
if (list.hasOwnProperty(id)) {
|
comp = list[id];
|
|
if (comp.isComponent) {
|
comp.destroy();
|
}
|
}
|
}
|
|
delete me.zIndexStack;
|
delete me.list;
|
delete me.container;
|
delete me.targetEl;
|
}
|
}, function() {
|
<span id='Ext-WindowManager'> /**
|
</span> * @class Ext.WindowManager
|
* @extends Ext.ZIndexManager
|
*
|
* The default global floating Component group that is available automatically.
|
*
|
* This manages instances of floating Components which were rendered programatically without
|
* being added to a {@link Ext.container.Container Container}, and for floating Components
|
* which were added into non-floating Containers.
|
*
|
* *Floating* Containers create their own instance of ZIndexManager, and floating Components
|
* added at any depth below there are managed by that ZIndexManager.
|
*
|
* @singleton
|
*/
|
Ext.WindowManager = Ext.WindowMgr = new this();
|
});
|
</pre>
|
</body>
|
</html>
|