/*!
- * OOjs UI v0.1.0-pre (7d2507b267)
+ * OOjs UI v0.1.0-pre (7b283a9dcc)
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2014 OOjs Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: Mon May 05 2014 14:13:13 GMT-0700 (PDT)
+ * Date: Tue May 27 2014 15:41:42 GMT-0700 (PDT)
*/
( function ( OO ) {
// Tool tip for a button that removes items from a list
'ooui-outline-control-remove': 'Remove item',
// Label for the toolbar group that contains a list of all other available tools
- 'ooui-toolbar-more': 'More'
+ 'ooui-toolbar-more': 'More',
+
+ // Label for the generic dialog used to confirm things
+ 'ooui-dialog-confirm-title': 'Confirm',
+ // The default prompt of a confirmation dialog
+ 'ooui-dialog-confirm-default-prompt': 'Are you sure?',
+ // The default OK button text on a confirmation dialog
+ 'ooui-dialog-confirm-default-ok': 'OK',
+ // The default cancel button text on a confirmation dialog
+ 'ooui-dialog-confirm-default-cancel': 'Cancel'
};
/**
this.loading = true;
// Figure out directionality:
- this.dir = this.$element.closest( '[dir]' ).prop( 'dir' ) || 'ltr';
+ this.dir = OO.ui.Element.getDir( this.$element ) || 'ltr';
// Initialize contents
doc.open();
* @fires initialize
*/
OO.ui.Window = function OoUiWindow( config ) {
+ var element = this;
// Parent constructor
OO.ui.Window.super.call( this, config );
.append( this.frame.$element );
// Events
- this.frame.connect( this, { 'load': 'initialize' } );
+ this.frame.on( 'load', function () {
+ element.initialize();
+ // Undo the visibility: hidden; hack and apply display: none;
+ // We can do this safely now that the iframe has initialized
+ // (don't do this from within #initialize because it has to happen
+ // after the all subclasses have been handled as well).
+ element.$element.hide().css( 'visibility', '' );
+ } );
};
/* Setup */
this.$overlay
);
- // Undo the visibility: hidden; hack from the constructor and apply display: none;
- // We can do this safely now that the iframe has initialized
- this.$element.hide().css( 'visibility', '' );
-
- this.emit( 'initialize' );
-
return this;
};
this.wasDisabled = isDisabled;
return this;
};
+/**
+ * Dialog for showing a confirmation/warning message.
+ *
+ * @class
+ * @extends OO.ui.Dialog
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+OO.ui.ConfirmationDialog = function OoUiConfirmationDialog( config ) {
+ // Configuration initialization
+ config = $.extend( { 'size': 'small' }, config );
+
+ // Parent constructor
+ OO.ui.Dialog.call( this, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( OO.ui.ConfirmationDialog, OO.ui.Dialog );
+
+/* Static Properties */
+
+OO.ui.ConfirmationDialog.static.name = 'confirm';
+
+OO.ui.ConfirmationDialog.static.icon = 'help';
+
+OO.ui.ConfirmationDialog.static.title = OO.ui.deferMsg( 'ooui-dialog-confirm-title' );
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+OO.ui.ConfirmationDialog.prototype.initialize = function () {
+ // Parent method
+ OO.ui.Dialog.prototype.initialize.call( this );
+
+ // Set up the layout
+ var contentLayout = new OO.ui.PanelLayout( {
+ '$': this.$,
+ 'padded': true
+ } );
+
+ this.$promptContainer = this.$( '<div>' ).addClass( 'oo-ui-dialog-confirm-promptContainer' );
+
+ this.cancelButton = new OO.ui.ButtonWidget();
+ this.cancelButton.connect( this, { 'click': [ 'emit', 'cancel' ] } );
+
+ this.okButton = new OO.ui.ButtonWidget();
+ this.okButton.connect( this, { 'click': [ 'emit', 'ok' ] } );
+
+ // Make the buttons
+ contentLayout.$element.append( this.$promptContainer );
+ this.$body.append( contentLayout.$element );
+
+ this.$foot.append(
+ this.okButton.$element,
+ this.cancelButton.$element
+ );
+
+ this.connect( this, {
+ 'ok': 'close',
+ 'cancel': 'close',
+ 'close': [ 'emit', 'cancel' ]
+ } );
+};
+
+/*
+ * Open a confirmation dialog.
+ *
+ * @param {Object} [data] Window opening data including text of the dialog and text for the buttons
+ * @param {jQuery|string} [data.prompt] Text to display or list of nodes to use as content of the dialog.
+ * @param {jQuery|string|Function|null} [data.okLabel] Label of the OK button
+ * @param {jQuery|string|Function|null} [data.cancelLabel] Label of the cancel button
+ * @param {string|string[]} [data.okFlags="constructive"] Flags for the OK button
+ * @param {string|string[]} [data.cancelFlags="destructive"] Flags for the cancel button
+ */
+OO.ui.ConfirmationDialog.prototype.setup = function ( data ) {
+ // Parent method
+ OO.ui.Dialog.prototype.setup.call( this, data );
+
+ var prompt = data.prompt || OO.ui.deferMsg( 'ooui-dialog-confirm-default-prompt' ),
+ okLabel = data.okLabel || OO.ui.deferMsg( 'ooui-dialog-confirm-default-ok' ),
+ cancelLabel = data.cancelLabel || OO.ui.deferMsg( 'ooui-dialog-confirm-default-cancel' ),
+ okFlags = data.okFlags || 'constructive',
+ cancelFlags = data.cancelFlags || 'destructive';
+
+ if ( typeof prompt === 'string' ) {
+ this.$promptContainer.text( prompt );
+ } else {
+ this.$promptContainer.empty().append( prompt );
+ }
+
+ this.okButton.setLabel( okLabel ).clearFlags().setFlags( okFlags );
+ this.cancelButton.setLabel( cancelLabel ).clearFlags().setFlags( cancelFlags );
+};
/**
* Element with a button.
*
/**
* Add one or more flags.
*
- * @param {string[]|Object.<string, boolean>} flags List of flags to add, or list of set/remove
- * values, keyed by flag name
+ * @param {string|string[]|Object.<string, boolean>} flags One or more flags to add, or an object
+ * keyed by flag name containing boolean set/remove instructions.
* @chainable
*/
OO.ui.FlaggableElement.prototype.setFlags = function ( flags ) {
var i, len, flag,
classPrefix = 'oo-ui-flaggableElement-';
- if ( $.isArray( flags ) ) {
+ if ( typeof flags === 'string' ) {
+ // Set
+ this.flags[flags] = true;
+ this.$element.addClass( classPrefix + flags );
+ } else if ( $.isArray( flags ) ) {
for ( i = 0, len = flags.length; i < len; i++ ) {
flag = flags[i];
// Set
this.$element.append( panels[i].$element );
}
if ( config.widths || config.heights ) {
- this.layout( config.widths || [1], config.heights || [1] );
+ this.layout( config.widths || [ 1 ], config.heights || [ 1 ] );
} else {
// Arrange in columns by default
widths = [];
for ( i = 0, len = this.panels.length; i < len; i++ ) {
widths[i] = 1;
}
- this.layout( widths, [1] );
+ this.layout( widths, [ 1 ] );
}
};
this.outlineWidget = new OO.ui.OutlineWidget( { '$': this.$ } );
this.outlinePanel = new OO.ui.PanelLayout( { '$': this.$, 'scrollable': true } );
this.gridLayout = new OO.ui.GridLayout(
- [this.outlinePanel, this.stackLayout], { '$': this.$, 'widths': [1, 2] }
+ [ this.outlinePanel, this.stackLayout ],
+ { '$': this.$, 'widths': [ 1, 2 ] }
);
this.outlineVisible = true;
if ( this.editable ) {
if ( config.padded ) {
this.$element.addClass( 'oo-ui-panelLayout-padded' );
}
-
- // Add directionality class:
- this.$element.addClass( 'oo-ui-' + OO.ui.Element.getDir( this.$.context ) );
};
/* Setup */
/**
* Horizontal bar layout of tools as icon buttons.
*
- * @abstract
* @class
* @extends OO.ui.ToolGroup
*
* @constructor
* @param {OO.ui.Toolbar} toolbar
* @param {Object} [config] Configuration options
+ * @cfg {string} [header] Text to display at the top of the pop-up
*/
OO.ui.PopupToolGroup = function OoUiPopupToolGroup( toolbar, config ) {
// Configuration initialization
this.$handle
.addClass( 'oo-ui-popupToolGroup-handle' )
.append( this.$icon, this.$label, this.$indicator );
+ // If the pop-up should have a header, add it to the top of the toolGroup.
+ // Note: If this feature is useful for other widgets, we could abstract it into an
+ // OO.ui.HeaderedElement mixin constructor.
+ if ( config.header !== undefined ) {
+ this.$group
+ .prepend( this.$( '<span>' )
+ .addClass( 'oo-ui-popupToolGroup-header' )
+ .text( config.header )
+ );
+ }
this.$element
.addClass( 'oo-ui-popupToolGroup' )
.prepend( this.$handle );
/**
* Drop down list layout of tools as labeled icon buttons.
*
- * @abstract
* @class
* @extends OO.ui.PopupToolGroup
*
/**
* Drop down menu layout of tools as selectable menu items.
*
- * @abstract
* @class
* @extends OO.ui.PopupToolGroup
*
/**
* Button widget.
*
- * @abstract
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.ButtonedElement
* @fires click
*/
OO.ui.ButtonWidget.prototype.onKeyPress = function ( e ) {
- if ( !this.isDisabled() && e.which === OO.ui.Keys.SPACE ) {
+ if ( !this.isDisabled() && ( e.which === OO.ui.Keys.SPACE || e.which === OO.ui.Keys.ENTER ) ) {
+ this.onClick();
if ( this.isHyperlink ) {
- this.onClick();
return true;
}
}
*
* Use with OO.ui.SelectWidget.
*
- * @abstract
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.IconedElement
*
* Use together with OO.ui.OptionWidget.
*
- * @abstract
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.GroupElement
* @constructor
* @param {Object} [config] Configuration options
* @cfg {OO.ui.InputWidget} [input] Input to bind keyboard handlers to
+ * @cfg {boolean} [autoHide=true] Hide the menu when the mouse is pressed outside the menu
*/
OO.ui.MenuWidget = function OoUiMenuWidget( config ) {
// Config intialization
OO.ui.ClippableElement.call( this, this.$group, config );
// Properties
+ this.autoHide = config.autoHide === undefined || !!config.autoHide;
this.newItems = null;
this.$input = config.input ? config.input.$input : null;
this.$previousFocus = null;
this.visible = false;
this.flashing = false;
this.onKeyDownHandler = OO.ui.bind( this.onKeyDown, this );
+ this.onDocumentMouseDownHandler = OO.ui.bind( this.onDocumentMouseDown, this );
// Initialization
this.$element.hide().addClass( 'oo-ui-menuWidget' );
/* Methods */
+/**
+ * Handles document mouse down events.
+ *
+ * @param {jQuery.Event} e Key down event
+ */
+OO.ui.MenuWidget.prototype.onDocumentMouseDown = function ( e ) {
+ if ( !$.contains( this.$element[0], e.target ) ) {
+ this.hide();
+ }
+};
+
/**
* Handles key down events.
*
}
this.setClipping( true );
+
+ // Auto-hide
+ if ( this.autoHide ) {
+ this.getElementDocument().addEventListener(
+ 'mousedown', this.onDocumentMouseDownHandler, true
+ );
+ }
}
return this;
this.$previousFocus = null;
}
+ this.getElementDocument().removeEventListener(
+ 'mousedown', this.onDocumentMouseDownHandler, true
+ );
+
this.setClipping( false );
return this;
'add': 'onOutlineChange',
'remove': 'onOutlineChange'
} );
- this.upButton.connect( this, { 'click': ['emit', 'move', -1] } );
- this.downButton.connect( this, { 'click': ['emit', 'move', 1] } );
- this.removeButton.connect( this, { 'click': ['emit', 'remove'] } );
+ this.upButton.connect( this, { 'click': [ 'emit', 'move', -1 ] } );
+ this.downButton.connect( this, { 'click': [ 'emit', 'move', 1 ] } );
+ this.removeButton.connect( this, { 'click': [ 'emit', 'remove' ] } );
// Initialization
this.$element.addClass( 'oo-ui-outlineControlsWidget' );
/**
* Switch that slides on and off.
*
- * @abstract
* @class
* @extends OO.ui.Widget
* @mixins OO.ui.ToggleWidget