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

Change subject: Single edit tab and section links
......................................................................


Single edit tab and section links

In addition to the couple of TODOs inline, we should do the following in
follow-up commits:
* Prevent FOUC due to changing things only on the client
* Make section link behaviour sensible

Bug: T58337
Change-Id: I65d966270491ffe017cb11a0daa915628fadf65c
---
M VisualEditor.hooks.php
M extension.json
M modules/ve-mw/i18n/en.json
M modules/ve-mw/i18n/qqq.json
M modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
M modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
A modules/ve-mw/init/ve.init.MWEditingTabDialog.js
7 files changed, 442 insertions(+), 57 deletions(-)

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



diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php
index a6ee8dd..67a4578 100644
--- a/VisualEditor.hooks.php
+++ b/VisualEditor.hooks.php
@@ -59,6 +59,54 @@
        }
 
        /**
+        * Decide whether to bother showing the wikitext editor at all.
+        * If not, we expect the VE initialisation JS to activate.
+        * @param $article Article
+        * @param $user User
+        * @return bool Whether to show the wikitext editor or not.
+        */
+       public static function onCustomEditor( Article $article, User $user ) {
+               $req = RequestContext::getMain()->getRequest();
+               $veConfig = ConfigFactory::getDefaultInstance()->makeConfig( 
'visualeditor' );
+
+               if (
+                       !$user->getOption( 'visualeditor-enable' ) ||
+                       $user->getOption( 'visualeditor-betatempdisable' ) ||
+                       $user->getOption( 'visualeditor-autodisable' ) ||
+                       $user->getOption( 'visualeditor-tabs' ) === 'preferwt' 
||
+                       ( $veConfig->get( 'VisualEditorDisableForAnons' ) && 
$user->isAnon() ) ||
+                       false // TODO: Detect incompatibility - P2373
+               ) {
+                       return true;
+               }
+
+               $title = $article->getTitle();
+
+               $availableNamespaces = $veConfig->get( 
'VisualEditorAvailableNamespaces' );
+
+               $params = $req->getValueNames();
+
+               if ( $user->isAnon() ) {
+                       $editor = $req->getCookie(
+                               'VEE',
+                               '',
+                               User::getDefaultOption( 'visualeditor-editor' )
+                       );
+               } else {
+                       $editor = $user->getOption( 'visualeditor-editor' );
+               }
+               return $req->getVal( 'action' ) !== 'edit' ||
+                       !$veConfig->get( 'VisualEditorUseSingleEditTab' ) ||
+                       $editor === 'wikitext' ||
+                       !$title->inNamespaces( array_keys( array_filter( 
$availableNamespaces ) ) ) ||
+                       $title->getContentModel() !== CONTENT_MODEL_WIKITEXT ||
+                       // check for parameters that VE does not handle
+                       in_array( 'preload', $params ) ||
+                       in_array( 'editintro', $params ) ||
+                       in_array( 'veswitched', $params );
+       }
+
+       /**
         * Convert the content model of messages that are actually JSON to JSON.
         * This only affects validation and UI when saving and editing, not
         * loading the content.
@@ -92,6 +140,42 @@
        public static function onSkinTemplateNavigation( SkinTemplate &$skin, 
array &$links ) {
                $config = ConfigFactory::getDefaultInstance()->makeConfig( 
'visualeditor' );
 
+               // Exit if there's no edit link for whatever reason (e.g. 
protected page)
+               if ( !isset( $links['views']['edit'] ) ) {
+                       return true;
+               }
+
+               // Exit if we're using the single edit tab.
+               if (
+                       $config->get( 'VisualEditorUseSingleEditTab' ) &&
+                       $skin->getUser()->getOption( 'visualeditor-tabs' ) !== 
'multi-tab'
+               ) {
+                       $dbr = wfGetDB( DB_SLAVE );
+                       $user = RequestContext::getMain()->getUser();
+                       if (
+                               $config->get( 'VisualEditorUseSingleEditTab' ) 
&&
+                               !$user->isAnon() &&
+                               !$user->getOption( 'visualeditor-hidetabdialog' 
) &&
+                               $user->getOption( 'visualeditor-tabs' ) === 
'remember-last' &&
+                               $dbr->select(
+                                       'revision',
+                                       '1',
+                                       array(
+                                               'rev_user' => $user->getId(),
+                                               'rev_timestamp < ' . 
$dbr->addQuotes(
+                                                       $config->get( 
'VisualEditorSingleEditTabSwitchTime' )
+                                               )
+                                       ),
+                                       __METHOD__,
+                                       array( 'LIMIT' => 1 )
+                               )->numRows() === 1
+                       ) {
+                               wfDebugLog( 'debug', 'ok' );
+                               $links['views']['edit']['class'] .= ' 
visualeditor-showtabdialog';
+                       }
+                       return true;
+               }
+
                // Exit if the user doesn't have VE enabled
                if (
                        !$skin->getUser()->getOption( 'visualeditor-enable' ) ||
@@ -99,11 +183,6 @@
                        $skin->getUser()->getOption( 'visualeditor-autodisable' 
) ||
                        ( $config->get( 'VisualEditorDisableForAnons' ) && 
$skin->getUser()->isAnon() )
                ) {
-                       return true;
-               }
-
-               // Exit if there's no edit link for whatever reason (e.g. 
protected page)
-               if ( !isset( $links['views']['edit'] ) ) {
                        return true;
                }
 
@@ -238,6 +317,14 @@
        ) {
                $config = ConfigFactory::getDefaultInstance()->makeConfig( 
'visualeditor' );
 
+               // Exit if we're using the single edit tab.
+               if (
+                       $config->get( 'VisualEditorUseSingleEditTab' ) &&
+                       $skin->getUser()->getOption( 'visualeditor-tabs' ) !== 
'multi-tab'
+               ) {
+                       return true;
+               }
+
                // Exit if we're in parserTests
                if ( isset( $GLOBALS[ 'wgVisualEditorInParserTests' ] ) ) {
                        return true;
@@ -342,9 +429,27 @@
                        'default' => $user->getOption( 
'visualeditor-betatempdisable' ) ||
                                $user->getOption( 'visualeditor-autodisable' )
                );
+
+               $config = ConfigFactory::getDefaultInstance()->makeConfig( 
'visualeditor' );
+               if ( $config->get( 'VisualEditorUseSingleEditTab' ) ) {
+                       $preferences['visualeditor-tabs'] = array(
+                               'type' => 'select',
+                               'label-message' => 
'visualeditor-preference-tabs',
+                               'section' => 'editing/editor',
+                               'options' => array(
+                                       wfMessage( 
'visualeditor-preference-tabs-remember-last' )->escaped() => 'remember-last',
+                                       wfMessage( 
'visualeditor-preference-tabs-prefer-ve' )->escaped() => 'prefer-ve',
+                                       wfMessage( 
'visualeditor-preference-tabs-prefer-wt' )->escaped() => 'prefer-wt',
+                                       wfMessage( 
'visualeditor-preference-tabs-multi-tab' )->escaped() => 'multi-tab'
+                               )
+                       );
+               }
+
                $api = array( 'type' => 'api' );
                $preferences['visualeditor-autodisable'] = $api;
+               $preferences['visualeditor-editor'] = $api;
                $preferences['visualeditor-hidebetawelcome'] = $api;
+               $preferences['visualeditor-hidetabdialog'] = $api;
                $preferences['visualeditor-hideusered'] = $api;
                $preferences['visualeditor-findAndReplace-findText'] = $api;
                $preferences['visualeditor-findAndReplace-replaceText'] = $api;
@@ -467,6 +572,7 @@
                        'skins' => $veConfig->get( 'VisualEditorSupportedSkins' 
),
                        'tabPosition' => $veConfig->get( 
'VisualEditorTabPosition' ),
                        'tabMessages' => $veConfig->get( 
'VisualEditorTabMessages' ),
+                       'singleEditTab' => $veConfig->get( 
'VisualEditorUseSingleEditTab' ),
                        'showBetaWelcome' => $veConfig->get( 
'VisualEditorShowBetaWelcome' ),
                        'enableTocWidget' => $veConfig->get( 
'VisualEditorEnableTocWidget' ),
                        'svgMaxSize' => $coreConfig->get( 'SVGMaxSize' ),
diff --git a/extension.json b/extension.json
index 5c29b5f..e28a4c4 100644
--- a/extension.json
+++ b/extension.json
@@ -108,7 +108,9 @@
                        "_merge_strategy": "array_plus"
                },
                "VisualEditorSkinToolbarScrollOffset": [],
-               "VisualEditorParsoidTimeout": 100
+               "VisualEditorParsoidTimeout": 100,
+               "VisualEditorUseSingleEditTab": false,
+               "VisualEditorSingleEditTabSwitchTime": 20160101000000
        },
        "APIModules": {
                "visualeditor": {
@@ -187,6 +189,9 @@
                ],
                "AuthPluginAutoCreate": [
                        "VisualEditorHooks::onAuthPluginAutoCreate"
+               ],
+               "CustomEditor": [
+                       "VisualEditorHooks::onCustomEditor"
                ]
        },
        "ResourceModules": {
@@ -268,6 +273,7 @@
                                "mediawiki.Title",
                                "mediawiki.Uri",
                                "mediawiki.util",
+                               "mediawiki.api.options",
                                "user.options",
                                "ext.visualEditor.track"
                        ],
@@ -975,7 +981,8 @@
                },
                "ext.visualEditor.switching": {
                        "scripts": [
-                               
"modules/ve-mw/init/ve.init.MWVESwitchConfirmDialog.js"
+                               
"modules/ve-mw/init/ve.init.MWVESwitchConfirmDialog.js",
+                               
"modules/ve-mw/init/ve.init.MWEditingTabDialog.js"
                        ],
                        "styles": 
"modules/ve-mw/init/styles/ve.init.MWVESwitchConfirmDialog.css",
                        "skinStyles": {
@@ -997,7 +1004,13 @@
                                "visualeditor-mweditmodeve-warning",
                                "visualeditor-mweditmodesource-warning-cancel",
                                "visualeditor-mweditmodesource-warning-switch",
-                               
"visualeditor-mweditmodesource-warning-switch-discard"
+                               
"visualeditor-mweditmodesource-warning-switch-discard",
+                               "visualeditor-editingtabdialog-body",
+                               "visualeditor-editingtabdialog-ok",
+                               "visualeditor-editingtabdialog-title",
+                               "visualeditor-preference-tabs-prefer-ve",
+                               "visualeditor-preference-tabs-prefer-wt",
+                               "visualeditor-preference-tabs-multi-tab"
                        ],
                        "targets": [
                                "desktop",
@@ -1722,7 +1735,10 @@
                "visualeditor-enable-experimental": 0,
                "visualeditor-enable-language": 0,
                "visualeditor-hidebetawelcome": 0,
-               "visualeditor-autodisable": 0
+               "visualeditor-autodisable": 0,
+               "visualeditor-tabs": "remember-last",
+               "visualeditor-editor": "wikitext",
+               "visualeditor-hidetabdialog": 0
        },
        "AutoloadClasses": {
                "ApiVisualEditor": "ApiVisualEditor.php",
diff --git a/modules/ve-mw/i18n/en.json b/modules/ve-mw/i18n/en.json
index 7937666..4c607e7 100644
--- a/modules/ve-mw/i18n/en.json
+++ b/modules/ve-mw/i18n/en.json
@@ -239,6 +239,9 @@
        "visualeditor-differror": "Error loading data from server: $1.",
        "visualeditor-donebutton-tooltip": "Done editing",
        "visualeditor-editconflict": "Your changes could not be saved because 
of an edit conflict. Would {{GENDER:|you}} like to resolve the conflict 
manually?",
+       "visualeditor-editingtabdialog-body": "{{SITENAME}} now remembers which 
editor you used last when you click on the \"$1\" tab.",
+       "visualeditor-editingtabdialog-ok": "OK",
+       "visualeditor-editingtabdialog-title": "Editing tabs",
        "visualeditor-editnotices-tool": "$1 {{PLURAL:$1|notice|notices}}",
        "visualeditor-editnotices-tooltip": "Edit notices",
        "visualeditor-editsummary": "Describe what you changed",
@@ -297,6 +300,11 @@
        "visualeditor-preference-core-info-link": 
"\/\/mediawiki.org\/wiki\/Special:MyLanguage\/VisualEditor\/Beta_Features\/General",
        "visualeditor-preference-core-label": "Visual editing",
        "visualeditor-preference-enable": "Enable the visual editor. It will be 
available in the following {{PLURAL:$2|namespace|namespaces}}: $1",
+       "visualeditor-preference-tabs": "Editing tabs",
+       "visualeditor-preference-tabs-multi-tab": "Show me both editor tabs",
+       "visualeditor-preference-tabs-prefer-ve": "Always give me the visual 
editor if possible",
+       "visualeditor-preference-tabs-prefer-wt": "Always give me the wikitext 
editor",
+       "visualeditor-preference-tabs-remember-last": "Remember my last editor",
        "visualeditor-recreate": "The page has been deleted since you started 
editing. Press \"$1\" to recreate it.",
        "visualeditor-reference-input-placeholder": "Search within current 
citations",
        "visualeditor-referenceslist-isempty": "There are no references with 
the group \"$1\" on this page to include in this list.",
diff --git a/modules/ve-mw/i18n/qqq.json b/modules/ve-mw/i18n/qqq.json
index 946fa8e..a66f15c 100644
--- a/modules/ve-mw/i18n/qqq.json
+++ b/modules/ve-mw/i18n/qqq.json
@@ -249,6 +249,9 @@
        "visualeditor-differror": "Text shown when the editor fails to load the 
diff.\n\nParameters:\n* $1 is an error message, in English.",
        "visualeditor-donebutton-tooltip": "Tooltip text for done editing 
button in mobile, closing the edit toolbar and blurring the surface.",
        "visualeditor-editconflict": "Alert message when saving a page causes 
an edit conflict",
+       "visualeditor-editingtabdialog-body": "Text shown to users to explain 
the single edit tab and give them the option to change.\n\nParameters:\n* $1 is 
the localised label of the edit tab.",
+       "visualeditor-editingtabdialog-ok": "Label of the button shown to users 
in the editing tab dialog to close the dialog and leave the default 
preference.",
+       "visualeditor-editingtabdialog-title": "Title of the editing tab 
dialog.",
        "visualeditor-editnotices-tool": "Text of tool in the toolbar that 
shows edit notices (such as [[MediaWiki:Editnotice-0]] and 
[[MediaWiki:Editnotice-8/en]]) as a pop-up.\n\nParameters:\n* $1 - the number 
of notices\n{{Identical|Notice}}",
        "visualeditor-editnotices-tooltip": "Text of tooltip for the tool in 
the toolbar that shows edit notices (i.e. “messages about the editing”), e.g. 
the “you are not currently logged in” notice",
        "visualeditor-editsummary": "Label for the edit summary box",
@@ -307,6 +310,11 @@
        "visualeditor-preference-core-info-link": "{{optional|Used on 
[[Special:Preferences]] as a link to a page where users can learn about this 
Beta Feature. Defaults to a page on MediaWiki.org.}}",
        "visualeditor-preference-core-label": "Used in 
[[Special:Preferences]].\n\nUsed as label for checkbox to enable 
VisualEditor.\n\nThe description for this checkbox is:\n* 
{{msg-mw|Visualeditor-preference-core-description}}",
        "visualeditor-preference-enable": "Label for the user preference to 
enable VisualEditor while it is in alpha (opt-in) mode.\nLinks are in 
{{msg-mw|Visualeditor-mainnamespacepagelink}} and 
{{msg-mw|visualeditor-usernamespacepagelink}}.\n\nParameters:\n* $1 - Comma 
separated list of namespace names.\n* $2 - Number of namespaces in which it 
will be used.\n\nSee also:\n* 
{{msg-mw|Visualeditor-preference-core-description}}",
+       "visualeditor-preference-tabs": "Label for the user preference to 
change how VisualEditor tabs display to the user",
+       "visualeditor-preference-tabs-multi-tab": "Used in 
[[Special:Preferences]].\n\nUsed as label for a radio button to have 
VisualEditor always use a separate tab.",
+       "visualeditor-preference-tabs-prefer-ve": "Used in 
[[Special:Preferences]].\n\nUsed as label for a radio button to have 
VisualEditor be the preferred editor.",
+       "visualeditor-preference-tabs-prefer-wt": "Used in 
[[Special:Preferences]].\n\nUsed as label for a radio button to have the 
wikitext editor be the preferred editor.",
+       "visualeditor-preference-tabs-remember-last": "Used in 
[[Special:Preferences]].\n\nUsed as label for a radio button to have 
VisualEditor remember whether it was the last editor or not.",
        "visualeditor-recreate": "Text shown when the editor fails to save the 
page due to it having been deleted since they opened VE. $1 is the message 
{{msg-mw|ooui-dialog-process-continue}}.",
        "visualeditor-reference-input-placeholder": "Placeholder text for 
reference search field: searches existing on-page references.",
        "visualeditor-referenceslist-isempty": "Message that appears in the 
references list when there are no references on the page of that 
group.\n\nParameters:\n* $1 - reference-group name",
diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js 
b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
index bd7e893..15f940a 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.init.js
@@ -18,9 +18,9 @@
  * @singleton
  */
 ( function () {
-       var conf, tabMessages, uri, pageExists, viewUri, veEditUri, isViewPage, 
pageCanLoadVE,
-               init, support, targetPromise, enable, tempdisable, autodisable, 
userPrefEnabled,
-               initialWikitext,
+       var conf, tabMessages, uri, pageExists, viewUri, veEditUri, isViewPage, 
isEditPage,
+               pageCanLoadVE, init, support, targetPromise, enable, 
tempdisable, autodisable,
+               userPrefEnabled, initialWikitext,
                active = false,
                progressStep = 0,
                progressSteps = [
@@ -148,17 +148,23 @@
                trackActivateStart( { type: 'page', mechanism: 'click' } );
 
                if ( !active ) {
-                       if ( history.pushState ) {
-                               // Replace the current state with one that is 
tagged as ours, to prevent the
-                               // back button from breaking when used to exit 
VE. FIXME: there should be a better
-                               // way to do this. See also similar code in the 
DesktopArticleTarget constructor.
-                               history.replaceState( { tag: 'visualeditor' }, 
document.title, uri );
-                               // Set veaction to edit
-                               history.pushState( { tag: 'visualeditor' }, 
document.title, veEditUri );
+                       if ( $( '#ca-edit a' ).data( 'original-text' ) ) {
+                               $( '#ca-edit a' ).text( $( '#ca-edit a' ).data( 
'original-text' ) );
                        }
 
-                       // Update mw.Uri instance
-                       uri = veEditUri;
+                       if ( uri.query.action !== 'edit' ) {
+                               if ( history.pushState ) {
+                                       // Replace the current state with one 
that is tagged as ours, to prevent the
+                                       // back button from breaking when used 
to exit VE. FIXME: there should be a better
+                                       // way to do this. See also similar 
code in the DesktopArticleTarget constructor.
+                                       history.replaceState( { tag: 
'visualeditor' }, document.title, uri );
+                                       // Set veaction to edit
+                                       history.pushState( { tag: 
'visualeditor' }, document.title, veEditUri );
+                               }
+
+                               // Update mw.Uri instance
+                               uri = veEditUri;
+                       }
 
                        activateTarget();
                }
@@ -187,6 +193,10 @@
                        .done( function () {
                                incrementLoadingProgress();
                        } );
+
+               $.cookie( 'VEE', 'visualeditor', { path: '/', expires: 30 } );
+               new mw.Api().saveOption( 'visualeditor-editor', 'visualeditor' 
);
+               mw.user.options.set( 'visualeditor-editor', 'visualeditor' );
 
                $( 'html' ).addClass( 've-activated ve-loading' );
                showLoading();
@@ -218,6 +228,14 @@
                mw.libs.ve.activationStart = ve.now();
        }
 
+       function getLastEditor() {
+               var editor = $.cookie( 'VEE' );
+               if ( !mw.user.isAnon() || !editor ) {
+                       editor = mw.user.options.get( 'visualeditor-editor' );
+               }
+               return editor;
+       }
+
        conf = mw.config.get( 'wgVisualEditorConfig' );
        tabMessages = conf.tabMessages;
        uri = new mw.Uri();
@@ -229,10 +247,19 @@
                mw.config.get( 'wgAction' ) === 'edit' ||
                mw.config.get( 'wgAction' ) === 'submit'
        );
+       isEditPage = conf.singleEditTab && (
+               uri.query.action === 'edit' ||
+               uri.query.action === 'submit'
+       );
        // On a view page, extend the current URI so parameters like oldid are 
carried over
        // On a non-view page, use viewUri
-       veEditUri = ( pageCanLoadVE ? uri : viewUri ).clone().extend( { 
veaction: 'edit' } );
-       delete veEditUri.query.action;
+       if ( conf.singleEditTab ) {
+               veEditUri = viewUri.clone().extend( { action: 'edit' } );
+               delete veEditUri.query.veaction;
+       } else {
+               veEditUri = ( pageCanLoadVE ? uri : viewUri ).clone().extend( { 
veaction: 'edit' } );
+               delete veEditUri.query.action;
+       }
 
        support = {
                es5: !!(
@@ -382,22 +409,6 @@
                        } else if ( pageCanLoadVE ) {
                                // Allow instant switching to edit mode, 
without refresh
                                $caVeEdit.click( init.onEditTabClick );
-
-                               if ( [ 'edit', 'submit' ].indexOf( 
mw.config.get( 'wgAction' ) ) !== -1 ) {
-                                       mw.loader.load( 
'ext.visualEditor.switching' );
-                                       $( '#wpTextbox1' ).on( 
'wikiEditor-toolbar-doneInitialSections', function () {
-                                               mw.loader.using( 
'ext.visualEditor.switching' ).done( function () {
-                                                       $( 
'.wikiEditor-ui-toolbar' ).prepend(
-                                                               new 
OO.ui.ButtonWidget( {
-                                                                       framed: 
false,
-                                                                       icon: 
'edit',
-                                                                       title: 
mw.msg( 'visualeditor-mweditmodeve-tool' ),
-                                                                       
classes: [ 've-init-mw-desktopArticleTarget-editSwitch' ]
-                                                               } ).on( 
'click', init.activateVe ).$element
-                                                       );
-                                               } );
-                                       } );
-                               }
                        }
 
                        // Alter the edit tab (#ca-edit)
@@ -636,6 +647,9 @@
                        conf.namespaces
                ) !== -1 &&
 
+               // Not on pages like Special:RevisionDelete
+               mw.config.get( 'wgNamespaceNumber' ) !== -1 &&
+
                // Not on pages which are outputs of the Page Translation 
feature
                mw.config.get( 'wgTranslatePageTranslation' ) !== 'translation' 
&&
 
@@ -664,36 +678,134 @@
        }
 
        $( function () {
-               var currentUri = new mw.Uri( location.href ),
-                       isSection;
-
-               if ( currentUri.query.action === 'edit' && $( '#wpTextbox1' 
).length ) {
+               var key;
+               if ( uri.query.action === 'edit' && $( '#wpTextbox1' ).length ) 
{
                        initialWikitext = $( '#wpTextbox1' ).val();
                }
 
                if ( init.isAvailable ) {
-                       if ( pageCanLoadVE && uri.query.veaction === 'edit' ) {
-                               isSection = uri.query.vesection !== undefined;
-
-                               trackActivateStart( { type: isSection ? 
'section' : 'page', mechanism: 'url' } );
+                       if (
+                               (
+                                       ( isViewPage && uri.query.veaction === 
'edit' ) ||
+                                       (
+                                               isEditPage &&
+                                               mw.user.options.get( 
'visualeditor-tabs' ) !== 'prefer-wt' &&
+                                               mw.user.options.get( 
'visualeditor-tabs' ) !== 'multi-tab'
+                                       )
+                               ) &&
+                               uri.query.veswitched === undefined && // TODO: 
other params too?
+                               (
+                                       (
+                                               mw.user.options.get( 
'visualeditor-tabs' ) === 'prefer-ve' &&
+                                               mw.config.get( 'wgAction' ) !== 
'submit'
+                                       ) || getLastEditor() !== 'wikitext'
+                               )
+                       ) {
+                               trackActivateStart( {
+                                       type: uri.query.vesection === undefined 
? 'page' : 'section',
+                                       mechanism: 'url'
+                               } );
                                activateTarget();
+                       }
+
+                       if ( [ 'edit', 'submit' ].indexOf( mw.config.get( 
'wgAction' ) ) !== -1 ) {
+                               mw.loader.load( 'ext.visualEditor.switching' );
+                               $( '#wpTextbox1' ).on( 
'wikiEditor-toolbar-doneInitialSections', function () {
+                                       mw.loader.using( 
'ext.visualEditor.switching' ).done( function () {
+                                               var windowManager, 
editingTabDialog;
+                                               $( '.wikiEditor-ui-toolbar' 
).prepend(
+                                                       new OO.ui.ButtonWidget( 
{
+                                                               framed: false,
+                                                               icon: 'edit',
+                                                               title: mw.msg( 
'visualeditor-mweditmodeve-tool' ),
+                                                               classes: [ 
've-init-mw-desktopArticleTarget-editSwitch' ]
+                                                       } ).on( 'click', 
init.activateVe ).$element
+                                               );
+
+                                               // Duplicate of this code in 
ve.init.mw.DesktopArticleTarget.js
+                                               if ( $( '#ca-edit' ).hasClass( 
'visualeditor-showtabdialog' ) ) {
+                                                       // Set up a temporary 
window manager
+                                                       windowManager = new 
OO.ui.WindowManager();
+                                                       $( 'body' ).append( 
windowManager.$element );
+                                                       editingTabDialog = new 
mw.libs.ve.EditingTabDialog();
+                                                       
windowManager.addWindows( [ editingTabDialog ] );
+                                                       
windowManager.openWindow( editingTabDialog, { message: mw.msg(
+                                                               
'visualeditor-editingtabdialog-body',
+                                                               $( '#ca-edit' 
).text()
+                                                       ) } )
+                                                               .then( function 
( opened ) { return opened; } )
+                                                               .then( function 
( closing ) { return closing; } )
+                                                               .then( function 
( data ) {
+                                                                       // 
Detach the temporary window manager
+                                                                       
windowManager.destroy();
+
+                                                                       if ( 
data && data.action === 'prefer-ve' ) {
+                                                                               
location.href = veEditUri;
+                                                                       }
+                                                               } );
+                                               }
+                                       } );
+                               } );
+                       }
+                       if (
+                               conf.singleEditTab &&
+                               mw.user.options.get( 'visualeditor-tabs' ) !== 
'multi-tab' &&
+                               userPrefEnabled
+                       ) {
+                               // Allow instant switching to edit mode, 
without refresh
+                               $( '#ca-edit' ).click( function ( e ) {
+                                       if (
+                                               mw.user.options.get( 
'visualeditor-tabs' ) === 'prefer-ve' ||
+                                               (
+                                                       getLastEditor() !== 
'wikitext' &&
+                                                       mw.user.options.get( 
'visualeditor-tabs' ) !== 'prefer-wt'
+                                               )
+                                       ) {
+                                               trackActivateStart( { type: 
'page', mechanism: 'click' } );
+                                               activateTarget();
+                                               e.preventDefault();
+                                       }
+                               } );
+                       } else if ( userPrefEnabled ) {
+                               init.setupSkin();
                        }
                }
 
-               if ( userPrefEnabled ) {
-                       init.setupSkin();
+               if (
+                       conf.singleEditTab &&
+                       mw.user.options.get( 'visualeditor-tabs' ) === 
'multi-tab' &&
+                       userPrefEnabled &&
+                       (
+                               init.isAvailable &&
+                               !mw.user.isAnon() &&
+                               getLastEditor() === 'wikitext'
+                       ) || (
+                               !init.isAvailable &&
+                               mw.user.options.get( 'visualeditor-tabs' ) === 
'prefer-ve'
+                       )
+               ) {
+                       key = pageExists ? 'edit' : 'create';
+                       if ( $( '#ca-view-foreign' ).length ) {
+                               key += 'localdescription';
+                       }
+                       key += 'source';
+                       if ( tabMessages[ key ] !== null ) {
+                               $( '#ca-edit a' )
+                                       .data( 'original-text', $( '#ca-edit a' 
).text() )
+                                       .text( mw.msg( tabMessages[ key ] ) );
+                       }
                }
 
-               if ( currentUri.query.venotify ) {
+               if ( uri.query.venotify ) {
                        // The following messages can be used here:
                        // postedit-confirmation-saved
                        // postedit-confirmation-created
                        // postedit-confirmation-restored
                        mw.hook( 'postEdit' ).fire( {
-                               message: mw.msg( 'postedit-confirmation-' + 
currentUri.query.venotify, mw.user )
+                               message: mw.msg( 'postedit-confirmation-' + 
uri.query.venotify, mw.user )
                        } );
 
-                       delete currentUri.query.venotify;
+                       delete uri.query.venotify;
                }
        } );
 }() );
diff --git a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js 
b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
index 73a9640..234867b 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.DesktopArticleTarget.js
@@ -232,11 +232,34 @@
  * @inheritdoc
  */
 ve.init.mw.DesktopArticleTarget.prototype.loadSuccess = function ( response ) {
-       var $checkboxes, defaults, data,
+       var $checkboxes, defaults, data, windowManager, editingTabDialog,
                target = this;
 
        // Parent method
        ve.init.mw.DesktopArticleTarget.super.prototype.loadSuccess.apply( 
this, arguments );
+
+       // Duplicate of this code in ve.init.mw.DesktopArticleTarget.init.js
+       if ( $( '#ca-edit' ).hasClass( 'visualeditor-showtabdialog' ) ) {
+               // Set up a temporary window manager
+               windowManager = new OO.ui.WindowManager();
+               $( 'body' ).append( windowManager.$element );
+               editingTabDialog = new mw.libs.ve.EditingTabDialog();
+               windowManager.addWindows( [ editingTabDialog ] );
+               windowManager.openWindow( editingTabDialog, { message: mw.msg(
+                       'visualeditor-editingtabdialog-body',
+                       $( '#ca-edit' ).text()
+               ) } )
+                       .then( function ( opened ) { return opened; } )
+                       .then( function ( closing ) { return closing; } )
+                       .then( function ( data ) {
+                               // Detach the temporary window manager
+                               windowManager.destroy();
+
+                               if ( data && data.action === 'prefer-wt' ) {
+                                       target.switchToWikitextEditor( true, 
false );
+                               }
+                       } );
+       }
 
        data = response ? response.visualeditor : {};
 
@@ -989,6 +1012,12 @@
        // separate tab sections for content actions and namespaces the below 
is a no-op.
        $( '#p-views' ).find( 'li.selected' ).removeClass( 'selected' );
        $( '#ca-ve-edit' ).addClass( 'selected' );
+       if (
+               mw.config.get( 'wgVisualEditorConfig' ).singleEditTab &&
+               mw.user.options.get( 'visualeditor-tabs' ) !== 'multi-tab'
+       ) {
+               $( '#ca-edit' ).addClass( 'selected' );
+       }
 
        mw.hook( 've.activate' ).fire();
 
@@ -997,12 +1026,23 @@
 
        // Push veaction=edit url in history (if not already. If we got here by 
a veaction=edit
        // permalink then it will be there already and the constructor called 
#activate)
-       if ( !this.actFromPopState && history.pushState && 
this.currentUri.query.veaction !== 'edit' ) {
+       if (
+               !this.actFromPopState &&
+               history.pushState &&
+               this.currentUri.query.veaction !== 'edit' &&
+               this.currentUri.query.action !== 'edit'
+       ) {
                // Set the current URL
                uri = this.currentUri;
-               uri.query.veaction = 'edit';
-               delete uri.query.action;
-               mw.config.set( 'wgAction', 'view' );
+
+               if ( mw.config.get( 'wgVisualEditorConfig' ).singleEditTab ) {
+                       uri.query.action = 'edit';
+                       mw.config.set( 'wgAction', 'edit' );
+               } else {
+                       uri.query.veaction = 'edit';
+                       delete uri.query.action;
+                       mw.config.set( 'wgAction', 'view' );
+               }
 
                history.pushState( this.popState, document.title, uri );
        }
@@ -1019,6 +1059,12 @@
        // selected. We didn't deselect the namespace tab, so we're ready after 
deselecting #ca-ve-edit.
        // In skins having #ca-view (like Vector), select that.
        $( '#ca-ve-edit' ).removeClass( 'selected' );
+       if (
+               mw.config.get( 'wgVisualEditorConfig' ).singleEditTab &&
+               mw.user.options.get( 'visualeditor-tabs' ) !== 'multi-tab'
+       ) {
+               $( '#ca-edit' ).removeClass( 'selected' );
+       }
        $( '#ca-view' ).addClass( 'selected' );
 
        mw.hook( 've.deactivate' ).fire();
@@ -1329,6 +1375,9 @@
  */
 ve.init.mw.DesktopArticleTarget.prototype.switchToWikitextEditor = function ( 
discardChanges, modified ) {
        var target = this;
+       $.cookie( 'VEE', 'wikitext', { path: '/', expires: 30 } );
+       new mw.Api().saveOption( 'visualeditor-editor', 'wikitext' );
+       mw.user.options.set( 'visualeditor-editor', 'wikitext' );
        if ( discardChanges ) {
                if ( modified ) {
                        ve.track( 'mwedit.abort', { type: 'switchwithout', 
mechanism: 'navigate' } );
diff --git a/modules/ve-mw/init/ve.init.MWEditingTabDialog.js 
b/modules/ve-mw/init/ve.init.MWEditingTabDialog.js
new file mode 100644
index 0000000..fd9018b
--- /dev/null
+++ b/modules/ve-mw/init/ve.init.MWEditingTabDialog.js
@@ -0,0 +1,86 @@
+/*!
+ * VisualEditor user interface MWEditingTabDialog class.
+ *
+ * @copyright 2011-2015 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+mw.libs.ve = mw.libs.ve || {};
+/**
+ * Dialog for allowing new users to change editing tab preferences to 
VisualEditor.
+ *
+ * @class
+ * @extends OO.ui.MessageDialog
+ *
+ * @constructor
+ * @param {Object} [config] Configuration options
+ */
+mw.libs.ve.EditingTabDialog = function MWLibsVEMWEditingTabDialog( config ) {
+       // Parent constructor
+       mw.libs.ve.EditingTabDialog.super.call( this, config );
+};
+
+/* Inheritance */
+
+OO.inheritClass( mw.libs.ve.EditingTabDialog, OO.ui.MessageDialog );
+
+/* Static Properties */
+
+mw.libs.ve.EditingTabDialog.static.name = 'editingtab';
+
+mw.libs.ve.EditingTabDialog.static.size = 'medium';
+
+mw.libs.ve.EditingTabDialog.static.verbose = true;
+
+mw.libs.ve.EditingTabDialog.static.icon = 'help';
+
+mw.libs.ve.EditingTabDialog.static.title = mw.msg( 
'visualeditor-editingtabdialog-title' );
+
+mw.libs.ve.EditingTabDialog.static.actions = [
+
+       {
+               action: 'prefer-wt',
+               label: mw.msg( 'visualeditor-preference-tabs-prefer-wt' )
+       },
+       {
+               action: 'prefer-ve',
+               label: mw.msg( 'visualeditor-preference-tabs-prefer-ve' )
+       },
+       {
+               action: 'multi-tab',
+               label: mw.msg( 'visualeditor-preference-tabs-multi-tab' )
+       },
+       {
+               label: mw.msg( 'visualeditor-editingtabdialog-ok' ),
+               flags: [ 'progressive', 'primary' ]
+       }
+];
+
+/* Methods */
+
+/**
+ * @inheritdoc
+ */
+mw.libs.ve.EditingTabDialog.prototype.getSetupProcess = function ( action ) {
+       return 
mw.libs.ve.EditingTabDialog.super.prototype.getSetupProcess.call( this, action )
+               .next( function () {
+                       new mw.Api().saveOption( 'visualeditor-hidetabdialog', 
1 );
+                       mw.user.options.set( 'visualeditor-hidetabdialog', 1 );
+               } );
+};
+
+/**
+ * @inheritdoc
+ */
+mw.libs.ve.EditingTabDialog.prototype.getActionProcess = function ( action ) {
+       if ( action ) {
+               return new OO.ui.Process( function () {
+                       new mw.Api().saveOption( 'visualeditor-tabs', action );
+                       mw.user.options.set( 'visualeditor-tabs', action );
+                       this.close( { action: action } );
+               }, this );
+       } else {
+               // Parent method
+               return 
mw.libs.ve.EditingTabDialog.super.prototype.getActionProcess.call( this, action 
);
+       }
+};

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I65d966270491ffe017cb11a0daa915628fadf65c
Gerrit-PatchSet: 40
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Alex Monk <[email protected]>
Gerrit-Reviewer: Alex Monk <[email protected]>
Gerrit-Reviewer: BBlack <[email protected]>
Gerrit-Reviewer: Esanders <[email protected]>
Gerrit-Reviewer: Jforrester <[email protected]>
Gerrit-Reviewer: Krinkle <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

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

Reply via email to