/*! * OOUI v0.30.3 * https://www.mediawiki.org/wiki/OOUI * * Copyright 2011–2019 OOUI Team and other contributors. * Released under the MIT license * http://oojs.mit-license.org * * Date: 2019-02-21T10:57:07Z */ ( function ( OO ) { 'use strict'; /** * An ActionWidget is a {@link OO.ui.ButtonWidget button widget} that executes an action. * Action widgets are used with OO.ui.ActionSet, which manages the behavior and availability * of the actions. * * Both actions and action sets are primarily used with {@link OO.ui.Dialog Dialogs}. * Please see the [OOUI documentation on MediaWiki] [1] for more information * and examples. * * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets * * @class * @extends OO.ui.ButtonWidget * @mixins OO.ui.mixin.PendingElement * * @constructor * @param {Object} [config] Configuration options * @cfg {string} [action] Symbolic name of the action (e.g., ‘continue’ or ‘cancel’). * @cfg {string[]} [modes] Symbolic names of the modes (e.g., ‘edit’ or ‘read’) in which the action * should be made available. See the action set's {@link OO.ui.ActionSet#setMode setMode} method * for more information about setting modes. * @cfg {boolean} [framed=false] Render the action button with a frame */ OO.ui.ActionWidget = function OoUiActionWidget( config ) { // Configuration initialization config = $.extend( { framed: false }, config ); // Parent constructor OO.ui.ActionWidget.parent.call( this, config ); // Mixin constructors OO.ui.mixin.PendingElement.call( this, config ); // Properties this.action = config.action || ''; this.modes = config.modes || []; this.width = 0; this.height = 0; // Initialization this.$element.addClass( 'oo-ui-actionWidget' ); }; /* Setup */ OO.inheritClass( OO.ui.ActionWidget, OO.ui.ButtonWidget ); OO.mixinClass( OO.ui.ActionWidget, OO.ui.mixin.PendingElement ); /* Methods */ /** * Check if the action is configured to be available in the specified `mode`. * * @param {string} mode Name of mode * @return {boolean} The action is configured with the mode */ OO.ui.ActionWidget.prototype.hasMode = function ( mode ) { return this.modes.indexOf( mode ) !== -1; }; /** * Get the symbolic name of the action (e.g., ‘continue’ or ‘cancel’). * * @return {string} */ OO.ui.ActionWidget.prototype.getAction = function () { return this.action; }; /** * Get the symbolic name of the mode or modes for which the action is configured to be available. * * The current mode is set with the action set's {@link OO.ui.ActionSet#setMode setMode} method. * Only actions that are configured to be available in the current mode will be visible. All other actions * are hidden. * * @return {string[]} */ OO.ui.ActionWidget.prototype.getModes = function () { return this.modes.slice(); }; /* eslint-disable no-unused-vars */ /** * ActionSets manage the behavior of the {@link OO.ui.ActionWidget action widgets} that comprise them. * Actions can be made available for specific contexts (modes) and circumstances * (abilities). Action sets are primarily used with {@link OO.ui.Dialog Dialogs}. * * ActionSets contain two types of actions: * * - Special: Special actions are the first visible actions with special flags, such as 'safe' and 'primary', the default special flags. Additional special flags can be configured in subclasses with the static #specialFlags property. * - Other: Other actions include all non-special visible actions. * * See the [OOUI documentation on MediaWiki][1] for more information. * * @example * // Example: An action set used in a process dialog * function MyProcessDialog( config ) { * MyProcessDialog.parent.call( this, config ); * } * OO.inheritClass( MyProcessDialog, OO.ui.ProcessDialog ); * MyProcessDialog.static.title = 'An action set in a process dialog'; * MyProcessDialog.static.name = 'myProcessDialog'; * // An action set that uses modes ('edit' and 'help' mode, in this example). * MyProcessDialog.static.actions = [ * { action: 'continue', modes: 'edit', label: 'Continue', flags: [ 'primary', 'progressive' ] }, * { action: 'help', modes: 'edit', label: 'Help' }, * { modes: 'edit', label: 'Cancel', flags: 'safe' }, * { action: 'back', modes: 'help', label: 'Back', flags: 'safe' } * ]; * * MyProcessDialog.prototype.initialize = function () { * MyProcessDialog.parent.prototype.initialize.apply( this, arguments ); * this.panel1 = new OO.ui.PanelLayout( { padded: true, expanded: false } ); * this.panel1.$element.append( '
This dialog uses an action set (continue, help, cancel, back) configured with modes. This is edit mode. Click \'help\' to see help mode.
' ); * this.panel2 = new OO.ui.PanelLayout( { padded: true, expanded: false } ); * this.panel2.$element.append( 'This is help mode. Only the \'back\' action widget is configured to be visible here. Click \'back\' to return to \'edit\' mode.
' ); * this.stackLayout = new OO.ui.StackLayout( { * items: [ this.panel1, this.panel2 ] * } ); * this.$body.append( this.stackLayout.$element ); * }; * MyProcessDialog.prototype.getSetupProcess = function ( data ) { * return MyProcessDialog.parent.prototype.getSetupProcess.call( this, data ) * .next( function () { * this.actions.setMode( 'edit' ); * }, this ); * }; * MyProcessDialog.prototype.getActionProcess = function ( action ) { * if ( action === 'help' ) { * this.actions.setMode( 'help' ); * this.stackLayout.setItem( this.panel2 ); * } else if ( action === 'back' ) { * this.actions.setMode( 'edit' ); * this.stackLayout.setItem( this.panel1 ); * } else if ( action === 'continue' ) { * var dialog = this; * return new OO.ui.Process( function () { * dialog.close(); * } ); * } * return MyProcessDialog.parent.prototype.getActionProcess.call( this, action ); * }; * MyProcessDialog.prototype.getBodyHeight = function () { * return this.panel1.$element.outerHeight( true ); * }; * var windowManager = new OO.ui.WindowManager(); * $( document.body ).append( windowManager.$element ); * var dialog = new MyProcessDialog( { * size: 'medium' * } ); * windowManager.addWindows( [ dialog ] ); * windowManager.openWindow( dialog ); * * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets * * @abstract * @class * @mixins OO.EventEmitter * * @constructor * @param {Object} [config] Configuration options */ OO.ui.ActionSet = function OoUiActionSet( config ) { // Configuration initialization config = config || {}; // Mixin constructors OO.EventEmitter.call( this ); // Properties this.list = []; this.categories = { actions: 'getAction', flags: 'getFlags', modes: 'getModes' }; this.categorized = {}; this.special = {}; this.others = []; this.organized = false; this.changing = false; this.changed = false; }; /* eslint-enable no-unused-vars */ /* Setup */ OO.mixinClass( OO.ui.ActionSet, OO.EventEmitter ); /* Static Properties */ /** * Symbolic name of the flags used to identify special actions. Special actions are displayed in the * header of a {@link OO.ui.ProcessDialog process dialog}. * See the [OOUI documentation on MediaWiki][2] for more information and examples. * * [2]:https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs * * @abstract * @static * @inheritable * @property {string} */ OO.ui.ActionSet.static.specialFlags = [ 'safe', 'primary' ]; /* Events */ /** * @event click * * A 'click' event is emitted when an action is clicked. * * @param {OO.ui.ActionWidget} action Action that was clicked */ /** * @event add * * An 'add' event is emitted when actions are {@link #method-add added} to the action set. * * @param {OO.ui.ActionWidget[]} added Actions added */ /** * @event remove * * A 'remove' event is emitted when actions are {@link #method-remove removed} * or {@link #clear cleared}. * * @param {OO.ui.ActionWidget[]} added Actions removed */ /** * @event change * * A 'change' event is emitted when actions are {@link #method-add added}, {@link #clear cleared}, * or {@link #method-remove removed} from the action set or when the {@link #setMode mode} is changed. * */ /* Methods */ /** * Handle action change events. * * @private * @fires change */ OO.ui.ActionSet.prototype.onActionChange = function () { this.organized = false; if ( this.changing ) { this.changed = true; } else { this.emit( 'change' ); } }; /** * Check if an action is one of the special actions. * * @param {OO.ui.ActionWidget} action Action to check * @return {boolean} Action is special */ OO.ui.ActionSet.prototype.isSpecial = function ( action ) { var flag; for ( flag in this.special ) { if ( action === this.special[ flag ] ) { return true; } } return false; }; /** * Get action widgets based on the specified filter: ‘actions’, ‘flags’, ‘modes’, ‘visible’, * or ‘disabled’. * * @param {Object} [filters] Filters to use, omit to get all actions * @param {string|string[]} [filters.actions] Actions that action widgets must have * @param {string|string[]} [filters.flags] Flags that action widgets must have (e.g., 'safe') * @param {string|string[]} [filters.modes] Modes that action widgets must have * @param {boolean} [filters.visible] Action widgets must be visible * @param {boolean} [filters.disabled] Action widgets must be disabled * @return {OO.ui.ActionWidget[]} Action widgets matching all criteria */ OO.ui.ActionSet.prototype.get = function ( filters ) { var i, len, list, category, actions, index, match, matches; if ( filters ) { this.organize(); // Collect category candidates matches = []; for ( category in this.categorized ) { list = filters[ category ]; if ( list ) { if ( !Array.isArray( list ) ) { list = [ list ]; } for ( i = 0, len = list.length; i < len; i++ ) { actions = this.categorized[ category ][ list[ i ] ]; if ( Array.isArray( actions ) ) { matches.push.apply( matches, actions ); } } } } // Remove by boolean filters for ( i = 0, len = matches.length; i < len; i++ ) { match = matches[ i ]; if ( ( filters.visible !== undefined && match.isVisible() !== filters.visible ) || ( filters.disabled !== undefined && match.isDisabled() !== filters.disabled ) ) { matches.splice( i, 1 ); len--; i--; } } // Remove duplicates for ( i = 0, len = matches.length; i < len; i++ ) { match = matches[ i ]; index = matches.lastIndexOf( match ); while ( index !== i ) { matches.splice( index, 1 ); len--; index = matches.lastIndexOf( match ); } } return matches; } return this.list.slice(); }; /** * Get 'special' actions. * * Special actions are the first visible action widgets with special flags, such as 'safe' and 'primary'. * Special flags can be configured in subclasses by changing the static #specialFlags property. * * @return {OO.ui.ActionWidget[]|null} 'Special' action widgets. */ OO.ui.ActionSet.prototype.getSpecial = function () { this.organize(); return $.extend( {}, this.special ); }; /** * Get 'other' actions. * * Other actions include all non-special visible action widgets. * * @return {OO.ui.ActionWidget[]} 'Other' action widgets */ OO.ui.ActionSet.prototype.getOthers = function () { this.organize(); return this.others.slice(); }; /** * Set the mode (e.g., ‘edit’ or ‘view’). Only {@link OO.ui.ActionWidget#modes actions} configured * to be available in the specified mode will be made visible. All other actions will be hidden. * * @param {string} mode The mode. Only actions configured to be available in the specified * mode will be made visible. * @chainable * @return {OO.ui.ActionSet} The widget, for chaining * @fires toggle * @fires change */ OO.ui.ActionSet.prototype.setMode = function ( mode ) { var i, len, action; this.changing = true; for ( i = 0, len = this.list.length; i < len; i++ ) { action = this.list[ i ]; action.toggle( action.hasMode( mode ) ); } this.organized = false; this.changing = false; this.emit( 'change' ); return this; }; /** * Set the abilities of the specified actions. * * Action widgets that are configured with the specified actions will be enabled * or disabled based on the boolean values specified in the `actions` * parameter. * * @param {Object.Popup contents.
Popup contents.
Popup contents.
' ), * padded: true * } * } ); * ... * }; * * @property {jQuery} */ this.$overlay = $( 'A simple dialog window. Press \'Esc\' to close.
' ); * this.$body.append( this.content.$element ); * }; * MyDialog.prototype.getBodyHeight = function () { * return this.content.$element.outerHeight( true ); * }; * var myDialog = new MyDialog( { * size: 'medium' * } ); * // Create and append a window manager, which opens and closes the window. * var windowManager = new OO.ui.WindowManager(); * $( document.body ).append( windowManager.$element ); * windowManager.addWindows( [ myDialog ] ); * // Open the window! * windowManager.openWindow( myDialog ); * * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Dialogs * * @abstract * @class * @extends OO.ui.Window * @mixins OO.ui.mixin.PendingElement * * @constructor * @param {Object} [config] Configuration options */ OO.ui.Dialog = function OoUiDialog( config ) { // Parent constructor OO.ui.Dialog.parent.call( this, config ); // Mixin constructors OO.ui.mixin.PendingElement.call( this ); // Properties this.actions = new OO.ui.ActionSet(); this.attachedActions = []; this.currentAction = null; this.onDialogKeyDownHandler = this.onDialogKeyDown.bind( this ); // Events this.actions.connect( this, { click: 'onActionClick', change: 'onActionsChange' } ); // Initialization this.$element .addClass( 'oo-ui-dialog' ) .attr( 'role', 'dialog' ); }; /* Setup */ OO.inheritClass( OO.ui.Dialog, OO.ui.Window ); OO.mixinClass( OO.ui.Dialog, OO.ui.mixin.PendingElement ); /* Static Properties */ /** * Symbolic name of dialog. * * The dialog class must have a symbolic name in order to be registered with OO.Factory. * Please see the [OOUI documentation on MediaWiki] [3] for more information. * * [3]: https://www.mediawiki.org/wiki/OOUI/Windows/Window_managers * * @abstract * @static * @inheritable * @property {string} */ OO.ui.Dialog.static.name = ''; /** * The dialog title. * * The title can be specified as a plaintext string, a {@link OO.ui.mixin.LabelElement Label} node, or a function * that will produce a Label node or string. The title can also be specified with data passed to the * constructor (see #getSetupProcess). In this case, the static value will be overridden. * * @abstract * @static * @inheritable * @property {jQuery|string|Function} */ OO.ui.Dialog.static.title = ''; /** * An array of configured {@link OO.ui.ActionWidget action widgets}. * * Actions can also be specified with data passed to the constructor (see #getSetupProcess). In this case, the static * value will be overridden. * * [2]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs#Action_sets * * @static * @inheritable * @property {Object[]} */ OO.ui.Dialog.static.actions = []; /** * Close the dialog when the 'Esc' key is pressed. * * @static * @abstract * @inheritable * @property {boolean} */ OO.ui.Dialog.static.escapable = true; /* Methods */ /** * Handle frame document key down events. * * @private * @param {jQuery.Event} e Key down event */ OO.ui.Dialog.prototype.onDialogKeyDown = function ( e ) { var actions; if ( e.which === OO.ui.Keys.ESCAPE && this.constructor.static.escapable ) { this.executeAction( '' ); e.preventDefault(); e.stopPropagation(); } else if ( e.which === OO.ui.Keys.ENTER && ( e.ctrlKey || e.metaKey ) ) { actions = this.actions.get( { flags: 'primary', visible: true, disabled: false } ); if ( actions.length > 0 ) { this.executeAction( actions[ 0 ].getAction() ); e.preventDefault(); e.stopPropagation(); } } }; /** * Handle action click events. * * @private * @param {OO.ui.ActionWidget} action Action that was clicked */ OO.ui.Dialog.prototype.onActionClick = function ( action ) { if ( !this.isPending() ) { this.executeAction( action.getAction() ); } }; /** * Handle actions change event. * * @private */ OO.ui.Dialog.prototype.onActionsChange = function () { this.detachActions(); if ( !this.isClosing() ) { this.attachActions(); if ( !this.isOpening() ) { // If the dialog is currently opening, this will be called automatically soon. this.updateSize(); } } }; /** * Get the set of actions used by the dialog. * * @return {OO.ui.ActionSet} */ OO.ui.Dialog.prototype.getActions = function () { return this.actions; }; /** * Get a process for taking action. * * When you override this method, you can create a new OO.ui.Process and return it, or add additional * accept steps to the process the parent method provides using the {@link OO.ui.Process#first 'first'} * and {@link OO.ui.Process#next 'next'} methods of OO.ui.Process. * * @param {string} [action] Symbolic name of action * @return {OO.ui.Process} Action process */ OO.ui.Dialog.prototype.getActionProcess = function ( action ) { return new OO.ui.Process() .next( function () { if ( !action ) { // An empty action always closes the dialog without data, which should always be // safe and make no changes this.close(); } }, this ); }; /** * @inheritdoc * * @param {Object} [data] Dialog opening data * @param {jQuery|string|Function|null} [data.title] Dialog title, omit to use * the {@link #static-title static title} * @param {Object[]} [data.actions] List of configuration options for each * {@link OO.ui.ActionWidget action widget}, omit to use {@link #static-actions static actions}. */ OO.ui.Dialog.prototype.getSetupProcess = function ( data ) { data = data || {}; // Parent method return OO.ui.Dialog.parent.prototype.getSetupProcess.call( this, data ) .next( function () { var config = this.constructor.static, actions = data.actions !== undefined ? data.actions : config.actions, title = data.title !== undefined ? data.title : config.title; this.title.setLabel( title ).setTitle( title ); this.actions.add( this.getActionWidgets( actions ) ); this.$element.on( 'keydown', this.onDialogKeyDownHandler ); }, this ); }; /** * @inheritdoc */ OO.ui.Dialog.prototype.getTeardownProcess = function ( data ) { // Parent method return OO.ui.Dialog.parent.prototype.getTeardownProcess.call( this, data ) .first( function () { this.$element.off( 'keydown', this.onDialogKeyDownHandler ); this.actions.clear(); this.currentAction = null; }, this ); }; /** * @inheritdoc */ OO.ui.Dialog.prototype.initialize = function () { // Parent method OO.ui.Dialog.parent.prototype.initialize.call( this ); // Properties this.title = new OO.ui.LabelWidget(); // Initialization this.$content.addClass( 'oo-ui-dialog-content' ); this.$element.attr( 'aria-labelledby', this.title.getElementId() ); this.setPendingElement( this.$head ); }; /** * Get action widgets from a list of configs * * @param {Object[]} actions Action widget configs * @return {OO.ui.ActionWidget[]} Action widgets */ OO.ui.Dialog.prototype.getActionWidgets = function ( actions ) { var i, len, widgets = []; for ( i = 0, len = actions.length; i < len; i++ ) { widgets.push( this.getActionWidget( actions[ i ] ) ); } return widgets; }; /** * Get action widget from config * * Override this method to change the action widget class used. * * @param {Object} config Action widget config * @return {OO.ui.ActionWidget} Action widget */ OO.ui.Dialog.prototype.getActionWidget = function ( config ) { return new OO.ui.ActionWidget( this.getActionWidgetConfig( config ) ); }; /** * Get action widget config * * Override this method to modify the action widget config * * @param {Object} config Initial action widget config * @return {Object} Action widget config */ OO.ui.Dialog.prototype.getActionWidgetConfig = function ( config ) { return config; }; /** * Attach action actions. * * @protected */ OO.ui.Dialog.prototype.attachActions = function () { // Remember the list of potentially attached actions this.attachedActions = this.actions.get(); }; /** * Detach action actions. * * @protected * @chainable * @return {OO.ui.Dialog} The dialog, for chaining */ OO.ui.Dialog.prototype.detachActions = function () { var i, len; // Detach all actions that may have been previously attached for ( i = 0, len = this.attachedActions.length; i < len; i++ ) { this.attachedActions[ i ].$element.detach(); } this.attachedActions = []; return this; }; /** * Execute an action. * * @param {string} action Symbolic name of action to execute * @return {jQuery.Promise} Promise resolved when action completes, rejected if it fails */ OO.ui.Dialog.prototype.executeAction = function ( action ) { this.pushPending(); this.currentAction = action; return this.getActionProcess( action ).execute() .always( this.popPending.bind( this ) ); }; /** * MessageDialogs display a confirmation or alert message. By default, the rendered dialog box * consists of a header that contains the dialog title, a body with the message, and a footer that * contains any {@link OO.ui.ActionWidget action widgets}. The MessageDialog class is the only type * of {@link OO.ui.Dialog dialog} that is usually instantiated directly. * * There are two basic types of message dialogs, confirmation and alert: * * - **confirmation**: the dialog title describes what a progressive action will do and the message provides * more details about the consequences. * - **alert**: the dialog title describes which event occurred and the message provides more information * about why the event occurred. * * The MessageDialog class specifies two actions: ‘accept’, the primary * action (e.g., ‘ok’) and ‘reject,’ the safe action (e.g., ‘cancel’). Both will close the window, * passing along the selected action. * * For more information and examples, please see the [OOUI documentation on MediaWiki][1]. * * @example * // Example: Creating and opening a message dialog window. * var messageDialog = new OO.ui.MessageDialog(); * * // Create and append a window manager. * var windowManager = new OO.ui.WindowManager(); * $( document.body ).append( windowManager.$element ); * windowManager.addWindows( [ messageDialog ] ); * // Open the window. * windowManager.openWindow( messageDialog, { * title: 'Basic message dialog', * message: 'This is the message' * } ); * * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Message_Dialogs * * @class * @extends OO.ui.Dialog * * @constructor * @param {Object} [config] Configuration options */ OO.ui.MessageDialog = function OoUiMessageDialog( config ) { // Parent constructor OO.ui.MessageDialog.parent.call( this, config ); // Properties this.verticalActionLayout = null; // Initialization this.$element.addClass( 'oo-ui-messageDialog' ); }; /* Setup */ OO.inheritClass( OO.ui.MessageDialog, OO.ui.Dialog ); /* Static Properties */ /** * @static * @inheritdoc */ OO.ui.MessageDialog.static.name = 'message'; /** * @static * @inheritdoc */ OO.ui.MessageDialog.static.size = 'small'; /** * Dialog title. * * The title of a confirmation dialog describes what a progressive action will do. The * title of an alert dialog describes which event occurred. * * @static * @inheritable * @property {jQuery|string|Function|null} */ OO.ui.MessageDialog.static.title = null; /** * The message displayed in the dialog body. * * A confirmation message describes the consequences of a progressive action. An alert * message describes why an event occurred. * * @static * @inheritable * @property {jQuery|string|Function|null} */ OO.ui.MessageDialog.static.message = null; /** * @static * @inheritdoc */ OO.ui.MessageDialog.static.actions = [ // Note that OO.ui.alert() and OO.ui.confirm() rely on these. { action: 'accept', label: OO.ui.deferMsg( 'ooui-dialog-message-accept' ), flags: 'primary' }, { action: 'reject', label: OO.ui.deferMsg( 'ooui-dialog-message-reject' ), flags: 'safe' } ]; /* Methods */ /** * Toggle action layout between vertical and horizontal. * * @private * @param {boolean} [value] Layout actions vertically, omit to toggle * @chainable * @return {OO.ui.MessageDialog} The dialog, for chaining */ OO.ui.MessageDialog.prototype.toggleVerticalActionLayout = function ( value ) { value = value === undefined ? !this.verticalActionLayout : !!value; if ( value !== this.verticalActionLayout ) { this.verticalActionLayout = value; this.$actions .toggleClass( 'oo-ui-messageDialog-actions-vertical', value ) .toggleClass( 'oo-ui-messageDialog-actions-horizontal', !value ); } return this; }; /** * @inheritdoc */ OO.ui.MessageDialog.prototype.getActionProcess = function ( action ) { if ( action ) { return new OO.ui.Process( function () { this.close( { action: action } ); }, this ); } return OO.ui.MessageDialog.parent.prototype.getActionProcess.call( this, action ); }; /** * @inheritdoc * * @param {Object} [data] Dialog opening data * @param {jQuery|string|Function|null} [data.title] Description of the action being confirmed * @param {jQuery|string|Function|null} [data.message] Description of the action's consequence * @param {string} [data.size] Symbolic name of the dialog size, see OO.ui.Window * @param {Object[]} [data.actions] List of OO.ui.ActionOptionWidget configuration options for each * action item */ OO.ui.MessageDialog.prototype.getSetupProcess = function ( data ) { data = data || {}; // Parent method return OO.ui.MessageDialog.parent.prototype.getSetupProcess.call( this, data ) .next( function () { this.title.setLabel( data.title !== undefined ? data.title : this.constructor.static.title ); this.message.setLabel( data.message !== undefined ? data.message : this.constructor.static.message ); this.size = data.size !== undefined ? data.size : this.constructor.static.size; }, this ); }; /** * @inheritdoc */ OO.ui.MessageDialog.prototype.getReadyProcess = function ( data ) { data = data || {}; // Parent method return OO.ui.MessageDialog.parent.prototype.getReadyProcess.call( this, data ) .next( function () { // Focus the primary action button var actions = this.actions.get(); actions = actions.filter( function ( action ) { return action.getFlags().indexOf( 'primary' ) > -1; } ); if ( actions.length > 0 ) { actions[ 0 ].focus(); } }, this ); }; /** * @inheritdoc */ OO.ui.MessageDialog.prototype.getBodyHeight = function () { var bodyHeight, oldOverflow, $scrollable = this.container.$element; oldOverflow = $scrollable[ 0 ].style.overflow; $scrollable[ 0 ].style.overflow = 'hidden'; OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] ); bodyHeight = this.text.$element.outerHeight( true ); $scrollable[ 0 ].style.overflow = oldOverflow; return bodyHeight; }; /** * @inheritdoc */ OO.ui.MessageDialog.prototype.setDimensions = function ( dim ) { var dialog = this, $scrollable = this.container.$element; OO.ui.MessageDialog.parent.prototype.setDimensions.call( this, dim ); // Twiddle the overflow property, otherwise an unnecessary scrollbar will be produced. // Need to do it after transition completes (250ms), add 50ms just in case. setTimeout( function () { var oldOverflow = $scrollable[ 0 ].style.overflow, activeElement = document.activeElement; $scrollable[ 0 ].style.overflow = 'hidden'; OO.ui.Element.static.reconsiderScrollbars( $scrollable[ 0 ] ); // Check reconsiderScrollbars didn't destroy our focus, as we // are doing this after the ready process. if ( activeElement && activeElement !== document.activeElement && activeElement.focus ) { activeElement.focus(); } $scrollable[ 0 ].style.overflow = oldOverflow; }, 300 ); dialog.fitActions(); // Wait for CSS transition to finish and do it again :( setTimeout( function () { dialog.fitActions(); }, 300 ); return this; }; /** * @inheritdoc */ OO.ui.MessageDialog.prototype.initialize = function () { // Parent method OO.ui.MessageDialog.parent.prototype.initialize.call( this ); // Properties this.$actions = $( 'This is a process dialog window. The header contains the title and two buttons: \'Cancel\' (a safe action) on the left and \'Done\' (a primary action) on the right.
' ); * this.$body.append( this.content.$element ); * }; * MyProcessDialog.prototype.getActionProcess = function ( action ) { * var dialog = this; * if ( action ) { * return new OO.ui.Process( function () { * dialog.close( { action: action } ); * } ); * } * return MyProcessDialog.parent.prototype.getActionProcess.call( this, action ); * }; * * var windowManager = new OO.ui.WindowManager(); * $( document.body ).append( windowManager.$element ); * * var dialog = new MyProcessDialog(); * windowManager.addWindows( [ dialog ] ); * windowManager.openWindow( dialog ); * * [1]: https://www.mediawiki.org/wiki/OOUI/Windows/Process_Dialogs * * @abstract * @class * @extends OO.ui.Dialog * * @constructor * @param {Object} [config] Configuration options */ OO.ui.ProcessDialog = function OoUiProcessDialog( config ) { // Parent constructor OO.ui.ProcessDialog.parent.call( this, config ); // Properties this.fitOnOpen = false; // Initialization this.$element.addClass( 'oo-ui-processDialog' ); }; /* Setup */ OO.inheritClass( OO.ui.ProcessDialog, OO.ui.Dialog ); /* Methods */ /** * Handle dismiss button click events. * * Hides errors. * * @private */ OO.ui.ProcessDialog.prototype.onDismissErrorButtonClick = function () { this.hideErrors(); }; /** * Handle retry button click events. * * Hides errors and then tries again. * * @private */ OO.ui.ProcessDialog.prototype.onRetryButtonClick = function () { this.hideErrors(); this.executeAction( this.currentAction ); }; /** * @inheritdoc */ OO.ui.ProcessDialog.prototype.initialize = function () { // Parent method OO.ui.ProcessDialog.parent.prototype.initialize.call( this ); // Properties this.$navigation = $( '