/** * An `{@link Ext.mixin.Observable Observable}` through which Ext fires global events. * * Ext.on() and Ext.un() are shorthand for {@link #addListener} and {@link #removeListener} * on this Observable. For example, to listen for the idle event: * * Ext.on('idle', function() { * // do something * }); */Ext.define('Ext.GlobalEvents', { extend: 'Ext.mixin.Observable', alternateClassName: 'Ext.globalEvents', // for compat with Ext JS 4.2 and earlier requires: [ 'Ext.dom.Element' ], observableType: 'global', singleton: true, /** * @private */ resizeBuffer: 100, /** * @event added * Fires when a Component is added to a Container. * @param {Ext.Component} component */ /** * @event beforeresponsiveupdate * Fires before {@link Ext.mixin.Responsive} perform any updates in response to * dynamic changes. This is prior to refreshing `responsiveFormulas`. * @param {Object} context The context object used by `responsiveConfig` expressions. * @since 5.0.1 */ /** * @event beginresponsiveupdate * Fires when {@link Ext.mixin.Responsive} is about to perform updates in response to * dynamic changes. At this point all `responsiveFormulas` have been refreshed. * @param {Object} context The context object used by `responsiveConfig` expressions. * @since 5.0.1 */ /** * @event responsiveupdate * Fires after {@link Ext.mixin.Responsive} has performed updates in response to * dynamic changes. * @param {Object} context The context object used by `responsiveConfig` expressions. * @since 5.0.1 */ /** * @event collapse * Fires when a Component is collapsed (e.g., a panel). * @param {Ext.Component} component */ /** * @event expand * Fires when a Component is expanded (e.g., a panel). * @param {Ext.Component} component */ /** * @event hide * Fires when a Component is hidden. * @param {Ext.Component} component */ /** * @event idle * Fires when an event handler finishes its run, just before returning to * browser control. * * This includes DOM event handlers, Ajax (including JSONP) event handlers, * and {@link Ext.util.TaskRunner TaskRunners} * * When called at the tail of a DOM event, the event object is passed as the * sole parameter. * * This can be useful for performing cleanup, or update tasks which need to * happen only after all code in an event handler has been run, but which * should not be executed in a timer due to the intervening browser * reflow/repaint which would take place. */ /** * @event onlinechange * Fires when the online status of the page changes. See {@link Ext#method-isOnline} * @param {Boolean} online `true` if in an online state. * * @since 6.2.1 */ /** * @event removed * Fires when a Component is removed from a Container. * @param {Ext.Component} component */ /** * @event resize * Fires when the browser window is resized. To avoid running resize handlers * too often resulting in sluggish window resizing, the resize event uses a buffer * of 100 milliseconds in the Classic toolkit, and fires on animation frame * in the Modern toolkit. * @param {Number} width The new width * @param {Number} height The new height */ /** * @event show * Fires when a Component is shown. * @param {Ext.Component} component */ /** * @event beforebindnotify * Fires before a scheduled set of bindings are fired. This allows interested parties * to react and do any required work. * @param {Ext.util.Scheduler} scheduler The scheduler triggering the bindings. * * @private * @since 5.1.0 */ /** * @event mousedown * A mousedown listener on the document that is immune to stopPropagation() * used in cases where we need to know if a mousedown event occurred on the * document regardless of whether some other handler tried to stop it. An * example where this is useful is a menu that needs to be hidden whenever * there is a mousedown event on the document. * @param {Ext.event.Event} e The event object */ /** * @property {Object} idleEventMask * This object holds event names for events that should not trigger an `idle` event * following their dispatch. * @private * @since 5.0.0 */ idleEventMask: { mousemove: 1, touchmove: 1, pointermove: 1, MSPointerMove: 1, unload: 1 }, constructor: function() { var me = this; me.callParent(); Ext.onInternalReady(function() { // using a closure here instead of attaching the event directly to the // attachListeners method gives us a chance to override the method me.attachListeners(); }); }, attachListeners: function() { var me = this, win = Ext.getWin(), doc = Ext.getDoc(), docElement, bufferedFn, winListeners = { scope: me, resize: { fn: 'fireResize' } }; me.onlineState = Ext.isOnline(); // Capture width/height to compare later in fireResize me.curHeight = curHeight = Ext.Element.getViewportHeight(); me.curWidth = curWidth = Ext.Element.getViewportWidth(); win.on({ scope: me, online: 'handleOnlineChange', offline: 'handleOnlineChange' }); // This function is not entirely harmless but since it is not directly related // to any component, element, or other destructible entity and effectively cannot // be cleaned up, we have to pretend it's OK for this timer to go unnoticed. //<debug> me.fireResize.$skipTimerCheck = true; //</debug> // In IE9- when using legacy onresize event via attachEvent or onresize property, // the event may fire for *content size changes* as well as actual document view // size changes. See this: https://msdn.microsoft.com/en-us/library/ms536959(v=vs.85).aspx // and this: http://stackoverflow.com/questions/1852751/window-resize-event-firing-in-internet-explorer // The amount of these events firing all at once can be entirely staggering, and they // often happen during layouts so we have to be über careful to execute as few JavaScript // statements as possible to improve overall framework performance. if (Ext.isIE8) { bufferedFn = Ext.Function.createBuffered(me.fireResize, me.resizeBuffer, me); docElement = doc.dom.documentElement; win.dom.attachEvent('onresize', function(e) { var w = docElement.clientWidth, h = docElement.clientHeight; // Ext.GlobalEvents is never destroyed so closing over it is no big deal if (w !== me.curWidth || h !== me.curHeight) { bufferedFn(); } }); } else { // CSS layouts only require buffering to the next anmation frame if (Ext.isModern) { winListeners.resize.onFrame = true; } else { winListeners.resize.buffer = me.resizeBuffer; }; win.on(winListeners); } doc.on('mousedown', 'fireMouseDown', me); }, fireMouseDown: function(e) { this.fireEvent('mousedown', e); }, fireResize: function() { var me = this, Element = Ext.Element, w = Element.getViewportWidth(), h = Element.getViewportHeight(); // In IE the resize event will sometimes fire even though the w/h are the same. if (me.curHeight !== h || me.curWidth !== w) { me.curHeight = h; me.curWidth = w; if (me.hasListeners.resize) { me.fireEvent('resize', w, h); } } }, handleOnlineChange: function() { var online = Ext.isOnline(); if (online !== this.onlineState) { this.onlineState = online; this.fireEvent('onlinechange', online); } } }, function(GlobalEvents) { /** * @member Ext * @method on * Shorthand for {@link Ext.GlobalEvents#addListener}. * @inheritdoc Ext.mixin.Observable#addListener */ Ext.on = function() { return GlobalEvents.addListener.apply(GlobalEvents, arguments); }; /** * @member Ext * @method un * Shorthand for {@link Ext.GlobalEvents#removeListener}. * @inheritdoc Ext.mixin.Observable#removeListener */ Ext.un = function() { return GlobalEvents.removeListener.apply(GlobalEvents, arguments); }; /** * @member Ext * @method fireEvent * Shorthand for {@link Ext.GlobalEvents#fireEvent}. * @inheritdoc Ext.mixin.Observable#fireEvent * * @since 6.2.0 */ Ext.fireEvent = function() { return GlobalEvents.fireEvent.apply(GlobalEvents, arguments); };});