ReplyWidget: Avoid buttons shifting when switching to source

When the preview loads, the "Reply" / "Cancel" buttons shift downwards,
which looks ugly. Try to wait for the preview before showing the source
editor interface.

Bug: T234403
Change-Id: I70989fb9fbcac17e1a0672eda8d34bf26003bb96
This commit is contained in:
Bartosz Dziewoński 2020-05-21 23:11:01 +02:00
parent 54db24f1f5
commit fbd6338331
2 changed files with 36 additions and 13 deletions

View file

@ -398,6 +398,7 @@ CommentController.prototype.switchToWikitext = function () {
oldWidget = this.replyWidget,
pageData = oldWidget.parsoidData.pageData,
target = oldWidget.replyBodyWidget.target,
previewDeferred = $.Deferred(),
commentController = this;
wikitextPromise = target.getWikitextFragment(
@ -411,14 +412,23 @@ CommentController.prototype.switchToWikitext = function () {
this.replyWidgetPromise = this.createReplyWidget( oldWidget.parsoidData, false );
return $.when( wikitextPromise, this.replyWidgetPromise ).then( function ( wikitext, replyWidget ) {
// Swap out the DOM nodes
oldWidget.$element.replaceWith( replyWidget.$element );
wikitext = controller.sanitizeWikitextLinebreaks( wikitext );
// Teardown the old widget
oldWidget.disconnect( commentController );
oldWidget.teardown();
// To prevent the "Reply" / "Cancel" buttons from shifting when the preview loads,
// wait for the preview (but no longer than 500 ms) before swithing the editors.
replyWidget.preparePreview( wikitext ).then( previewDeferred.resolve );
setTimeout( previewDeferred.resolve, 500 );
commentController.setupReplyWidget( replyWidget, controller.sanitizeWikitextLinebreaks( wikitext ) );
return previewDeferred.then( function () {
// Swap out the DOM nodes
oldWidget.$element.replaceWith( replyWidget.$element );
// Teardown the old widget
oldWidget.disconnect( commentController );
oldWidget.teardown();
commentController.setupReplyWidget( replyWidget, wikitext );
} );
} );
};

View file

@ -320,7 +320,19 @@ ReplyWidget.prototype.onKeyDown = function ( e ) {
};
ReplyWidget.prototype.onInputChange = function () {
var wikitext, parsePromise,
this.updateButtons();
this.storage.set( this.storagePrefix + '/saveable', this.isEmpty() ? '' : '1' );
this.preparePreview( this.getValue() );
};
/**
* Update the interface with the preview of the given wikitext.
*
* @param {string} wikitext
* @return {jQuery.Promise} Promise resolved when we're done
*/
ReplyWidget.prototype.preparePreview = function ( wikitext ) {
var parsePromise,
widget = this,
indent = {
dl: ':',
@ -328,19 +340,20 @@ ReplyWidget.prototype.onInputChange = function () {
ol: '#'
}[ this.context ];
this.updateButtons();
this.storage.set( this.storagePrefix + '/saveable', this.isEmpty() ? '' : '1' );
if ( this.getMode() !== 'source' ) {
return;
return $.Deferred().resolve().promise();
}
if ( this.previewWikitext === wikitext ) {
return $.Deferred().resolve().promise();
}
this.previewWikitext = wikitext;
if ( this.previewRequest ) {
this.previewRequest.abort();
this.previewRequest = null;
}
wikitext = this.getValue();
if ( !wikitext.trim() ) {
parsePromise = $.Deferred().resolve( null ).promise();
} else {
@ -360,7 +373,7 @@ ReplyWidget.prototype.onInputChange = function () {
}
// TODO: Add list context
parsePromise.then( function ( response ) {
return parsePromise.then( function ( response ) {
widget.$preview.html( response ? response.parse.text : '' );
if ( response ) {