mediawiki-extensions-Echo/modules/ui/mw.echo.ui.MenuItemWidget.js
Bartosz Dziewoński 54c27e5763 Fix notification dynamic actions outside of the dropdown
* Event handler was not registered for the non-dropdown version
* Clicks would be handled by both the action and by the default link

Also remove returning false to prevent default and stop propagation,
this is not supported by OOUI events and did nothing. Handling a
'click' event always returns false to jQuery (so this was not needed),
handling 'choose' event never does (hence my other fix was needed).

Change-Id: Ia8a21749a8edc20f34b2a3e445278ea6922b9109
2022-08-24 00:28:54 +02:00

143 lines
4.5 KiB
JavaScript

( function () {
/**
* Secondary menu item
*
* @class
* @extends OO.ui.ButtonOptionWidget
* @mixins OO.ui.mixin.PendingElement
*
* @constructor
* @param {Object} [config] Configuration object
* @cfg {string} [type] Optional action type. Used to note a dynamic action, by setting it to 'dynamic-action'
* @cfg {string} [url] Item URL for links
* @cfg {string} [tooltip] Tooltip for links
* @cfg {string} [description] An optional description for the item
* @cfg {Object} [actionData] Action data
* @cfg {boolean} [prioritized] The item is prioritized outside the
* popup menu.
*/
mw.echo.ui.MenuItemWidget = function MwEchoUiMenuItemWidget( config ) {
config = config || {};
this.dynamic = config.type === 'dynamic-action';
// Needs to be set before parent constructor is called
// as it changes the value of getTagName.
this.isLink = config.url && !this.isDynamicAction();
// Parent constructor
mw.echo.ui.MenuItemWidget.super.call( this, $.extend( { framed: false }, config ) );
// Mixin constructors
OO.ui.mixin.PendingElement.call( this, config );
this.prioritized = !!config.prioritized;
this.messages = this.isDynamicAction() ?
config.actionData.messages :
{};
this.actionData = config.actionData || {};
// Optional description
this.descriptionLabel = new OO.ui.LabelWidget( {
classes: [ 'mw-echo-ui-menuItemWidget-description' ],
label: config.description || ''
} );
this.descriptionLabel.toggle( !this.prioritized && config.description );
this.$label.append( this.descriptionLabel.$element );
// Build the option
this.$element
.addClass( 'mw-echo-ui-menuItemWidget' )
.toggleClass( 'mw-echo-ui-menuItemWidget-prioritized', this.prioritized )
.toggleClass( 'mw-echo-ui-menuItemWidget-dynamic-action', this.isDynamicAction() );
if ( this.isLink ) {
this.$element.attr( {
href: config.url,
title: config.tooltip
} );
}
};
/* Initialization */
OO.inheritClass( mw.echo.ui.MenuItemWidget, OO.ui.ButtonOptionWidget );
OO.mixinClass( mw.echo.ui.MenuItemWidget, OO.ui.mixin.PendingElement );
/* Static Properties */
mw.echo.ui.MenuItemWidget.static.highlightable = false;
mw.echo.ui.MenuItemWidget.static.pressable = false;
/* Methods */
mw.echo.ui.MenuItemWidget.prototype.getTagName = function () {
return this.isLink ? 'a' : 'div';
};
mw.echo.ui.MenuItemWidget.prototype.onClick = function ( e ) {
// Stop propagation, so that the default dynamic action of the notification isn't triggered
// (e.g. expanding a bundled notification).
e.stopPropagation();
// If this is a dynamic action, also prevent default to disable the native browser behavior,
// the default link of the notification won't be followed.
// (If this is a link, default link of the notification is ignored as native browser behavior.)
if ( !this.isLink ) {
e.preventDefault();
}
return mw.echo.ui.MenuItemWidget.super.prototype.onClick.apply( this, arguments );
};
mw.echo.ui.MenuItemWidget.prototype.isSelectable = function () {
// If we have a link force selectability to false, otherwise defer to parent method
// Without a link (for dynamic actions or specific internal actions) we need this widget
// to be selectable so it emits the 'choose' event
return !this.isLink && mw.echo.ui.MenuItemWidget.super.prototype.isSelectable.apply( this, arguments );
};
/**
* Check whether this item is prioritized
*
* @return {boolean} Item is prioritized
*/
mw.echo.ui.MenuItemWidget.prototype.isPrioritized = function () {
return this.prioritized;
};
/**
* Get the messages for the confirmation dialog
* We expect optionally two messages - title and description.
*
* NOTE: The messages are parsed as HTML. If user-input is expected
* please make sure to properly escape it.
*
* @return {Object} Messages for the confirmation dialog
* @return {string} return.title Title for the confirmation dialog
* @return {string} return.description Description for the confirmation dialog
*/
mw.echo.ui.MenuItemWidget.prototype.getConfirmationMessages = function () {
return this.messages.confirmation;
};
/**
* Get the action data associated with this item
*
* @return {Object} Action data
*/
mw.echo.ui.MenuItemWidget.prototype.getActionData = function () {
return this.actionData;
};
/**
* This item is a dynamic action
*
* @return {boolean} Item is a dynamic action
*/
mw.echo.ui.MenuItemWidget.prototype.isDynamicAction = function () {
return this.dynamic;
};
}() );