jenkins-bot has submitted this change and it was merged.

Change subject: A guided tour for publishing a translated page
......................................................................


A guided tour for publishing a translated page

The general structure and the i18n should be more or less done,
but the flow and the cookies need work.

This patch relies on the following core change:
I2765248f61ecd3089a9f4e06571a378e39ec1db3

It introduces two cookies:

1. A general GuidedTour cookie, named "(prefix)-mw-tour",
   with the usual GuidedTour info: tour name, start time,
   first step, etc.
2. A cookie specific to this extension, named
   "(prefix)-cx-published", which includes the username
   and the name of the translated page.

Both cookies are created when the user publishes
the first draft of a translated page, and both are deleted
when the user completes the page publishing by
moving it from the user space to the article space.

Change-Id: I15759019aea56a952eeb03aa25b83b9fb35e9c30
---
M ContentTranslation.hooks.php
M Resources.php
M i18n/en.json
M i18n/qqq.json
A modules/tours/ext.cx.tours.publish.js
M modules/translation/ext.cx.publish.js
6 files changed, 261 insertions(+), 7 deletions(-)

Approvals:
  KartikMistry: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/ContentTranslation.hooks.php b/ContentTranslation.hooks.php
index 7425310..8f557ec 100644
--- a/ContentTranslation.hooks.php
+++ b/ContentTranslation.hooks.php
@@ -24,12 +24,17 @@
                $redlinkFeatureEnabled = class_exists( 'BetaFeatures' ) &&
                        BetaFeatures::isFeatureEnabled( $user, 
'red-interlanguage-link' );
 
-               if ( $user->isLoggedIn() &&
-                       $redlinkFeatureEnabled &&
-                       $title->inNamespace( NS_MAIN ) &&
-                       $out->getLanguage()->getCode() !== 
$title->getPageLanguage()->getCode()
-               ) {
-                       $out->addModules( 'ext.cx.redlink' );
+               if ( $user->isLoggedIn() ) {
+                       if ( $redlinkFeatureEnabled &&
+                               $title->inNamespace( NS_MAIN ) &&
+                               $out->getLanguage()->getCode() !== 
$title->getPageLanguage()->getCode()
+                       ) {
+                               $out->addModules( 'ext.cx.redlink' );
+                       }
+
+                       if ( class_exists( 'GuidedTourHooks' ) ) {
+                               $out->addModules( 'ext.guidedTour' );
+                       }
                }
 
                // If EventLogging integration is enabled, load the schema 
module
@@ -41,6 +46,16 @@
                        ) );
                }
 
+               if ( $wgContentTranslationExperimentalFeatures ) {
+                       // WYSIWYGEditor
+                       $out->addModules( 'ext.cx.editor.medium' );
+                       // Reference card
+                       $out->addModules( 'ext.cx.tools.reference' );
+               } else {
+                       // Just ContentEditable
+                       $out->addModules( 'ext.cx.editor' );
+               }
+
                return true;
        }
 
diff --git a/Resources.php b/Resources.php
index e94ce18..ae0db61 100644
--- a/Resources.php
+++ b/Resources.php
@@ -238,7 +238,9 @@
        'scripts' => 'translation/ext.cx.publish.js',
        'dependencies' => array(
                'ext.cx.model',
+               'json',
                'mediawiki.api.edit',
+               'mediawiki.cookie',
        ),
        'messages' => array(
                'cx-publish-page',
@@ -281,6 +283,30 @@
        ),
 ) + $resourcePaths;
 
+$wgResourceModules['ext.guidedTour.tour.cxpublish'] = array(
+       'scripts' => 'tours/ext.cx.tours.publish.js',
+       'dependencies' => array(
+               'ext.guidedTour',
+               'json',
+               'mediawiki.cookie',
+               'mediawiki.Title',
+       ),
+       'messages' => array(
+               'vector-action-move',
+               'vector-view-edit',
+               'cx-publish-gt-no-permission-to-move-title',
+               'cx-publish-gt-no-permission-to-move-description',
+               'cx-publish-gt-first-step-title',
+               'cx-publish-gt-first-step-description',
+               'cx-publish-gt-move-page-title',
+               'cx-publish-gt-move-page-description',
+               'cx-publish-gt-moved-title',
+               'cx-publish-gt-moved-description',
+               'cx-publish-gt-published-title',
+               'cx-publish-gt-published-description',
+       ),
+) + $resourcePaths;
+
 $wgResourceModules['ext.cx.editor'] = array(
        'scripts' => array(
                'editor/ext.cx.editor.js',
@@ -300,3 +326,4 @@
                'editor/medium/theme/agora.css',
        ),
 ) + $resourcePaths;
