Ext.define('Ext.overrides.Widget', {
override: 'Ext.Widget',
mixins: [
'Ext.mixin.Traversable'
],
requires: [
'Ext.behavior.Translatable'
],
statics: {
onDocumentMouseDown: function(e) {
var selector = Ext.Widget.prototype.floatedSelector,
targetFloated = Ext.Component.fromElement(e.getTarget(selector, Ext.getBody()));
if (targetFloated) {
targetFloated.toFront(true);
}
},
onModalMaskTap: function() {
var top = this.topModal;
if (top && top.getHideOnMaskTap && top.getHideOnMaskTap()) {
top.hide();
this.topModal = null;
}
},
range: document.createRange()
},
config: {
flex: {
evented: true,
$value: null
},
itemId: undefined,
floated: null,
relative: null,
x: null,
y: null,
shadow: null,
shim: null,
alwaysOnTop: null,
toFrontOnShow: true,
translatable: null,
constrainTo: null
},
floatedCls: Ext.baseCSSPrefix + 'floated',
floatedSelector: '.' + Ext.baseCSSPrefix + 'floated',
shadowCls: Ext.baseCSSPrefix + 'shadow',
noShadowCls: Ext.baseCSSPrefix + 'no-shadow',
floatWrapCls: Ext.baseCSSPrefix + 'float-wrap',
shimCls: Ext.baseCSSPrefix + 'shim',
isInner: true,
constructor: function(config) {
this.callParent([config]);
this.initBindable();
},
applyFlex: function(flex) {
if (flex) {
flex = Number(flex);
if (isNaN(flex)) {
flex = null;
}
}
else {
flex = null;
}
return flex;
},
beforeHide: Ext.emptyFn,
afterHide: function() {
var me = this,
parent = me.getParent();
if (parent && parent.afterItemHide) {
parent.afterItemHide(me);
}
if (me.isFloated()) {
me.syncShim();
}
},
beforeShow: function() {
var me = this;
if (me.isFloated()) {
if (!Ext.getBody().contains(me.element)) {
me.findFloatParent();
}
if (me.getToFrontOnShow()) {
me.toFront();
} else {
me.syncAlwaysOnTop();
}
}
},
afterShow: function() {
var me = this,
parent = me.getParent();
if (parent && parent.afterItemShow) {
parent.afterItemShow(me);
}
},
applyItemId: function(itemId) {
return itemId || this.getId();
},
render: function(container, insertBeforeElement) {
this.renderTo(container, insertBeforeElement);
},
renderTo: function(container, insertBeforeElement) {
var dom = this.renderElement.dom,
containerDom = Ext.getDom(container),
insertBeforeChildDom;
if (Ext.isNumber(insertBeforeChildDom)) {
insertBeforeElement = containerDom.childNodes[insertBeforeElement];
}
insertBeforeChildDom = Ext.getDom(insertBeforeElement);
if (containerDom) {
if (insertBeforeChildDom) {
containerDom.insertBefore(dom, insertBeforeChildDom);
}
else {
containerDom.appendChild(dom);
}
this.setRendered(Boolean(dom.offsetParent));
}
},
destroy: function() {
var me = this,
parent = me.getParent();
if (parent && parent.remove) {
parent.remove(me, false);
}
me.setShim(false);
Ext.destroy(me.getTranslatable());
me.removeBindings();
me.callParent();
},
isInnerItem: function() {
return this.isInner;
},
isCentered: function() {
return false;
},
isDocked: function() {
return Boolean(this.getDocked());
},
isFloating: function() {
return false;
},
isPositioned: function() {
return false;
},
isFloated: function() {
return Boolean(this.getFloated());
},
isRelative: function() {
return Boolean(this.getRelative());
},
getDocked: function() {
return this._docked;
},
onAdded: function(parent, instanced) {
var me = this,
inheritedState = me.inheritedState,
currentParent = me.parent;
if (currentParent && currentParent !== parent) {
currentParent.remove(me, false);
}
me.parent = parent;
me.onInheritedAdd(parent, instanced);
if (me.isFloated()) {
me.findFloatParent();
}
},
onRemoved: function(destroying) {
if (!destroying) {
this.removeBindings();
}
this.onInheritedRemove(destroying);
this.parent = null;
},
setLayoutSizeFlags: Ext.emptyFn,
setRendered: function(rendered) {
var wasRendered = this.rendered;
if (rendered !== wasRendered) {
this.rendered = rendered;
return true;
}
return false;
},
doRefreshSizeState: function() {
var me = this,
floatWrap = me.floatWrap,
mask,
mySize;
if (me.isFloated() && me.isVisible()) {
mySize = me.el.getSize();
me.syncShim();
if (floatWrap) {
if (me.isRelative()) {
floatWrap.setSize(mySize);
} else {
mask = floatWrap.getData().modalMask;
if (mask) {
mask.setSize(mySize);
}
}
}
}
},
setIsInner: function(isInner) {
if (isInner !== this.isInner) {
this.isInner = isInner;
if (this.initialized) {
this.fireEvent('innerstatechange', this, isInner);
}
}
},
refreshInnerState: function() {
this.setIsInner(!this.isFloated() && !this.isCentered() && !this.isPositioned() && !this.isDocked());
},
toFront: function( fromMousedown) {
if (!this.isFloated()) {
Ext.raise('Cannot use toFront on a non-floated component');
}
var me = this,
floatParent = me.getFloatParent();
if (!me.hasListeners.beforetofront || me.fireEvent('beforetofront', me) !== false) {
me.syncAlwaysOnTop(fromMousedown);
if (floatParent && floatParent.isFloated()) {
floatParent.toFront(fromMousedown);
}
if (me.hasListeners.tofront) {
me.fireEvent('tofront', me);
}
}
return me;
},
getTranslatableBehavior: function() {
var behavior = this.translatableBehavior;
if (!behavior) {
behavior = this.translatableBehavior = new Ext.behavior.Translatable(this);
}
return behavior;
},
applyTranslatable: function(config) {
this.getTranslatableBehavior().setConfig(config);
},
getTranslatable: function() {
return this.getTranslatableBehavior().getTranslatable();
},
translate: function() {
var translatable = this.getTranslatable();
if (!translatable) {
this.setTranslatable(true);
translatable = this.getTranslatable();
}
translatable.translate.apply(translatable, arguments);
},
getAlignmentInfo: function (component, alignment){
var me = this,
alignToBox = component.isRegion ? component : (component.isComponent ? component.renderElement : Ext.fly(component)).getBox(),
element = me.renderElement,
box = element.getBox(),
stats = {
alignToBox: alignToBox,
alignment: alignment,
top: alignToBox.top,
left: alignToBox.left,
alignToWidth: alignToBox.width || 0,
alignToHeight: alignToBox.height || 0,
width: box.width,
height: box.height,
anchor: me.getAnchor()
},
currentAlignmentInfo = me.getCurrentAlignmentInfo(),
isAligned = true;
if (!Ext.isEmpty(currentAlignmentInfo)) {
Ext.Object.each(stats, function(key, value) {
if (!Ext.isObject(value) && currentAlignmentInfo[key] !== value) {
isAligned = false;
return false;
}
return true;
});
} else {
isAligned = false;
}
return {isAligned: isAligned, stats: stats};
},
getCurrentAlignmentInfo: function() {
return this.$currentAlignmentInfo;
},
setCurrentAlignmentInfo: function(alignmentInfo) {
this.$currentAlignmentInfo = Ext.isEmpty(alignmentInfo) ? null : Ext.merge({}, alignmentInfo.stats ? alignmentInfo.stats : alignmentInfo);
},
alignTo: function(component, alignment, options) {
var me = this,
alignmentInfo = me.getAlignmentInfo(component, alignment),
config = me.initialConfig,
positioned = me.isPositioned(),
setX = positioned ? me.setLeft : me.setX,
setY = positioned ? me.setTop : me.setY,
oldHeight, resultRegion;
if (alignmentInfo.isAligned) {
return;
}
if ('unconstrainedWidth' in me) {
me.setWidth(me.unconstrainedWidth);
}
if ('unconstrainedHeight' in me) {
me.setHeight(me.unconstrainedHeight);
}
resultRegion = me.getAlignRegion(component, alignment, options);
setX.call(me, resultRegion.x);
setY.call(me, resultRegion.y);
if (resultRegion.constrainWidth) {
me.unconstrainedWidth = config.width || me.self.prototype.width;
oldHeight = me.el.getHeight();
me.setWidth(alignmentInfo.stats.width = resultRegion.getWidth());
if (resultRegion.align.position === 0) {
setY.call(me, resultRegion.y + (oldHeight - me.el.getHeight()));
}
}
if (resultRegion.constrainHeight) {
me.unconstrainedHeight = config.height || me.self.prototype.height;
me.setHeight(alignmentInfo.stats.height = resultRegion.getHeight());
}
me.setCurrentAlignmentInfo(alignmentInfo);
},
getAlignRegion: function(component, alignment, options) {
var me = this,
alignmentInfo = me.getAlignmentInfo(component, alignment),
constrainModifier,
inside;
if (alignmentInfo.isAligned) {
return;
}
var alignToBox = alignmentInfo.stats.alignToBox,
constrainBox = me.getConstrainRegion(),
height = alignmentInfo.stats.height,
width = alignmentInfo.stats.width;
if (!alignment || alignment === 'auto') {
if (constrainBox.bottom - alignToBox.bottom < height) {
if (alignToBox.top - constrainBox.top < height) {
if (alignToBox.left - constrainBox.left < width) {
alignment = 'l-r?';
}
else {
alignment = 'r-l?';
}
}
else {
alignment = 'b-t?';
}
}
else {
alignment = 't-b?';
}
}
constrainModifier = alignment[alignment.length - 1];
if (me.getConstrainTo()) {
inside = constrainBox;
} else {
if (constrainModifier === '!') {
inside = component.el.getRegion();
alignment = alignment.substr(0, alignment.length - 1);
} else if (constrainModifier === '?') {
inside = constrainBox;
alignment = alignment.substr(0, alignment.length - 1);
}
}
return me.el.getRegion().alignTo(Ext.apply({
target: Ext.util.Region.from(alignmentInfo.stats.alignToBox),
align: alignment,
inside: inside,
minWidth: me.getMinWidth && me.getMinWidth(),
minHeight: me.getMinHeight && me.getMinHeight()
}, options));
},
privates: {
owns: function(element) {
var result = false,
cmp;
if (element.isEvent) {
element = element.target;
} else if (element.isElement) {
element = element.dom;
}
cmp = Ext.Component.fromElement(element);
if (cmp) {
result = (cmp === this) || (!!cmp.up(this));
}
return result;
},
getBubbleTarget: function() {
return this.getParent();
},
getConstrainRegion: function() {
var me = this,
parent,
constrainTo = me.getConstrainTo();
if (!constrainTo) {
if (me.isFloated()) {
constrainTo = me.floatParentNode.getData().component;
if (constrainTo) {
constrainTo = constrainTo.bodyElement;
} else {
constrainTo = Ext.getBody();
}
}
else {
parent = me.getParent();
constrainTo = parent ? parent.bodyElement : me.element.parent();
}
}
if (!constrainTo.isRegion) {
constrainTo = constrainTo.getConstrainRegion();
}
return constrainTo;
},
getFloatParent: function() {
var result = this.floatParentNode.getData().component;
return result && result.isFloated() ? result : null;
},
applyFloated: function(floated) {
var me = this;
floated = Boolean(floated);
if (floated) {
me.refreshInnerState = Ext.emptyFn;
if (me.isPositioned()) {
me.resetPositioned();
}
if (me.isDocked()) {
me.setDocked(false);
}
me.setIsInner(false);
delete me.refreshInnerState;
}
if (me.initialized) {
me.fireEvent('floatedchange', me, floated);
}
return floated;
},
updateFloated: function(floated, oldFloated) {
var me = this,
modal;
me.el.toggleCls(me.floatedCls, floated);
if (oldFloated != null) {
modal = me.getModal && me.getModal();
if (modal) {
Ext.destroy(modal);
me.setModal(true);
}
if (me.getHideOnMaskTap && me.getHideOnMaskTap()) {
me.setHideOnMaskTap(false);
me.setHideOnMaskTap(true);
}
}
if (floated) {
me.findFloatParent();
if (me.isConfiguring && me.getHidden() == null) {
me.setHidden(true);
} else if (me.isVisible()) {
if (me.isCentered()) {
me.getWidth();
me.getHeight();
me.center();
} else {
me.syncXYPosition();
}
me.showModalMask();
}
} else {
me.refreshInnerState();
me.translate(0, 0, 0);
}
},
findFloatParent: function() {
var me = this,
parent = me.getParent();
while (parent && !parent.isFloated()) {
parent = parent.getParent();
}
if (!parent) {
me.floatParentNode = Ext.getFloatRoot();
}
else {
me.floatParentNode = parent.getFloatWrap();
}
me.insertFloatedDom();
},
getFloatWrap: function() {
var me = this,
fw = me.floatWrap,
viewport = Ext['Viewport'],
parentNode;
if (!fw) {
parentNode = me.el.up('') || (viewport ? viewport.el : Ext.getBody());
fw = me.link('floatWrap', parentNode.createChild({
cls: me.floatWrapCls,
id: me.id + '-floatWrap',
"data-componentId": me.id
}));
fw.getData().component = me;
fw.dom.appendChild(me.element.dom);
fw.getData().alwaysOnTop = me.element.getData().alwaysOnTop;
}
return fw;
},
insertFloatedDom: function() {
var me = this,
floatParentNode = me.floatParentNode,
positionEl = me.floatWrap || me.element,
Widget = Ext.Widget;
floatParentNode.dom.appendChild(positionEl.dom);
me.syncXYPosition();
if (!Widget.$mousedownListeners) {
Widget.$mousedownListeners = Ext.getDoc().on({
mousedown: Widget.onDocumentMouseDown,
destroyable: true
});
}
},
applyShim: function(shim) {
if (shim && !this.isFloated()) {
Ext.raise('Cannot use setShim on a non-floated component');
}
if (shim) {
return Ext.getBody().createChild(Ext.apply({
cls: this.shimCls
}, shim));
} else {
Ext.destroy(this.shim);
return null;
}
},
updateShim: function() {
this.syncShim();
},
hideModalMask: function() {
var me = this,
mask = me.floatParentNode.getData().modalMask;
if (mask && mask.dom.parentNode) {
mask = mask.dom;
Ext.getDetachedBody().appendChild(mask);
}
},
showModalMask: function() {
var me = this,
Widget = Ext.Widget,
positionEl = me.floatWrap || me.element,
parent = me.getParent(),
floatParentNode = me.floatParentNode,
data = floatParentNode.getData(),
mask = data.modalMask;
if (me.isFloated() && me.getModal && me.getModal()) {
if (mask) {
floatParentNode.dom.insertBefore(mask.dom, positionEl.dom);
} else {
mask = data.modalMask = floatParentNode.createChild({
cls: 'x-mask'
}, positionEl);
mask.on({
tap: Widget.onModalMaskTap,
scope: Widget
});
}
Widget.topModal = me;
if (parent && parent.isFloated() && !parent.isRelative()) {
parent.doRefreshSizeState();
parent.syncXYPosition();
}
}
},
syncShim: function() {
var me = this,
shim = me.getShim();
if (shim) {
if (me.isVisible(true)) {
shim.show();
me.el.dom.parentNode.insertBefore(shim.dom, me.el.dom);
shim.setSize(me.getSize());
if (me.floatWrap) {
shim.translate(0, 0);
} else {
shim.translate(me.getX() || 0, me.getY() || 0);
}
} else {
shim.hide();
}
}
},
updateAlwaysOnTop: function(alwaysOnTop) {
var positionEl = this.floatWrap || this.element;
positionEl.getData().alwaysOnTop = Number(alwaysOnTop);
this.syncAlwaysOnTop();
},
syncAlwaysOnTop: function( fromMousedown) {
var me = this,
positionEl = (me.floatWrap || me.element).dom,
parentEl = me.floatParentNode,
nodes = parentEl.dom.childNodes,
len = nodes.length,
i, startIdx,
alwaysOnTop = Number(me.getAlwaysOnTop()),
refNode,
range = me.statics().range;
startIdx = parentEl === Ext.floatRoot ? 0 : 1;
for (i = len - 1; i >= startIdx; i--) {
if (!Ext.fly(nodes[i]).is('.' + me.shimCls) && nodes[i] !== positionEl) {
if (alwaysOnTop >= (Ext.get(nodes[i]).getData().alwaysOnTop || 0)) {
refNode = nodes[i].nextSibling;
break;
}
}
}
if (refNode === positionEl) {
return;
}
if (i < startIdx) {
refNode = nodes[0];
}
if (me.containsFocus || fromMousedown) {
range.setStartAfter(positionEl);
range.setEndAfter(refNode || nodes[len - 1]);
parentEl.dom.insertBefore(range.extractContents(), positionEl);
} else {
parentEl.dom.insertBefore(positionEl, refNode);
}
me.showModalMask();
me.syncShim();
if (refNode) {
Ext.Component.fromElement(refNode).syncShim();
} else {
return true;
}
},
updateRelative: function() {
this.syncXYPosition();
},
updateShadow: function(shadow) {
this.el.toggleCls(this.shadowCls, shadow);
this.el.toggleCls(this.noShadowCls, shadow === false);
},
updateX: function() {
if (!this.isFloated()) {
Ext.raise('Cannot use setX on a non-floated component');
}
this.syncXYPosition();
},
updateY: function() {
if (!this.isFloated()) {
Ext.raise('Cannot use setY on a non-floated component');
}
this.syncXYPosition();
},
syncXYPosition: function() {
var me = this,
floatWrap = me.floatWrap,
mask,
x = me.getX() || 0,
y = me.getY() || 0;
if (me.isRelative()) {
floatWrap = floatWrap || me.getFloatWrap();
floatWrap.translate(x, y);
floatWrap.setWidth(me.el.getWidth());
floatWrap.setHeight(me.el.getHeight());
me.translate(0, 0);
mask = floatWrap.getData().modalMask;
if (mask) {
mask.translate(0, 0);
}
}
else {
me.translate(x, y);
mask = me.floatWrap && me.floatWrap.getData().modalMask;
if (mask) {
mask.translate(x, y);
}
}
me.syncShim();
}
}
}, function(Widget) {
this.borrow(Ext.util.Positionable, ['clipTo', 'clearClip']);
Ext.getFloatRoot = function() {
var fp = Ext.floatRoot,
viewport = Ext['Viewport'];
if (fp) {
fp.el.dom.parentNode.appendChild(fp.dom);
} else {
if (viewport) {
fp = viewport.floatWrap = viewport.element.createChild({
cls: Widget.prototype.floatWrapCls,
id: 'global-floatWrap',
"data-sticky": true
});
} else {
fp = Ext.getBody().createChild({
cls: Widget.prototype.floatWrapCls,
id: 'global-floatWrap',
"data-sticky": true
});
}
Ext.floatRoot = fp;
}
return fp;
};
});