diff --git a/VisualEditor.i18n.php b/VisualEditor.i18n.php index 7f0b1e31c7..10f7e3e359 100644 --- a/VisualEditor.i18n.php +++ b/VisualEditor.i18n.php @@ -11,6 +11,10 @@ $messages['en'] = array( 'visualeditor-notification-saved' => 'Your changes to $1 have been saved.', 'visualeditor-notification-created' => '$1 has been created.', 'visualeditor-ca-editsource' => 'Edit source', + 'visualeditor-ca-ve-edit' => 'VisualEditor', + 'visualeditor-ca-ve-create' => 'VisualEditor', + 'tooltip-ca-ve-edit' => 'Edit this page with VisualEditor', + 'accesskey-ca-ve-edit' => '', 'visualeditor-inspector-title' => 'Inspect', 'visualeditor-linkinspector-title' => 'Hyperlink', 'visualeditor-linkinspector-label-pagetitle' => 'Page title', @@ -58,7 +62,11 @@ $messages['qqq'] = array( 'visualeditor-desc' => '{{desc}}', 'visualeditor-notification-saved' => '$1 is a page name.', 'visualeditor-notification-created' => '$1 is a page name.', - 'visualeditor-ca-editsource' => 'Text for the edit source link in the tab dropdown', + 'visualeditor-ca-editsource' => '{{Optional}} {{Identical|visualeditor}} Text for the edit source link in the tab dropdown', + 'visualeditor-ca-ve-edit' => '{{Optional}} {{Identical|visualeditor}} Link text of the dedicated VisualEditor Edit tab.', + 'visualeditor-ca-ve-create' => 'Link text of the dedicated VisualEditor Create tab.', + 'tooltip-ca-ve-edit' => 'Tooltip of the dedicated VisualEditor Edit tab.', + 'accesskey-ca-ve-edit' => '{{Ignore}}', 'visualeditor-inspector-title' => 'Title of an unnamed inspector', 'visualeditor-linkinspector-title' => 'Title of the link inspector dialog', # Fuzzy 'visualeditor-linkinspector-label-pagetitle' => 'Label for the text field that holds the link target in the link inspector', diff --git a/VisualEditor.php b/VisualEditor.php index 717e113ee0..5cccd849c9 100644 --- a/VisualEditor.php +++ b/VisualEditor.php @@ -126,8 +126,12 @@ $wgResourceModules += array( 'edit', 'create', 'accesskey-ca-edit', + 'accesskey-ca-ve-edit', 'tooltip-ca-edit', + 'tooltip-ca-ve-edit', 'viewsource', + 'visualeditor-ca-ve-edit', + 'visualeditor-ca-ve-create', 'visualeditor-notification-saved', 'visualeditor-notification-created', 'visualeditor-ca-editsource', diff --git a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js index 149c44ed2d..d449ccbfd2 100644 --- a/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js +++ b/modules/ve/init/mw/targets/ve.init.mw.ViewPageTarget.js @@ -60,6 +60,10 @@ ve.init.mw.ViewPageTarget = function VeInitMwViewPageTarget() { 'vewhitelist' in currentUri.query ); this.editSummaryByteLimit = 255; + // Tab layout. + // * add: Adds #ca-ve-edit. + // * replace: Re-creates #ca-edit for VisualEditor and adds #ca-editsource. + this.tabLayout = 'add'; // Events this.addListenerMethods( this, { @@ -456,71 +460,78 @@ ve.init.mw.ViewPageTarget.prototype.tearDownSurface = function () { * @method */ ve.init.mw.ViewPageTarget.prototype.setupSkinTabs = function () { - var action, $viewSource, pVeEdit; + var action, pTabsId, $caSource, $caEdit, caVeEdit; + $caEdit = $( '#ca-edit' ); + $caSource = $( '#ca-viewsource' ); - // Only sysop users will have a native edit tab in this namespace - // If there isn't an edit tab, there's a view source tab we'll move into - // p-cactions. - if ( $( '#ca-edit' ).length === 0 ) { + 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; + } - $viewSource = $( '#ca-viewsource' ); - if ( $viewSource.length > 0 ) { - // Re-create instead of moving the original one since we don't want to copy - // over accesskey etc., access+e should trigger VE edit. - mw.util.addPortletLink( - 'p-cactions', - $viewSource.find( 'a' ).attr( 'href' ), - $viewSource.find( 'a' ).text(), - $viewSource.attr( 'id' ) - ); - $viewSource.remove(); - } + action = mw.config.get( 'wgArticleId', 0 ) === 0 ? 'create' : 'edit'; + pTabsId = $( '#p-views' ).length ? 'p-views' : 'p-cactions'; - // For sysops, remove the native edit tab in favour - // of an editsource link in p-cactions. - // Re-create instead of moving the original one since we don't want to copy - // over accesskey etc., access+e should trigger VE edit. + // Add independent ve-edit tab. + if ( this.tabLayout === 'add' ) { + // Create "Edit" tab. + 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. + this.veEditUri, + // Message: 'visualeditor-ca-ve-edit' or 'visualeditor-ca-ve-create' + ve.msg( 'visualeditor-ca-ve-' + action ), + 'ca-ve-edit', + ve.msg( 'tooltip-ca-ve-edit' ), + ve.msg( 'accesskey-ca-ve-edit' ), + '#ca-history' + ); + + // Replace edit with ve version, add editsource link. } else { + // Create "Edit source" link. + // Re-create instead of convert ca-edit since we don't want to copy over accesskey etc. mw.util.addPortletLink( 'p-cactions', // Use original href to preserve oldid etc. (bug 38125) - $( '#ca-edit a' ).attr( 'href' ), + $caEdit.find( 'a' ).attr( 'href' ), ve.msg( 'visualeditor-ca-editsource' ), 'ca-editsource' ); - $( '#ca-edit' ).remove(); - } + $caEdit.remove(); - // Whether we moved viewsource or transformed edit - // into editsource, add a new "VisualEditor" Edit tab - action = mw.config.get( 'wgArticleId', 0 ) === 0 ? 'create' : 'edit'; - pVeEdit = mw.util.addPortletLink( - $( '#p-views' ).length ? 'p-views' : 'p-cactions', - // 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. - this.veEditUri, - ve.msg( action ), // 'edit' or 'create' - 'ca-edit', - ve.msg( 'tooltip-ca-edit' ), - ve.msg( 'accesskey-ca-edit' ), - '#ca-history' - ); + // Create "Edit" tab. + 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. + this.veEditUri, + // Message: 'edit' or 'create' + ve.msg( action ), + 'ca-edit', + ve.msg( 'tooltip-ca-edit' ), + ve.msg( 'accesskey-ca-edit' ), + '#ca-history' + ); + } if ( this.isViewPage ) { // Allow instant switching to edit mode, without refresh - $( pVeEdit ).click( ve.bind( this.onEditTabClick, this ) ); + $( caVeEdit ).click( ve.bind( this.onEditTabClick, this ) ); // Allow instant switching back to view mode, without refresh $( '#ca-view a, #ca-nstab-visualeditor a' ) .click( ve.bind( this.onViewTabClick, this ) ); } - // Source editing shouldn't highlight the edit tab - if ( mw.config.get( 'wgAction' ) === 'edit' ) { - $( '#ca-edit' ).removeClass( 'selected' ); - } - // Fix the URL if there was a veaction param in it + + // If there got here via veaction=edit, hide it from the URL. if ( this.currentUri.query.veaction === 'edit' && window.history.replaceState ) { window.history.replaceState( null, document.title, this.viewUri ); } @@ -946,7 +957,8 @@ ve.init.mw.ViewPageTarget.prototype.restorePageTitle = function () { ve.init.mw.ViewPageTarget.prototype.transformSkinTabs = function () { $( $( '#p-views' ).length ? '#p-views' : '#p-cactions' ) .find( 'li.selected' ).removeClass( 'selected' ); - $( '#ca-edit' ).addClass( 'selected' ); + $( this.tabLayout === 'add' ? '#ca-ve-edit' : '#ca-edit' ) + .addClass( 'selected' ); }; /** diff --git a/modules/ve/init/mw/ve.init.mw.Target.js b/modules/ve/init/mw/ve.init.mw.Target.js index 1e041bc4bc..4afb1a518c 100644 --- a/modules/ve/init/mw/ve.init.mw.Target.js +++ b/modules/ve/init/mw/ve.init.mw.Target.js @@ -35,7 +35,7 @@ ve.init.mw.Target = function VeInitMwTarget( pageName, oldId ) { this.dom = null; this.isMobileDevice = ( 'ontouchstart' in window || - ( window.DocumentTouch && document instanceof window.DocumentTouch ) + ( window.DocumentTouch && document instanceof window.DocumentTouch ) ); };