Santhosh has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/192786

Change subject: Publish module refactoring for title collision
......................................................................

Publish module refactoring for title collision

Better module restructuring for publishing error handling and
title validations

Bug: T85138
Change-Id: I95b904d9ab2f7ca882c32e91b2441d7cc5e796ab
---
M modules/publish/ext.cx.publish.dialog.js
M modules/publish/ext.cx.publish.js
2 files changed, 191 insertions(+), 158 deletions(-)


  git pull 
ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/ContentTranslation 
refs/changes/86/192786/1

diff --git a/modules/publish/ext.cx.publish.dialog.js 
b/modules/publish/ext.cx.publish.dialog.js
index 6860adc..20ff9b7 100644
--- a/modules/publish/ext.cx.publish.dialog.js
+++ b/modules/publish/ext.cx.publish.dialog.js
@@ -21,22 +21,18 @@
                this.$dialog = null;
                this.$close = null;
                this.$message = null;
+               this.$publishButton = null;
+               this.$keepButton = null;
                this.init();
        }
 
        /**
         * Initializes the publishing dialog instance.
-        * @param {string} title The title of the existing article
         */
        CXPublishingDialog.prototype.init = function () {
                var title = $( '.cx-column--translation > h2' ).text();
 
-               if ( this.$dialog ) {
-                       this.setMessage( title );
-               } else {
-                       this.render( title );
-               }
-               this.listen();
+               this.render( title );
                this.position();
                this.show();
        };
