Add and listen to 'modified' event for popup clip()

Separate the behavior of promise vs event when changes happen and
we need to clip the popup. The popup should only clip itself after
the DOM has finished populating, not "just" after the model has
been populated with data.

Adding an event that triggers whenever the main list changes anything
that is in its DOM, and having the badge widget trigger a popup clip
will solve this issue and untangle the expectation of the promises
vs. the widgets populating themselves through the events.

Change-Id: Iff9996eb1810e7ade135359139e16837e6dc74f0
This commit is contained in:
Moriel Schottlender 2017-03-07 14:35:42 -08:00
parent 1928a7bc9a
commit bee8aaa499
2 changed files with 29 additions and 1 deletions

View file

@ -176,6 +176,7 @@
this.badgeButton.connect( this, {
click: 'onBadgeButtonClick'
} );
this.notificationsWidget.connect( this, { modified: 'onNotificationsListModified' } );
this.$element
.prop( 'id', 'pt-notifications-' + adjustedTypeString )
@ -215,6 +216,16 @@
/* Methods */
/**
* Respond to list widget modified event.
*
* This means the list's actual DOM was modified and we should make sure
* that the popup resizes itself.
*/
mw.echo.ui.NotificationBadgeWidget.prototype.onNotificationsListModified = function () {
this.popup.clip();
};
mw.echo.ui.NotificationBadgeWidget.prototype.onFooterNoticeDismiss = function () {
// Clip again to recalculate height
this.popup.clip();
@ -339,7 +350,6 @@
// 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();
}
@ -357,6 +367,7 @@
)
.then( this.emit.bind( this, 'finishLoading' ) )
.always( function () {
widget.popup.clip();
// Pop pending
widget.popPending();
widget.promiseRunning = false;

View file

@ -71,6 +71,16 @@
OO.inheritClass( mw.echo.ui.NotificationsListWidget, mw.echo.ui.SortedListWidget );
/* Events */
/**
* @event modified
*
* The content of this list has changed.
* This event is to state that not only has the content changed
* but the actual DOM has been manipulated.
*/
/* Methods */
mw.echo.ui.NotificationsListWidget.prototype.onModelManagerDiscard = function ( modelName ) {
@ -90,6 +100,8 @@
}
}
}
this.emit( 'modified' );
};
/**
@ -99,6 +111,7 @@
*
* @param {Object} models Object of new models to populate the
* list.
* @fires modified
*/
mw.echo.ui.NotificationsListWidget.prototype.resetDataFromModel = function ( models ) {
var i, modelId, model, subItems, subItem, widget,
@ -169,6 +182,8 @@
this.addItems( itemWidgets );
this.checkForEmptyNotificationsList();
this.emit( 'modified' );
};
/**
@ -196,6 +211,7 @@
*
* @param {string} [label] Label for the option widget
* @param {string} [link] Link for the option widget
* @fires modified
*/
mw.echo.ui.NotificationsListWidget.prototype.resetLoadingOption = function ( label, link ) {
this.loadingOptionWidget.setLabel( label || '' );
@ -203,6 +219,7 @@
if ( this.isEmpty() ) {
this.addItems( [ this.loadingOptionWidget ] );
}
this.emit( 'modified' );
};
/**