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

Change subject: Move edit tab generation into PHP and make it more configurable
......................................................................


Move edit tab generation into PHP and make it more configurable

* Generate the edit tabs and the section edit links in PHP, with a
  fallback in JS for cases where we don't have them yet due to
  caching. But only change things if VE is enabled, and have the JS
  correct the state if the wrong cached HTML comes through.
* Make the order of the tabs/links and the messages to use as captions
  configurable
* Make the edit tabs and section edit links always be present in the
  page (regardless of namespace, user prefs, etc.) but be hidden and
  have JS unhide them (using html.ve-available) if appropriate
* Add appendix messages so we can do a superscript "beta" even in places
  where we can't use HTML in the message

VisualEditor.php:
* Add new hook registrations
* Remove edit link caption messages from the init init module because
  they're now added dynamically in VisualEditor.hooks.php
* Add a noscript CSS module so we can hide some things in JS-less
  environments
* Remove $wgVisualEditorTabLayout and replace it with
  $wgVisualEditorPosition
* Add config vars for link captions, with null causing us to use
  the default caption
* Add config vars for link caption appendices. Too many config vars
  but we'll clean that up later

VisualEditor.hooks.php:
* Dynamically add tab messages to the init init module
* Remove unused globals in onBeforePageDisplay()
* Add noscript CSS module
* Add a SkinTemplateNavigation hook that changes and reorders the edit
  tabs as appropriate
* Add a DoEditSectionLink hook that overwrites the edit section links
* Export the new config variables to JS

VisualEditor.i18n.php:
* Add beta appendix message
* Add a message for the default VE edit section link

ve.init.mw.ViewPageTarget.init.css:
* Remove the animation on the edit section links
* Darken the color of the brackets and the pipe from #ccc to #555
* Style the beta message to be superscript-like (but not real <sup> to
  avoid moving the baseline)

ve.init.mw.ViewPageTarget.noscript.css:
* Hide the VE edit tab, the pipe and the VE edit section link initally
  unless and until JS unhides

ve.init.mw.ViewPageTarget.init.js:
* Toggle .ve-not-available / .ve-available
* Edit tabs
** Only generate the the edit tabs if they're not already there from PHP
** Rewrite the edit tab generation to mirror what's being done in PHP
* Section edit links
** Same as for edit tabs
** Also add mw-visualeditor-expanded to pad the brackets

ve.init.mw.ViewPageTarget.js:
* #ca-ve-edit is now always the VE tab (and #ca-edit always the
  edit source tab) so update the .selected behavior accordingly

Change-Id: Idcb15faea7fabe5fe7578b1508079969b27d2469
---
M VisualEditor.hooks.php
M VisualEditor.i18n.php
M VisualEditor.php
M modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.init.css
A modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.noscript.css
M modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.init.js
M modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js
7 files changed, 346 insertions(+), 168 deletions(-)

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



diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php
index 7b1153a..88059ed 100644
--- a/VisualEditor.hooks.php
+++ b/VisualEditor.hooks.php
@@ -14,7 +14,7 @@
 
        public static function onSetup() {
                global $wgVisualEditorEnableEventLogging, $wgResourceModules,
-                       $wgVisualEditorResourceTemplate;
+                       $wgVisualEditorResourceTemplate, 
$wgVisualEditorTabMessages;
 
                // This prevents VisualEditor from being run in environments 
that don't
                // have the dependent code in core; this should be updated as a 
part of
@@ -24,6 +24,13 @@
                // this should have no impact on deploying to Wikimedia's wiki 
cluster.
                // Is fine for release tarballs because 1.22wmf11 < 1.22alpha < 
1.22.0.
                wfUseMW( '1.22wmf11' );
+
+               // Add tab messages to the init init module
+               foreach ( $wgVisualEditorTabMessages as $msg ) {
+                       if ( $msg !== null ) {
+                               
$wgResourceModules['ext.visualEditor.viewPageTarget.init']['messages'][] = $msg;
+                       }
+               }
 
                if ( $wgVisualEditorEnableEventLogging ) {
                        if ( class_exists( 'ResourceLoaderSchemaModule' ) ) {
@@ -78,7 +85,7 @@
        }
 
        /**
-        * Adds VisualEditor JS to the output if in the correct namespace.
+        * Adds VisualEditor JS to the output.
         *
         * This is attached to the MediaWiki 'BeforePageDisplay' hook.
         *
@@ -86,14 +93,147 @@
         * @param $skin Skin
         */
        public static function onBeforePageDisplay( &$output, &$skin ) {
-               global $wgVisualEditorNamespaces, 
$wgVisualEditorEnableEventLogging,
-                       $wgVisualEditorDisableForAnons;
+               global $wgVisualEditorEnableEventLogging;
 
                if ( $wgVisualEditorEnableEventLogging ) {
                        $output->addModules( array( 'schema.Edit' ) );
                }
 
                $output->addModules( array( 
'ext.visualEditor.viewPageTarget.init' ) );
+               $output->addModuleStyles( array( 
'ext.visualEditor.viewPageTarget.noscript' ) );
+
+               return true;
+       }
+
+       /**
+        * Changes the Edit tab and adds the VisualEditor tab.
+        *
+        * This is attached to the MediaWiki 'SkinTemplateNavigation' hook.
+        *
+        * @param SkinTemplate $skin
+        * @param array $links Navigation links
+        * @return boolean
+        */
+       public static function onSkinTemplateNavigation( &$skin, &$links ) {
+               // Only do this if the user has VE enabled
+               if (
+                       !$skin->getUser()->getOption( 'visualeditor-enable' ) ||
+                       $skin->getUser()->getOption( 
'visualeditor-betatempdisable' )
+               ) {
+                       return true;
+               }
+
+               global $wgVisualEditorTabMessages, $wgVisualEditorTabPosition;
+               if ( !isset( $links['views']['edit'] ) ) {
+                       // There's no edit link, nothing to do
+                       return true;
+               }
+               $title = $skin->getRelevantTitle();
+               // Rebuild the $links['views'] array and inject the 
VisualEditor tab before or after
+               // the edit tab as appropriate. We have to rebuild the array 
because PHP doesn't allow
+               // us to splice into the middle of an associative array.
+               $newViews = array();
+               foreach ( $links['views'] as $action => $data ) {
+                       if ( $action === 'edit' ) {
+                               // Build the VisualEditor tab
+                               $existing = $title->exists() || (
+                                       $title->getNamespace() == NS_MEDIAWIKI 
&&
+                                       $title->getDefaultMessageText() !== 
false
+                               );
+                               $veParams = $skin->editUrlOptions();
+                               unset( $veParams['action'] ); // Remove 
action=edit
+                               $veParams['veaction'] = 'edit'; // Set 
veaction=edit
+                               $veTabMessage = 
$wgVisualEditorTabMessages[$existing ? 'edit' : 'create'];
+                               $veTabText = $veTabMessage === null ? 
$data['text'] :
+                                       wfMessage( $veTabMessage )->setContext( 
$skin->getContext() )->text();
+                               $veTab = array(
+                                       'href' => $title->getLocalURL( 
$veParams ),
+                                       'text' => $veTabText,
+                                       'primary' => true,
+                                       'class' => '',
+                               );
+
+                               // Alter the edit tab
+                               $editTab = $data;
+                               $editTabMessage = 
$wgVisualEditorTabMessages[$existing ? 'editsource' : 'createsource'];
+                               if ( $editTabMessage !== null ) {
+                                       $editTab['text'] = wfMessage( 
$editTabMessage )->setContext( $skin->getContext() )->text();
+                               }
+
+                               // Inject the VE tab before or after the edit 
tab
+                               if ( $wgVisualEditorTabPosition === 'before' ) {
+                                       $newViews['ve-edit'] = $veTab;
+                                       $newViews['edit'] = $editTab;
+                               } else {
+                                       $newViews['edit'] = $editTab;
+                                       $newViews['ve-edit'] = $veTab;
+                               }
+                       } else {
+                               // Just pass through
+                               $newViews[$action] = $data;
+                       }
+               }
+               $links['views'] = $newViews;
+               return true;
+       }
+
+       /**
+        * Changes the section edit links to add a VE edit link.
+        *
+        * This is attached to the MediaWiki 'DoEditSectionLink' hook.
+        *
+        * @param $skin Skin
+        * @param $title Title
+        * @param $section string
+        * @param $tooltip string
+        * @param $result string HTML
+        * @param $lang Language
+        * @returns bool true
+        */
+       public static function onDoEditSectionLink( $skin, $title, $section, 
$tooltip, &$result, $lang ) {
+               // Only do this if the user has VE enabled
+               if (
+                       !$skin->getUser()->getOption( 'visualeditor-enable' ) ||
+                       $skin->getUser()->getOption( 
'visualeditor-betatempdisable' )
+               ) {
+                       return;
+               }
+
+               global $wgVisualEditorTabMessages, $wgVisualEditorTabPosition;
+               $veEditSection = $wgVisualEditorTabMessages['editsection'] !== 
null ?
+                       $wgVisualEditorTabMessages['editsection'] : 
'editsection';
+               $sourceEditSection = 
$wgVisualEditorTabMessages['editsectionsource'] !== null ?
+                       $wgVisualEditorTabMessages['editsectionsource'] : 
'editsection';
+
+               // Code mostly duplicated from Skin::doEditSectionLink() :(
+               $attribs = array();
+               if ( !is_null( $tooltip ) ) {
+                       # Bug 25462: undo double-escaping.
+                       $tooltip = Sanitizer::decodeCharReferences( $tooltip );
+                       $attribs['title'] = wfMessage( 'editsectionhint' 
)->rawParams( $tooltip )
+                               ->inLanguage( $lang )->text();
+               }
+               $veLink = Linker::link( $title, wfMessage( $veEditSection 
)->inLanguage( $lang )->text(),
+                       $attribs + array( 'class' => 
'mw-editsection-visualeditor' ),
+                       array( 'veaction' => 'edit', 'section' => $section ),
+                       array( 'noclasses', 'known' )
+               );
+               $sourceLink = Linker::link( $title, wfMessage( 
$sourceEditSection )->inLanguage( $lang )->text(),
+                       $attribs,
+                       array( 'action' => 'edit', 'section' => $section ),
+                       array( 'noclasses', 'known' )
+               );
+
+               $veFirst = $wgVisualEditorTabPosition === 'before';
+               $result = '<span class="mw-editsection">'
+                       . '<span class="mw-editsection-bracket">[</span>'
+                       . ( $veFirst ? $veLink : $sourceLink )
+                       . '<span class="mw-editsection-divider">'
+                       . wfMessage( 'pipe-separator' )->inLanguage( $lang 
)->text()
+                       . '</span>'
+                       . ( $veFirst ? $sourceLink : $veLink )
+                       . '<span class="mw-editsection-bracket">]</span>'
+                       . '</span>';
 
                return true;
        }
@@ -146,7 +286,8 @@
                        $wgVisualEditorEnableExperimentalCode,
                        $wgVisualEditorNamespaces,
                        $wgVisualEditorPluginModules,
-                       $wgVisualEditorTabLayout;
+                       $wgVisualEditorTabPosition,
+                       $wgVisualEditorTabMessages;
 
                $vars['wgVisualEditorConfig'] = array(
                        'disableForAnons' => $wgVisualEditorDisableForAnons,
@@ -159,7 +300,8 @@
                                'betatempdisable' => 
$wgDefaultUserOptions['visualeditor-betatempdisable'],
                        ),
                        'skins' => self::$supportedSkins,
-                       'tabLayout' => $wgVisualEditorTabLayout,
+                       'tabPosition' => $wgVisualEditorTabPosition,
+                       'tabMessages' => $wgVisualEditorTabMessages,
                );
 
                return true;
diff --git a/VisualEditor.i18n.php b/VisualEditor.i18n.php
index f4aacde..1da0d2f 100644
--- a/VisualEditor.i18n.php
+++ b/VisualEditor.i18n.php
@@ -35,12 +35,14 @@
        'visualeditor-annotationbutton-language-tooltip' => 'Language',
        'visualeditor-beta-label' => 'beta',
        'visualeditor-beta-warning' => 'VisualEditor is in \'beta\'. You may 
encounter software issues, and you may not be able to edit parts of the page. 
Click "{{int:visualeditor-ca-editsource}}" to switch to wikitext mode – unsaved 
changes will be lost.',
+       'visualeditor-beta-appendix' => 'beta',
        'visualeditor-browserwarning' => 'You are using a browser which is not 
officially supported by VisualEditor.',
        'visualeditor-ca-createsource' => 'Create source',
        'visualeditor-ca-editsource' => 'Edit source',
        'visualeditor-ca-editsource-section' => 'edit source',
        'visualeditor-ca-ve-create' => 'VisualEditor',
        'visualeditor-ca-ve-edit' => 'VisualEditor',
+       'visualeditor-ca-ve-edit-section' => 'VisualEditor',
        'visualeditor-clearbutton-tooltip' => 'Clear formatting',
        'visualeditor-desc' => 'Visual editor for MediaWiki',
        'visualeditor-descriptionpagelink' => 'Project:VisualEditor',
diff --git a/VisualEditor.php b/VisualEditor.php
index b4db84c..0eb7f35 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -46,11 +46,13 @@
 
 // Register Hooks
 $wgHooks['BeforePageDisplay'][] = 'VisualEditorHooks::onBeforePageDisplay';
+$wgHooks['DoEditSectionLink'][] = 'VisualEditorHooks::onDoEditSectionLink';
 $wgHooks['GetPreferences'][] = 'VisualEditorHooks::onGetPreferences';
 $wgHooks['ListDefinedTags'][] = 'VisualEditorHooks::onListDefinedTags';
 $wgHooks['MakeGlobalVariablesScript'][] = 
'VisualEditorHooks::onMakeGlobalVariablesScript';
 $wgHooks['ResourceLoaderGetConfigVars'][] = 
'VisualEditorHooks::onResourceLoaderGetConfigVars';
 $wgHooks['ResourceLoaderTestModules'][] = 
'VisualEditorHooks::onResourceLoaderTestModules';
+$wgHooks['SkinTemplateNavigation'][] = 
'VisualEditorHooks::onSkinTemplateNavigation';
 $wgExtensionFunctions[] = 'VisualEditorHooks::onSetup';
 
 // Bug 49604: Running split test in production if 
$wgVisualEditorEnableSplitTest is true.
@@ -144,13 +146,13 @@
                        'tooltip-ca-createsource',
                        'tooltip-ca-editsource',
                        'tooltip-ca-ve-edit',
-                       'visualeditor-ca-createsource',
-                       'visualeditor-ca-editsource',
                        'visualeditor-ca-editsource-section',
-                       'visualeditor-ca-ve-create',
-                       'visualeditor-ca-ve-edit',
                ),
                'position' => 'top',