@@ -46,8 +42,7 @@
         * @param {string} title The title of the existing article
         */
        CXPublishingDialog.prototype.render = function ( title ) {
-               var $buttons, $keepButton, $publishAnywayButton, username, 
namespace,
-                       cxPublishingDialog = this;
+               var $buttons, username, namespace;
 
                username = mw.user.getName();
                namespace = mw.config.get( 
'wgContentTranslationTargetNamespace' );
@@ -57,49 +52,33 @@
                        .hide();
 
                this.$close = $( '<div>' )
-                       .addClass( 'cx-publishing-dialog__close' )
-                       .on( 'click', function () {
-                               cxPublishingDialog.$dialog.hide();
-                       } );
+                       .addClass( 'cx-publishing-dialog__close' );
 
                this.$message = $( '<p>' )
                        .addClass( 'cx-publishing-dialog__message' );
 
-               $( '.cx-publishing-dialog__message > a' ).prop( 'target', 
'_blank' );
+               this.$dialog.find( '.cx-publishing-dialog__message > a' ).prop( 
'target', '_blank' );
 
                $buttons = $( '<div>' )
                        .addClass( 'cx-publishing-dialog__buttons' );
 
-               $keepButton = $( '<button>' )
+               this.$keepButton = $( '<button>' )
                        .addClass( 'cx-publishing-dialog__buttons-keep 
mw-ui-button mw-ui-quiet' );
 
                if ( namespace === 'User' ) {
-                       $keepButton.text( mw.msg( 
'cx-publishing-dialog-keep-button' ) );
+                       this.$keepButton.text( mw.msg( 
'cx-publishing-dialog-keep-button' ) );
                } else {
-                       $keepButton.text( mw.msg( 
'cx-publishing-dialog-publish-draft-button' ) );
+                       this.$keepButton.text( mw.msg( 
'cx-publishing-dialog-publish-draft-button' ) );
                }
 
-               $keepButton.on( 'click', function () {
-                       cxPublishingDialog.$dialog.hide();
-                       mw.hook( 'mw.cx.publish' ).fire( false );
-               } );
-
-               $publishAnywayButton = $( '<button>' )
+               this.$publishButton = $( '<button>' )
                        .addClass( 'cx-publishing-dialog__buttons-publishanyway 
mw-ui-button mw-ui-progressive' )
-                       .text( mw.msg( 
'cx-publishing-dialog-publish-anyway-button' ) )
-                       .on( 'click', function () {
-                               cxPublishingDialog.$dialog.hide();
-                               mw.hook( 'mw.cx.publish' ).fire( true );
-                       } );
+                       .text( mw.msg( 
'cx-publishing-dialog-publish-anyway-button' ) );
 
                this.setMessage( title );
-
-               $buttons.append( $publishAnywayButton, $keepButton );
-
+               $buttons.append( this.$publishButton, this.$keepButton );
                this.$dialog.append( this.$close, this.$message, $buttons );
-
                $( 'body' ).append( this.$dialog );
-
        };
 
        /**
@@ -129,10 +108,7 @@
                buttonPosition = this.$trigger.position();
                buttonCenter = buttonPosition.left + ( 
this.$trigger.outerWidth() / 2 );
                dialogLeft = buttonCenter - ( this.$dialog.outerWidth() / 2 );
-               dialogTop = $( window ).scrollTop() +
-                       buttonPosition.top +
-                       this.$trigger.height() + 20;
-
+               dialogTop = $( window ).scrollTop() + buttonPosition.top + 
this.$trigger.height() + 20;
                this.$dialog.css( {
                        top: dialogTop,
                        left: dialogLeft,
@@ -142,11 +118,28 @@
        };
 
        /**
-        * A listener that adjust the positioning when the page is scrolled
-        * Necessary because the publishing button moves to the left on window 
scroll
+        * Listen for events
+        * @return {jQuery.Promise}
         */
        CXPublishingDialog.prototype.listen = function () {
+               var deferred = $.Deferred(),
+                       self = this;
+
                $( window ).on( 'scroll', $.proxy( this.position, this ) );
+               this.$keepButton.on( 'click', function () {
+                       deferred.resolve( false );
+                       self.$dialog.remove();
+               } );
+               this.$publishButton.on( 'click', function () {
+                       deferred.resolve( true );
+                       self.$dialog.remove();
+               } );
+               this.$close.on( 'click', function () {
+                       deferred.reject();
+                       self.$dialog.remove();
+               } );
+
+               return deferred.promise();
        };
 
        /**
@@ -161,16 +154,8 @@
         */
        $.fn.cxPublishingDialog = function () {
                return this.each( function () {
-                       /*jshint validthis:true */
-                       var $this = $( this ),
-                               data = $this.data( 'cxPublishingDialog' );
-
-                       if ( !data ) {
-                               $this.data( 'cxPublishingDialog', ( data = new 
CXPublishingDialog( this ) ) );
-                       }
-
-                       data.init();
-
+                       var $this = $( this );
+                       $this.data( 'cxPublishingDialog', new 
CXPublishingDialog( this ) );
                } );
        };
 } )( jQuery, mediaWiki );
