/*!
- * OOjs UI v0.21.3
+ * OOjs UI v0.22.3
* https://www.mediawiki.org/wiki/OOjs_UI
*
* Copyright 2011–2017 OOjs UI Team and other contributors.
* Released under the MIT license
* http://oojs.mit-license.org
*
- * Date: 2017-05-10T00:55:40Z
+ * Date: 2017-07-11T22:12:33Z
*/
( function ( OO ) {
* @extends OO.ui.TabPanelLayout
*
* @constructor
- * @deprecated since v0.22.0
+ * @deprecated since v0.21.3
*/
OO.ui.CardLayout = function OoUiCardLayout() {
OO.ui.warnDeprecation( 'CardLayout has been renamed to TabPanel layout. Use that instead. See T155152' );
* @chainable
*/
OO.ui.BookletLayout.prototype.toggleOutline = function ( show ) {
+ var booklet = this;
+
if ( this.outlined ) {
show = show === undefined ? !this.outlineVisible : !!show;
this.outlineVisible = show;
this.toggleMenu( show );
+ if ( show && this.editable ) {
+ // HACK: When the sidebar stops animating, kill dumb scrollbars (T161798). Only necessary when
+ // outline controls are present, The delay matches transition on `.oo-ui-menuLayout-menu`.
+ setTimeout( function () {
+ OO.ui.Element.static.reconsiderScrollbars( booklet.outlinePanel.$element[ 0 ] );
+ }, 200 );
+ }
}
return this;
*
* var index = new OO.ui.IndexLayout();
*
- * index.addTabPanelss ( [ tabPanel1, tabPanel2 ] );
+ * index.addTabPanels ( [ tabPanel1, tabPanel2 ] );
* $( 'body' ).append( index.$element );
*
* @class
*
* @param {OO.ui.TabPanelLayout} tabPanel Tab panel to use as a reference point
* @return {OO.ui.TabPanelLayout|null} Tab panel closest to the specified
- * @deprecated since v0.22.0, use `getClosestTabPanel` instead
+ * @deprecated since v0.21.3, use `getClosestTabPanel` instead
*/
OO.ui.IndexLayout.prototype.getClosestCard = function ( tabPanel ) {
OO.ui.warnDeprecation( 'IndexLayout\'s getClosestCard method is deprecated. Use getClosestTabPanel instead. See T155152' );
*
* @param {string} name Symbolic name of tab panel
* @return {OO.ui.TabPanelLayout|undefined} Tab panel, if found
- * @deprecated since v0.22.0, use `getTabPanel` instead
+ * @deprecated since v0.21.3, use `getTabPanel` instead
*/
OO.ui.IndexLayout.prototype.getCard = function ( name ) {
OO.ui.warnDeprecation( 'IndexLayout\'s getCard method is deprecated. Use getTabPanel instead. See T155152' );
* Get the current tab panel.
*
* @return {OO.ui.TabPanelLayout|undefined} Current tab panel, if found
- * @deprecated since v0.22.0, use `getCurrentTabPanel` instead
+ * @deprecated since v0.21.3, use `getCurrentTabPanel` instead
*/
OO.ui.IndexLayout.prototype.getCurrentCard = function () {
OO.ui.warnDeprecation( 'IndexLayout\'s getCurrentCard method is deprecated. Use getCurrentTabPanel instead. See T155152' );
* Get the symbolic name of the current tab panel.
*
* @return {string|null} Symbolic name of the current tab panel
- * @deprecated since v0.22.0, use `getCurrentTabPanelName` instead
+ * @deprecated since v0.21.3, use `getCurrentTabPanelName` instead
*/
OO.ui.IndexLayout.prototype.getCurrentCardName = function () {
OO.ui.warnDeprecation( 'IndexLayout\'s getCurrentCardName method is deprecated. Use getCurrentTabPanelName instead. See T155152' );
* @param {number} index Index of the insertion point
* @fires add
* @chainable
- * @deprecated since v0.22.0, use `addTabPanels` instead
+ * @deprecated since v0.21.3, use `addTabPanels` instead
*/
OO.ui.IndexLayout.prototype.addCards = function ( tabPanels, index ) {
OO.ui.warnDeprecation( 'IndexLayout\'s addCards method is deprecated. Use addTabPanels instead. See T155152' );
* @param {OO.ui.TabPanelLayout[]} tabPanels An array of tab panels to remove
* @fires remove
* @chainable
- * @deprecated since v0.22.0, use `removeTabPanels` instead
+ * @deprecated since v0.21.3, use `removeTabPanels` instead
*/
OO.ui.IndexLayout.prototype.removeCards = function ( tabPanels ) {
OO.ui.warnDeprecation( 'IndexLayout\'s removeCards method is deprecated. Use removeTabPanels instead. See T155152.' );
*
* @fires remove
* @chainable
- * @deprecated since v0.22.0, use `clearTabPanels` instead
+ * @deprecated since v0.21.3, use `clearTabPanels` instead
*/
OO.ui.IndexLayout.prototype.clearCards = function () {
OO.ui.warnDeprecation( 'IndexLayout\'s clearCards method is deprecated. Use clearTabPanels instead. See T155152.' );
*
* @fires set
* @param {string} name Symbolic name of tab panel
- * @deprecated since v0.22.0, use `setTabPanel` instead
+ * @deprecated since v0.21.3, use `setTabPanel` instead
*/
OO.ui.IndexLayout.prototype.setCard = function ( name ) {
OO.ui.warnDeprecation( 'IndexLayout\'s setCard method is deprecated. Use setTabPanel instead. See T155152.' );
* Select the first selectable tab panel.
*
* @chainable
- * @deprecated since v0.22.0, use `selectFirstSelectableTabPanel` instead
+ * @deprecated since v0.21.3, use `selectFirstSelectableTabPanel` instead
*/
OO.ui.IndexLayout.prototype.selectFirstSelectableCard = function () {
OO.ui.warnDeprecation( 'IndexLayout\'s selectFirstSelectableCard method is deprecated. Use selectFirestSelectableTabPanel instead. See T155152.' );
return this;
};
+/**
+ * @inheritdoc
+ */
+OO.ui.ToggleSwitchWidget.prototype.simulateLabelClick = function () {
+ if ( !this.isDisabled() ) {
+ this.setValue( !this.value );
+ }
+ this.focus();
+};
+
/**
* OutlineControlsWidget is a set of controls for an {@link OO.ui.OutlineSelectWidget outline select widget}.
* Controls include moving items up and down, removing items, and adding different kinds of items.
} );
this.removeButton = new OO.ui.ButtonWidget( {
framed: false,
- icon: 'remove',
+ icon: 'trash',
title: OO.ui.msg( 'ooui-outline-control-remove' )
} );
this.abilities = { move: true, remove: true };
// Events
this.closeButton = new OO.ui.ButtonWidget( {
framed: false,
- indicator: 'clear',
+ icon: 'close',
tabIndex: -1
} ).on( 'click', this.onCloseClick.bind( this ) );
}
};
-/**
- * Focuses the capsule
- */
-OO.ui.CapsuleItemWidget.prototype.focus = function () {
- this.$element.focus();
-};
-
/**
* CapsuleMultiselectWidgets are something like a {@link OO.ui.ComboBoxInputWidget combo box widget}
* that allows for selecting multiple values.
OO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IndicatorElement );
OO.mixinClass( OO.ui.CapsuleMultiselectWidget, OO.ui.mixin.IconElement );
-/* Static Properties */
-
-OO.ui.CapsuleMultiselectWidget.static.supportsSimpleLabel = true;
-
/* Events */
/**
};
/**
- * Get the widget's input's id, or generate one, if it has an input.
- *
- * @return {string}
+ * @inheritdoc
*/
OO.ui.CapsuleMultiselectWidget.prototype.getInputId = function () {
- var id;
if ( !this.$input ) {
- return false;
- }
-
- id = this.$input.attr( 'id' );
- if ( id === undefined ) {
- id = OO.ui.generateElementId();
- this.$input.attr( 'id', id );
+ return null;
}
-
- return id;
+ return OO.ui.mixin.TabIndexedElement.prototype.getInputId.call( this );
};
/**
*/
OO.ui.CapsuleMultiselectWidget.prototype.onInputFocus = function () {
if ( !this.isDisabled() ) {
+ this.updateInputSize();
this.menu.toggle( true );
}
};
* Focus the widget
*
* @chainable
- * @return {OO.ui.CapsuleMultiselectWidget}
*/
OO.ui.CapsuleMultiselectWidget.prototype.focus = function () {
if ( !this.isDisabled() ) {
this.popup.toggle( true );
OO.ui.findFocusable( this.popup.$element ).focus();
} else {
- this.updateInputSize();
- this.menu.toggle( true );
- this.$input.focus();
+ OO.ui.mixin.TabIndexedElement.prototype.focus.call( this );
}
}
return this;
this.closeButton = new OO.ui.ButtonWidget( {
framed: false,
- indicator: 'clear',
+ icon: 'close',
tabIndex: -1
} );
this.closeButton.setDisabled( this.isDisabled() );
}
};
-/**
- * Focuses the capsule
- */
-OO.ui.TagItemWidget.prototype.focus = function () {
- if ( !this.isDisabled() ) {
- this.$element.focus();
- }
-};
-
/**
* Select this item
*
* a meta key like 'ctrl'
* @return {boolean} Whether to prevent defaults
*/
-OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function () {
+OO.ui.TagMultiselectWidget.prototype.doInputBackspace = function ( e, withMetaKey ) {
var items, item;
if (
// Delete the last item
items = this.getItems();
item = items[ items.length - 1 ];
- this.input.setValue( item.getData() );
this.removeItems( [ item ] );
+ // If Ctrl/Cmd was pressed, delete item entirely.
+ // Otherwise put it into the text field for editing.
+ if ( !withMetaKey ) {
+ this.input.setValue( item.getData() );
+ }
return false;
}
* @return {boolean} Value is allowed
*/
OO.ui.TagMultiselectWidget.prototype.isAllowedData = function ( data ) {
- if ( this.allowArbitrary ) {
- return true;
- }
-
if (
!this.allowDuplicates &&
this.isDuplicateData( data )
return false;
}
+ if ( this.allowArbitrary ) {
+ return true;
+ }
+
// Check with allowed values
if (
this.getAllowedValues().some( function ( value ) {
}
};
-/**
- * Focus the widget
- */
-OO.ui.TagMultiselectWidget.prototype.focus = function () {
- if ( this.hasInput ) {
- this.input.focus();
- }
-};
-
/**
* Get the datas of the currently selected items
*
OO.ui.TagMultiselectWidget.prototype.updateInputSize = function () {
var $lastItem, direction, contentWidth, currentWidth, bestWidth;
if ( this.inputPosition === 'inline' && !this.isDisabled() ) {
+ if ( this.input.$input[ 0 ].scrollWidth === 0 ) {
+ // Input appears to be attached but not visible.
+ // Don't attempt to adjust its size, because our measurements
+ // are going to fail anyway.
+ return;
+ }
this.input.$input.css( 'width', '1em' );
$lastItem = this.$group.children().last();
direction = OO.ui.Element.static.getDir( this.$handle );
this.on( 'resize', this.popup.updateDimensions.bind( this.popup ) );
this.popup.connect( this, { toggle: 'onPopupToggle' } );
this.$tabIndexed
- .on( 'focus', this.focus.bind( this ) );
+ .on( 'focus', this.onFocus.bind( this ) );
// Initialize
this.$element
/* Methods */
/**
- * @inheritdoc
+ * Focus event handler.
+ *
+ * @private
*/
-OO.ui.PopupTagMultiselectWidget.prototype.focus = function () {
- // Since the parent deals with input focus, only
- // call the parent method if our input isn't in the
- // popup
- if ( !this.popupInput ) {
- // Parent method
- OO.ui.PopupTagMultiselectWidget.parent.prototype.focus.call( this );
- }
-
+OO.ui.PopupTagMultiselectWidget.prototype.onFocus = function () {
this.popup.toggle( true );
};
.append( this.menu.$element );
this.$element
.addClass( 'oo-ui-menuTagMultiselectWidget' );
+ // TagMultiselectWidget already does this, but it doesn't work right because this.menu is not yet
+ // set up while the parent constructor runs, and #getAllowedValues rejects everything.
+ if ( config.selected ) {
+ this.setValue( config.selected );
+ }
};
/* Initialization */
*/
OO.ui.MenuTagMultiselectWidget.prototype.addTagFromInput = function () {
var inputValue = this.input.getValue(),
+ validated = false,
highlightedItem = this.menu.getHighlightedItem(),
item = this.menu.getItemFromData( inputValue );
// Look for a highlighted item first
if ( highlightedItem ) {
- this.addTag( highlightedItem.getData(), highlightedItem.getLabel() );
+ validated = this.addTag( highlightedItem.getData(), highlightedItem.getLabel() );
} else if ( item ) {
// Look for the element that fits the data
- this.addTag( item.getData(), item.getLabel() );
+ validated = this.addTag( item.getData(), item.getLabel() );
} else {
// Otherwise, add the tag - the method will only add if the
// tag is valid or if invalid tags are allowed
- this.addTag( inputValue );
+ validated = this.addTag( inputValue );
+ }
+
+ if ( validated ) {
+ this.clearInput();
+ this.focus();
}
};
* @return {string[]} Allowed data values
*/
OO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {
- var menuDatas = this.menu.getItems().map( function ( menuItem ) {
- return menuItem.getData();
- } );
- return this.allowedValues.concat( menuDatas );
-};
-
-/**
- * @inheritdoc
- */
-OO.ui.MenuTagMultiselectWidget.prototype.focus = function () {
- // Parent method
- OO.ui.MenuTagMultiselectWidget.parent.prototype.focus.call( this );
-
- if ( !this.isDisabled() ) {
- this.menu.toggle( true );
+ var menuDatas = [];
+ if ( this.menu ) {
+ // If the parent constructor is calling us, we're not ready yet, this.menu is not set up.
+ menuDatas = this.menu.getItems().map( function ( menuItem ) {
+ return menuItem.getData();
+ } );
}
+ return this.allowedValues.concat( menuDatas );
};
/**
* @chainable
*/
OO.ui.SelectFileWidget.prototype.focus = function () {
- this.selectButton.$button[ 0 ].focus();
+ this.selectButton.focus();
return this;
};
+/**
+ * Blur the widget.
+ *
+ * @chainable
+ */
+OO.ui.SelectFileWidget.prototype.blur = function () {
+ this.selectButton.blur();
+ return this;
+};
+
+/**
+ * @inheritdoc
+ */
+OO.ui.SelectFileWidget.prototype.simulateLabelClick = function () {
+ this.focus();
+};
+
/**
* Update the user interface when a file is selected or unselected
*
disabled: this.isDisabled(),
tabIndex: -1,
classes: [ 'oo-ui-numberInputWidget-minusButton' ],
- label: '−'
+ icon: 'subtract'
},
config.minusButton
) );
disabled: this.isDisabled(),
tabIndex: -1,
classes: [ 'oo-ui-numberInputWidget-plusButton' ],
- label: '+'
+ icon: 'add'
},
config.plusButton
) );