+       ),
+
+       'ext.visualEditor.viewPageTarget.noscript' => 
$wgVisualEditorResourceTemplate + array(
+               'styles' => 
've-mw/init/styles/ve.init.mw.ViewPageTarget.noscript.css',
        ),
 
        'ext.visualEditor.viewPageTarget' => $wgVisualEditorResourceTemplate + 
array(
@@ -774,7 +776,40 @@
 // Whether to enable incomplete experimental code
 $wgVisualEditorEnableExperimentalCode = false;
 
-// Whether to use the 'add' or 'replace' tabLayout
-// * add: Adds #ca-ve-edit.
-// * replace: Re-creates #ca-edit for VisualEditor and adds #ca-editsource.
-$wgVisualEditorTabLayout = 'replace';
+// Where to put the VisualEditor edit tab
+// 'before': put it right before the old edit tab
+// 'after': put it right after the old edit tab
+$wgVisualEditorTabPosition = 'before';
+
+$wgVisualEditorTabMessages = array(
+       // i18n message key to use for the VisualEditor edit tab
+       // If null, the default edit tab caption will be used
+       // The 'visualeditor-ca-ve-edit' message is available for this
+       'edit' => null,
+       // i18n message key to use for the old edit tab
+       // If null, the tab's caption will not be changed
+       'editsource' => 'visualeditor-ca-editsource',
+       // i18n message key to use for the VisualEditor create tab
+       // If null, the default create tab caption will be used
+       // The 'visualeditor-ca-ve-create' message is available for this
+       'create' => null,
+       // i18n message key to use for the old create tab
+       // If null, the tab's caption will not be changed
+       'createsource' => 'visualeditor-ca-createsource',
+       // i18n message key to use for the VisualEditor section edit link
+       // If null, the default edit section link caption will be used
+       'editsection' => null,
+       // i18n message key to use for the source section edit link
+       // If null, the link's caption will not be changed
+       'editsectionsource' => 'visualeditor-ca-editsource-section',
+
+       // i18n message key for an optional appendix to add to each of these 
from JS
+       // Use this if you have HTML messages to add
+       // The 'visualeditor-beta-appendix' message is available for this 
purpose
+       'editappendix' => null,
+       'editsourceappendix' => null,
+       'createappendix' => null,
+       'createsourceappendix' => null,
+       'editsectionappendix' => null,
+       'editsectionsourceappendix' => null,
+);
diff --git a/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.init.css 
b/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.init.css
index ac43b05..c860036 100644
--- a/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.init.css
+++ b/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.init.css
@@ -17,15 +17,7 @@
 }
 
 .mw-editsection-divider {
-       color: #ccc;
-}
-
-.mw-editsection-bracket {
-       -webkit-transition: color 100ms ease-out, margin 100ms ease-out;
-       -moz-transition: color 100ms ease-out, margin 100ms ease-out;
-       -ms-transition: color 100ms ease-out, margin 100ms ease-out;
-       -o-transition: color 100ms ease-out, margin 100ms ease-out;
-       transition: color 100ms ease-out, margin 100ms ease-out;
+       color: #555;
 }
 
 /* @noflip */
