/** * @private */Ext.define('Ext.util.sizemonitor.Abstract', { mixins: ['Ext.mixin.Templatable'], requires: [ 'Ext.TaskQueue' ], config: { element: null, callback: Ext.emptyFn, scope: null, args: [] }, width: null, height: null, contentWidth: null, contentHeight: null, constructor: function(config) { var me = this; me.refresh = me.refresh.bind(me); me.info = { width: 0, height: 0, contentWidth: 0, contentHeight: 0, flag: 0 }; me.initElement(); me.initConfig(config); me.bindListeners(true); }, bindListeners: Ext.emptyFn, applyElement: function(element) { if (element) { return Ext.get(element); } }, updateElement: function(element) { element.append(this.detectorsContainer, true); element.addCls(Ext.baseCSSPrefix + 'size-monitored'); }, applyArgs: function(args) { return args.concat([this.info]); }, refreshMonitors: Ext.emptyFn, forceRefresh: function() { Ext.TaskQueue.requestRead('refresh', this); }, getContentBounds: function() { return this.detectorsContainer.getBoundingClientRect(); }, getContentWidth: function() { return this.detectorsContainer.clientWidth; }, getContentHeight: function() { return this.detectorsContainer.clientHeight; }, refreshSize: function() { var element = this.getElement(); if (!element || element.destroyed) { return false; } // eslint-disable-next-line vars-on-top var me = this, size = element.measure(), width = size.width, height = size.height, contentWidth = me.getContentWidth(), contentHeight = me.getContentHeight(), currentContentWidth = me.contentWidth, currentContentHeight = me.contentHeight, info = me.info, resized = false, flag; me.width = width; me.height = height; me.contentWidth = contentWidth; me.contentHeight = contentHeight; flag = ((currentContentWidth !== contentWidth ? 1 : 0) + (currentContentHeight !== contentHeight ? 2 : 0)); if (flag > 0) { info.width = width; info.height = height; info.contentWidth = contentWidth; info.contentHeight = contentHeight; info.flag = flag; resized = true; me.getCallback().apply(me.getScope(), me.getArgs()); } return resized; }, refresh: function() { if (this.destroying || this.destroyed) { return; } this.refreshSize(); // We should always refresh the monitors regardless of whether or not refreshSize // resulted in a new size. This avoids race conditions in situations such as // panel placeholder expand where we layout the panel in its expanded state momentarily // just so we can measure its animation destination, then immediately collapse it. // In such a scenario refreshSize() will be acting on the original size since it // is asynchronous, so it will not detect a size change, but we still need to // ensure that the monitoring elements are in sync, or else the next resize event // will not fire. Ext.TaskQueue.requestWrite('refreshMonitors', this); }, destroy: function() { var me = this, element = me.getElement(); me.bindListeners(false); if (element && !element.destroyed) { element.removeCls(Ext.baseCSSPrefix + 'size-monitored'); } delete me._element; // This is a closure so Base destructor won't null it me.refresh = null; me.callParent(); }});