/*!
- * OOjs UI v0.21.0
+ * OOjs UI v0.21.2
* 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-04-11T22:51:05Z
+ * Date: 2017-04-26T01:05:10Z
*/
( function ( OO ) {
*
* @constructor
* @param {Object} [config] Configuration options
- * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning
+ * @cfg {jQuery} [$overlay] Overlay for the lookup menu; defaults to relative positioning.
+ * See <https://www.mediawiki.org/wiki/OOjs_UI/Concepts#Overlays>.
* @cfg {jQuery} [$container=this.$element] The container element. The lookup menu is rendered beneath the specified element.
* @cfg {boolean} [allowSuggestionsWhenEmpty=false] Request and display a lookup menu when the text input is empty.
* By default, the lookup menu is not generated and displayed until the user begins to type.
} );
// Initialization
+ this.$input.attr( {
+ role: 'combobox',
+ 'aria-owns': this.lookupMenu.getElementId(),
+ 'aria-autocomplete': 'list'
+ } );
this.$element.addClass( 'oo-ui-lookupElement' );
this.lookupMenu.$element.addClass( 'oo-ui-lookupElement-menu' );
this.$overlay.append( this.lookupMenu.$element );
* its containing `<div>`. The specified overlay layer is usually on top of
* the containing `<div>` and has a larger area. By default, the menu uses
* relative positioning.
+ * See <https://www.mediawiki.org/wiki/OOjs_UI/Concepts#Overlays>.
*/
OO.ui.CapsuleMultiselectWidget = function OoUiCapsuleMultiselectWidget( config ) {
var $tabFocus;
this.$input.prop( 'disabled', this.isDisabled() );
this.$input.attr( {
role: 'combobox',
+ 'aria-owns': this.menu.getElementId(),
'aria-autocomplete': 'list'
} );
}
* @constructor
* @param {Object} config Configuration object
* @cfg {Object} [input] Configuration options for the input widget
+ * @cfg {OO.ui.InputWidget} [inputWidget] An optional input widget. If given, it will
+ * replace the input widget used in the TagMultiselectWidget. If not given,
+ * TagMultiselectWidget creates its own.
* @cfg {boolean} [inputPosition='inline'] Position of the input. Options are:
* - inline: The input is invisible, but exists inside the tag list, so
* the user types into the tag groups to add tags.
// Initialize
this.$element
.addClass( 'oo-ui-tagMultiselectWidget' )
- .addClass( 'oo-ui-tagMultiselectWidget-inputPosition-' + this.inputPosition )
.append( this.$handle );
if ( this.hasInput ) {
- this.input = new OO.ui.TextInputWidget( $.extend( {
- placeholder: config.placeholder,
- classes: [ 'oo-ui-tagMultiselectWidget-input' ]
- }, config.input ) );
+ if ( config.inputWidget ) {
+ this.input = config.inputWidget;
+ } else {
+ this.input = new OO.ui.TextInputWidget( $.extend( {
+ placeholder: config.placeholder,
+ classes: [ 'oo-ui-tagMultiselectWidget-input' ]
+ }, config.input ) );
+ }
this.input.setDisabled( this.isDisabled() );
inputEvents = {
// in the case the widget is outline so it can
// stretch all the way if the widet is wide
this.input.$element.css( 'max-width', 'inherit' );
- this.$element.append( this.input.$element );
+ this.$element
+ .addClass( 'oo-ui-tagMultiselectWidget-outlined' )
+ .append( this.input.$element );
} else {
+ this.$element.addClass( 'oo-ui-tagMultiselectWidget-inlined' );
// HACK: When the widget is using 'inline' input, the
// behavior needs to only use the $input itself
// so we style and size it accordingly (otherwise
* Check whether a given value is allowed to be added
*
* @param {string|Object} data Requested value
- * @return {boolean} Value exists in the allowed values list
+ * @return {boolean} Value is allowed
*/
OO.ui.TagMultiselectWidget.prototype.isAllowedData = function ( data ) {
- var hash = OO.getHash( data );
-
if ( this.allowArbitrary ) {
return true;
}
// Check with allowed values
if (
this.getAllowedValues().some( function ( value ) {
- return hash === OO.getHash( value );
+ return data === value;
} )
) {
return true;
* @mixins OO.ui.mixin.PopupElement
*
* @param {Object} config Configuration object
- * @cfg {jQuery} [$overlay] An overlay for the popup
+ * @cfg {jQuery} [$overlay] An overlay for the popup.
+ * See <https://www.mediawiki.org/wiki/OOjs_UI/Concepts#Overlays>.
* @cfg {Object} [popup] Configuration options for the popup
* @cfg {OO.ui.InputWidget} [popupInput] An input widget inside the popup that will be
* focused when the popup is opened and will be used as replacement for the
}
// Events
+ this.on( 'resize', this.popup.updateDimensions.bind( this.popup ) );
this.popup.connect( this, { toggle: 'onPopupToggle' } );
this.$tabIndexed
.on( 'focus', this.focus.bind( this ) );
* @constructor
* @param {Object} [config] Configuration object
* @cfg {Object} [menu] Configuration object for the menu widget
- * @cfg {jQuery} [$overlay] An overlay for the menu
+ * @cfg {jQuery} [$overlay] An overlay for the menu.
+ * See <https://www.mediawiki.org/wiki/OOjs_UI/Concepts#Overlays>.
* @cfg {Object[]} [options=[]] Array of menu options in the format `{ data: …, label: … }`
*/
OO.ui.MenuTagMultiselectWidget = function OoUiMenuTagMultiselectWidget( config ) {
};
/**
- * @inheritdoc
+ * Get the allowed values list
+ *
+ * @return {string[]} Allowed data values
*/
-OO.ui.MenuTagMultiselectWidget.prototype.isAllowedData = function ( data ) {
- return OO.ui.MenuTagMultiselectWidget.parent.prototype.isAllowedData.call( this, data ) &&
- !!this.menu.getItemFromData( data );
+OO.ui.MenuTagMultiselectWidget.prototype.getAllowedValues = function () {
+ var menuDatas = this.menu.getItems().map( function ( menuItem ) {
+ return menuItem.getData();
+ } );
+ return this.allowedValues.concat( menuDatas );
};
/**
* $( 'body' ).append( numberInput.$element );
*
* @class
- * @extends OO.ui.Widget
+ * @extends OO.ui.TextInputWidget
*
* @constructor
* @param {Object} [config] Configuration options
- * @cfg {Object} [input] Configuration options to pass to the {@link OO.ui.TextInputWidget text input widget}.
* @cfg {Object} [minusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget decrementing button widget}.
* @cfg {Object} [plusButton] Configuration options to pass to the {@link OO.ui.ButtonWidget incrementing button widget}.
- * @cfg {boolean} [isInteger=false] Whether the field accepts only integer values.
+ * @cfg {boolean} [allowInteger=false] Whether the field accepts only integer values.
* @cfg {number} [min=-Infinity] Minimum allowed value
* @cfg {number} [max=Infinity] Maximum allowed value
* @cfg {number} [step=1] Delta when using the buttons or up/down arrow keys
* @cfg {boolean} [showButtons=true] Whether to show the plus and minus buttons.
*/
OO.ui.NumberInputWidget = function OoUiNumberInputWidget( config ) {
+ var $field = $( '<div>' )
+ .addClass( 'oo-ui-numberInputWidget-field' );
+
// Configuration initialization
config = $.extend( {
isInteger: false,
showButtons: true
}, config );
+ // For backward compatibility
+ $.extend( config, config.input );
+ this.input = this;
+
// Parent constructor
- OO.ui.NumberInputWidget.parent.call( this, config );
+ OO.ui.NumberInputWidget.parent.call( this, $.extend( config, {
+ type: 'number'
+ } ) );
- // Properties
- this.input = new OO.ui.TextInputWidget( $.extend(
- {
- disabled: this.isDisabled(),
- type: 'number'
- },
- config.input
- ) );
if ( config.showButtons ) {
this.minusButton = new OO.ui.ButtonWidget( $.extend(
{
}
// Events
- this.input.connect( this, {
- change: this.emit.bind( this, 'change' ),
- enter: this.emit.bind( this, 'enter' )
- } );
- this.input.$input.on( {
+ this.$input.on( {
keydown: this.onKeyDown.bind( this ),
'wheel mousewheel DOMMouseScroll': this.onWheel.bind( this )
} );
} );
}
- // Initialization
- this.setIsInteger( !!config.isInteger );
- this.setRange( config.min, config.max );
- this.setStep( config.step, config.pageStep );
-
- this.$field = $( '<div>' ).addClass( 'oo-ui-numberInputWidget-field' )
- .append( this.input.$element );
- this.$element.addClass( 'oo-ui-numberInputWidget' ).append( this.$field );
+ // Build the field
+ $field.append( this.$input );
if ( config.showButtons ) {
- this.$field
+ $field
.prepend( this.minusButton.$element )
.append( this.plusButton.$element );
- this.$element.addClass( 'oo-ui-numberInputWidget-buttoned' );
}
- this.input.setValidation( this.validateNumber.bind( this ) );
-};
-/* Setup */
-
-OO.inheritClass( OO.ui.NumberInputWidget, OO.ui.Widget );
+ // Initialization
+ this.setAllowInteger( config.isInteger || config.allowInteger );
+ this.setRange( config.min, config.max );
+ this.setStep( config.step, config.pageStep );
+ // Set the validation method after we set isInteger and range
+ // so that it doesn't immediately call setValidityFlag
+ this.setValidation( this.validateNumber.bind( this ) );
-/* Events */
+ this.$element
+ .addClass( 'oo-ui-numberInputWidget' )
+ .toggleClass( 'oo-ui-numberInputWidget-buttoned', config.showButtons )
+ .append( $field );
+};
-/**
- * A `change` event is emitted when the value of the input changes.
- *
- * @event change
- */
+/* Setup */
-/**
- * An `enter` event is emitted when the user presses 'enter' inside the text box.
- *
- * @event enter
- */
+OO.inheritClass( OO.ui.NumberInputWidget, OO.ui.TextInputWidget );
/* Methods */
*
* @param {boolean} flag
*/
-OO.ui.NumberInputWidget.prototype.setIsInteger = function ( flag ) {
+OO.ui.NumberInputWidget.prototype.setAllowInteger = function ( flag ) {
this.isInteger = !!flag;
- this.input.setValidityFlag();
+ this.setValidityFlag();
};
+// Backward compatibility
+OO.ui.NumberInputWidget.prototype.setIsInteger = OO.ui.NumberInputWidget.prototype.setAllowInteger;
/**
* Get whether only integers are allowed
*
* @return {boolean} Flag value
*/
-OO.ui.NumberInputWidget.prototype.getIsInteger = function () {
+OO.ui.NumberInputWidget.prototype.getAllowInteger = function () {
return this.isInteger;
};
+// Backward compatibility
+OO.ui.NumberInputWidget.prototype.getIsInteger = OO.ui.NumberInputWidget.prototype.getAllowInteger;
/**
* Set the range of allowed values
}
this.min = min;
this.max = max;
- this.input.setValidityFlag();
+ this.setValidityFlag();
};
/**
return [ this.step, this.pageStep ];
};
-/**
- * Get the current value of the widget
- *
- * @return {string}
- */
-OO.ui.NumberInputWidget.prototype.getValue = function () {
- return this.input.getValue();
-};
-
/**
* Get the current value of the widget as a number
*
* @return {number} May be NaN, or an invalid number
*/
OO.ui.NumberInputWidget.prototype.getNumericValue = function () {
- return +this.input.getValue();
-};
-
-/**
- * Set the value of the widget
- *
- * @param {string} value Invalid values are allowed
- */
-OO.ui.NumberInputWidget.prototype.setValue = function ( value ) {
- this.input.setValue( value );
+ return +this.getValue();
};
/**
this.setValue( n );
}
};
-
/**
* Validate input
*
*/
OO.ui.NumberInputWidget.prototype.validateNumber = function ( value ) {
var n = +value;
+ if ( value === '' ) {
+ return !this.isRequired();
+ }
+
if ( isNaN( n ) || !isFinite( n ) ) {
return false;
}
OO.ui.NumberInputWidget.prototype.onWheel = function ( event ) {
var delta = 0;
- if ( !this.isDisabled() && this.input.$input.is( ':focus' ) ) {
+ if ( !this.isDisabled() && this.$input.is( ':focus' ) ) {
// Standard 'wheel' event
if ( event.originalEvent.deltaMode !== undefined ) {
this.sawWheelEvent = true;
// Parent method
OO.ui.NumberInputWidget.parent.prototype.setDisabled.call( this, disabled );
- if ( this.input ) {
- this.input.setDisabled( this.isDisabled() );
- }
if ( this.minusButton ) {
this.minusButton.setDisabled( this.isDisabled() );
}