( function () { /** * Action menu popup widget for echo items. * * We don't currently have anything that properly answers the complete * design for our popup menus in OOUI, so this widget serves two purposes: * 1. The MenuSelectWidget is intended to deliver a menu that relates * directly to its anchor, so its sizing is dictated by whatever anchors * it. This is not what we require, so we have to override the 'click' event * to reset the width of the menu. * 2. It abstracts the behavior of the item menus for easier management * in the item widget itself (which is fairly large) * * @class * @extends OO.ui.ButtonWidget * * @constructor * @param {Object} [config] Configuration object * @param {jQuery} [config.$overlay] A jQuery element functioning as an overlay * for popups. * @param {Object} [config.horizontalPosition='auto'] How to position the menu, see OO.ui.FloatableElement. * By default, 'start' will be tried first, and if that doesn't fit, 'end' will be used. */ mw.echo.ui.ActionMenuPopupWidget = function MwEchoUiActionMenuPopupWidget( config ) { config = config || {}; // Parent constructor mw.echo.ui.ActionMenuPopupWidget.super.call( this, config ); this.$overlay = config.$overlay || this.$element; // Menu this.customMenuPosition = ( config.horizontalPosition || 'auto' ) !== 'auto'; this.menu = new OO.ui.MenuSelectWidget( { $floatableContainer: this.$element, horizontalPosition: this.customMenuPosition ? config.horizontalPosition : 'start', classes: [ 'mw-echo-ui-actionMenuPopupWidget-menu' ], widget: this } ); this.$overlay.append( this.menu.$element ); // Events this.connect( this, { click: 'onAction' } ); this.getMenu().connect( this, { remove: 'decideToggle', add: 'decideToggle', clear: 'decideToggle' } ); // Initialization this.$element .addClass( 'mw-echo-ui-actionMenuPopupWidget' ); }; /* Setup */ OO.inheritClass( mw.echo.ui.ActionMenuPopupWidget, OO.ui.ButtonWidget ); /** * Handle the button action being triggered. * * @private */ mw.echo.ui.ActionMenuPopupWidget.prototype.onAction = function () { // HACK: If config.horizontalPosition isn't set, first try 'start', then 'end' if ( !this.customMenuPosition ) { this.menu.setHorizontalPosition( 'start' ); } this.menu.toggle(); if ( !this.customMenuPosition && this.menu.isClipped() ) { this.menu.setHorizontalPosition( 'end' ); } }; /** * Decide whether the menu should be visible, based on whether it is * empty or not. */ mw.echo.ui.ActionMenuPopupWidget.prototype.decideToggle = function () { this.toggle( !this.getMenu().isEmpty() ); }; /** * Get the widget's action menu * * @return {OO.ui.MenuSelectWidget} Menu */ mw.echo.ui.ActionMenuPopupWidget.prototype.getMenu = function () { return this.menu; }; }() );