diff --git a/VisualEditor.hooks.php b/VisualEditor.hooks.php
index 7b1153acbf..88059ed1c4 100644
--- a/VisualEditor.hooks.php
+++ b/VisualEditor.hooks.php
@@ -14,7 +14,7 @@ class VisualEditorHooks {
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
@@ -25,6 +25,13 @@ class VisualEditorHooks {
// 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' ) ) {
// EventLogging schema module for logging edit events.
@@ -78,7 +85,7 @@ class VisualEditorHooks {
}
/**
- * 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 @@ class VisualEditorHooks {
* @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 = ''
+ . '['
+ . ( $veFirst ? $veLink : $sourceLink )
+ . ''
+ . wfMessage( 'pipe-separator' )->inLanguage( $lang )->text()
+ . ''
+ . ( $veFirst ? $sourceLink : $veLink )
+ . ']'
+ . '';
return true;
}
@@ -146,7 +286,8 @@ class VisualEditorHooks {
$wgVisualEditorEnableExperimentalCode,
$wgVisualEditorNamespaces,
$wgVisualEditorPluginModules,
- $wgVisualEditorTabLayout;
+ $wgVisualEditorTabPosition,
+ $wgVisualEditorTabMessages;
$vars['wgVisualEditorConfig'] = array(
'disableForAnons' => $wgVisualEditorDisableForAnons,
@@ -159,7 +300,8 @@ class VisualEditorHooks {
'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 f4aacde1a4..1da0d2fa89 100644
--- a/VisualEditor.i18n.php
+++ b/VisualEditor.i18n.php
@@ -35,12 +35,14 @@ $messages['en'] = array(
'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 b4db84c6ab..0eb7f353ba 100644
--- a/VisualEditor.php
+++ b/VisualEditor.php
@@ -46,11 +46,13 @@ $wgAPIModules['visualeditoredit'] = 'ApiVisualEditorEdit';
// 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,15 +146,15 @@ $wgResourceModules += array(
'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(
'scripts' => array(
've-mw/init/targets/ve.init.mw.ViewPageTarget.js',
@@ -774,7 +776,40 @@ $wgVisualEditorDisableForAnons = false;
// 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 ac43b0513e..c860036288 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 0000000000..5dfa321889
--- /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 0b7af16ccb..f5bee9d269 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 ( !$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 ( !$caEdit.length || $caSource.length ) {
// 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(
+ $( '' )
+ .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(
+ $( '' )
+ .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 = $( '' ),
- 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 = $( '' ),
+ 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( $( '' ).addClass( 'mw-editsection-bracket' ) )
- .parent();
- }
+ // Process appendix messages
+ if ( tabMessages.editsectionappendix ) {
+ $editsections.find( '.mw-editsection-visualeditor' )
+ .append(
+ $( '' )
+ .addClass( 've-tabmessage-appendix' )
+ .text( mw.msg( tabMessages.editsectionappendix ) )
+ );
+ }
+ if ( tabMessages.editsectionsourceappendix ) {
+ $editsections.find( 'a:not(.mw-editsection-visualeditor)' )
+ .append(
+ $( '' )
+ .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 d88678c488..520f1521b9 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 @@ ve.init.mw.ViewPageTarget.prototype.transformPage = function () {
// 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)