Merge "(re)Add JavaScript hooks to Notifications"

This commit is contained in:
jenkins-bot 2016-10-14 22:36:37 +00:00 committed by Gerrit Code Review
commit 84ad297d8e
6 changed files with 75 additions and 24 deletions

View file

@ -2,6 +2,25 @@ hooks.txt
This documents Echo's client-side hooks:
'ext.echo.overlay.beforeShowingOverlay': Before showing the Echo overlay, it is
passed to this hook, which can modify the DOM or take other actions.
$overlay: the jQuery-wrapped element for the overlay
'ext.echo.notifications.beforeRender': Before notification widgets are rendered
the wrapper of the notifications and the individual notification jQuery elements
are passed to this hook, which can modify the DOM or take other actions.
* $wrapper: The jQuery object that is the wrapper for the notification items
* $elements: A jQuery group of all notification elements that are about to be rendered.
'ext.echo.badge.countChange': When the count changes in the Notifications popup
badge, this hook is fired with the new count.
* type: Notifications type that the badge represents. Can be 'message', 'alert' or 'all'
* count: The new numerical count in the notifications popup.
* label: The label for this number, for presentation purposes.
'ext.echo.popup.onInitialize': Fired when the popup is opened and after notifications
were fetched from the API.
* types: Notifications type that the badge represents. Can be 'message', 'alert' or 'all'
* controller: The instance of the controller responsible for the specific popup operations
'ext.echo.special.onInitialize': Fired when the special page is initialized. Note that this
is also fired whenever the special page notification display is changed, like when clicking
a filter, changing pagination, or viewing notifications for a remote wiki or page.
* types: Notifications type that the badge represents. Can be 'message', 'alert' or 'all'
* controller: The instance of the controller responsible for the specific popup operations

View file

@ -7,6 +7,8 @@
*
* @constructor
* @param {Object} [config] Configuration object
* @cfg {string} [type] The notification types this button represents;
* 'message', 'alert' or 'all'
* @cfg {string} [href] URL the badge links to
*/
mw.echo.ui.BadgeLinkWidget = function MwEchoUiBadgeLinkWidget( config ) {
@ -24,6 +26,8 @@
this.$element
.addClass( 'mw-echo-notifications-badge' );
this.count = 0;
this.type = config.type || 'alert';
this.setCount( config.numItems, config.label );
if ( config.href !== undefined && OO.ui.isSafeUrl( config.href ) ) {
@ -48,6 +52,13 @@
mw.echo.ui.BadgeLinkWidget.prototype.setCount = function ( numItems, label ) {
label = label || numItems;
if ( this.count !== numItems ) {
this.count = numItems;
// Fire badge count change hook
mw.hook( 'ext.echo.badge.countChange' ).fire( this.type, this.count, label );
}
this.$element
.toggleClass( 'mw-echo-notifications-badge-all-read', !numItems )
.attr( 'data-counter-num', numItems )

View file

@ -61,6 +61,7 @@
this.badgeButton = new mw.echo.ui.BadgeLinkWidget( {
label: this.badgeLabel,
type: this.manager.getTypeString(),
numItems: this.numItems,
flags: buttonFlags,
// The following messages can be used here:
@ -334,6 +335,9 @@
// Success
function () {
if ( widget.popup.isVisible() ) {
// Fire initialization hook
mw.hook( 'ext.echo.popup.onInitialize' ).fire( widget.manager.getTypeString(), widget.controller );
widget.popup.clip();
// Update seen time
return widget.controller.updateSeenTime();

View file

@ -239,6 +239,9 @@
.then(
// Success
function () {
// Fire initialization hook
mw.hook( 'ext.echo.special.onInitialize' ).fire( widget.controller.manager.getTypeString(), widget.controller );
widget.popPending();
// Update seen time
widget.controller.updateSeenTime();

View file

@ -1,4 +1,4 @@
( function ( mw ) {
( function ( mw, $ ) {
/**
* Notifications list widget.
* All of its items must be of the mw.echo.ui.NotificationItem type.
@ -101,8 +101,9 @@
* list.
*/
mw.echo.ui.NotificationsListWidget.prototype.resetDataFromModel = function ( models ) {
var i, modelId, model, subItems, subItem,
itemWidgets = [];
var i, modelId, model, subItems, subItem, widget,
itemWidgets = [],
$elements = $();
// Detach all attached models
for ( modelId in this.models ) {
@ -118,17 +119,17 @@
if ( model.isGroup() ) {
if ( model.isForeign() ) {
// One Widget to Rule Them All
itemWidgets.push( new mw.echo.ui.CrossWikiNotificationItemWidget(
widget = new mw.echo.ui.CrossWikiNotificationItemWidget(
this.controller,
model,
{
$overlay: this.$overlay,
animateSorting: this.animated
}
) );
);
} else {
// local bundle
itemWidgets.push( new mw.echo.ui.BundleNotificationItemWidget(
widget = new mw.echo.ui.BundleNotificationItemWidget(
this.controller,
model,
{
@ -136,27 +137,35 @@
bundle: false,
animateSorting: this.animated
}
) );
);
}
itemWidgets.push( widget );
$elements = $elements.add( widget.$element );
} else {
subItems = model.getItems();
// Separate widgets per item
for ( i = 0; i < subItems.length; i++ ) {
subItem = subItems[ i ];
itemWidgets.push( new mw.echo.ui.SingleNotificationItemWidget(
widget = new mw.echo.ui.SingleNotificationItemWidget(
this.controller,
subItem,
{
$overlay: this.$overlay,
bundle: false
}
) );
);
itemWidgets.push( widget );
$elements = $elements.add( widget.$element );
}
}
}
// Reset the current items and re-add the new item widgets
this.clearItems();
// fire render hook
mw.hook( 'ext.echo.notifications.beforeRender' ).fire( this.$element, $elements );
this.addItems( itemWidgets );
this.checkForEmptyNotificationsList();
@ -215,4 +224,4 @@
itemWidgets[ i ].resetInitiallyUnseen();
}
};
} )( mediaWiki );
} )( mediaWiki, jQuery );

View file

@ -152,26 +152,31 @@
* If this is empty, the widget will request all the items from the model.
*/
mw.echo.ui.SubGroupListWidget.prototype.resetItemsFromModel = function ( items ) {
var i,
itemWidgets = [];
var i, widget,
itemWidgets = [],
$elements = $();
items = items || this.model.getItems();
for ( i = 0; i < items.length; i++ ) {
itemWidgets.push(
new mw.echo.ui.SingleNotificationItemWidget(
this.controller,
items[ i ],
{
$overlay: this.$overlay,
bundle: items[ i ].isBundled()
}
)
widget = new mw.echo.ui.SingleNotificationItemWidget(
this.controller,
items[ i ],
{
$overlay: this.$overlay,
bundle: items[ i ].isBundled()
}
);
itemWidgets.push( widget );
$elements = $elements.add( widget.$element );
}
// Clear the current items if any exist
this.getListWidget().clearItems();
// fire render hook
mw.hook( 'ext.echo.notifications.beforeRender' ).fire( this.$element, $elements );
// Add the new items
this.getListWidget().addItems( itemWidgets );
};