From bee8aaa4995f678b82437dffb3c13041c84e1041 Mon Sep 17 00:00:00 2001 From: Moriel Schottlender Date: Tue, 7 Mar 2017 14:35:42 -0800 Subject: [PATCH] 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 --- .../ui/mw.echo.ui.NotificationBadgeWidget.js | 13 ++++++++++++- .../ui/mw.echo.ui.NotificationsListWidget.js | 17 +++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/modules/ui/mw.echo.ui.NotificationBadgeWidget.js b/modules/ui/mw.echo.ui.NotificationBadgeWidget.js index 788f70541..25170f4a8 100644 --- a/modules/ui/mw.echo.ui.NotificationBadgeWidget.js +++ b/modules/ui/mw.echo.ui.NotificationBadgeWidget.js @@ -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; diff --git a/modules/ui/mw.echo.ui.NotificationsListWidget.js b/modules/ui/mw.echo.ui.NotificationsListWidget.js index 6365fbce5..14348d5fb 100644 --- a/modules/ui/mw.echo.ui.NotificationsListWidget.js +++ b/modules/ui/mw.echo.ui.NotificationsListWidget.js @@ -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' ); }; /**