mediawiki-extensions-Echo/modules/ooui/mw.echo.ui.NotificationOptionWidget.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

137 lines
3.6 KiB
JavaScript

( function ( mw, $ ) {
/**
* Notification option widget for echo popup.
*
* @class
* @extends OO.ui.OptionWidget
*
* @constructor
* @param {Object} [config] Configuration object
* @cfg {boolean} [markReadWhenSeen=false] This option is marked as read when it is viewed
*/
mw.echo.ui.NotificationOptionWidget = function MwEchoUiNotificationOptionWidget( model, config ) {
config = config || {};
this.model = model;
// Parent constructor
mw.echo.ui.NotificationOptionWidget.parent.call( this, $.extend( { data: this.model.getId() }, config ) );
this.markAsReadButton = new OO.ui.ButtonWidget( {
icon: 'close',
framed: false,
classes: [ 'mw-echo-ui-notificationOptionWidget-markAsReadButton' ]
} );
this.setLabel( this.model.getContent() );
this.toggleRead( this.model.isRead() );
this.toggleSeen( this.model.isSeen() );
this.markReadWhenSeen = !!config.markReadWhenSeen;
// Events
this.markAsReadButton.connect( this, { click: 'onMarkAsReadButtonClick' } );
this.model.connect( this, {
seen: 'toggleSeen',
read: 'toggleRead'
} );
this.$element
.addClass( 'mw-echo-ui-notificationOptionWidget' )
.append(
// HACK: Wrap the entire option with a link that takes
// the user to the primary url. This is not perfect,
// but it makes the behavior native to the browser rather
// than us listening to click events and opening new
// windows.
$( '<a>' )
.addClass( 'mw-echo-ui-notificationOptionWidget-linkWrapper' )
.attr( 'href', this.model.getPrimaryUrl() )
.append(
this.markAsReadButton.$element,
this.$label
)
);
this.$element.toggleClass( 'mw-echo-ui-notificationOptionWidget-initiallyUnseen', !this.model.isSeen() );
if ( this.markReadWhenSeen ) {
this.$element.addClass( 'mw-echo-ui-notificationOptionWidget-markReadWhenSeen' );
}
};
/* Initialization */
OO.inheritClass( mw.echo.ui.NotificationOptionWidget, OO.ui.OptionWidget );
/* Events */
/**
* @event markAsRead
*
* Mark this notification as read
*/
/* Methods */
/**
* Respond to mark as read button click
*/
mw.echo.ui.NotificationOptionWidget.prototype.onMarkAsReadButtonClick = function () {
this.model.toggleRead( true );
};
/**
* Toggle the read state of the widget
*
* @param {boolean} [read] The current read state. If not given, the state will
* become the opposite of its current state.
*/
mw.echo.ui.NotificationOptionWidget.prototype.toggleRead = function ( read ) {
this.read = read !== undefined ? read : !this.read;
this.$element.toggleClass( 'mw-echo-ui-notificationOptionWidget-unread', !this.read );
this.markAsReadButton.toggle( !this.read );
};
/**
* Toggle the seen state of the widget
*
* @param {boolean} [seen] The current seen state. If not given, the state will
* become the opposite of its current state.
*/
mw.echo.ui.NotificationOptionWidget.prototype.toggleSeen = function ( seen ) {
this.seen = seen !== undefined ? seen : !this.seen;
this.$element
.toggleClass( 'mw-echo-ui-notificationOptionWidget-unseen', !this.seen );
};
/**
* Get the notification link
*
* @return {string} Notification link
*/
mw.echo.ui.NotificationOptionWidget.prototype.getModel = function () {
return this.model;
};
/**
* Get the notification link
*
* @return {string} Notification link
*/
mw.echo.ui.NotificationOptionWidget.prototype.getPrimaryUrl = function () {
return this.model.getPrimaryUrl();
};
/**
* Disconnect events when widget is destroyed.
*/
mw.echo.ui.NotificationOptionWidget.prototype.destroy = function () {
this.model.disconnect( this );
};
} )( mediaWiki, jQuery );