@@ -33,7 +25,7 @@
 .mw-content-rtl .mw-editsection-expanded 
.mw-editsection-bracket:not(:first-of-type) {
        margin-left: -0.25em;
        margin-right: 0.25em;
-       color: #ccc;
+       color: #555;
 }
 
 /* @noflip */
@@ -41,5 +33,15 @@
 .mw-content-ltr .mw-editsection-expanded 
.mw-editsection-bracket:not(:first-of-type) {
        margin-right: -0.25em;
        margin-left: 0.25em;
-       color: #ccc;
+       color: #555;
+}
+
+.ve-tabmessage-appendix {
+       font-size: 0.7em;
+       vertical-align: top;
+       line-height: 1.43em;
+       padding-left: 0.5em;
+       /* Use !important to override div.vectorTabs span */
+       background-image: none !important;
+       display: inline !important;
 }
diff --git a/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.noscript.css 
b/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.noscript.css
new file mode 100644
index 0000000..5dfa321
--- /dev/null
+++ b/modules/ve-mw/init/styles/ve.init.mw.ViewPageTarget.noscript.css
@@ -0,0 +1,13 @@
+/*!
+ * VisualEditor MediaWiki ViewPageTarget noscript styles
+ *
+ * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt
+ * @license The MIT License (MIT); see LICENSE.txt
+ */
+
+/* Hide VE edit tab and section edit things by default, and unhide them if VE 
is available. */
+.client-nojs #ca-ve-edit, .ve-not-available #ca-ve-edit,
+.client-nojs .mw-editsection-divider, .ve-not-available 
.mw-editsection-divider,
+.client-nojs .mw-editsection-visualeditor, .ve-not-available 
.mw-editsection-visualeditor {
+       display: none;
+}
diff --git a/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.init.js 
b/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.init.js
index 0b7af16..f5bee9d 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.init.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.init.js
@@ -149,177 +149,159 @@
                },
 
                setupTabLayout: function () {
-                       var caVeEdit, caVeEditSource,
+                       var caVeEdit,
                                action = pageExists ? 'edit' : 'create',
                                pTabsId = $( '#p-views' ).length ? 'p-views' : 
'p-cactions',
                                $caSource = $( '#ca-viewsource' ),
                                $caEdit = $( '#ca-edit' ),
+                               $caVeEdit = $( '#ca-ve-edit' ),
                                $caEditLink = $caEdit.find( 'a' ),
+                               $caVeEditLink = $caVeEdit.find( 'a' ),
                                reverseTabOrder = $( 'body' ).hasClass( 'rtl' ) 
&& pTabsId === 'p-views',
-                               caVeEditNextnode = reverseTabOrder ? 
$caEdit.get( 0 ) : $caEdit.next().get( 0 );
+                               /*jshint bitwise:false */
+                               caVeEditNextnode = ( reverseTabOrder ^ 
conf.tabPosition === 'before' ) ? $caEdit.get( 0 ) : $caEdit.next().get( 0 ),
+                               tabMessages = conf.tabMessages;
 
-                       if ( !$caEdit.length || $caSource.length ) {
+                       if ( !$caVeEdit.length ) {
+                               // The below duplicates the functionality of 
VisualEditorHooks::onSkinTemplateNavigation()
+                               // in case we're running on a cached page that 
doesn't have these tabs yet.
+
                                // If there is no edit tab or a view-source tab,
                                // the user doesn't have permission to edit.
-                               return;
+                               if ( $caEdit.length && !$caSource.length ) {
+                                       // Add the VisualEditor tab 
(#ca-ve-edit)
+                                       caVeEdit = mw.util.addPortletLink(
+                                               pTabsId,
+                                               // Use url instead of '#'.
+                                               // So that 1) one can always 
open it in a new tab, even when
+                                               // onEditTabClick is bound.
+                                               // 2) when onEditTabClick is 
not bound (!isViewPage) it will
+                                               // just work.
+                                               veEditUri,
+                                               tabMessages[action] !== null ? 
mw.msg( tabMessages[action] ) : $caEditLink.text(),
+                                               'ca-ve-edit',
+                                               mw.msg( 'tooltip-ca-ve-edit' ),
+                                               mw.msg( 'accesskey-ca-ve-edit' 
),
+                                               caVeEditNextnode
+                                       );
+
+                                       $caVeEdit = $( caVeEdit );
+                                       $caVeEditLink = $caVeEdit.find( 'a' );
+                               }
+                       } else {
+                               // Make the state of the page consistent with 
the config if needed
+                               /*jshint bitwise:false */
+                               if ( reverseTabOrder ^ conf.tabPosition === 
'before' ) {
+                                       if ( $caEdit[0].nextSibling === 
$caVeEdit[0] ) {
+                                               $caVeEdit.after( $caEdit );
+                                       }
+                               } else {
+                                       if ( $caVeEdit[0].nextSibling === 
$caEdit[0] ) {
+                                               $caEdit.after( $caVeEdit );
+                                       }
+                               }
+                               if ( tabMessages[action] !== null ) {
+                                       $caVeEditLink.text( mw.msg( 
tabMessages[action] ) );
+                               }
                        }
 
-                       // Add independent "VisualEditor" tab (#ca-ve-edit).
-                       if ( conf.tabLayout === 'add' ) {
-
-                               caVeEdit = mw.util.addPortletLink(
-                                       pTabsId,
-                                       // Use url instead of '#'.
-                                       // So that 1) one can always open it in 
a new tab, even when
-                                       // onEditTabClick is bound.
-                                       // 2) when onEditTabClick is not bound 
(!isViewPage) it will
-                                       // just work.
-                                       veEditUri,
-                                       // visualeditor-ca-ve-create
-                                       // visualeditor-ca-ve-edit
-                                       mw.msg( 'visualeditor-ca-ve-' + action 
),
-                                       'ca-ve-edit',
-                                       mw.msg( 'tooltip-ca-ve-edit' ),
-                                       mw.msg( 'accesskey-ca-ve-edit' ),
-                                       caVeEditNextnode
+                       // Alter the edit tab (#ca-edit)
+                       if ( tabMessages[action + 'source'] !== null ) {
+                               $caEditLink.text( mw.msg( tabMessages[action + 
'source'] ) );
+                       }
+                       // Process appendix messages
+                       if ( tabMessages[action + 'appendix'] !== null ) {
+                               $caVeEditLink.append(
+                                       $( '<span>' )
+                                               .addClass( 
've-tabmessage-appendix' )
+                                               .text( mw.msg( 
tabMessages[action + 'appendix'] ) )
                                );
-
-                       // Replace "Edit" tab with a veEditUri version, add 
"Edit source" tab.
-                       } else {
-                               // Create "Edit source" link.
-                               // Re-create instead of convert ca-edit since 
we don't want to copy over accesskey etc.
-                               caVeEditSource = mw.util.addPortletLink(
-                                       pTabsId,
-                                       // Use original href to preserve oldid 
etc. (bug 38125)
-                                       $caEditLink.attr( 'href' ),
-                                       // visualeditor-ca-createsource
-                                       // visualeditor-ca-editsource
-                                       mw.msg( 'visualeditor-ca-' + action + 
'source' ),
-                                       'ca-editsource',
-                                       // tooltip-ca-editsource
-                                       // tooltip-ca-createsource
-                                       mw.msg( 'tooltip-ca-' + action + 
'source' ),
-                                       mw.msg( 'accesskey-ca-editsource' ),
-                                       caVeEditNextnode
-                               );
-                               // Copy over classes (e.g. 'selected')
-                               $( caVeEditSource ).addClass( $caEdit.attr( 
'class' ) );
-
-                               // Create "Edit" tab.
-                               $caEdit.remove();
-                               caVeEdit = mw.util.addPortletLink(
-                                       pTabsId,
-                                       // Use url instead of '#'.
-                                       // So that 1) one can always open it in 
a new tab, even when
-                                       // onEditTabClick is bound.
-                                       // 2) when onEditTabClick is not bound 
(!isViewPage) it will
-                                       // just work.
-                                       veEditUri,
-                                       $caEditLink.text(),
-                                       $caEdit.attr( 'id' ),
-                                       $caEditLink.attr( 'title' ),
-                                       mw.msg( 'accesskey-ca-ve-edit' ),
-                                       reverseTabOrder ? 
caVeEditSource.nextSibling : caVeEditSource
+                       }
+                       if ( tabMessages[action + 'sourceappendix'] !== null ) {
+                               $caEditLink.append(
+                                       $( '<span>' )
+                                               .addClass( 
've-tabmessage-appendix' )
+                                               .text( mw.msg( 
tabMessages[action + 'sourceappendix'] ) )
                                );
                        }
 
                        if ( isViewPage ) {
                                // Allow instant switching to edit mode, 
without refresh
-                               $( caVeEdit ).click( init.onEditTabClick );
+                               $caVeEdit.click( init.onEditTabClick );
                        }
                },
 
                setupSectionEditLinks: function () {
-                       var $editsections = $( '#mw-content-text 
.mw-editsection' );
+                       var $editsections = $( '#mw-content-text 
.mw-editsection' ),
+                               tabMessages = conf.tabMessages;
 
                        // match direction to the user interface
                        $editsections.css( 'direction', $( 'body' ).css( 
'direction' ) );
                        // The "visibility" css construct ensures we always 
occupy the same space in the layout.
                        // This prevents the heading from changing its wrap 
when the user toggles editSourceLink.
-                       $editsections.each( function () {
-                               var $closingBracket, $expandedOnly, 
$hiddenBracket, $outerClosingBracket,
-                                       expandTimeout, shrinkTimeout,
-                                       $editsection = $( this ),
-                                       $heading = $editsection.closest( 'h1, 
h2, h3, h4, h5, h6' ),
-                                       $editLink = $editsection.find( 'a' 
).eq( 0 ),
-                                       $editSourceLink = $editLink.clone(),
-                                       $links = $editLink.add( $editSourceLink 
),
-                                       $divider = $( '<span>' ),
-                                       dividerText = $.trim( mw.msg( 
'pipe-separator' ) ),
-                                       $brackets = $( [ this.firstChild, 
this.lastChild ] );
+                       if ( $editsections.find( '.mw-editsection-visualeditor' 
).length === 0 ) {
+                               // If PHP didn't build the section edit links 
(because of caching), build them
+                               $editsections.each( function () {
+                                       var $editsection = $( this ),
+                                               $editSourceLink = 
$editsection.find( 'a' ).eq( 0 ),
+                                               $editLink = 
$editSourceLink.clone(),
+                                               $divider = $( '<span>' ),
+                                               dividerText = mw.msg( 
'pipe-separator' );
 
-                               function expandSoon() {
-                                       // Cancel pending shrink, schedule 
expansion instead
-                                       clearTimeout( shrinkTimeout );
-                                       expandTimeout = setTimeout( expand, 100 
);
-                               }
-
-                               function expand() {
-                                       clearTimeout( shrinkTimeout );
-                                       $closingBracket.css( 'visibility', 
'hidden' );
-                                       $expandedOnly.css( 'visibility', 
'visible' );
-                                       $heading.addClass( 
'mw-editsection-expanded' );
-                               }
-
-                               function shrinkSoon() {
-                                       // Cancel pending expansion, schedule 
shrink instead
-                                       clearTimeout( expandTimeout );
-                                       shrinkTimeout = setTimeout( shrink, 100 
);
-                               }
-
-                               function shrink() {
-                                       clearTimeout( expandTimeout );
-                                       if ( !$links.is( ':focus' ) ) {
-                                               $closingBracket.css( 
'visibility', 'visible' );
-                                               $expandedOnly.css( 
'visibility', 'hidden' );
-                                               $heading.removeClass( 
'mw-editsection-expanded' );
+                                       if ( tabMessages.editsectionsource !== 
null ) {
+                                               $editSourceLink.text( mw.msg( 
tabMessages.editsectionsource ) );
                                        }
-                               }
+                                       if ( tabMessages.editsection !== null ) 
{
+                                               $editLink.text( mw.msg( 
tabMessages.editsection ) );
+                                       }
+                                       $divider
+                                               .addClass( 
'mw-editsection-divider' )
+                                               .text( dividerText );
+                                       $editLink
+                                               .attr( 'href', function ( i, 
val ) {
+                                                       return new mw.Uri( 
veEditUri ).extend( {
+                                                               'vesection': 
new mw.Uri( val ).query.section
+                                                       } );
+                                               } )
+                                               .addClass( 
'mw-editsection-visualeditor' );
+                                       if ( conf.tabPosition === 'before' ) {
+                                               $editSourceLink.before( 
$editLink, $divider );
+                                       } else {
+                                               $editSourceLink.after( 
$divider, $editLink );
+                                       }
+                               } );
+                       }
 
-                               // TODO: Remove this (see Id27555c6 in 
mediawiki/core)
-                               if ( !$brackets.hasClass( 
'mw-editsection-bracket' ) ) {
-                                       $brackets = $brackets
-                                               .wrap( $( '<span>' ).addClass( 
'mw-editsection-bracket' ) )
-                                               .parent();
-                               }
+                       // Process appendix messages
+                       if ( tabMessages.editsectionappendix ) {
+                               $editsections.find( 
'.mw-editsection-visualeditor' )
+                                       .append(
+                                               $( '<span>' )
+                                                       .addClass( 
've-tabmessage-appendix' )
+                                                       .text( mw.msg( 
tabMessages.editsectionappendix ) )
+                                       );
+                       }
+                       if ( tabMessages.editsectionsourceappendix ) {
+                               $editsections.find( 
'a:not(.mw-editsection-visualeditor)' )
+                                       .append(
+                                               $( '<span>' )
+                                                       .addClass( 
've-tabmessage-appendix' )
+                                                       .text( mw.msg( 
tabMessages.editsectionsourceappendix ) )
+                                       );
+                       }
 
-                               $closingBracket = $brackets.last();
-                               $outerClosingBracket = $closingBracket.clone();
-                               $expandedOnly = $divider.add( $editSourceLink 
).add( $outerClosingBracket )
-                                       .css( 'visibility', 'hidden' );
-                               // The hidden bracket after the devider ensures 
we have balanced space before and after
-                               // divider. The space before the devider is 
provided by the original closing bracket.
-                               $hiddenBracket = $closingBracket.clone().css( 
'visibility', 'hidden' );
-
-                               // Events
-                               $heading.on( { 'mouseenter': expandSoon, 
'mouseleave': shrinkSoon } );
-                               $links.on( { 'focus': expand, 'blur': 
shrinkSoon } );
-                               if ( isViewPage ) {
-                                       // Only init without refresh if we're 
on a view page. Though section edit links
-                                       // are rarely shown on non-view pages, 
they appear in one other case, namely
-                                       // when on a diff against the latest 
version of a page. In that case we mustn't
-                                       // init without refresh as that'd 
initialise for the wrong rev id (bug 50925)
-                                       // and would preserve the wrong DOM 
with a diff on top.
-                                       $editLink.click( 
init.onEditSectionLinkClick );
-                               }
-
-                               // Initialization
-                               $editSourceLink
-                                       .addClass( 
'mw-editsection-link-secondary' )
-                                       .text( mw.msg( 
'visualeditor-ca-editsource-section' ) );
-                               $divider
-                                       .addClass( 'mw-editsection-divider' )
-                                       .text( dividerText );
-                               $editLink
-                                       .attr( 'href', function ( i, val ) {
-                                               return new mw.Uri( veEditUri 
).extend( {
-                                                       'vesection': new 
mw.Uri( val ).query.section
-                                               } );
-                                       } )
-                                       .addClass( 
'mw-editsection-link-primary' );
-                               $closingBracket
-                                       .after( $divider, $hiddenBracket, 
$editSourceLink, $outerClosingBracket );
-                       } );
+                       if ( isViewPage ) {
+                               // Only init without refresh if we're on a view 
page. Though section edit links
+                               // are rarely shown on non-view pages, they 
appear in one other case, namely
+                               // when on a diff against the latest version of 
a page. In that case we mustn't
+                               // init without refresh as that'd initialise 
for the wrong rev id (bug 50925)
+                               // and would preserve the wrong DOM with a diff 
on top.
+                               $editsections
+                                       .addClass( 'mw-editsection-expanded' )
+                                       .find( '.mw-editsection-visualeditor' )
+                                               .click( 
init.onEditSectionLinkClick )
+                               ;
+                       }
                },
 
                onEditTabClick: function ( e ) {
@@ -415,8 +397,11 @@
        mw.libs.ve = init;
 
        if ( !init.isAvailable ) {
+               $( 'html' ).addClass( 've-not-available' );
                return;
        }
+       $( 'html' ).addClass( 've-available' );
+
 
        $( function () {
                if ( isViewPage ) {
@@ -428,5 +413,4 @@
                }
                init.skinSetup();
        } );
-
 }() );
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 d88678c..520f152 100644
--- a/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js
+++ b/modules/ve-mw/init/targets/ve.init.mw.ViewPageTarget.js
@@ -1976,7 +1976,7 @@
        // Put skin tabs in "edit" mode
        $( $( '#p-views' ).length ? '#p-views' : '#p-cactions' )
                .find( 'li.selected' ).removeClass( 'selected' );
-       $( this.tabLayout === 'add' ? '#ca-ve-edit' : '#ca-edit' )
+       $( '#ca-ve-edit' )
                .addClass( 'selected' );
 
        // Hide site notice (if present)

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

Gerrit-MessageType: merged
Gerrit-Change-Id: Idcb15faea7fabe5fe7578b1508079969b27d2469
Gerrit-PatchSet: 20
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Esanders <[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