+
diff --git a/i18n/en.json b/i18n/en.json
index 67a8408..4fb6e14 100644
--- a/i18n/en.json
+++ b/i18n/en.json
@@ -18,6 +18,15 @@
        "cx-publish-button": "Publish translation",
        "cx-publish-button-publishing": "Publishing...",
        "cx-publish-summary": "Created by translating the page \"$1\"",
+       "cx-publish-gt-no-permission-to-move-description": "Please ask an 
experienced user of this site to help you review your translation and publish 
it in the article space.",
+       "cx-publish-gt-first-step-title": "The translation has been published 
as a draft under your user page for review",
+       "cx-publish-gt-first-step-description": "Click on the 
\"{{int:vector-action-move}}\" action under this menu to make the content 
available to all users as a regular page.",
+       "cx-publish-gt-move-page-title": "Move the page",
+       "cx-publish-gt-move-page-description": "Select the \"(main)\" namespace 
and give it the right title.",
+       "cx-publish-gt-moved-title": "The translated page was moved",
+       "cx-publish-gt-moved-description": "Click this link to read and improve 
your new translated page",
+       "cx-publish-gt-published-title": "Congratulations, the page has been 
published",
+       "cx-publish-gt-published-description": "You can click 
\"{{int:vector-view-edit}}\" to keep improving the page. Make sure it reads 
naturally.",
        "cx-translation-add-translation": "+ Add translation",
        "tag-contenttranslation": "ContentTranslation",
        "cx-source-loading": "Loading $1",
diff --git a/i18n/qqq.json b/i18n/qqq.json
index de86fe6..de4d119 100644
--- a/i18n/qqq.json
+++ b/i18n/qqq.json
@@ -21,6 +21,16 @@
        "cx-publish-button": "Publish button text in 
[[Special:ContentTranslation]].\n\nAlso used in 
{{msg-mw|Cx-tools-instructions-text6}}.",
        "cx-publish-button-publishing": "Publish button text in 
[[Special:ContentTranslation]], shown while publishing is in progress. Replaces 
{{msg-mw|cx-publish-button}}.",
        "cx-publish-summary": "This is an automatic edit summary for pages that 
were created by [[Special:ContentTranslation]].\n\nParameters:\n* $1 - the 
source page name",
+       "cx-publish-summary": "This is an automatic edit summary for pages that 
were created by [[Special:ContentTranslation]].\n\nParameters:\n* $1 - the 
source page name",
+       "cx-publish-gt-no-permission-to-move-description": "Description for a 
guider that is shown to a user after publishing a page when the user doesn't 
have a move permission.",
+       "cx-publish-gt-first-step-title": "Title for a guider that is shown to 
a user after publishing a page.",
+       "cx-publish-gt-first-step-description": "Description for a guider that 
is shown to a user after publishing a page.",
+       "cx-publish-gt-move-page-title": "Title for a guider that is shown to a 
user when moving the page. It's attached to the dropdown box that lists the 
namespaces.",
+       "cx-publish-gt-move-page-description": "Title for a guider that is 
shown to a user when moving the page. It's attached to the dropdown box that 
lists the namespaces. \"(main)\" is the name of the main namespace - 
{{mw-msg|blanknamespace}}.",
+       "cx-publish-gt-moved-title": "Title for a guider that is shown to a 
user after moving a page. It's shown near a link to the new page",
+       "cx-publish-gt-moved-description": "Description for a guider that is 
shown to a user after moving a page. It's shown near a link to the new page",
+       "cx-publish-gt-published-title": "Title for a guider that is shown to a 
user after going to a published translated page. It's shown near the Edit link 
on the top of the page.",
+       "cx-publish-gt-published-description": "Title for a guider that is 
shown to a user after going to a published translated page. It's shown near the 
Edit link on the top of the page.",
        "cx-translation-add-translation": "This appears in the empty paragraph 