diff --git a/modules/publish/ext.cx.publish.js 
b/modules/publish/ext.cx.publish.js
index c6a6c75..be4918e 100644
--- a/modules/publish/ext.cx.publish.js
+++ b/modules/publish/ext.cx.publish.js
@@ -16,6 +16,7 @@
         */
        function CXPublish( $trigger ) {
                this.$trigger = $trigger;
+               this.targetTitle = null;
        }
 
        /**
@@ -26,28 +27,49 @@
                var apiParams,
                        self = this;
 
+               this.targetTitle = $( '.cx-column--translation > h2' ).text();
                apiParams = $.extend( {}, params, {
-                       action: 'cxpublish'
+                       action: 'cxpublish',
+                       from: mw.cx.sourceLanguage,
+                       to: mw.cx.targetLanguage,
+                       sourcetitle: mw.cx.sourceTitle,
+                       html: self.getContent(),
+                       status: 'published',
+                       sourcerevision: mw.cx.sourceRevision,
+                       categories: this.getCategories(),
+                       progress: JSON.stringify( mw.cx.getProgress() )
                } );
 
-               return new mw.Api().postWithToken( 'edit', apiParams, {
-                       // A bigger timeout since publishing after converting 
html to wikitext
-                       // parsoid is not a fast operation.
-                       timeout: 100 * 1000 // in milliseconds
-               } ).then( function ( response ) {
-                       if ( response.cxpublish.result === 'success' ) {
-                               return;
-                       }
+               // Disable the trigger button
+               this.$trigger.prop( 'disabled', true ).text( mw.msg( 
'cx-publish-button-publishing' ) );
 
-                       if ( response.cxpublish.edit.captcha ) {
-                               return self.captchaHandler( 
response.cxpublish.edit.captcha )
-                                       .then( function ( captchaResult ) {
-                                               return self.publish( $.extend( 
params, captchaResult ) );
-                                       } );
-                       }
+               this.checkTargetTitle( this.targetTitle ).then( function ( 
title ) {
+                       apiParams.title = self.targetTitle = title;
 
-                       // If it's a different error, log it
-                       mw.log( '[CX] Unexpected error while publishing: ', 
response.cxpublish );
+                       new mw.Api().postWithToken( 'edit', apiParams, {
+                               // A bigger timeout since publishing after 
converting html to wikitext
+                               // parsoid is not a fast operation.
+                               timeout: 100 * 1000 // in milliseconds
+                       } ).done( function ( response ) {
+                               if ( response.cxpublish.result === 'success' ) {
+                                       self.success();
+                                       return;
+                               }
+
+                               if ( response.cxpublish.edit.captcha ) {
+                                       return self.captchaHandler( 
response.cxpublish.edit.captcha )
+                                               .then( function ( captchaResult 
) {
+                                                       return self.publish( 
$.extend( params, captchaResult ) );
+                                               } );
+                               }
+
+                               // If it's a different error, log it
+                               mw.log( '[CX] Unexpected error while 
publishing: ', response.cxpublish );
+                       } ).fail( function ( code, details ) {
+                               self.fail( code, details );
+                       } ).always( function () {
+                               self.$trigger.prop( 'disabled', true ).text( 
mw.msg( 'cx-publish-button' ) );
+                       } );
                } );
        };
 
@@ -108,8 +130,9 @@
        /**
         * Checks to see if there is already a published article with the title
         * @param {string} title The title to check
+        * @return {jQuery.promise}
         */
