diff options
author | Pierre Schmitz <pierre@archlinux.de> | 2015-12-20 09:00:55 +0100 |
---|---|---|
committer | Pierre Schmitz <pierre@archlinux.de> | 2015-12-20 09:00:55 +0100 |
commit | a2190ac74dd4d7080b12bab90e552d7aa81209ef (patch) | |
tree | 8b31f38de9882d18df54cf8d9e0de74167a094eb /vendor/oojs/oojs-ui/src/widgets/SelectWidget.js | |
parent | 15e69f7b20b6596b9148030acce5b59993b95a45 (diff) | |
parent | 257401d8b2cf661adf36c84b0e3fd1cf85e33c22 (diff) |
Merge branch 'mw-1.26'
Diffstat (limited to 'vendor/oojs/oojs-ui/src/widgets/SelectWidget.js')
-rw-r--r-- | vendor/oojs/oojs-ui/src/widgets/SelectWidget.js | 630 |
1 files changed, 0 insertions, 630 deletions
diff --git a/vendor/oojs/oojs-ui/src/widgets/SelectWidget.js b/vendor/oojs/oojs-ui/src/widgets/SelectWidget.js deleted file mode 100644 index 91172af0..00000000 --- a/vendor/oojs/oojs-ui/src/widgets/SelectWidget.js +++ /dev/null @@ -1,630 +0,0 @@ -/** - * A SelectWidget is of a generic selection of options. The OOjs UI library contains several types of - * select widgets, including {@link OO.ui.ButtonSelectWidget button selects}, - * {@link OO.ui.RadioSelectWidget radio selects}, and {@link OO.ui.MenuSelectWidget - * menu selects}. - * - * This class should be used together with OO.ui.OptionWidget or OO.ui.DecoratedOptionWidget. For more - * information, please see the [OOjs UI documentation on MediaWiki][1]. - * - * @example - * // Example of a select widget with three options - * var select = new OO.ui.SelectWidget( { - * items: [ - * new OO.ui.OptionWidget( { - * data: 'a', - * label: 'Option One', - * } ), - * new OO.ui.OptionWidget( { - * data: 'b', - * label: 'Option Two', - * } ), - * new OO.ui.OptionWidget( { - * data: 'c', - * label: 'Option Three', - * } ) - * ] - * } ); - * $( 'body' ).append( select.$element ); - * - * [1]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options - * - * @abstract - * @class - * @extends OO.ui.Widget - * @mixins OO.ui.GroupElement - * - * @constructor - * @param {Object} [config] Configuration options - * @cfg {OO.ui.OptionWidget[]} [items] An array of options to add to the select. - * Options are created with {@link OO.ui.OptionWidget OptionWidget} classes. See - * the [OOjs UI documentation on MediaWiki] [2] for examples. - * [2]: https://www.mediawiki.org/wiki/OOjs_UI/Widgets/Selects_and_Options - */ -OO.ui.SelectWidget = function OoUiSelectWidget( config ) { - // Configuration initialization - config = config || {}; - - // Parent constructor - OO.ui.SelectWidget.super.call( this, config ); - - // Mixin constructors - OO.ui.GroupWidget.call( this, $.extend( {}, config, { $group: this.$element } ) ); - - // Properties - this.pressed = false; - this.selecting = null; - this.onMouseUpHandler = this.onMouseUp.bind( this ); - this.onMouseMoveHandler = this.onMouseMove.bind( this ); - this.onKeyDownHandler = this.onKeyDown.bind( this ); - - // Events - this.$element.on( { - mousedown: this.onMouseDown.bind( this ), - mouseover: this.onMouseOver.bind( this ), - mouseleave: this.onMouseLeave.bind( this ) - } ); - - // Initialization - this.$element - .addClass( 'oo-ui-selectWidget oo-ui-selectWidget-depressed' ) - .attr( 'role', 'listbox' ); - if ( Array.isArray( config.items ) ) { - this.addItems( config.items ); - } -}; - -/* Setup */ - -OO.inheritClass( OO.ui.SelectWidget, OO.ui.Widget ); - -// Need to mixin base class as well -OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupElement ); -OO.mixinClass( OO.ui.SelectWidget, OO.ui.GroupWidget ); - -/* Events */ - -/** - * @event highlight - * - * A `highlight` event is emitted when the highlight is changed with the #highlightItem method. - * - * @param {OO.ui.OptionWidget|null} item Highlighted item - */ - -/** - * @event press - * - * A `press` event is emitted when the #pressItem method is used to programmatically modify the - * pressed state of an option. - * - * @param {OO.ui.OptionWidget|null} item Pressed item - */ - -/** - * @event select - * - * A `select` event is emitted when the selection is modified programmatically with the #selectItem method. - * - * @param {OO.ui.OptionWidget|null} item Selected item - */ - -/** - * @event choose - * A `choose` event is emitted when an item is chosen with the #chooseItem method. - * @param {OO.ui.OptionWidget} item Chosen item - */ - -/** - * @event add - * - * An `add` event is emitted when options are added to the select with the #addItems method. - * - * @param {OO.ui.OptionWidget[]} items Added items - * @param {number} index Index of insertion point - */ - -/** - * @event remove - * - * A `remove` event is emitted when options are removed from the select with the #clearItems - * or #removeItems methods. - * - * @param {OO.ui.OptionWidget[]} items Removed items - */ - -/* Methods */ - -/** - * Handle mouse down events. - * - * @private - * @param {jQuery.Event} e Mouse down event - */ -OO.ui.SelectWidget.prototype.onMouseDown = function ( e ) { - var item; - - if ( !this.isDisabled() && e.which === 1 ) { - this.togglePressed( true ); - item = this.getTargetItem( e ); - if ( item && item.isSelectable() ) { - this.pressItem( item ); - this.selecting = item; - this.getElementDocument().addEventListener( - 'mouseup', - this.onMouseUpHandler, - true - ); - this.getElementDocument().addEventListener( - 'mousemove', - this.onMouseMoveHandler, - true - ); - } - } - return false; -}; - -/** - * Handle mouse up events. - * - * @private - * @param {jQuery.Event} e Mouse up event - */ -OO.ui.SelectWidget.prototype.onMouseUp = function ( e ) { - var item; - - this.togglePressed( false ); - if ( !this.selecting ) { - item = this.getTargetItem( e ); - if ( item && item.isSelectable() ) { - this.selecting = item; - } - } - if ( !this.isDisabled() && e.which === 1 && this.selecting ) { - this.pressItem( null ); - this.chooseItem( this.selecting ); - this.selecting = null; - } - - this.getElementDocument().removeEventListener( - 'mouseup', - this.onMouseUpHandler, - true - ); - this.getElementDocument().removeEventListener( - 'mousemove', - this.onMouseMoveHandler, - true - ); - - return false; -}; - -/** - * Handle mouse move events. - * - * @private - * @param {jQuery.Event} e Mouse move event - */ -OO.ui.SelectWidget.prototype.onMouseMove = function ( e ) { - var item; - - if ( !this.isDisabled() && this.pressed ) { - item = this.getTargetItem( e ); - if ( item && item !== this.selecting && item.isSelectable() ) { - this.pressItem( item ); - this.selecting = item; - } - } - return false; -}; - -/** - * Handle mouse over events. - * - * @private - * @param {jQuery.Event} e Mouse over event - */ -OO.ui.SelectWidget.prototype.onMouseOver = function ( e ) { - var item; - - if ( !this.isDisabled() ) { - item = this.getTargetItem( e ); - this.highlightItem( item && item.isHighlightable() ? item : null ); - } - return false; -}; - -/** - * Handle mouse leave events. - * - * @private - * @param {jQuery.Event} e Mouse over event - */ -OO.ui.SelectWidget.prototype.onMouseLeave = function () { - if ( !this.isDisabled() ) { - this.highlightItem( null ); - } - return false; -}; - -/** - * Handle key down events. - * - * @protected - * @param {jQuery.Event} e Key down event - */ -OO.ui.SelectWidget.prototype.onKeyDown = function ( e ) { - var nextItem, - handled = false, - currentItem = this.getHighlightedItem() || this.getSelectedItem(); - - if ( !this.isDisabled() && this.isVisible() ) { - switch ( e.keyCode ) { - case OO.ui.Keys.ENTER: - if ( currentItem && currentItem.constructor.static.highlightable ) { - // Was only highlighted, now let's select it. No-op if already selected. - this.chooseItem( currentItem ); - handled = true; - } - break; - case OO.ui.Keys.UP: - case OO.ui.Keys.LEFT: - nextItem = this.getRelativeSelectableItem( currentItem, -1 ); - handled = true; - break; - case OO.ui.Keys.DOWN: - case OO.ui.Keys.RIGHT: - nextItem = this.getRelativeSelectableItem( currentItem, 1 ); - handled = true; - break; - case OO.ui.Keys.ESCAPE: - case OO.ui.Keys.TAB: - if ( currentItem && currentItem.constructor.static.highlightable ) { - currentItem.setHighlighted( false ); - } - this.unbindKeyDownListener(); - // Don't prevent tabbing away / defocusing - handled = false; - break; - } - - if ( nextItem ) { - if ( nextItem.constructor.static.highlightable ) { - this.highlightItem( nextItem ); - } else { - this.chooseItem( nextItem ); - } - nextItem.scrollElementIntoView(); - } - - if ( handled ) { - // Can't just return false, because e is not always a jQuery event - e.preventDefault(); - e.stopPropagation(); - } - } -}; - -/** - * Bind key down listener. - * - * @protected - */ -OO.ui.SelectWidget.prototype.bindKeyDownListener = function () { - this.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true ); -}; - -/** - * Unbind key down listener. - * - * @protected - */ -OO.ui.SelectWidget.prototype.unbindKeyDownListener = function () { - this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true ); -}; - -/** - * Get the closest item to a jQuery.Event. - * - * @private - * @param {jQuery.Event} e - * @return {OO.ui.OptionWidget|null} Outline item widget, `null` if none was found - */ -OO.ui.SelectWidget.prototype.getTargetItem = function ( e ) { - return $( e.target ).closest( '.oo-ui-optionWidget' ).data( 'oo-ui-optionWidget' ) || null; -}; - -/** - * Get selected item. - * - * @return {OO.ui.OptionWidget|null} Selected item, `null` if no item is selected - */ -OO.ui.SelectWidget.prototype.getSelectedItem = function () { - var i, len; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - if ( this.items[ i ].isSelected() ) { - return this.items[ i ]; - } - } - return null; -}; - -/** - * Get highlighted item. - * - * @return {OO.ui.OptionWidget|null} Highlighted item, `null` if no item is highlighted - */ -OO.ui.SelectWidget.prototype.getHighlightedItem = function () { - var i, len; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - if ( this.items[ i ].isHighlighted() ) { - return this.items[ i ]; - } - } - return null; -}; - -/** - * Toggle pressed state. - * - * Press is a state that occurs when a user mouses down on an item, but - * has not yet let go of the mouse. The item may appear selected, but it will not be selected - * until the user releases the mouse. - * - * @param {boolean} pressed An option is being pressed - */ -OO.ui.SelectWidget.prototype.togglePressed = function ( pressed ) { - if ( pressed === undefined ) { - pressed = !this.pressed; - } - if ( pressed !== this.pressed ) { - this.$element - .toggleClass( 'oo-ui-selectWidget-pressed', pressed ) - .toggleClass( 'oo-ui-selectWidget-depressed', !pressed ); - this.pressed = pressed; - } -}; - -/** - * Highlight an option. If the `item` param is omitted, no options will be highlighted - * and any existing highlight will be removed. The highlight is mutually exclusive. - * - * @param {OO.ui.OptionWidget} [item] Item to highlight, omit for no highlight - * @fires highlight - * @chainable - */ -OO.ui.SelectWidget.prototype.highlightItem = function ( item ) { - var i, len, highlighted, - changed = false; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - highlighted = this.items[ i ] === item; - if ( this.items[ i ].isHighlighted() !== highlighted ) { - this.items[ i ].setHighlighted( highlighted ); - changed = true; - } - } - if ( changed ) { - this.emit( 'highlight', item ); - } - - return this; -}; - -/** - * Programmatically select an option by its data. If the `data` parameter is omitted, - * or if the item does not exist, all options will be deselected. - * - * @param {Object|string} [data] Value of the item to select, omit to deselect all - * @fires select - * @chainable - */ -OO.ui.SelectWidget.prototype.selectItemByData = function ( data ) { - var itemFromData = this.getItemFromData( data ); - if ( data === undefined || !itemFromData ) { - return this.selectItem(); - } - return this.selectItem( itemFromData ); -}; - -/** - * Programmatically select an option by its reference. If the `item` parameter is omitted, - * all options will be deselected. - * - * @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all - * @fires select - * @chainable - */ -OO.ui.SelectWidget.prototype.selectItem = function ( item ) { - var i, len, selected, - changed = false; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - selected = this.items[ i ] === item; - if ( this.items[ i ].isSelected() !== selected ) { - this.items[ i ].setSelected( selected ); - changed = true; - } - } - if ( changed ) { - this.emit( 'select', item ); - } - - return this; -}; - -/** - * Press an item. - * - * Press is a state that occurs when a user mouses down on an item, but has not - * yet let go of the mouse. The item may appear selected, but it will not be selected until the user - * releases the mouse. - * - * @param {OO.ui.OptionWidget} [item] Item to press, omit to depress all - * @fires press - * @chainable - */ -OO.ui.SelectWidget.prototype.pressItem = function ( item ) { - var i, len, pressed, - changed = false; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - pressed = this.items[ i ] === item; - if ( this.items[ i ].isPressed() !== pressed ) { - this.items[ i ].setPressed( pressed ); - changed = true; - } - } - if ( changed ) { - this.emit( 'press', item ); - } - - return this; -}; - -/** - * Choose an item. - * - * Note that ‘choose’ should never be modified programmatically. A user can choose - * an option with the keyboard or mouse and it becomes selected. To select an item programmatically, - * use the #selectItem method. - * - * This method is identical to #selectItem, but may vary in subclasses that take additional action - * when users choose an item with the keyboard or mouse. - * - * @param {OO.ui.OptionWidget} item Item to choose - * @fires choose - * @chainable - */ -OO.ui.SelectWidget.prototype.chooseItem = function ( item ) { - this.selectItem( item ); - this.emit( 'choose', item ); - - return this; -}; - -/** - * Get an option by its position relative to the specified item (or to the start of the option array, - * if item is `null`). The direction in which to search through the option array is specified with a - * number: -1 for reverse (the default) or 1 for forward. The method will return an option, or - * `null` if there are no options in the array. - * - * @param {OO.ui.OptionWidget|null} item Item to describe the start position, or `null` to start at the beginning of the array. - * @param {number} direction Direction to move in: -1 to move backward, 1 to move forward - * @return {OO.ui.OptionWidget|null} Item at position, `null` if there are no items in the select - */ -OO.ui.SelectWidget.prototype.getRelativeSelectableItem = function ( item, direction ) { - var currentIndex, nextIndex, i, - increase = direction > 0 ? 1 : -1, - len = this.items.length; - - if ( item instanceof OO.ui.OptionWidget ) { - currentIndex = $.inArray( item, this.items ); - nextIndex = ( currentIndex + increase + len ) % len; - } else { - // If no item is selected and moving forward, start at the beginning. - // If moving backward, start at the end. - nextIndex = direction > 0 ? 0 : len - 1; - } - - for ( i = 0; i < len; i++ ) { - item = this.items[ nextIndex ]; - if ( item instanceof OO.ui.OptionWidget && item.isSelectable() ) { - return item; - } - nextIndex = ( nextIndex + increase + len ) % len; - } - return null; -}; - -/** - * Get the next selectable item or `null` if there are no selectable items. - * Disabled options and menu-section markers and breaks are not selectable. - * - * @return {OO.ui.OptionWidget|null} Item, `null` if there aren't any selectable items - */ -OO.ui.SelectWidget.prototype.getFirstSelectableItem = function () { - var i, len, item; - - for ( i = 0, len = this.items.length; i < len; i++ ) { - item = this.items[ i ]; - if ( item instanceof OO.ui.OptionWidget && item.isSelectable() ) { - return item; - } - } - - return null; -}; - -/** - * Add an array of options to the select. Optionally, an index number can be used to - * specify an insertion point. - * - * @param {OO.ui.OptionWidget[]} items Items to add - * @param {number} [index] Index to insert items after - * @fires add - * @chainable - */ -OO.ui.SelectWidget.prototype.addItems = function ( items, index ) { - // Mixin method - OO.ui.GroupWidget.prototype.addItems.call( this, items, index ); - - // Always provide an index, even if it was omitted - this.emit( 'add', items, index === undefined ? this.items.length - items.length - 1 : index ); - - return this; -}; - -/** - * Remove the specified array of options from the select. Options will be detached - * from the DOM, not removed, so they can be reused later. To remove all options from - * the select, you may wish to use the #clearItems method instead. - * - * @param {OO.ui.OptionWidget[]} items Items to remove - * @fires remove - * @chainable - */ -OO.ui.SelectWidget.prototype.removeItems = function ( items ) { - var i, len, item; - - // Deselect items being removed - for ( i = 0, len = items.length; i < len; i++ ) { - item = items[ i ]; - if ( item.isSelected() ) { - this.selectItem( null ); - } - } - - // Mixin method - OO.ui.GroupWidget.prototype.removeItems.call( this, items ); - - this.emit( 'remove', items ); - - return this; -}; - -/** - * Clear all options from the select. Options will be detached from the DOM, not removed, - * so that they can be reused later. To remove a subset of options from the select, use - * the #removeItems method. - * - * @fires remove - * @chainable - */ -OO.ui.SelectWidget.prototype.clearItems = function () { - var items = this.items.slice(); - - // Mixin method - OO.ui.GroupWidget.prototype.clearItems.call( this ); - - // Clear selection - this.selectItem( null ); - - this.emit( 'remove', items ); - - return this; -}; |