mediawiki-extensions-Echo/modules/ooui/mw.echo.ui.NotificationsWidget.js
Moriel Schottlender bfd27ae712 Wrap notifications with a link for native click behavior
Remove the behavior of the SelectWidget 'choose' and instead wrap
the notifications with their primary url links. That way, the click
handler returns to browser native response, and we gain automatic
behavior for ctrl+click, middle click, and regular click.

CSS had to be adjusted as well.

Bug: T112004
Change-Id: If10a4d3be71a8cf3ce966f15b922da0b9a2ddcc7
2015-09-11 09:48:00 -07:00

129 lines
3.3 KiB
JavaScript

( function ( mw, $ ) {
/**
* Notification widget for echo popup.
*
* @class
* @extends OO.ui.Widget
*
* @constructor
* @param {mw.echo.dm.NotificationsModel} model Notifications view model
* @param {Object} [config] Configuration object
* @cfg {boolean} [markReadWhenSeen=false] State whether the notifications are all
* marked as read when they are seen.
*/
mw.echo.ui.NotificationsWidget = function MwEchoUiNotificationsWidget( model, config ) {
config = config || {};
this.model = model;
this.markReadWhenSeen = !!config.markReadWhenSeen;
// Parent constructor
mw.echo.ui.NotificationsWidget.parent.call( this, config );
// Dummy 'loading' option widget
this.loadingOptionWidget = new OO.ui.OptionWidget( {
data: null,
classes: [ 'mw-echo-ui-notificationsWidget-loadingOption' ]
} );
this.addItems( [ this.loadingOptionWidget ] );
// Events
this.model.connect( this, {
add: 'onModelNotificationAdd',
remove: 'onModelNotificationRemove',
clear: 'onModelNotificationClear'
} );
this.$element
.addClass( 'mw-echo-ui-notificationsWidget' );
};
/* Initialization */
OO.inheritClass( mw.echo.ui.NotificationsWidget, OO.ui.SelectWidget );
/* Methods */
/**
* Respond to model add event
*
* @param {mw.echo.dm.NotificationItem[]} Added notification items
*/
mw.echo.ui.NotificationsWidget.prototype.onModelNotificationAdd = function ( notificationItems, index ) {
var i, len, widget,
$elements = $(),
optionWidgets = [];
for ( i = 0, len = notificationItems.length; i < len; i++ ) {
widget = new mw.echo.ui.NotificationOptionWidget(
notificationItems[i],
{
markReadWhenSeen: this.markReadWhenSeen
}
);
optionWidgets.push( widget );
// Collect the elements for the hook firing
$elements = $elements.add( widget.$element );
}
// Fire hook for gadgets to update the option list
mw.hook( 'ext.echo.overlay.beforeShowingOverlay' ).fire( $elements );
// Remove dummy option
this.removeItems( [ this.loadingOptionWidget ] );
this.addItems( optionWidgets, index );
};
/**
* Respond to model add event
*
* @param {mw.echo.dm.NotificationItem[]} Removed notification items
*/
mw.echo.ui.NotificationsWidget.prototype.onModelNotificationClear = function () {
var i, len,
items = this.getItems();
// Destroy all the widgets and their events
for ( i = 0, len = items.length; i < len; i++ ) {
if ( typeof items[i].destroy === 'function' ) {
// Destroy if destroyable
items[i].destroy();
}
}
this.clearItems();
// Add dummy option
this.addItems( [ this.loadingOptionWidget ] );
};
/**
* Respond to model add event
*
* @param {mw.echo.dm.NotificationItem[]} Removed notification items
*/
mw.echo.ui.NotificationsWidget.prototype.onModelNotificationRemove = function ( notificationItems ) {
var i, len, widget, items,
removalWidgets = [];
for ( i = 0, len = notificationItems.length; i < len; i++ ) {
widget = this.getItemById( notificationItems[i].getId() );
if ( widget && typeof widget.destroy === 'function' ) {
// Destroy all widgets that can be destroyed
widget.destroy();
}
removalWidgets.push( widget );
}
this.removeItems( removalWidgets );
items = this.getItems();
if ( !items.length ) {
// Add dummy option
this.addItems( [ this.loadingOptionWidget ] );
}
};
} )( mediaWiki, jQuery );