-       function checkTargetTitle( title ) {
+       function getTitle( title ) {
                var api,
                        $deferred = $.Deferred();
 
@@ -131,8 +154,59 @@
        }
 
        /**
+        * Generate an alternate title in case of title collision
+        * @param {string} title The title
+        * @return {string}
+        */
+       function getAlternateTitle( title ) {
+               var username = mw.user.getName();
+
+               if ( new mw.Title( title ).getNamespaceId() === 2 ) {
+                       return increaseVersion( title );
+               } else {
+                       return 'User:' + username + '/' + title;
+               }
+       }
+
+       /**
+        * Checks to see if there is already a published article with the title
+        * @param {string} title The title to check
+        * @return {jQuery.promise}
+        */
+       CXPublish.prototype.checkTargetTitle = function ( title ) {
+               var deferred = $.Deferred(),
+                       self = this;
+
+               title = mw.cx.SiteMapper.prototype.getTargetTitle( title );
+
+               getTitle( title ).done( function ( titleExists ) {
+                       var $dialog;
+
+                       if ( titleExists ) {
+                               // Show a dialog to decide what to do now
+                               self.$trigger.cxPublishingDialog();
+                               $dialog = self.$trigger.data( 
'cxPublishingDialog' );
+                               $dialog.listen().done( function ( overwrite ) {
+                                       if ( !overwrite ) {
+                                               title = getAlternateTitle( 
title );
+                                       }
+
+                                       deferred.resolve( title );
+                               } ).fail( function () {
+                                       deferred.reject();
+                               } );
+                       } else {
+                               deferred.resolve( title );
+                       }
+               } );
+
+               return deferred.promise();
+       };
+
+       /**
         * Increase the version number of a title starting with 1.
         * @param {string} title The title to increase the version on.
+        * @return {string}
         */
        function increaseVersion( title ) {
                var match, version;
@@ -148,110 +222,79 @@
        }
 
        /**
-        * Publish the translation
-        * @param {boolean} overwrite Flag to overwrite translation
-        * @param {string} title [optional], Optional title for the translation
+        * Get categories for the current translation pair
+        * @return {string} Category titles with '|' delimiter
         */
-       function publish( overwrite, title ) {
-               var $publishArea, $publishButton, publisher,
-                       translatedContent, targetCategories, targetTitle,
-                       sortedKeys, i, categoryTitles, categories, 
publishedTitle;
+       CXPublish.prototype.getCategories = function () {
+               var i, categories, sortedKeys, categoryTitles, targetCategories;
 
-               $publishArea = $( '.cx-header__publish' );
-               $publishButton = $publishArea.find( 
'.cx-header__publish-button' );
-               targetTitle = title || $( '.cx-column--translation > h2' 
).text();
-               translatedContent = prepareTranslationForPublish(
+               targetCategories = mw.cx.categoryTool.categories.target;
+               sortedKeys = Object.keys( targetCategories ).sort();
+               categoryTitles = [];
+               for ( i = 0; i < sortedKeys.length; i++ ) {
+                       categoryTitles.push( targetCategories[ sortedKeys[ i ] 
] );
+               }
+               categories = categoryTitles.join( '|' );
+               return categories;
+       };
+
+       /**
+        * Get the current translation content
+        * @return {string}
+        */
+       CXPublish.prototype.getContent = function () {
+               return this.prepareTranslationForPublish(
                        $( '.cx-column--translation .cx-column__content' 
).clone()
                );
+       };
 
-               publishedTitle = mw.cx.SiteMapper.prototype.getTargetTitle( 
targetTitle );
+       /**
+        * Success handler for publishing
+        */
+       CXPublish.prototype.success = function () {
+               $( '.cx-column--translation > h2' )
+                       .text( this.targetTitle )
+                       .keepAlignment();
+               mw.hook( 'mw.cx.success' )
+                       .fire( mw.message( 'cx-publish-page-success',
+                               $( '<a>' ).attr( {
+                                       href: mw.util.getUrl( this.targetTitle 
),
+                                       target: '_blank'
+                               } ).text( this.targetTitle )[ 0 ].outerHTML
+                       ) );
+               mw.hook( 'mw.cx.translation.published' ).fire(
+                       mw.cx.sourceLanguage,
+                       mw.cx.targetLanguage,
+                       this.targetTitle
+               );
+               mw.cx.dirty = false;
+       };
 
-               checkTargetTitle( publishedTitle )
-                       .done( function ( titleExists ) {
-                               var username;
-
-                               username = mw.user.getName();
-
-                               if ( titleExists === false || overwrite === 
true ) {
-                                       $publishButton
-                                               .prop( 'disabled', true )
-                                               .text( mw.msg( 
'cx-publish-button-publishing' ) );
-
-                                       targetCategories = 
mw.cx.categoryTool.categories.target;
-                                       sortedKeys = Object.keys( 
targetCategories ).sort();
-                                       categoryTitles = [];
-                                       for ( i = 0; i < sortedKeys.length; i++ 
) {
-                                               categoryTitles.push( 
targetCategories[ sortedKeys[ i ] ] );
-                                       }
-                                       categories = categoryTitles.join( '|' );
-
-                                       publisher = new CXPublish( $publishArea 
);
-                                       publisher.publish( {
-                                               from: mw.cx.sourceLanguage,
-                                               to: mw.cx.targetLanguage,
-                                               sourcetitle: mw.cx.sourceTitle,
-                                               title: targetTitle,
-                                               html: translatedContent,
-                                               status: 'published',
-                                               sourcerevision: 
mw.cx.sourceRevision,
-                                               categories: categories,
-                                               progress: JSON.stringify( 
mw.cx.getProgress() )
-                                       } ).done( function () {
-                                               $( '.cx-column--translation > 
h2' )
-                                                       .text( publishedTitle )
-                                                       .keepAlignment();
-                                               mw.hook( 'mw.cx.success' )
-                                                       .fire( mw.message( 
'cx-publish-page-success',
-                                                               $( '<a>' 
).attr( {
-                                                                       href: 
mw.util.getUrl( publishedTitle ),
-                                                                       target: 
'_blank'
-                                                               } ).text( 
publishedTitle )[ 0 ].outerHTML
-                                                       ) );
-                                               mw.hook( 
'mw.cx.translation.published' ).fire(
-                                                       mw.cx.sourceLanguage,
-                                                       mw.cx.targetLanguage,
-                                                       targetTitle
-                                               );
-                                               mw.cx.dirty = false;
-                                       } ).fail( function ( code, details ) {
-                                               var trace = {
-                                                       sourceLanguage: 
mw.cx.sourceLanguage,
-                                                       targetLanguage: 
mw.cx.targetLanguage,
-                                                       sourceTitle: 
mw.cx.sourceTitle,
-                                                       sourceRevision: 
mw.cx.sourceRevision,
-                                                       targetTitle: 
targetTitle,
-                                                       error: details
-                                               };
-                                               mw.hook( 'mw.cx.error' ).fire( 
mw.msg( 'cx-publish-page-error' ) );
-                                               mw.log( '[CX] Error while 
publishing:', code, trace );
-                                       } ).always( function () {
-                                               $publishButton
-                                                       .prop( 'disabled', true 
)
-                                                       .text( mw.msg( 
'cx-publish-button' ) );
-                                       } );
-                               } else if ( overwrite === false ) {
-                                       if ( new mw.Title( publishedTitle 
).getNamespaceId() === 2 ) {
-                                               publishedTitle = 
increaseVersion( publishedTitle );
-                                       } else {
-                                               publishedTitle = 'User:' + 
username + '/' + publishedTitle;
-                                       }
-                                       publish( false, publishedTitle );
-                               } else {
-                                       $publishButton.cxPublishingDialog();
-                               }
-                       } );
-       }
+       /**
+        * Failure handler for publishing
+        */
+       CXPublish.prototype.fail = function ( code, details ) {
+               var trace = {
+                       sourceLanguage: mw.cx.sourceLanguage,
+                       targetLanguage: mw.cx.targetLanguage,
+                       sourceTitle: mw.cx.sourceTitle,
+                       sourceRevision: mw.cx.sourceRevision,
+                       targetTitle: this.targetTitle,
+                       error: details
+               };
+               mw.hook( 'mw.cx.error' ).fire( mw.msg( 'cx-publish-page-error' 
) );
+               mw.log( '[CX] Error while publishing:', code, trace );
+       };
 
        /**
         * Prepare the translated content for publishing by removing
         * unwanted parts.
         * @return {string} processed html
         */
-       function prepareTranslationForPublish( $content ) {
+       CXPublish.prototype.prepareTranslationForPublish = function ( $content 
) {
                $content.find( '.cx-segment' ).replaceWith( function () {
                        return $( this ).html();
                } );
-               // TODO: This clean up should be done even before segmentation 
at server.
                $content.find( 'link, title' ).remove();
 
                // Remove placeholder sections
@@ -266,12 +309,17 @@
                } );
 
                return $content.html();
-       }
+       };
 
        // Expose the CXPublish
        mw.cx.publish = CXPublish;
 
        $( function () {
-               mw.hook( 'mw.cx.publish' ).add( $.proxy( publish, this ) );
+               var cxPublish, $publishButton;
+
+               $publishButton = $( '.cx-header__publish 
.cx-header__publish-button' );
+               cxPublish = new mw.cx.publish( $publishButton );
+
+               mw.hook( 'mw.cx.publish' ).add( $.proxy( cxPublish.publish, 
cxPublish ) );
        } );
 }( jQuery, mediaWiki ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/192786
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I95b904d9ab2f7ca882c32e91b2441d7cc5e796ab
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Santhosh <santhosh.thottin...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to