in the translation column. Clicking the paragraph adds an automatic translation 
of the corresponding source paragraph. The plus sign is used as an icon that 
hints that something is being added.",
        "tag-contenttranslation": "A short description of the 
contenttranslation revision tag. It appears in the edit summary when a 
translated page is created. It doesn't have to be CamelCase.",
        "cx-source-loading": "Status text shown in the source article pane 
while article is being loaded.\n\nParameters:\n* $1 - the title of the page 
being loaded",
diff --git a/modules/tours/ext.cx.tours.publish.js 
b/modules/tours/ext.cx.tours.publish.js
new file mode 100644
index 0000000..fad51ba
--- /dev/null
+++ b/modules/tours/ext.cx.tours.publish.js
@@ -0,0 +1,172 @@
+/*
+ * Guided Tour for ContentTranslation publishing.
+ */
+( function ( $, mw ) {
+       'use strict';
+
+       var tour,
+               cactions, $moveLink,
+               editId, veEditId, editElement,
+               publishData, translatedTitle, translatorUsername, draftTitle,
+               currentTitle = mw.config.get( 'wgTitle' ),
+               canonicalNamespace = mw.config.get( 'wgCanonicalNamespace' ),
+               username = mw.user.getName(),
+               cookieName = '-cx-published',
+               publishCookie = mw.cookie.get( cookieName );
+
+       if ( publishCookie === null ) {
+               return;
+       }
+
+       publishData = JSON.parse( publishCookie );
+       translatedTitle = publishData.translatedTitle;
+       translatorUsername = publishData.username;
+       draftTitle = username + '/' + translatedTitle;
+
+       function isUserDraft() {
+               return canonicalNamespace === 'User' &&
+                       username === translatorUsername &&
+                       currentTitle === draftTitle;
+       }
+
+       function isMovePage() {
+               var relevantPage, draftPage, title;
+
+               if ( mw.config.get( 'wgCanonicalSpecialPageName' ) !== 
'Movepage' ) {
+                       return false;
+               }
+
+               title = mw.Title.newFromText( draftTitle, 2 ); // 2 is user 
space
+
+               if ( title === null ) {
+                       return false;
+               }
+
+               draftPage = title.getPrefixedDb();
+               relevantPage = mw.config.get( 'wgRelevantPageName' );
+
+               return draftPage === relevantPage;
+       }
+
+       function isMoveSuccessPage() {
+               return mw.config.get( 'wgCanonicalSpecialPageName' ) === 
'Movepage' &&
+                       mediaWiki.guidedTour.hasQuery( { action: 'submit' } );
+       }
+
+       function isPublishedPage() {
+               return canonicalNamespace === '' && // Main (article) space
+                       currentTitle === translatedTitle;
+       }
+
+       function deletePublishCookie() {
+               mw.cookie.set( cookieName, null );
+       }
+
+       if ( !isUserDraft() &&
+               !isMovePage() &&
+               !isMoveSuccessPage() &&
+               !isPublishedPage()
+       ) {
+               return;
+       }
+
+       tour = new mediaWiki.guidedTour.TourBuilder( { name: 'cxpublish' } );
+       cactions = '#p-cactions';
+       $moveLink = $( '#ca-move a' );
+       editId = '#ca-edit';
+       veEditId = '#ca-ve-edit';
+       editElement = $( veEditId ).length ? veEditId : editId;
+
+       if ( isUserDraft() && !$moveLink.length ) {
+               tour.firstStep( {
+                       name: 'suggestmovestart',
+                       attachTo: '#firstHeading',
+                       position: 'bottom',
+                       // The title is the same as in the usual first step,
+                       // but the description suggest a different action
+                       titlemsg: 'cx-publish-gt-first-step-title',
+                       descriptionmsg: 
'cx-publish-gt-no-permission-to-move-description',
+                       onShow: deletePublishCookie,
+                       buttons: [ {
+                               action: 'end'
+                       } ]
+               } );
+
+               return;
+       }
+
+       tour.firstStep( {
+               name: 'suggestmovestart',
+               attachTo: cactions,
+               position: 'leftBottom',
+               titlemsg: 'cx-publish-gt-first-step-title',
+               descriptionmsg: 'cx-publish-gt-first-step-description',
+               onShow: function () {
+                       var $cactions = $( cactions ),
+                               $actionsMenu = $cactions.find( '.menu' );
+
+                       // Show the actions menu immediately when the tour 
begins
+                       // so the user won't wonder where is that "Move" action
+                       $actionsMenu
+                               .css( 'display', 'block' );
+
+                       // ... but hide it and show it usually on further
+                       // hovering in and out.
+                       $cactions
+                               .on( 'mouseleave', function () {
+                                       $actionsMenu.css( 'display', 'none' );
+                               } )
+                               .on( 'mouseenter', function () {
+                                       $actionsMenu.css( 'display', 'block' );
+                               } );
+               }
+       } )
+       .transition( function () {
+               if ( isMovePage() ) {
+                       return 'movehelpstart';
+               }
+       } );
+
+       // Help the user to move the page correctly
+       tour.step( {
+               name: 'movehelpstart',
+               attachTo: '#wpNewTitleNs',
+               position: 'topRight',
+               titlemsg: 'cx-publish-gt-move-page-title',
+               descriptionmsg: 'cx-publish-gt-move-page-description'
+       } )
+       .transition( function () {
+               if ( isMoveSuccessPage() ) {
+                       return 'movedstart';
+               }
+       } );
+
+       // The page was moved.
+       // The move action result is shown.
+       tour.step( {
+               name: 'movedstart',
+               attachTo: '#movepage-newlink',
+               position: 'bottom',
+               titlemsg: 'cx-publish-gt-moved-title',
+               descriptionmsg: 'cx-publish-gt-moved-description'
+       } )
+       .transition( function () {
+               if ( isPublishedPage() ) {
+                       return 'publishedstart';
+               }
+       } );
+
+       // The page was moved to the main space.
+       // Suggest more editing.
+       tour.step( {
+               name: 'publishedstart',
+               attachTo: editElement,
+               position: 'bottom',
+               titlemsg: 'cx-publish-gt-published-title',
+               descriptionmsg: 'cx-publish-gt-published-description',
+               onShow: deletePublishCookie,
+               buttons: [ {
+                       action: 'end'
+               } ]
+       } );
+}( jQuery, mediaWiki ) );
diff --git a/modules/translation/ext.cx.publish.js 
b/modules/translation/ext.cx.publish.js
index 985c15b..dbf7d92 100644
--- a/modules/translation/ext.cx.publish.js
+++ b/modules/translation/ext.cx.publish.js
@@ -31,7 +31,6 @@
                $translatedContent.find( '.placeholder' ).remove();
 
                return $translatedContent.html();
