/*
* Copyright 2017 Anyware Services
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// ------------------------------
// Here are ExtJS bug fixes
// ------------------------------
(function()
{
Ext.override(Ext.layout.ContextItem, {
// Fix CMS-5908 http://www.sencha.com/forum/showthread.php?291412-Error-after-upgrade-to-ExtJS-4.2.3
init: function (full, options) {
var me = this;
var protection = false;
if (me.ownerLayout && !target.ownerLayout.isItemBoxParent)
{
target.ownerLayout.isItemBoxParent = function() { return false; };
protection = true;
}
var returnValue = this.callParent(arguments);
if (protection)
{
delete target.ownerLayout.isItemBoxParent;
}
return returnValue;
}
});
Ext.override(Ext.menu.Menu, {
initComponent: function()
{
this.callParent(arguments);
this.on('resize', this._onResize, this);
},
// Fix for CMS-5997 http://www.sencha.com/forum/showthread.php?297558-ExtJs-4.2.3-Adding-items-to-an-opened-menu-on-a-floating-parent&p=1086597#post1086597
_onResize: function(menu, width, height, oldWidth, oldHeight, eOpts)
{
if (this.isVisible() /*&& oldHeight != null && oldWidth != null */&& this.floatParent && !this._doingShowBy)
{
this._doingShowBy = true; // let's avoid infinite showBy -> needResize -> showBy -> ...
this.showBy(this.ownerCmp, this.ownerCmp.menuAlign);
this._doingShowBy = false;
}
}
});
Ext.override(Ext.view.DropZone, {
// Fix for CMS-6262 https://www.sencha.com/forum/showthread.php?301552-ExtJS-4.2.3-Drag-n-drop-in-a-grid-and-invalid-zone.&p=1101961#post1101961
containsRecordAtOffset: function(records, record, offset)
{
if (!record) {
return false;
}
var view = this.view,
recordIndex = view.indexOf(record),
nodeBefore = view.getNode(recordIndex + offset, true),
recordBefore = nodeBefore ? view.getRecord(nodeBefore) : null;
var containsRecordAtOffset = recordBefore && Ext.Array.contains(records, recordBefore);
if (!containsRecordAtOffset)
{
return false;
}
else if (record.store.getGroupField() != null && Ext.Array.findBy(this.view.features, function(item) { return item.ftype == "grouping" }) != null)
{
// using groups, we need to ignore items from different groups
var groups = [];
for (var i = 0; i < records.length; i++)
{
groups.push(records[i].get(record.store.getGroupField()));
}
var targetGroup = record.get(record.store.getGroupField());
return Ext.Array.contains(groups, targetGroup);
}
else
{
return true;
}
}
});
// Fix for CMS-6366 https://www.sencha.com/forum/showthread.php?304867-D-n-D-over-an-IFrame-issue
if (Ext.ux && Ext.ux.IFrame)
{
Ext.override(Ext.dd.DragDropManager, {
/**
* @private
* @member Ext.dd.DragDropManager
* @method _onAll
* @ametys
* @since Ametys-Runtime-4.1
* Execute action on all that need to be protected
* @param {Function} action The action to do
* @param {Ext.Component} action.component The component to act on
*/
_onAll: function(action)
{
Ext.ComponentManager.each(function(key, component) {
if (component.isXType('uxiframe') || component.isXType('richtextfield'))
{
action(component);
}
});
},
handleMouseDown: function(e, oDD)
{
this.callParent(arguments);
// Find all iframes to "protect them"
this._onAll(function (component) {
component = component.bodyEl ? /* richtext or code, need to apply on underlying element, if not a UI issue will appear */ component.bodyEl : /* iframe */component;
component.addCls("iframe-protected")
component.mask();
});
},
handleMouseUp: function(e)
{
this.callParent(arguments);
// Find all iframes to "unprotect them"
this._onAll(function (component) {
component = component.bodyEl ? /* richtext or code, need to apply on underlying element, if not a UI issue will appear */ component.bodyEl : /* iframe */component;
component.removeCls("iframe-protected")
component.unmask();
});
}
});
Ext.override(Ext.ux.IFrame, {
// Fix for RUNTIME-3116
// Loading url while iframe is not rendered yet
load: function(src)
{
var me = this;
if (me.rendered)
{
me.callParent(arguments);
}
else
{
// We will load when the rendering will be done
var args = Array.from(arguments);
me.on({'render': { fn: function() { me.load.call(me, args); }, scope: me, single: true }});
}
}
});
}
Ext.override(Ext.data.Model, {
privates: {
statics: {
// Fix for https://issues.ametys.org/browse/CMS-6363
// Actually, this enables to specify a convert or calculate function for an id field in a Ext.data.Model (which does not work, is it a bug ?)
// See https://www.sencha.com/forum/showthread.php?292044-Ext.data.Field.convert%28%29-not-called-for-idField-if-only-calculated
initFields: function (data, cls, proto) {
var me = this,
idField;
me.callParent(arguments);
idField = proto.idField;
idField.defaultValue = (idField.convert) ? undefined : null; // defaultValue must be undefined instead of null if a convert function is specified
}
}
},
inheritableStatics: {
// Fix for https://issues.ametys.org/browse/CMS-8330
// When updating model and reconfiguring columns, the new columns sometimes did not have their value set (cache on fieldExtractors not cleared)
replaceFields: function(newFields, removeFields) {
var me = this;
me.callParent(arguments);
if (me.fieldExtractors)
{
delete me.fieldExtractors[me.getProxy().getReader().$className];
}
}
}
});
Ext.override(Ext.form.field.Base, {
// Fix for https://issues.ametys.org/browse/RUNTIME-1858
// See https://www.sencha.com/forum/showthread.php?311209-Autocomplete-with-Chrome&p=1136279#post1136279
getSubTplMarkup: function(fieldData)
{
var value = this.callParent(arguments);
if (Ext.isChrome && fieldData.$comp && fieldData.$comp.inputType == 'password')
{
value = value.replace('autocomplete="off"', 'autocomplete="new-password"');
}
return value;
}
});
Ext.override(Ext.form.field.Date, {
// Fix for https://issues.ametys.org/browse/RUNTIME-2658
formatText: null
});
Ext.override(Ext.form.field.Time, {
// Fix for https://issues.ametys.org/browse/RUNTIME-2658
formatText: null
});
Ext.override(Ext.form.field.ComboBox, {
// Fix for https://issues.ametys.org/browse/CMS-5934
// https://www.sencha.com/forum/showthread.php?339854-ExtJS-6-2-Filtering-a-combox-tagfield-and-backspace&p=1179339#post1179339
// Also fix for https://issues.ametys.org/browse/CMS-8760 [Widget] Typing a comma in the select-referencetable-content widget
// as we still want to search the entire user input if it contains the delimiter
/**
* @private
* @member Ext.form.field.ComboBox
* @property {String} _lastRawValue The last raw input value
* @since Ametys-Runtime-4.0
* @ametys
*/
_lastRawValue: null,
doRawQuery: function() {
var me = this,
rawValue = me.inputEl.dom.value;
// Use final bit after comma as query value if multiselecting (Ametys edit: no !!)
// if (me.multiSelect) {
// rawValue = rawValue.split(me.delimiter).pop();
// }
// Here is the fix
if (Ext.isString(me._lastRawValue) && Ext.isString(rawValue) && rawValue.length < me.minChars && me.minChars <= me._lastRawValue.length)
{
// last value is longer than current, so the user removed some characters in the query (by pressing BACKSPACE for instance...)
// and current value is shorter than the threshold (me.minChars)
// and last value is equal or greater than the threshold
// So force to query in order to always have the same results with the same inputs
me.doQuery("", true, true);
}
else
{
me.doQuery(rawValue, false, true);
}
me._lastRawValue = rawValue;
}
});
Ext.override(Ext.form.field.Tag, {
// Fix for RUNTIME-3342
getSubmitValue: function() {
var value = this.getValue();
// If the value is null/undefined, we still return an empty string. If we
// don't, the field will never get posted to the server since nulls are ignored.
if (value === null || value === undefined/*Ext.isEmpty(value)*/) {
value = '';
}
return value;
},
getSubTplData: function(fieldData) {
var data = this.callParent(arguments);
if (!this.grow && !Ext.theme.is.Material)
{
data.wrapperStyle += 'min-height: 100%;';// Fix when grow is false, the height of tag does not apply internaly
}
return data;
},
// FIXME for WORKSPACES-1023
afterComponentLayout: function()
{
this.callSuper(arguments); // Simulate the missing callParent in parent method by calling here my grand parent.
return this.callParent(arguments);
},
syncInputWidth: function(scrollIntoView)
{
var me = this,
inputEl = me.inputEl,
editable = !!(inputEl && inputEl.dom.value) || (me.editable && me.hasFocus),
width;
if (me.grow) {
return;
}
me.toggleCls(me.notEditableCls, !editable);
// Don't need to sync width when not editable because inputEl is
// absolutely positioned when field is not editable
if (editable) {
width = Ext.util.TextMetrics.measure(inputEl, inputEl.dom.value).width;
// Fudge factor to ensure there is enough width to accommodate both
// current text and cursor:
width += 3 + 20;
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
// We need some additionnal space on the right of the input so the user can select text with the mouse easily => RUNTIME-3994
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
// FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX ^^^ FIX
inputEl.setWidth(width);
if (scrollIntoView) {
// Since the inputEl is always last we can just scroll to "bottom"
// using a large number to ensure it is fully visible:
me.listWrapper.dom.scrollTop = 99999;
}
}
},
onCollapse: function()
{
// should also reset the input to avoid having a text when search has ended RUNTIME-3993
this.callParent(arguments);
if (this.inputEl && this.inputEl.dom)
{
if (this.originalTriggerOnClick !== undefined)
{
this.triggerOnClick = this.originalTriggerOnClick; // Click should not close when expanded RUNTIME-3993
}
this.inputEl.dom.value = "";
}
},
onExpand: function()
{
// Click should not close when expanded RUNTIME-3993
this.callParent(arguments);
this.originalTriggerOnClick = this.triggerOnClick;
this.triggerOnClick = false;
}
});
// Fix for RUNTIME-2575 https://www.sencha.com/forum/showthread.php?454691-In-Ext-data-Store-the-remove-method-is-not-ok-with-doc
Ext.override(Ext.data.Store, {
remove: function(records, isMove, silent) {
if (Ext.isNumber(records))
{
records = [records];
}
return this.callParent(arguments);
}
});
// Fix for CTREE-19 https://www.sencha.com/forum/showthread.php?366515-Untranslated-labels-in-ExtJS-6-5-1&p=1210058#post1210058
Ext.override(Ext.tree.plugin.TreeViewDragDrop, {
dragText: "{{i18n PLUGINS_CORE_UI_TREEDRAGNDROP_LABEL}}"
});
// Fix for RUNTIME-1640 https://www.sencha.com/forum/showthread.php?366515-Untranslated-labels-in-ExtJS-6-5-1&p=1210058#post1210058
Ext.override(Ext.panel.Panel, {
collapseToolText: "{{i18n PLUGINS_CORE_UI_PANEL_COLLAPSE}}",
expandToolText: "{{i18n PLUGINS_CORE_UI_PANEL_EXPAND}}"
});
// Fix I18N for filters
Ext.override(Ext.grid.filters.Filters, {
menuFilterText: "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_LABEL}}"
});
Ext.override(Ext.grid.filters.filter.Number, {
emptyText: "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_NUMBER_EMPTY_TEXT_LABEL}}"
});
Ext.override(Ext.grid.filters.filter.String, {
emptyText: "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_STRING_EMPTY_TEXT_LABEL}}"
});
Ext.override(Ext.grid.filters.filter.Boolean, {
yesText: "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_BOOLEAN_YES_TEXT_LABEL}}",
noText: "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_BOOLEAN_NO_TEXT_LABEL}}"
});
Ext.grid.filters.filter.Date.prototype.config.fields.lt.text = "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_DATE_LT_TEXT_LABEL}}"
Ext.grid.filters.filter.Date.prototype.config.fields.gt.text = "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_DATE_GT_TEXT_LABEL}}"
Ext.grid.filters.filter.Date.prototype.config.fields.eq.text = "{{i18n PLUGINS_CORE_UI_GRID_FILTERS_DATE_EQ_TEXT_LABEL}}"
Ext.override(Ext.window.Window, {
closeToolText: "{{i18n PLUGINS_CORE_UI_DIALOG_BOX_CLOSE_LABEL}}"
});
// Fix for CMS-8635
Ext.override(Ext.tree.Panel, {
ensureVisible: function()
{
if ((this.lockedGrid ? this.lockedGrid : this).getView().getNodeContainer()
|| this.ownerCt.isVisible(true))
{
try
{
this.callParent(arguments);
}
catch(e)
{
this.getLogger().warn({message: "Unable to expand tree until path '" + arguments[0] + "'. Path isn't part of this tree or node may be hidden by a filter.", details: e});
}
}
else
{
this.getLogger().warn("Avoid a UI crash by discarding Ext.tree.Panel#ensureVisible on a semi rendered tree view");
}
},
expandNode: function(record, deep, callback, scope) {
return (this.lockedGrid ? this.lockedGrid : this).getView().expand(record, deep, callback, scope || this);
}
});
// Fix for CMS-8958
Ext.override(Ext.view.BoundList, {
onEndUpdate: function() {
var me = this;
if (me.updateSuspendCounter) {
--me.updateSuspendCounter;
Ext.resumeLayouts(true); // The fix is putting this line inside the if instead of after
}
else
{
this.getLogger().warn("resuming an unsuspended layout");
}
if (me.refreshSizePending) {
me.refreshSize(true);
me.refreshSizePending = false;
}
}
});
// Fix for RUNTIME-3119
Ext.override(Ext.Component, {
mask: function()
{
if (this.rendered)
{
this.callParent(arguments);
}
if (!this._layoutedForMask)
{
this._shouldBeMasked = Ext.Array.from(arguments);
}
},
unmask: function()
{
if (this.rendered)
{
this.callParent(arguments);
}
if (!this._layoutedForMask)
{
this._shouldBeMasked = null;
}
},
afterComponentLayout: function()
{
this.callParent(arguments);
if (!this._layoutedForMask && this._shouldBeMasked)
{
this.mask.apply(this, this._shouldBeMasked);
this._shouldBeMasked = null;
}
this._layoutedForMask = true;
},
destroy: function()
{
this._shouldBeMasked = null;
this.callParent(arguments);
}
});
// Fix for RUNTIME-3121
Ext.override(Ext.dom.Element, {
unmask: function()
{
var data = this.getData(),
maskEl = data.maskEl;
if (maskEl && maskEl.dom == null)
{
maskEl.dom = {
style: {}
};
}
this.callParent(arguments);
}
});
// Material theme Text.js should not use a default value for listeners configuration (opended in support EXTJS-29238)
if (Ext.form.field.Text.prototype.listeners)
{
let defaultListeners = Ext.form.field.Text.prototype.listeners;
Ext.form.field.Text.prototype.listeners = undefined;
Ext.override(Ext.form.field.Text, {
initField: function()
{
this.callParent(arguments);
for (var i in defaultListeners)
{
this.on(i, defaultListeners[i]);
}
}
});
}
// Material theme Tag.js should not use a default value for listeners configuration (opended in support EXTJS-29238)
if (Ext.form.field.Tag.prototype.listeners)
{
let defaultListeners = Ext.form.field.Tag.prototype.listeners;
Ext.form.field.Tag.prototype.listeners = undefined;
Ext.override(Ext.form.field.Tag, {
initField: function()
{
this.callParent(arguments);
for (var i in defaultListeners)
{
this.on(i, defaultListeners[i]);
}
}
});
}
// https://issues.ametys.org/browse/RUNTIME-3466 Opened in sencha support under jira ticket EXTJS-29248
Ext.override(Ext.tip.QuickTip, {
onTargetOver: function(event) {
var me = this,
currentTarget = me.currentTarget,
target = event.target,
targets, registeredTarget, key;
// If the over target is not an HTMLElement, or is the <html> or the <body>, then return
if (!target || target.nodeType !== 1 || target === document.documentElement ||
target === document.body) {
return;
}
me.pointerEvent = event;
targets = me.targets;
// Loop through registered targets seeing if we are over one.
for (key in targets) {
if (targets.hasOwnProperty(key)) {
registeredTarget = targets[key];
target = Ext.getDom(registeredTarget.target);
// If we moved over a registered target from outside of it, activate it.
if (target && Ext.fly(target).contains(event.target)) {
if (!Ext.fly(target).contains(event.relatedTarget)) { /* <================== FIX HERE */
currentTarget.attach(target);
me.activeTarget = registeredTarget;
registeredTarget.el = currentTarget;
me.anchor = registeredTarget.anchor;
me.activateTarget();
}
return;
}
}
}
// We found no registered targets, now continue as a regular ToolTip, and
// see if we are over any of our delegated targets.
me.callSuper([event]);
}
});
// https://issues.ametys.org/browse/RUNTIME-3518 Opened in sencha support under
Ext.override(Ext.button.Button, {
onEnable: function() {
this.disabled = false;
this.callParent(arguments);
},
onDisable: function() {
this.disabled = true;
this.callParent(arguments);
}
});
Ext.override(Ext.grid.NavigationModel, {
// https://issues.ametys.org/browse/RUNTIME-3953
// https://issues.ametys.org/browse/RUNTIME-3970
onCellMouseDown: function(view, cell, cellIndex, record, row, recordIndex, mousedownEvent) {
var me = this,
targetComponent = Ext.Component.from(mousedownEvent, cell),
actionableEl = mousedownEvent.getTarget(me.isFocusableEl, cell),
ac, position;
// If actionable mode, and
// (mousedown on a tabbable, or anywhere in the ownership tree of an inner active
// component), we should just keep the action position synchronized.
// The tabbable element will be part of actionability.
// If the mousedown was NOT on some focusable object, we need to exit actionable mode.
if (view.actionableMode) {
// Attempt to see if we are clicking on another actionable cell.
// findFocusPosition will focus and activate any action on the target cell
// and return the focusTarget item should be activated.
if (me.previousPosition
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
&& (mousedownEvent.position.colIdx != me.previousPosition.colIdx || mousedownEvent.position.rowIdx != me.previousPosition.rowIdx)
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
) {
position = view.focusPosition(cell, mousedownEvent.position);
}
// If the target cell contains an actionable item, update the actionPosition
// and focus on the item.
if (position
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
// ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼ FIX HERE ▼▼▼
&& (!me.actionPosition || !position.view.actionPosition || (position.colIdx != me.actionPosition.colIdx && position.rowIdx != me.actionPosition.rowIdx))
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
// ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲ FIX HERE ▲▲▲
) {
me.actionPosition = position.view.actionPosition = position;
mousedownEvent.preventDefault();
}
/*else*/ { // <-- OTHER FIX HERE --- OTHER FIX HERE --- OTHER FIX HERE --- OTHER FIX HERE ---
// If mousedown is on a focusable element, or in the component tree of the active
// component (which is NOT this)
if (!actionableEl) {
actionableEl = (ac = Ext.ComponentManager.getActiveComponent()) &&
ac !== view && ac.owns(mousedownEvent);
}
if (actionableEl) {
// Keep actionPosition synched
view.setActionableMode(true, mousedownEvent.position);
}
// Not on anything actionable, then exit actionable mode
else {
view.setActionableMode(false, mousedownEvent.position);
}
}
return;
}
}
});
Ext.override(Ext.grid.header.Container, {
getHeaderMenu: function() {
var menu = this.getMenu(),
item;
if (menu) {
item = menu.child('#columnItem');
if (item && item.menu) // FIX here the following line introduced in 7.8.0 without any protection
{
item.menu.hideOnScroll = false;
}
if (item) {
return item.menu;
}
}
return null;
},
})
/**
* @member Ext.app.ViewController
* @method afterRender
* After render
*/
/**
* @member Ext.util.Floating
* @event tofront
* When bring to front
*/
/**
* @member Ext.data.proxy.Server
* @event beginprocessresponse
* When starting to process answer
* @param {Object} response The response
* @param {Object} operation The running operation
*/
/**
* @member Ext.data.proxy.Server
* @event endprocessresponse
* When starting to process answer
* @param {Object} response The response
* @param {Object} operation The running operation
*/
/**
* @member Ext.panel.Table
* @event viewcreated
* When a table view was created
* @param {Ext.panel.Table} panel The view owner
* @param {Ext.view.Table} view The view
*/
/**
* @member Ext.panel.Panel
* @event beginfloat
* When a collasped panel is starting to float
* @param {Ext.panel.Panel} panel The panel
*/
/**
* @member Ext.panel.Panel
* @event endfloat
* When a collasped panel is stopping to float
* @param {Ext.panel.Panel} panel The panel
*/
})();