mediawiki-extensions-Visual.../modules/oojs-ui/widgets/OO.ui.MenuWidget.js
Trevor Parscal db9f941fa6 Rename this.$ to this.$element, and this.$$ to this.$
Objectives:
* Rename this.$ to this.$element
* Rename this.$$ to this.$
* Get rid of the need to use this.frame.$$
* Rename OO.ui.Element.get$$ to OO.ui.Element.getJQuery

Changes: (using Sublime Text regex patterns)
* Replace "get$$" with "getJQuery"
* Replace "\.(\$)([^\$a-zA-Z])" with ".$element$2"
* Replace "\.(\$\$)" with ".$"
* Replace "'$$'" with "'$'"
* Set this.$ to null in constructor of OO.ui.Window
* Set this.$ to this.frame.$ in initialize method of OO.ui.Window
* Replace "\.(frame.\$)([^\$a-zA-Z])" with ".\$$2"

Bonus:
* Use this.$() in a bunch of places where $() was erroneously used

Change-Id: If3d870124ab8d10f8223532cda95c2b2b075db94
2013-11-03 23:03:49 -08:00

245 lines
5 KiB
JavaScript

/*!
* ObjectOriented UserInterface MenuWidget class.
*
* @copyright 2011-2013 OOJS Team and others; see AUTHORS.txt
* @license The MIT License (MIT); see LICENSE.txt
*/
/**
* Create an OO.ui.MenuWidget object.
*
* @class
* @extends OO.ui.SelectWidget
* @mixins OO.ui.ClippableElement
*
* @constructor
* @param {Object} [config] Configuration options
* @cfg {OO.ui.InputWidget} [input] Input to bind keyboard handlers to
*/
OO.ui.MenuWidget = function OoUiMenuWidget( config ) {
// Config intialization
config = config || {};
// Parent constructor
OO.ui.SelectWidget.call( this, config );
// Mixin constructor
OO.ui.ClippableElement.call( this, this.$group );
// Properties
this.newItems = [];
this.$input = config.input ? config.input.$input : null;
this.$previousFocus = null;
this.isolated = !config.input;
this.visible = false;
this.onKeyDownHandler = OO.ui.bind( this.onKeyDown, this );
// Initialization
this.$element.hide().addClass( 'oo-ui-menuWidget' );
};
/* Inheritance */
OO.inheritClass( OO.ui.MenuWidget, OO.ui.SelectWidget );
OO.mixinClass( OO.ui.MenuWidget, OO.ui.ClippableElement );
/* Methods */
/**
* Handles key down events.
*
* @method
* @param {jQuery.Event} e Key down event
*/
OO.ui.MenuWidget.prototype.onKeyDown = function ( e ) {
var nextItem,
handled = false,
highlightItem = this.getHighlightedItem();
if ( !this.disabled && this.visible ) {
if ( !highlightItem ) {
highlightItem = this.getSelectedItem();
}
switch ( e.keyCode ) {
case OO.ui.Keys.ENTER:
this.selectItem( highlightItem );
handled = true;
break;
case OO.ui.Keys.UP:
nextItem = this.getRelativeSelectableItem( highlightItem, -1 );
handled = true;
break;
case OO.ui.Keys.DOWN:
nextItem = this.getRelativeSelectableItem( highlightItem, 1 );
handled = true;
break;
case OO.ui.Keys.ESCAPE:
if ( highlightItem ) {
highlightItem.setHighlighted( false );
}
this.hide();
handled = true;
break;
}
if ( nextItem ) {
this.highlightItem( nextItem );
nextItem.scrollElementIntoView();
}
if ( handled ) {
e.preventDefault();
e.stopPropagation();
return false;
}
}
};
/**
* Check if the menu is visible.
*
* @method
* @returns {boolean} Menu is visible
*/
OO.ui.MenuWidget.prototype.isVisible = function () {
return this.visible;
};
/**
* Bind key down listener
*
* @method
*/
OO.ui.MenuWidget.prototype.bindKeyDownListener = function () {
if ( this.$input ) {
this.$input.on( 'keydown', this.onKeyDownHandler );
} else {
// Capture menu navigation keys
this.getElementWindow().addEventListener( 'keydown', this.onKeyDownHandler, true );
}
};
/**
* Unbind key down listener
*
* @method
*/
OO.ui.MenuWidget.prototype.unbindKeyDownListener = function () {
if ( this.$input ) {
this.$input.off( 'keydown' );
} else {
this.getElementWindow().removeEventListener( 'keydown', this.onKeyDownHandler, true );
}
};
/**
* Select an item.
*
* The menu will stay open if an item is silently selected.
*
* @method
* @param {OO.ui.OptionWidget} [item] Item to select, omit to deselect all
* @chainable
*/
OO.ui.MenuWidget.prototype.selectItem = function ( item ) {
// Parent method
OO.ui.SelectWidget.prototype.selectItem.call( this, item );
if ( !this.disabled ) {
if ( item ) {
this.disabled = true;
item.flash( OO.ui.bind( function () {
this.hide();
this.disabled = false;
}, this ) );
} else {
this.hide();
}
}
return this;
};
/**
* Add items.
*
* Adding an existing item (by value) will move it.
*
* @method
* @param {OO.ui.MenuItemWidget[]} items Items to add
* @param {number} [index] Index to insert items after
* @chainable
*/
OO.ui.MenuWidget.prototype.addItems = function ( items, index ) {
var i, len, item;
// Parent method
OO.ui.SelectWidget.prototype.addItems.call( this, items, index );
for ( i = 0, len = items.length; i < len; i++ ) {
item = items[i];
if ( this.visible ) {
// Defer fitting label until
item.fitLabel();
} else {
this.newItems.push( item );
}
}
return this;
};
/**
* Show the menu.
*
* @method
* @chainable
*/
OO.ui.MenuWidget.prototype.show = function () {
var i, len;
if ( this.items.length ) {
this.$element.show();
this.visible = true;
this.bindKeyDownListener();
// Change focus to enable keyboard navigation
if ( this.isolated && this.$input && !this.$input.is( ':focus' ) ) {
this.$previousFocus = this.$( ':focus' );
this.$input.focus();
}
if ( this.newItems.length ) {
for ( i = 0, len = this.newItems.length; i < len; i++ ) {
this.newItems[i].fitLabel();
}
this.newItems = [];
}
this.setClipping( true );
}
return this;
};
/**
* Hide the menu.
*
* @method
* @chainable
*/
OO.ui.MenuWidget.prototype.hide = function () {
this.$element.hide();
this.visible = false;
this.unbindKeyDownListener();
if ( this.isolated && this.$previousFocus ) {
this.$previousFocus.focus();
this.$previousFocus = null;
}
this.setClipping( false );
return this;
};