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)