-
        }
 
        mw.cx.publish = function () {
@@ -44,6 +43,8 @@
 
                translatedTitle = $( '.cx-column--translation > h2' ).text();
                translatedContent = prepareTranslationForPublish();
+
+               initGuidedTour( translatedTitle );
 
                // To be saved under User:UserName
                translatedTitle = 'User:' + mw.user.getName() + '/' + 
translatedTitle;
@@ -86,6 +87,26 @@
                } );
        }
 
+       /**
+        * If GuidedTour is available, set cookies to start a tour.
+        * @param {string} translatedTitle
+        */
+       function initGuidedTour( translatedTitle ) {
+               if ( !mw.guidedTour ) {
+                       return;
+               }
+
+               mw.cookie.set(
+                       '-cx-published',
+                       JSON.stringify( {
+                               translatedTitle: translatedTitle,
+                               username: mw.user.getName()
+                       } )
+               );
+
+               mw.guidedTour.setTourCookie( 'cxpublish', 'suggestmovestart' );
+       }
+
        $( function () {
                mw.hook( 'mw.cx.publish' ).add( $.proxy( mw.cx.publish, this ) 
);
        } );

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I15759019aea56a952eeb03aa25b83b9fb35e9c30
Gerrit-PatchSet: 31
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Amire80 <[email protected]>
Gerrit-Reviewer: Alexandros Kosiaris <[email protected]>
Gerrit-Reviewer: Amire80 <[email protected]>
Gerrit-Reviewer: BBlack <[email protected]>
Gerrit-Reviewer: Bene <[email protected]>
Gerrit-Reviewer: KartikMistry <[email protected]>
Gerrit-Reviewer: Mattflaschen <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Phuedx <[email protected]>
Gerrit-Reviewer: Robmoen <[email protected]>
Gerrit-Reviewer: Santhosh <[email protected]>
Gerrit-Reviewer: Swalling <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to