jenkins-bot has submitted this change and it was merged. Change subject: Make save dialog ready for async initialization ......................................................................
Make save dialog ready for async initialization initialize() is currently called synchronously, but once the CSS transplantation code is fixed and it goes back to being async, that'll cause problems. * Add this.setupDeferred and use it to defer setupCheckboxes() until after initialization * Move code populating the edit summary from ViewPageTarget into MWSaveDialog and use .setValue() rather than manipulating the TextInputWidget's DOM. Defer this until after init as well * Move clearing of the diff from ViewPageTarget into MWSaveDialog, and don't connect it to the transact event at startup, only when we've actually shown a diff * Remove swapPanel( 'save' ) from ViewPageTarget, instead do this on setup in the dialog itself Bonus: * Document events * Get rid of onFooButtonClick handlers in favor of array syntax Change-Id: Idcdae5e013340f4519db4387bab507e714d47941 --- M modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js M modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js 2 files changed, 86 insertions(+), 62 deletions(-) Approvals: Krinkle: Looks good to me, approved jenkins-bot: Verified diff --git a/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js b/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js index 9e87625..8cc588d 100644 --- a/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js +++ b/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js @@ -565,7 +565,9 @@ ve.init.mw.ViewPageTarget.prototype.onShowChanges = function ( diffHtml ) { ve.track( 'performance.user.reviewComplete', { 'duration': ve.now() - this.timings.saveDialogReview } ); // Invalidate the viewer diff on next change - this.surface.getModel().getDocument().connect( this, { 'transact': 'clearSaveDialogDiff' } ); + this.surface.getModel().getDocument().once( 'transact', + ve.bind( this.saveDialog.clearDiff, this.saveDialog ) + ); this.saveDialog.setDiffAndReview( diffHtml ); }; @@ -578,7 +580,9 @@ ve.init.mw.ViewPageTarget.prototype.onSerialize = function ( wikitext ) { ve.track( 'performance.user.reviewComplete', { 'duration': ve.now() - this.timings.saveDialogReview } ); // Invalidate the viewer wikitext on next change - this.surface.getModel().getDocument().connect( this, { 'transact': 'clearSaveDialogDiff' } ); + this.surface.getModel().getDocument().once( 'transact', + ve.bind( this.saveDialog.clearDiff, this.saveDialog ) + ); this.saveDialog.setDiffAndReview( $( '<pre>' ).text( wikitext ) ); }; @@ -689,22 +693,6 @@ */ ve.init.mw.ViewPageTarget.prototype.onToolbarMetaButtonClick = function () { this.surface.getDialogs().getWindow( 'meta' ).open(); -}; - -/** - * Clear the diff in the save dialog. - * - * This method is bound to the 'transact' event on the document model, and unbinds itself the first - * time it runs. It's bound when the surface is set up and rebound every time a diff is loaded into - * the save dialog. - * - * @method - * @param {ve.dm.Transaction} tx Processed transaction - */ -ve.init.mw.ViewPageTarget.prototype.clearSaveDialogDiff = function () { - // Clear the diff - this.saveDialog.$reviewViewer.empty(); - this.surface.getModel().getDocument().disconnect( this, { 'transact': 'clearSaveDialogDiff' } ); }; /** @@ -967,9 +955,6 @@ // Initialize surface target.surface.getContext().hide(); target.$document = target.surface.$element.find( '.ve-ce-documentNode' ); - target.surface.getModel().getDocument().connect( target, { - 'transact': 'clearSaveDialogDiff' - } ); target.surface.getModel().getDocument().connect( target, { 'transact': 'recordLastTransactionTime' } ); @@ -1239,7 +1224,7 @@ if ( this.section ) { sectionTitle = this.$document.find( 'h1, h2, h3, h4, h5, h6' ).eq( this.section - 1 ).text(); sectionTitle = '/* ' + ve.graphemeSafeSubstring( sectionTitle, 0, 244 ) + ' */ '; - this.saveDialog.editSummaryInput.$input.val( sectionTitle ); + this.saveDialog.setEditSummary( sectionTitle ); this.sectionTitleRestored = true; if ( this.sectionPositionRestored ) { this.onSectionRestored(); @@ -1263,7 +1248,6 @@ */ ve.init.mw.ViewPageTarget.prototype.showSaveDialog = function () { this.saveDialog.setSanityCheck( this.sanityCheckVerified ); - this.saveDialog.swapPanel( 'save' ); this.surface.getDialogs().getWindow( 'mwSave' ).open(); this.timings.saveDialogOpen = ve.now(); ve.track( 'behavior.lastTransactionTillSaveDialogOpen', { diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js index db1a07f..40efb00 100644 --- a/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js +++ b/modules/ve-mw/ui/dialogs/ve.ui.MWSaveDialog.js @@ -10,6 +10,9 @@ /** * Dialog for saving MediaWiki articles. * + * Note that most methods are not safe to call before the dialog has initialized, except where + * noted otherwise. + * * @class * @extends ve.ui.MWDialog * @@ -29,6 +32,7 @@ this.editSummaryByteLimit = 255; this.restoring = false; this.messages = {}; + this.setupDeferred = $.Deferred(); }; /* Inheritance */ @@ -41,26 +45,27 @@ ve.ui.MWSaveDialog.static.titleMessage = 'visualeditor-savedialog-title-save'; -/* Methods */ - -ve.ui.MWSaveDialog.prototype.onSaveButtonClick = function () { - this.emit( 'save' ); -}; - -ve.ui.MWSaveDialog.prototype.onReviewButtonClick = function () { - this.emit( 'review' ); -}; - -ve.ui.MWSaveDialog.prototype.onReviewGoodButtonClick = function () { - this.swapPanel( 'save' ); -}; - -ve.ui.MWSaveDialog.prototype.onResolveConflictButtonClick = function () { - this.emit( 'resolve' ); -}; +/* Events */ /** - * Set review content and show review panel + * @event save + * Emitted when the user clicks the save button + */ + +/** + * @event review + * Emitted when the user clicks the review changes button + */ + +/** + * @event resolve + * Emitted when the user clicks the resolve conflict button + */ + +/* Methods */ + +/** + * Set review content and show review panel. * * @param {string} content Diff HTML or wikitext */ @@ -69,6 +74,13 @@ this.reviewGoodButton.setDisabled( false ); this.$loadingIcon.hide(); this.swapPanel( 'review' ); +}; + +/** + * Clear the diff displayed in the review panel, if any. + */ +ve.ui.MWSaveDialog.prototype.clearDiff = function () { + this.$reviewViewer.empty(); }; /** @@ -224,27 +236,46 @@ }; /** - * Initialize MediaWiki page specific checkboxes + * Initialize MediaWiki page specific checkboxes. + * + * This method is safe to call even when the dialog hasn't been initialized yet. * * @param {string} checkboxes Multiline HTML */ ve.ui.MWSaveDialog.prototype.setupCheckboxes = function ( checkboxes ) { - this.$saveOptions.find( '.ve-ui-mwSaveDialog-checkboxes' ) - .html( checkboxes ) - .find( 'a' ) - .attr( 'target', '_blank' ) - .end() - .find( '#wpMinoredit' ) - .prop( 'checked', mw.user.options.get( 'minordefault' ) ) - .prop( 'tabIndex', 0 ) - .end() - .find( '#wpWatchthis' ) - .prop( 'checked', - mw.user.options.get( 'watchdefault' ) || - ( mw.user.options.get( 'watchcreations' ) && !this.pageExists ) || - mw.config.get( 'wgVisualEditor' ).isPageWatched - ).prop( 'tabIndex', 0 ); - // TODO: Need to set all checkboxes provided by api tabindex to 0 for proper accessibility + var saveDialog = this; + this.setupDeferred.done( function () { + saveDialog.$saveOptions.find( '.ve-ui-mwSaveDialog-checkboxes' ) + .html( checkboxes ) + .find( 'a' ) + .attr( 'target', '_blank' ) + .end() + .find( '#wpMinoredit' ) + .prop( 'checked', mw.user.options.get( 'minordefault' ) ) + .prop( 'tabIndex', 0 ) + .end() + .find( '#wpWatchthis' ) + .prop( 'checked', + mw.user.options.get( 'watchdefault' ) || + ( mw.user.options.get( 'watchcreations' ) && !this.pageExists ) || + mw.config.get( 'wgVisualEditor' ).isPageWatched + ).prop( 'tabIndex', 0 ); + // TODO: Need to set all checkboxes provided by api tabindex to 0 for proper accessibility + } ); +}; + +/** + * Change the edit summary prefilled in the save dialog. + * + * This method is safe to call even when the dialog hasn't been initialized yet. + * + * @param {string} summary Edit summary to prefill + */ +ve.ui.MWSaveDialog.prototype.setEditSummary = function ( summary ) { + var saveDialog = this; + this.setupDeferred.done( function () { + saveDialog.editSummaryInput.setValue( summary ); + } ); }; /** @@ -341,26 +372,26 @@ ), 'flags': ['constructive'] } ); - this.saveButton.connect( this, { 'click': 'onSaveButtonClick' } ); + this.saveButton.connect( this, { 'click': [ 'emit', 'save' ] } ); // Review button for "save" panel this.reviewButton = new OO.ui.PushButtonWidget( { 'label': ve.msg( 'visualeditor-savedialog-label-review' ) } ); - this.reviewButton.connect( this, { 'click': 'onReviewButtonClick' } ); + this.reviewButton.connect( this, { 'click': [ 'emit', 'review' ] } ); // Review good button on "review" panel this.reviewGoodButton = new OO.ui.PushButtonWidget( { 'label': ve.msg( 'visualeditor-savedialog-label-review-good' ), 'flags': ['constructive'] } ); - this.reviewGoodButton.connect( this, { 'click': 'onReviewGoodButtonClick' } ); + this.reviewGoodButton.connect( this, { 'click': [ 'swapPanel', 'save' ] } ); // Resolve conflict this.resolveConflictButton = new OO.ui.PushButtonWidget( { 'label': ve.msg( 'visualeditor-savedialog-label-resolve-conflict' ), 'flags': ['constructive'] } ); - this.resolveConflictButton.connect( this, { 'click': 'onResolveConflictButtonClick' } ); + this.resolveConflictButton.connect( this, { 'click': [ 'emit', 'resolve' ] } ); this.$loadingIcon = this.$( '<div>' ).addClass( 've-ui-mwSaveDialog-working' ); @@ -373,6 +404,15 @@ this.resolveConflictButton.$element, this.$loadingIcon ); + + this.setupDeferred.resolve(); +}; + +/** + * @inheritdoc + */ +ve.ui.MWSaveDialog.prototype.setup = function () { + this.swapPanel( 'save' ); }; /* Registration */ -- To view, visit https://gerrit.wikimedia.org/r/95564 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: merged Gerrit-Change-Id: Idcdae5e013340f4519db4387bab507e714d47941 Gerrit-PatchSet: 9 Gerrit-Project: mediawiki/extensions/VisualEditor Gerrit-Branch: master Gerrit-Owner: Catrope <roan.katt...@gmail.com> Gerrit-Reviewer: Catrope <roan.katt...@gmail.com> Gerrit-Reviewer: Krinkle <krinklem...@gmail.com> Gerrit-Reviewer: Robmoen <rm...@wikimedia.org> Gerrit-Reviewer: jenkins-bot _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits