summaryrefslogtreecommitdiff
path: root/vendor/oojs/oojs-ui/src/WindowManager.js
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/oojs/oojs-ui/src/WindowManager.js')
-rw-r--r--vendor/oojs/oojs-ui/src/WindowManager.js675
1 files changed, 0 insertions, 675 deletions
diff --git a/vendor/oojs/oojs-ui/src/WindowManager.js b/vendor/oojs/oojs-ui/src/WindowManager.js
deleted file mode 100644
index 4731011a..00000000
--- a/vendor/oojs/oojs-ui/src/WindowManager.js
+++ /dev/null
@@ -1,675 +0,0 @@
-/**
- * Window managers are used to open and close {@link OO.ui.Window windows} and control their presentation.
- * Managed windows are mutually exclusive. If a new window is opened while a current window is opening
- * or is opened, the current window will be closed and any ongoing {@link OO.ui.Process process} will be cancelled. Windows
- * themselves are persistent and—rather than being torn down when closed—can be repopulated with the
- * pertinent data and reused.
- *
- * Over the lifecycle of a window, the window manager makes available three promises: `opening`,
- * `opened`, and `closing`, which represent the primary stages of the cycle:
- *
- * **Opening**: the opening stage begins when the window manager’s #openWindow or a window’s
- * {@link OO.ui.Window#open open} method is used, and the window manager begins to open the window.
- *
- * - an `opening` event is emitted with an `opening` promise
- * - the #getSetupDelay method is called and the returned value is used to time a pause in execution before
- * the window’s {@link OO.ui.Window#getSetupProcess getSetupProcess} method is called on the
- * window and its result executed
- * - a `setup` progress notification is emitted from the `opening` promise
- * - the #getReadyDelay method is called the returned value is used to time a pause in execution before
- * the window’s {@link OO.ui.Window#getReadyProcess getReadyProcess} method is called on the
- * window and its result executed
- * - a `ready` progress notification is emitted from the `opening` promise
- * - the `opening` promise is resolved with an `opened` promise
- *
- * **Opened**: the window is now open.
- *
- * **Closing**: the closing stage begins when the window manager's #closeWindow or the
- * window's {@link OO.ui.Window#close close} methods is used, and the window manager begins
- * to close the window.
- *
- * - the `opened` promise is resolved with `closing` promise and a `closing` event is emitted
- * - the #getHoldDelay method is called and the returned value is used to time a pause in execution before
- * the window's {@link OO.ui.Window#getHoldProcess getHoldProces} method is called on the
- * window and its result executed
- * - a `hold` progress notification is emitted from the `closing` promise
- * - the #getTeardownDelay() method is called and the returned value is used to time a pause in execution before
- * the window's {@link OO.ui.Window#getTeardownProcess getTeardownProcess} method is called on the
- * window and its result executed
- * - a `teardown` progress notification is emitted from the `closing` promise
- * - the `closing` promise is resolved. The window is now closed
- *
- * See the [OOjs UI documentation on MediaWiki][1] for more information.
- *
- * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @class
- * @extends OO.ui.Element
- * @mixins OO.EventEmitter
- *
- * @constructor
- * @param {Object} [config] Configuration options
- * @cfg {OO.Factory} [factory] Window factory to use for automatic instantiation
- * Note that window classes that are instantiated with a factory must have
- * a {@link OO.ui.Dialog#static-name static name} property that specifies a symbolic name.
- * @cfg {boolean} [modal=true] Prevent interaction outside the dialog
- */
-OO.ui.WindowManager = function OoUiWindowManager( config ) {
- // Configuration initialization
- config = config || {};
-
- // Parent constructor
- OO.ui.WindowManager.super.call( this, config );
-
- // Mixin constructors
- OO.EventEmitter.call( this );
-
- // Properties
- this.factory = config.factory;
- this.modal = config.modal === undefined || !!config.modal;
- this.windows = {};
- this.opening = null;
- this.opened = null;
- this.closing = null;
- this.preparingToOpen = null;
- this.preparingToClose = null;
- this.currentWindow = null;
- this.globalEvents = false;
- this.$ariaHidden = null;
- this.onWindowResizeTimeout = null;
- this.onWindowResizeHandler = this.onWindowResize.bind( this );
- this.afterWindowResizeHandler = this.afterWindowResize.bind( this );
-
- // Initialization
- this.$element
- .addClass( 'oo-ui-windowManager' )
- .toggleClass( 'oo-ui-windowManager-modal', this.modal );
-};
-
-/* Setup */
-
-OO.inheritClass( OO.ui.WindowManager, OO.ui.Element );
-OO.mixinClass( OO.ui.WindowManager, OO.EventEmitter );
-
-/* Events */
-
-/**
- * An 'opening' event is emitted when the window begins to be opened.
- *
- * @event opening
- * @param {OO.ui.Window} win Window that's being opened
- * @param {jQuery.Promise} opening An `opening` promise resolved with a value when the window is opened successfully.
- * When the `opening` promise is resolved, the first argument of the value is an 'opened' promise, the second argument
- * is the opening data. The `opening` promise emits `setup` and `ready` notifications when those processes are complete.
- * @param {Object} data Window opening data
- */
-
-/**
- * A 'closing' event is emitted when the window begins to be closed.
- *
- * @event closing
- * @param {OO.ui.Window} win Window that's being closed
- * @param {jQuery.Promise} closing A `closing` promise is resolved with a value when the window
- * is closed successfully. The promise emits `hold` and `teardown` notifications when those
- * processes are complete. When the `closing` promise is resolved, the first argument of its value
- * is the closing data.
- * @param {Object} data Window closing data
- */
-
-/**
- * A 'resize' event is emitted when a window is resized.
- *
- * @event resize
- * @param {OO.ui.Window} win Window that was resized
- */
-
-/* Static Properties */
-
-/**
- * Map of the symbolic name of each window size and its CSS properties.
- *
- * @static
- * @inheritable
- * @property {Object}
- */
-OO.ui.WindowManager.static.sizes = {
- small: {
- width: 300
- },
- medium: {
- width: 500
- },
- large: {
- width: 700
- },
- larger: {
- width: 900
- },
- full: {
- // These can be non-numeric because they are never used in calculations
- width: '100%',
- height: '100%'
- }
-};
-
-/**
- * Symbolic name of the default window size.
- *
- * The default size is used if the window's requested size is not recognized.
- *
- * @static
- * @inheritable
- * @property {string}
- */
-OO.ui.WindowManager.static.defaultSize = 'medium';
-
-/* Methods */
-
-/**
- * Handle window resize events.
- *
- * @private
- * @param {jQuery.Event} e Window resize event
- */
-OO.ui.WindowManager.prototype.onWindowResize = function () {
- clearTimeout( this.onWindowResizeTimeout );
- this.onWindowResizeTimeout = setTimeout( this.afterWindowResizeHandler, 200 );
-};
-
-/**
- * Handle window resize events.
- *
- * @private
- * @param {jQuery.Event} e Window resize event
- */
-OO.ui.WindowManager.prototype.afterWindowResize = function () {
- if ( this.currentWindow ) {
- this.updateWindowSize( this.currentWindow );
- }
-};
-
-/**
- * Check if window is opening.
- *
- * @return {boolean} Window is opening
- */
-OO.ui.WindowManager.prototype.isOpening = function ( win ) {
- return win === this.currentWindow && !!this.opening && this.opening.state() === 'pending';
-};
-
-/**
- * Check if window is closing.
- *
- * @return {boolean} Window is closing
- */
-OO.ui.WindowManager.prototype.isClosing = function ( win ) {
- return win === this.currentWindow && !!this.closing && this.closing.state() === 'pending';
-};
-
-/**
- * Check if window is opened.
- *
- * @return {boolean} Window is opened
- */
-OO.ui.WindowManager.prototype.isOpened = function ( win ) {
- return win === this.currentWindow && !!this.opened && this.opened.state() === 'pending';
-};
-
-/**
- * Check if a window is being managed.
- *
- * @param {OO.ui.Window} win Window to check
- * @return {boolean} Window is being managed
- */
-OO.ui.WindowManager.prototype.hasWindow = function ( win ) {
- var name;
-
- for ( name in this.windows ) {
- if ( this.windows[ name ] === win ) {
- return true;
- }
- }
-
- return false;
-};
-
-/**
- * Get the number of milliseconds to wait after opening begins before executing the ‘setup’ process.
- *
- * @param {OO.ui.Window} win Window being opened
- * @param {Object} [data] Window opening data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getSetupDelay = function () {
- return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after setup has finished before executing the ‘ready’ process.
- *
- * @param {OO.ui.Window} win Window being opened
- * @param {Object} [data] Window opening data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getReadyDelay = function () {
- return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after closing has begun before executing the 'hold' process.
- *
- * @param {OO.ui.Window} win Window being closed
- * @param {Object} [data] Window closing data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getHoldDelay = function () {
- return 0;
-};
-
-/**
- * Get the number of milliseconds to wait after the ‘hold’ process has finished before
- * executing the ‘teardown’ process.
- *
- * @param {OO.ui.Window} win Window being closed
- * @param {Object} [data] Window closing data
- * @return {number} Milliseconds to wait
- */
-OO.ui.WindowManager.prototype.getTeardownDelay = function () {
- return this.modal ? 250 : 0;
-};
-
-/**
- * Get a window by its symbolic name.
- *
- * If the window is not yet instantiated and its symbolic name is recognized by a factory, it will be
- * instantiated and added to the window manager automatically. Please see the [OOjs UI documentation on MediaWiki][3]
- * for more information about using factories.
- * [3]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @param {string} name Symbolic name of the window
- * @return {jQuery.Promise} Promise resolved with matching window, or rejected with an OO.ui.Error
- * @throws {Error} An error is thrown if the symbolic name is not recognized by the factory.
- * @throws {Error} An error is thrown if the named window is not recognized as a managed window.
- */
-OO.ui.WindowManager.prototype.getWindow = function ( name ) {
- var deferred = $.Deferred(),
- win = this.windows[ name ];
-
- if ( !( win instanceof OO.ui.Window ) ) {
- if ( this.factory ) {
- if ( !this.factory.lookup( name ) ) {
- deferred.reject( new OO.ui.Error(
- 'Cannot auto-instantiate window: symbolic name is unrecognized by the factory'
- ) );
- } else {
- win = this.factory.create( name );
- this.addWindows( [ win ] );
- deferred.resolve( win );
- }
- } else {
- deferred.reject( new OO.ui.Error(
- 'Cannot get unmanaged window: symbolic name unrecognized as a managed window'
- ) );
- }
- } else {
- deferred.resolve( win );
- }
-
- return deferred.promise();
-};
-
-/**
- * Get current window.
- *
- * @return {OO.ui.Window|null} Currently opening/opened/closing window
- */
-OO.ui.WindowManager.prototype.getCurrentWindow = function () {
- return this.currentWindow;
-};
-
-/**
- * Open a window.
- *
- * @param {OO.ui.Window|string} win Window object or symbolic name of window to open
- * @param {Object} [data] Window opening data
- * @return {jQuery.Promise} An `opening` promise resolved when the window is done opening.
- * See {@link #event-opening 'opening' event} for more information about `opening` promises.
- * @fires opening
- */
-OO.ui.WindowManager.prototype.openWindow = function ( win, data ) {
- var manager = this,
- opening = $.Deferred();
-
- // Argument handling
- if ( typeof win === 'string' ) {
- return this.getWindow( win ).then( function ( win ) {
- return manager.openWindow( win, data );
- } );
- }
-
- // Error handling
- if ( !this.hasWindow( win ) ) {
- opening.reject( new OO.ui.Error(
- 'Cannot open window: window is not attached to manager'
- ) );
- } else if ( this.preparingToOpen || this.opening || this.opened ) {
- opening.reject( new OO.ui.Error(
- 'Cannot open window: another window is opening or open'
- ) );
- }
-
- // Window opening
- if ( opening.state() !== 'rejected' ) {
- // If a window is currently closing, wait for it to complete
- this.preparingToOpen = $.when( this.closing );
- // Ensure handlers get called after preparingToOpen is set
- this.preparingToOpen.done( function () {
- if ( manager.modal ) {
- manager.toggleGlobalEvents( true );
- manager.toggleAriaIsolation( true );
- }
- manager.currentWindow = win;
- manager.opening = opening;
- manager.preparingToOpen = null;
- manager.emit( 'opening', win, opening, data );
- setTimeout( function () {
- win.setup( data ).then( function () {
- manager.updateWindowSize( win );
- manager.opening.notify( { state: 'setup' } );
- setTimeout( function () {
- win.ready( data ).then( function () {
- manager.opening.notify( { state: 'ready' } );
- manager.opening = null;
- manager.opened = $.Deferred();
- opening.resolve( manager.opened.promise(), data );
- } );
- }, manager.getReadyDelay() );
- } );
- }, manager.getSetupDelay() );
- } );
- }
-
- return opening.promise();
-};
-
-/**
- * Close a window.
- *
- * @param {OO.ui.Window|string} win Window object or symbolic name of window to close
- * @param {Object} [data] Window closing data
- * @return {jQuery.Promise} A `closing` promise resolved when the window is done closing.
- * See {@link #event-closing 'closing' event} for more information about closing promises.
- * @throws {Error} An error is thrown if the window is not managed by the window manager.
- * @fires closing
- */
-OO.ui.WindowManager.prototype.closeWindow = function ( win, data ) {
- var manager = this,
- closing = $.Deferred(),
- opened;
-
- // Argument handling
- if ( typeof win === 'string' ) {
- win = this.windows[ win ];
- } else if ( !this.hasWindow( win ) ) {
- win = null;
- }
-
- // Error handling
- if ( !win ) {
- closing.reject( new OO.ui.Error(
- 'Cannot close window: window is not attached to manager'
- ) );
- } else if ( win !== this.currentWindow ) {
- closing.reject( new OO.ui.Error(
- 'Cannot close window: window already closed with different data'
- ) );
- } else if ( this.preparingToClose || this.closing ) {
- closing.reject( new OO.ui.Error(
- 'Cannot close window: window already closing with different data'
- ) );
- }
-
- // Window closing
- if ( closing.state() !== 'rejected' ) {
- // If the window is currently opening, close it when it's done
- this.preparingToClose = $.when( this.opening );
- // Ensure handlers get called after preparingToClose is set
- this.preparingToClose.done( function () {
- manager.closing = closing;
- manager.preparingToClose = null;
- manager.emit( 'closing', win, closing, data );
- opened = manager.opened;
- manager.opened = null;
- opened.resolve( closing.promise(), data );
- setTimeout( function () {
- win.hold( data ).then( function () {
- closing.notify( { state: 'hold' } );
- setTimeout( function () {
- win.teardown( data ).then( function () {
- closing.notify( { state: 'teardown' } );
- if ( manager.modal ) {
- manager.toggleGlobalEvents( false );
- manager.toggleAriaIsolation( false );
- }
- manager.closing = null;
- manager.currentWindow = null;
- closing.resolve( data );
- } );
- }, manager.getTeardownDelay() );
- } );
- }, manager.getHoldDelay() );
- } );
- }
-
- return closing.promise();
-};
-
-/**
- * Add windows to the window manager.
- *
- * Windows can be added by reference, symbolic name, or explicitly defined symbolic names.
- * See the [OOjs ui documentation on MediaWiki] [2] for examples.
- * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Windows/Window_managers
- *
- * @param {Object.<string,OO.ui.Window>|OO.ui.Window[]} windows An array of window objects specified
- * by reference, symbolic name, or explicitly defined symbolic names.
- * @throws {Error} An error is thrown if a window is added by symbolic name, but has neither an
- * explicit nor a statically configured symbolic name.
- */
-OO.ui.WindowManager.prototype.addWindows = function ( windows ) {
- var i, len, win, name, list;
-
- if ( Array.isArray( windows ) ) {
- // Convert to map of windows by looking up symbolic names from static configuration
- list = {};
- for ( i = 0, len = windows.length; i < len; i++ ) {
- name = windows[ i ].constructor.static.name;
- if ( typeof name !== 'string' ) {
- throw new Error( 'Cannot add window' );
- }
- list[ name ] = windows[ i ];
- }
- } else if ( OO.isPlainObject( windows ) ) {
- list = windows;
- }
-
- // Add windows
- for ( name in list ) {
- win = list[ name ];
- this.windows[ name ] = win.toggle( false );
- this.$element.append( win.$element );
- win.setManager( this );
- }
-};
-
-/**
- * Remove the specified windows from the windows manager.
- *
- * Windows will be closed before they are removed. If you wish to remove all windows, you may wish to use
- * the #clearWindows method instead. If you no longer need the window manager and want to ensure that it no
- * longer listens to events, use the #destroy method.
- *
- * @param {string[]} names Symbolic names of windows to remove
- * @return {jQuery.Promise} Promise resolved when window is closed and removed
- * @throws {Error} An error is thrown if the named windows are not managed by the window manager.
- */
-OO.ui.WindowManager.prototype.removeWindows = function ( names ) {
- var i, len, win, name, cleanupWindow,
- manager = this,
- promises = [],
- cleanup = function ( name, win ) {
- delete manager.windows[ name ];
- win.$element.detach();
- };
-
- for ( i = 0, len = names.length; i < len; i++ ) {
- name = names[ i ];
- win = this.windows[ name ];
- if ( !win ) {
- throw new Error( 'Cannot remove window' );
- }
- cleanupWindow = cleanup.bind( null, name, win );
- promises.push( this.closeWindow( name ).then( cleanupWindow, cleanupWindow ) );
- }
-
- return $.when.apply( $, promises );
-};
-
-/**
- * Remove all windows from the window manager.
- *
- * Windows will be closed before they are removed. Note that the window manager, though not in use, will still
- * listen to events. If the window manager will not be used again, you may wish to use the #destroy method instead.
- * To remove just a subset of windows, use the #removeWindows method.
- *
- * @return {jQuery.Promise} Promise resolved when all windows are closed and removed
- */
-OO.ui.WindowManager.prototype.clearWindows = function () {
- return this.removeWindows( Object.keys( this.windows ) );
-};
-
-/**
- * Set dialog size. In general, this method should not be called directly.
- *
- * Fullscreen mode will be used if the dialog is too wide to fit in the screen.
- *
- * @chainable
- */
-OO.ui.WindowManager.prototype.updateWindowSize = function ( win ) {
- // Bypass for non-current, and thus invisible, windows
- if ( win !== this.currentWindow ) {
- return;
- }
-
- var viewport = OO.ui.Element.static.getDimensions( win.getElementWindow() ),
- sizes = this.constructor.static.sizes,
- size = win.getSize();
-
- if ( !sizes[ size ] ) {
- size = this.constructor.static.defaultSize;
- }
- if ( size !== 'full' && viewport.rect.right - viewport.rect.left < sizes[ size ].width ) {
- size = 'full';
- }
-
- this.$element.toggleClass( 'oo-ui-windowManager-fullscreen', size === 'full' );
- this.$element.toggleClass( 'oo-ui-windowManager-floating', size !== 'full' );
- win.setDimensions( sizes[ size ] );
-
- this.emit( 'resize', win );
-
- return this;
-};
-
-/**
- * Bind or unbind global events for scrolling.
- *
- * @private
- * @param {boolean} [on] Bind global events
- * @chainable
- */
-OO.ui.WindowManager.prototype.toggleGlobalEvents = function ( on ) {
- on = on === undefined ? !!this.globalEvents : !!on;
-
- var scrollWidth, bodyMargin,
- $body = $( this.getElementDocument().body ),
- // We could have multiple window managers open so only modify
- // the body css at the bottom of the stack
- stackDepth = $body.data( 'windowManagerGlobalEvents' ) || 0 ;
-
- if ( on ) {
- if ( !this.globalEvents ) {
- $( this.getElementWindow() ).on( {
- // Start listening for top-level window dimension changes
- 'orientationchange resize': this.onWindowResizeHandler
- } );
- if ( stackDepth === 0 ) {
- scrollWidth = window.innerWidth - document.documentElement.clientWidth;
- bodyMargin = parseFloat( $body.css( 'margin-right' ) ) || 0;
- $body.css( {
- overflow: 'hidden',
- 'margin-right': bodyMargin + scrollWidth
- } );
- }
- stackDepth++;
- this.globalEvents = true;
- }
- } else if ( this.globalEvents ) {
- $( this.getElementWindow() ).off( {
- // Stop listening for top-level window dimension changes
- 'orientationchange resize': this.onWindowResizeHandler
- } );
- stackDepth--;
- if ( stackDepth === 0 ) {
- $body.css( {
- overflow: '',
- 'margin-right': ''
- } );
- }
- this.globalEvents = false;
- }
- $body.data( 'windowManagerGlobalEvents', stackDepth );
-
- return this;
-};
-
-/**
- * Toggle screen reader visibility of content other than the window manager.
- *
- * @private
- * @param {boolean} [isolate] Make only the window manager visible to screen readers
- * @chainable
- */
-OO.ui.WindowManager.prototype.toggleAriaIsolation = function ( isolate ) {
- isolate = isolate === undefined ? !this.$ariaHidden : !!isolate;
-
- if ( isolate ) {
- if ( !this.$ariaHidden ) {
- // Hide everything other than the window manager from screen readers
- this.$ariaHidden = $( 'body' )
- .children()
- .not( this.$element.parentsUntil( 'body' ).last() )
- .attr( 'aria-hidden', '' );
- }
- } else if ( this.$ariaHidden ) {
- // Restore screen reader visibility
- this.$ariaHidden.removeAttr( 'aria-hidden' );
- this.$ariaHidden = null;
- }
-
- return this;
-};
-
-/**
- * Destroy the window manager.
- *
- * Destroying the window manager ensures that it will no longer listen to events. If you would like to
- * continue using the window manager, but wish to remove all windows from it, use the #clearWindows method
- * instead.
- */
-OO.ui.WindowManager.prototype.destroy = function () {
- this.toggleGlobalEvents( false );
- this.toggleAriaIsolation( false );
- this.clearWindows();
- this.$element.remove();
-};