mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-24 07:43:47 +00:00
Merge "Remove custom rendering of the user links overflow menu in favor of using 'vector-user-menu-overflow', a vector specific menu bucket in Hooks.php"
This commit is contained in:
commit
feab2431f6
|
@ -83,6 +83,10 @@
|
|||
background-image: url("data:image/svg+xml;charset=utf8,%3C?xml version='1.0' encoding='UTF-8'?%3E%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3Euser avatar%3C/title%3E%3Cpath d='M10 11c-5.92 0-8 3-8 5v3h16v-3c0-2-2.08-5-8-5z'/%3E%3Ccircle cx='10' cy='5.5' r='4.5'/%3E%3C/svg%3E");
|
||||
}
|
||||
|
||||
.mw-ui-icon-wikimedia-watchlist:before {
|
||||
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='20' viewBox='0 0 20 20'%3E%3Ctitle%3E watchlist %3C/title%3E%3Cpath d='M1 3h16v2H1V3Zm0 6h6v2H1V9Zm0 6h8v2H1v-2Zm8-4.24h3.85L14.5 7l1.65 3.76H20l-3 3.17.9 4.05-3.4-2.14L11.1 18l.9-4.05-3-3.19Z'/%3E%3C/svg%3E")
|
||||
}
|
||||
|
||||
.vector-user-menu-legacy #pt-anonuserpage,
|
||||
.vector-user-menu-legacy #pt-tmpuserpage,
|
||||
.vector-user-menu-legacy #pt-userpage a {
|
||||
|
|
|
@ -265,42 +265,66 @@ class Hooks implements
|
|||
}
|
||||
|
||||
/**
|
||||
* Updates personal navigation menu (user links) overflow items for modern Vector
|
||||
* including 'notification', 'user-interface-preferences', 'user-page', 'vector-user-menu-overflow'
|
||||
* Populates 'vector-user-menu-overflow' bucket for modern Vector with modified personal navigation (user links)
|
||||
* menu items, including 'notification', 'user-interface-preferences', 'user-page', 'vector-user-menu-overflow'
|
||||
*
|
||||
* @param SkinTemplate $sk
|
||||
* @param array &$content_navigation
|
||||
* @suppress PhanTypeInvalidDimOffset False positives
|
||||
* @suppress PhanTypeMismatchArgumentInternal False positives
|
||||
*/
|
||||
private static function updateUserLinksOverflowItems( &$content_navigation ) {
|
||||
// Upgrade preferences, notifications, and watchlist to icon buttons
|
||||
// for extensions that have opted in.
|
||||
if ( isset( $content_navigation['notifications'] ) ) {
|
||||
self::updateMenuItems( $content_navigation, 'notifications' );
|
||||
}
|
||||
private static function updateUserLinksOverflowItems( $sk, &$content_navigation ) {
|
||||
$overflow = 'vector-user-menu-overflow';
|
||||
$content_navigation[$overflow] = [];
|
||||
|
||||
// Logged in and logged out overflow items
|
||||
if ( isset( $content_navigation['user-interface-preferences']['uls'] ) ) {
|
||||
$content_navigation['user-interface-preferences']['uls'] += [
|
||||
$content_navigation[$overflow]['uls'] = array_merge(
|
||||
$content_navigation['user-interface-preferences']['uls'], [
|
||||
'collapsible' => true,
|
||||
];
|
||||
self::updateMenuItems( $content_navigation, 'user-interface-preferences' );
|
||||
] );
|
||||
}
|
||||
|
||||
// Logged in overflow items
|
||||
if ( isset( $content_navigation['user-page']['userpage'] ) ) {
|
||||
$content_navigation['user-page']['userpage'] = array_merge( $content_navigation['user-page']['userpage'], [
|
||||
$content_navigation[$overflow]['userpage'] = array_merge(
|
||||
$content_navigation['user-page']['userpage'], [
|
||||
'button' => true,
|
||||
'collapsible' => true,
|
||||
'icon' => null,
|
||||
// Remove icon
|
||||
'icon' => '',
|
||||
] );
|
||||
self::updateMenuItems( $content_navigation, 'user-page' );
|
||||
}
|
||||
if ( isset( $content_navigation['vector-user-menu-overflow']['watchlist'] ) ) {
|
||||
$content_navigation['vector-user-menu-overflow']['watchlist'] += [
|
||||
if ( isset( $content_navigation['notifications'] ) ) {
|
||||
foreach ( $content_navigation['notifications'] as $key => $data ) {
|
||||
$content_navigation[$overflow][$key] = $data;
|
||||
}
|
||||
}
|
||||
if ( isset( $content_navigation['user-menu']['watchlist'] ) ) {
|
||||
$content_navigation[$overflow]['watchlist'] = array_merge(
|
||||
$content_navigation['user-menu']['watchlist'], [
|
||||
'id' => 'pt-watchlist-2',
|
||||
'button' => true,
|
||||
'collapsible' => true,
|
||||
'text-hidden' => true,
|
||||
'id' => 'pt-watchlist-2',
|
||||
];
|
||||
self::updateMenuItems( $content_navigation, 'vector-user-menu-overflow' );
|
||||
] );
|
||||
}
|
||||
|
||||
// Anon/temp overflow items
|
||||
$user = $sk->getUser();
|
||||
$isTemp = $user->isTemp();
|
||||
$isRegistered = $user->isRegistered();
|
||||
$isCreateAccountAllowed = ( !$isRegistered || $isTemp );
|
||||
if ( isset( $content_navigation['user-menu']['createaccount'] ) && $isCreateAccountAllowed ) {
|
||||
$content_navigation[$overflow]['createaccount'] = array_merge(
|
||||
$content_navigation['user-menu']['createaccount'], [
|
||||
'id' => 'pt-createaccount-2',
|
||||
'button' => true,
|
||||
'collapsible' => true,
|
||||
// Remove icon
|
||||
'icon' => '',
|
||||
] );
|
||||
}
|
||||
|
||||
self::updateMenuItems( $content_navigation, $overflow );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -318,18 +342,8 @@ class Hooks implements
|
|||
// users in legacy Vector.
|
||||
unset( $content_navigation['user-page'] );
|
||||
} else {
|
||||
if ( isset( $content_navigation['user-menu'] ) ) {
|
||||
if ( isset( $content_navigation['user-menu']['watchlist'] ) ) {
|
||||
// Copy watchlist data into 'vector-user-menu-overflow'
|
||||
$content_navigation['vector-user-menu-overflow'] = [
|
||||
'watchlist' => $content_navigation['user-menu']['watchlist']
|
||||
];
|
||||
}
|
||||
|
||||
self::updateUserLinksDropdownItems( $sk, $content_navigation );
|
||||
}
|
||||
|
||||
self::updateUserLinksOverflowItems( $content_navigation );
|
||||
self::updateUserLinksOverflowItems( $sk, $content_navigation );
|
||||
self::updateUserLinksDropdownItems( $sk, $content_navigation );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -253,15 +253,6 @@ abstract class SkinVector extends SkinMustache {
|
|||
return $this->makeLink( 'create-account', $createAccountData );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for the watchlist link inside user links
|
||||
* @param array|null $watchlistMenuData (optional)
|
||||
* @return string
|
||||
*/
|
||||
private function getWatchlistHTML( $watchlistMenuData = null ) {
|
||||
return $watchlistMenuData ? $watchlistMenuData['html-items'] : '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns HTML for the create account button, login button and learn more link inside the anon user menu
|
||||
* @param string[] $returnto array of query strings used to build the login link
|
||||
|
@ -324,33 +315,7 @@ abstract class SkinVector extends SkinMustache {
|
|||
$isTempUser = $user->isTemp();
|
||||
$returnto = $this->getReturnToParam();
|
||||
$useCombinedLoginLink = $this->useCombinedLoginLink();
|
||||
$htmlCreateAccount = $this->getCreateAccountHTML( $returnto, false );
|
||||
|
||||
$templateParser = $this->getTemplateParser();
|
||||
// See T288428#7303233. The following conditional checks whether config is disabling account creation for
|
||||
// anonymous users in modern Vector. This check excludes the use case of extensions using core and legacy hooks
|
||||
// to remove the "Create account" link from the personal toolbar. Ideally this should be managed with a new hook
|
||||
// that tracks account creation ability.
|
||||
// Supporting removing items via hook involves unnecessary additional complexity we'd rather avoid at this time.
|
||||
// (see https://gerrit.wikimedia.org/r/c/mediawiki/skins/Vector/+/713505/3)
|
||||
// Account creation can be disabled by setting `$wgGroupPermissions['*']['createaccount'] = false;`
|
||||
$isCreateAccountAllowed = ( $isAnon || $isTempUser )
|
||||
&& $this->getAuthority()->isAllowed( 'createaccount' );
|
||||
$userMoreHtmlItems = $templateParser->processTemplate( 'UserLinks__more', [
|
||||
'is-anon' => $isAnon,
|
||||
'is-create-account-allowed' => $isCreateAccountAllowed,
|
||||
'html-create-account' => $htmlCreateAccount,
|
||||
'data-user-interface-preferences' => $menuData[ 'data-user-interface-preferences' ],
|
||||
'data-notifications' => $menuData[ 'data-notifications' ],
|
||||
'data-user-page' => $menuData[ 'data-user-page' ],
|
||||
'html-vector-watchlist' => $this->getWatchlistHTML( $menuData[ 'data-vector-user-menu-overflow' ] ?? null ),
|
||||
] );
|
||||
$userMoreData = $this->decoratePortletData( 'data-user-more', [
|
||||
'id' => 'p-personal-more',
|
||||
'class' => 'mw-portlet mw-portlet-personal-more vector-user-menu-more',
|
||||
'html-items' => $userMoreHtmlItems,
|
||||
] );
|
||||
|
||||
$userMenuOverflowData = $menuData[ 'data-vector-user-menu-overflow' ];
|
||||
$userMenuData = $menuData[ 'data-user-menu' ];
|
||||
if ( $isAnon || $isTempUser ) {
|
||||
$userMenuData[ 'html-before-portal' ] .= $this->getAnonMenuBeforePortletHTML(
|
||||
|
@ -363,10 +328,10 @@ abstract class SkinVector extends SkinMustache {
|
|||
$userMenuData[ 'html-after-portal' ] .= $this->getLogoutHTML();
|
||||
}
|
||||
|
||||
$moreItems = substr_count( $userMoreData['html-items'], '<li' );
|
||||
$moreItems = substr_count( $userMenuOverflowData['html-items'], '<li' );
|
||||
return [
|
||||
'is-wide' => $moreItems > 3,
|
||||
'data-user-more' => $userMoreData,
|
||||
'data-user-menu-overflow' => $menuData[ 'data-vector-user-menu-overflow' ],
|
||||
'data-user-menu' => $userMenuData
|
||||
];
|
||||
}
|
||||
|
@ -468,7 +433,6 @@ abstract class SkinVector extends SkinMustache {
|
|||
$skin = $this;
|
||||
|
||||
$parentData = $this->decoratePortletsData( parent::getTemplateData() );
|
||||
$featureManager = VectorServices::getFeatureManager();
|
||||
|
||||
// SkinVector sometimes serves new Vector as part of removing the
|
||||
// skin version user preference. TCho avoid T302461 we need to unset it here.
|
||||
|
@ -814,6 +778,9 @@ abstract class SkinVector extends SkinMustache {
|
|||
case 'p-cactions':
|
||||
$portletData['class'] .= ' vector-menu-dropdown-noicon';
|
||||
break;
|
||||
case 'p-vector-user-menu-overflow':
|
||||
$portletData['class'] .= ' vector-user-menu-overflow';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -880,7 +847,7 @@ abstract class SkinVector extends SkinMustache {
|
|||
case 'data-notifications':
|
||||
case 'data-personal':
|
||||
case 'data-user-page':
|
||||
case 'data-user-more':
|
||||
case 'data-vector-user-menu-overflow':
|
||||
$type = self::MENU_TYPE_DEFAULT;
|
||||
break;
|
||||
case 'data-languages':
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<nav class="vector-user-links{{#is-wide}} vector-user-links-wide{{/is-wide}}" aria-label="{{msg-personaltools}}" role="navigation">
|
||||
{{#data-user-more}}{{>Menu}}{{/data-user-more}}
|
||||
<nav class="vector-user-links{{#is-wide}} vector-user-links-wide{{/is-wide}}" aria-label="{{msg-personaltools}}" role="navigation" >
|
||||
{{#data-user-menu-overflow}}{{>Menu}}{{/data-user-menu-overflow}}
|
||||
{{#data-user-menu}}{{>Menu}}{{/data-user-menu}}
|
||||
</nav>
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
{{#data-user-interface-preferences}}{{{html-items}}}{{/data-user-interface-preferences}}
|
||||
{{#is-create-account-allowed}}
|
||||
<li id="p-createaccount" class="user-links-collapsible-item">
|
||||
{{{html-create-account}}}
|
||||
</li>
|
||||
{{/is-create-account-allowed}}
|
||||
{{^is-anon}}
|
||||
{{#data-user-page}}{{{html-items}}}{{/data-user-page}}
|
||||
{{#data-notifications}}{{{html-items}}}{{/data-notifications}}
|
||||
{{{html-vector-watchlist}}}
|
||||
{{/is-anon}}
|
|
@ -49,7 +49,9 @@
|
|||
/**
|
||||
* Horizontal links menu - logged in and logged out.
|
||||
*/
|
||||
.vector-user-menu-more {
|
||||
// TODO: Remove vector-user-menu-more after I371bb11903d8cdd8f0da89266fcf549050c0da8c has been in prod for a week
|
||||
.vector-user-menu-more,
|
||||
.vector-user-menu-overflow {
|
||||
.vector-menu-content-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
@ -3,7 +3,6 @@ import mustache from 'mustache';
|
|||
import { menuTemplate, legacyMenuTemplate } from './Menu.stories.data';
|
||||
import userLinksTemplateLegacy from '!!raw-loader!../includes/templates/LegacyUserLinks.mustache';
|
||||
import userLinksTemplate from '!!raw-loader!../includes/templates/UserLinks.mustache';
|
||||
import userLinksMoreTemplate from '!!raw-loader!../includes/templates/UserLinks__more.mustache';
|
||||
import userLinksLogoutTemplate from '!!raw-loader!../includes/templates/UserLinks__logout.mustache';
|
||||
import userLinksLoginTemplate from '!!raw-loader!../includes/templates/UserLinks__login.mustache';
|
||||
import { helperClassName, helperMakeMenuData } from './utils';
|
||||
|
@ -59,73 +58,77 @@ const PERSONAL_MENU_TEMPLATE_DATA = {
|
|||
*/
|
||||
|
||||
const LOGGED_IN_ITEMS = `
|
||||
<li id="pt-userpage" class="user-links-collapsible-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-userAvatar" href="/wiki/User:Test" dir="auto" title="Your user page [ctrl-option-.]" accesskey="."><span>Test</span></a></li>
|
||||
<li id="pt-mytalk"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-userTalk" href="/wiki/User_talk:WikiUser" title="Your talk page [⌃⌥n]" accesskey="n"><span>Talk</span></a></li>
|
||||
<li id="pt-sandbox"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-sandbox" href="/wiki/User:WikiUser/sandbox" title="Your sandbox"><span>Sandbox</span></a></li>
|
||||
<li id="pt-preferences"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-settings" href="/wiki/Special:Preferences" title="Your preferences"><span>Preferences</span></a></li>
|
||||
<li id="pt-watchlist"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-unStar" href="/wiki/Special:Watchlist" title="A list of pages you are monitoring for changes [⌃⌥l]" accesskey="l"><span>Watchlist</span></a></li>
|
||||
<li id="pt-mycontris"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-userContributions" href="/wiki/Special:Contributions/WikiUser" title="A list of your contributions [⌃⌥y]" accesskey="y"><span>Contributions</span></a></li>
|
||||
<li id="pt-userpage" class="user-links-collapsible-item mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-userAvatar mw-ui-icon-wikimedia-userAvatar" href="/wiki/User:Admin" title="Your user page [⌃⌥.]" accesskey="."><span>Admin</span></a></li>
|
||||
<li id="pt-mytalk" class="mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-userTalk mw-ui-icon-wikimedia-userTalk" href="/wiki/User_talk:Admin" title="Your talk page [⌃⌥n]" accesskey="n"><span>Talk</span></a></li>
|
||||
<li id="pt-sandbox" class="new mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-sandbox mw-ui-icon-wikimedia-sandbox" href="/w/index.php?title=User:Admin/sandbox&action=edit&redlink=1" title="Your sandbox (page does not exist)"><span>Sandbox</span></a></li>
|
||||
<li id="pt-preferences" class="mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-settings mw-ui-icon-wikimedia-settings" href="/wiki/Special:Preferences" title="Your preferences"><span>Preferences</span></a></li>
|
||||
<li id="pt-betafeatures" class="mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-labFlask mw-ui-icon-wikimedia-labFlask" href="/wiki/Special:Preferences#mw-prefsection-betafeatures" title="Beta features"><span>Beta</span></a></li>
|
||||
<li id="pt-watchlist" class="user-links-collapsible-item mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist" href="/wiki/Special:Watchlist" title="A list of pages you are monitoring for changes [⌃⌥l]" accesskey="l"><span>Watchlist</span></a></li>
|
||||
<li id="pt-uploads" class="mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-imageGallery mw-ui-icon-wikimedia-imageGallery" href="/w/index.php?title=Special:ListFiles/Admin&ilshowall=1" title="List of files you have uploaded"><span>Uploads</span></a></li>
|
||||
<li id="pt-mycontris" class="mw-list-item"><a class="mw-ui-icon mw-ui-icon-before mw-ui-icon-userContributions mw-ui-icon-wikimedia-userContributions" href="/wiki/Special:Contributions/Admin" title="A list of your contributions [⌃⌥y]" accesskey="y"><span>Contributions</span></a></li>
|
||||
`;
|
||||
|
||||
const LOGGED_OUT_ITEMS = `
|
||||
<li id="pt-anontalk"><a href="/wiki/Special:MyTalk" title="Discussion about edits from this IP address [ctrl-option-n]" accesskey="n"><span>Talk</span></a></li>
|
||||
<li id="pt-anoncontribs"><a href="/wiki/Special:MyContributions" title="A list of edits made from this IP address [ctrl-option-y]" accesskey="y"><span>Contributions</span></a></li>
|
||||
<li id="pt-anontalk" class="mw-list-item"><a href="/wiki/Special:MyTalk" title="Discussion about edits from this IP address [⌃⌥n]" accesskey="n"><span>Talk</span></a></li>
|
||||
<li id="pt-anoncontribs" class="mw-list-item"><a href="/wiki/Special:MyContributions" title="A list of edits made from this IP address [⌃⌥y]" accesskey="y"><span>Contributions</span></a></li>
|
||||
`;
|
||||
|
||||
const additionalUserMoreData = {
|
||||
class: 'vector-user-menu-more',
|
||||
'heading-class': '',
|
||||
'is-dropdown': false
|
||||
};
|
||||
const LOGGED_IN_OVERFLOW_ITEMS = `
|
||||
<li id="pt-userpage-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/User:Admin" class="mw-ui-button mw-ui-quiet" title="Your user page [⌃⌥.]" accesskey="."><span>Admin</span></a></li>
|
||||
<li id="pt-notifications-alert" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-bell mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your alerts"><span>Alerts (0)</span></a></li>
|
||||
<li id="pt-notifications-notice" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-tray mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your notices"><span>Notices (0)</span></a></li>
|
||||
<li id="pt-watchlist-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/Special:Watchlist" class="mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist" title="A list of pages you are monitoring for changes [⌃⌥l]" accesskey="l"><span>Watchlist</span></a></li>
|
||||
`;
|
||||
|
||||
const userMoreHtmlItems = ( isAnon = true ) => mustache.render( userLinksMoreTemplate, {
|
||||
'is-anon': isAnon,
|
||||
'is-create-account-allowed': isAnon,
|
||||
'html-create-account': `<a href="/w/index.php?title=Special:CreateAccount&returnto=Main+Page" class="mw-ui-button mw-ui-quiet" title="You are encouraged to create an account and log in; however, it is not mandatory">Create account</a>`,
|
||||
'data-user-page': helperMakeMenuData( 'user-page', `
|
||||
<li id="pt-userpage-2" class="user-links-collapsible-item">
|
||||
<a href="/wiki/User:WikiUser" dir="auto" title="Your user page [⌃⌥.]" accesskey="." class="mw-ui-button mw-ui-quiet"><span>WikiUser</span></a>
|
||||
</li>
|
||||
` ),
|
||||
'data-notifications': helperMakeMenuData( 'notifications', ECHO_ITEMS )
|
||||
} );
|
||||
const LOGGED_OUT_OVERFLOW_ITEMS = `
|
||||
<li id="pt-createaccount-2" class="user-links-collapsible-item mw-list-item"><a href="/w/index.php?title=Special:CreateAccount&returnto=Main+Page" class="mw-ui-button mw-ui-quiet" title="You are encouraged to create an account and log in; however, it is not mandatory"><span>Create account</span></a></li>
|
||||
`;
|
||||
|
||||
const loggedInData = {
|
||||
class: 'vector-user-menu vector-menu-dropdown vector-user-menu-logged-in',
|
||||
'is-dropdown': true,
|
||||
'heading-class': 'mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-userAvatar',
|
||||
'is-anon': false,
|
||||
'html-after-portal': mustache.render( userLinksLogoutTemplate, {
|
||||
htmlLogout: `<a class="vector-menu-content-item vector-menu-content-item-logout mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-logOut" data-mw="interface" href="/w/index.php?title=Special:UserLogout&returnto=Main+Page"><span>Log out</span></a>`
|
||||
} )
|
||||
} ),
|
||||
'is-anon': false,
|
||||
'is-dropdown': true,
|
||||
'has-label': true
|
||||
};
|
||||
|
||||
const loggedOutData = {
|
||||
class: 'vector-user-menu vector-menu-dropdown vector-user-menu-logged-out',
|
||||
'is-dropdown': true,
|
||||
'heading-class': 'mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-wikimedia-ellipsis',
|
||||
'is-anon': true,
|
||||
'html-before-portal': mustache.render( userLinksLoginTemplate, {
|
||||
htmlCreateAccount: `<a href="/w/index.php?title=Special:CreateAccount&returnto=Special%3AUserLogout" icon="userAvatar" class="user-links-collapsible-item vector-menu-content-item mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-userAvatar" title="You are encouraged to create an account and log in; however, it is not mandatory"><span>Create account</span></a>`,
|
||||
htmlLogin: `<a class="vector-menu-content-item vector-menu-content-item-login mw-ui-icon mw-ui-icon-before mw-ui-icon-wikimedia-logIn" href="/w/index.php?title=Special:UserLogin&returnto=Main+Page" title="You are encouraged to log in; however, it is not mandatory [ctrl-option-o]" accesskey="o"><span>Log in</span></a>`,
|
||||
msgLearnMore: msgs[ 'vector-anon-user-menu-pages' ],
|
||||
htmlLearnMoreLink: `<a href="/wiki/Help:Introduction"><span>${msgs[ 'vector-anon-user-menu-pages-learn' ]}</span></a>:`
|
||||
} )
|
||||
} ),
|
||||
'is-anon': false,
|
||||
'is-dropdown': true,
|
||||
'has-label': true
|
||||
};
|
||||
|
||||
const overflowData = {
|
||||
class: 'vector-menu vector-user-menu-overflow',
|
||||
'heading-class': '',
|
||||
'is-dropdown': false
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {UserLinksDefinition}
|
||||
*/
|
||||
const USER_LINKS_LOGGED_IN_TEMPLATE_DATA = {
|
||||
'data-user-more': helperMakeMenuData( 'personal-more', userMoreHtmlItems( false ), additionalUserMoreData ),
|
||||
'data-user-menu': helperMakeMenuData( 'new-personal', LOGGED_IN_ITEMS, loggedInData )
|
||||
'data-user-menu-overflow': helperMakeMenuData( 'vector-user-menu-overflow', LOGGED_IN_OVERFLOW_ITEMS, overflowData ),
|
||||
'data-user-menu': helperMakeMenuData( 'personal-more', LOGGED_IN_ITEMS, loggedInData )
|
||||
};
|
||||
|
||||
/**
|
||||
* @type {UserLinksDefinition}
|
||||
*/
|
||||
const USER_LINKS_LOGGED_OUT_TEMPLATE_DATA = {
|
||||
'data-user-more': helperMakeMenuData( 'personal-more', userMoreHtmlItems( true ), additionalUserMoreData ),
|
||||
'data-user-menu': helperMakeMenuData( 'new-personal', LOGGED_OUT_ITEMS, loggedOutData )
|
||||
'data-user-menu-overflow': helperMakeMenuData( 'vector-user-menu-overflow', LOGGED_OUT_OVERFLOW_ITEMS, overflowData ),
|
||||
'data-user-menu': helperMakeMenuData( 'personal-more', LOGGED_OUT_ITEMS, loggedOutData )
|
||||
};
|
||||
|
||||
const USER_LINK_PARTIALS = {
|
||||
|
|
|
@ -81,6 +81,6 @@
|
|||
|
||||
/**
|
||||
* @typedef {Object} UserLinksDefinition
|
||||
* @property {MenuDefinition} data-user-more
|
||||
* @property {MenuDefinition} data-user-menu-overflow
|
||||
* @property {MenuDefinition} data-user-menu
|
||||
*/
|
||||
|
|
|
@ -3,14 +3,15 @@
|
|||
exports[`UserLinks renders 1`] = `
|
||||
"<nav class=\\"vector-user-links\\" aria-label=\\"\\" role=\\"navigation\\">
|
||||
|
||||
<div id=\\"p-personal-more\\" class=\\"vector-menu mw-portlet mw-portlet-personal-more vector-user-menu-more\\">
|
||||
<div id=\\"p-personal-more\\" class=\\"vector-menu mw-portlet mw-portlet-vector-user-menu-overflow vector-user-menu-overflow\\">
|
||||
<div class=\\"vector-menu-content\\">
|
||||
|
||||
<ul class=\\"vector-menu-content-list\\">
|
||||
<li id=\\"ca-uls\\" class=\\"user-links-collapsible-item mw-list-item active\\"><a href=\\"#\\" class=\\"uls-trigger mw-ui-button mw-ui-quiet\\"><span class=\\"mw-ui-icon mw-ui-icon-wikimedia-language\\"></span> <span>English</span></a></li>
|
||||
<li id=\\"pt-userpage-2\\" class=\\"user-links-collapsible-item mw-list-item\\"><a href=\\"/wiki/User:Admin\\" class=\\"mw-ui-button mw-ui-quiet\\" title=\\"Your user page [.]\\" accesskey=\\".\\"><span>Admin</span></a></li>
|
||||
<li id=\\"pt-notifications-alert\\" class=\\"mw-list-item\\"><a href=\\"/wiki/Special:Notifications\\" class=\\"mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-bell mw-echo-notifications-badge-all-read\\" data-counter-num=\\"0\\" data-counter-text=\\"0\\" title=\\"Your alerts\\"><span>Alerts (0)</span></a></li><li id=\\"pt-notifications-notice\\" class=\\"mw-list-item\\"><a href=\\"/wiki/Special:Notifications\\" class=\\"mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-tray mw-echo-notifications-badge-all-read\\" data-counter-num=\\"0\\" data-counter-text=\\"0\\" title=\\"Your notices\\"><span>Notices (0)</span></a></li>
|
||||
<li id=\\"pt-watchlist-2\\" class=\\"user-links-collapsible-item mw-list-item\\"><a href=\\"/wiki/Special:Watchlist\\" class=\\"mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist\\" title=\\"A list of pages you are monitoring for changes [l]\\" accesskey=\\"l\\"><span>Watchlist</span></a></li>
|
||||
<li id=\\"pt-userpage-2\\" class=\\"user-links-collapsible-item mw-list-item\\"><a href=\\"/wiki/User:Admin\\" class=\\"mw-ui-button mw-ui-quiet\\" title=\\"Your user page [⌃⌥.]\\" accesskey=\\".\\"><span>Admin</span></a></li>
|
||||
<li id=\\"pt-notifications-alert\\" class=\\"mw-list-item\\"><a href=\\"/wiki/Special:Notifications\\" class=\\"mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-bell mw-echo-notifications-badge-all-read\\" data-counter-num=\\"0\\" data-counter-text=\\"0\\" title=\\"Your alerts\\"><span>Alerts (0)</span></a></li>
|
||||
<li id=\\"pt-notifications-notice\\" class=\\"mw-list-item\\"><a href=\\"/wiki/Special:Notifications\\" class=\\"mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-tray mw-echo-notifications-badge-all-read\\" data-counter-num=\\"0\\" data-counter-text=\\"0\\" title=\\"Your notices\\"><span>Notices (0)</span></a></li>
|
||||
<li id=\\"pt-watchlist-2\\" class=\\"user-links-collapsible-item mw-list-item\\"><a href=\\"/wiki/Special:Watchlist\\" class=\\"mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist\\" title=\\"A list of pages you are monitoring for changes [⌃⌥l]\\" accesskey=\\"l\\"><span>Watchlist</span></a></li>
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
|
|
|
@ -5,15 +5,16 @@ const menuTemplate = fs.readFileSync( 'includes/templates/Menu.mustache', 'utf8'
|
|||
|
||||
const templateData = {
|
||||
'is-wide': false,
|
||||
'data-user-more': {
|
||||
'data-user-menu-overflow': {
|
||||
id: 'p-personal-more',
|
||||
class: 'mw-portlet mw-portlet-personal-more vector-user-menu-more',
|
||||
class: 'mw-portlet mw-portlet-vector-user-menu-overflow vector-user-menu-overflow',
|
||||
label: 'Toggle sidebar',
|
||||
'html-items': `
|
||||
<li id="ca-uls" class="user-links-collapsible-item mw-list-item active"><a href="#" class="uls-trigger mw-ui-button mw-ui-quiet"><span class="mw-ui-icon mw-ui-icon-wikimedia-language"></span> <span>English</span></a></li>
|
||||
<li id="pt-userpage-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/User:Admin" class="mw-ui-button mw-ui-quiet" title="Your user page [.]" accesskey="."><span>Admin</span></a></li>
|
||||
<li id="pt-notifications-alert" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-bell mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your alerts"><span>Alerts (0)</span></a></li><li id="pt-notifications-notice" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-tray mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your notices"><span>Notices (0)</span></a></li>
|
||||
<li id="pt-watchlist-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/Special:Watchlist" class="mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist" title="A list of pages you are monitoring for changes [l]" accesskey="l"><span>Watchlist</span></a></li>
|
||||
<li id="pt-userpage-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/User:Admin" class="mw-ui-button mw-ui-quiet" title="Your user page [⌃⌥.]" accesskey="."><span>Admin</span></a></li>
|
||||
<li id="pt-notifications-alert" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-bell mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your alerts"><span>Alerts (0)</span></a></li>
|
||||
<li id="pt-notifications-notice" class="mw-list-item"><a href="/wiki/Special:Notifications" class="mw-echo-notifications-badge mw-echo-notification-badge-nojs oo-ui-icon-tray mw-echo-notifications-badge-all-read" data-counter-num="0" data-counter-text="0" title="Your notices"><span>Notices (0)</span></a></li>
|
||||
<li id="pt-watchlist-2" class="user-links-collapsible-item mw-list-item"><a href="/wiki/Special:Watchlist" class="mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-watchlist mw-ui-icon-wikimedia-watchlist" title="A list of pages you are monitoring for changes [⌃⌥l]" accesskey="l"><span>Watchlist</span></a></li>
|
||||
`
|
||||
},
|
||||
'data-user-menu': {
|
||||
|
|
|
@ -466,5 +466,4 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase {
|
|||
$shouldLanguageAlertBeInSidebarMethod->invoke( $mockSkinVector )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -440,11 +440,6 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
'login' => [ 'class' => [], 'icon' => 'login' ],
|
||||
]
|
||||
];
|
||||
$contentNavWatchlist = [
|
||||
'user-menu' => [
|
||||
'watchlist' => [ 'class' => [], 'icon' => 'watchlist' ],
|
||||
]
|
||||
];
|
||||
$vectorLegacySkin = new SkinVectorLegacy( [ 'name' => 'vector' ] );
|
||||
$contentNavLegacy = [
|
||||
'user-page' => [
|
||||
|
@ -453,22 +448,14 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
];
|
||||
|
||||
Hooks::onSkinTemplateNavigation( $vector2022Skin, $contentNav );
|
||||
$this->assertFalse( isset( $contentNav['vector-user-menu-overflow'] ),
|
||||
'watchlist data is not copied to vector-user-menu-overflow when not provided'
|
||||
);
|
||||
$this->assertFalse( isset( $contentNav['user-page']['login'] ),
|
||||
'updateUserLinksDropdownItems is called when user-page is defined'
|
||||
'updateUserLinksDropdownItems is called when not legacy'
|
||||
);
|
||||
$this->assertContains( 'mw-ui-button',
|
||||
$contentNav['user-page']['userpage']['link-class'],
|
||||
$contentNav['vector-user-menu-overflow']['userpage']['link-class'],
|
||||
'updateUserLinksOverflowItems is called when not legacy'
|
||||
);
|
||||
|
||||
Hooks::onSkinTemplateNavigation( $vector2022Skin, $contentNavWatchlist );
|
||||
$this->assertTrue( isset( $contentNavWatchlist['vector-user-menu-overflow'] ),
|
||||
'watchlist data is copied to vector-user-menu-overflow when provided'
|
||||
);
|
||||
|
||||
Hooks::onSkinTemplateNavigation( $vectorLegacySkin, $contentNavLegacy );
|
||||
$this->assertFalse( isset( $contentNavLegacy['user-page'] ),
|
||||
'user-page is unset for legacy vector'
|
||||
|
@ -545,6 +532,14 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
'updateUserLinksOverflowItems'
|
||||
);
|
||||
$updateUserLinksOverflowItems->setAccessible( true );
|
||||
$skin = new SkinVector22( [ 'name' => 'vector-2022' ] );
|
||||
|
||||
// Registered user
|
||||
$registeredUser = $this->createMock( User::class );
|
||||
$registeredUser->method( 'isRegistered' )->willReturn( true );
|
||||
$context = new RequestContext();
|
||||
$context->setUser( $registeredUser );
|
||||
$skin->setContext( $context );
|
||||
$content = [
|
||||
'notifications' => [
|
||||
'alert' => [ 'class' => [], 'icon' => 'alert' ],
|
||||
|
@ -554,30 +549,31 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
],
|
||||
'user-page' => [
|
||||
'userpage' => [ 'class' => [], 'icon' => 'userpage' ],
|
||||
'watchlist' => [ 'class' => [], 'icon' => 'watchlist' ],
|
||||
],
|
||||
'vector-user-menu-overflow' => [
|
||||
'user-menu' => [
|
||||
'watchlist' => [ 'class' => [], 'icon' => 'watchlist' ],
|
||||
],
|
||||
];
|
||||
$updateUserLinksOverflowItems->invokeArgs( null, [ &$content ] );
|
||||
$updateUserLinksOverflowItems->invokeArgs( null, [ $skin, &$content ] );
|
||||
$this->assertContains( 'user-links-collapsible-item',
|
||||
$content['user-interface-preferences']['uls']['class'],
|
||||
$content['vector-user-menu-overflow']['uls']['class'],
|
||||
'ULS link in user links overflow requires collapsible class'
|
||||
);
|
||||
$this->assertContains( 'user-links-collapsible-item',
|
||||
$content['user-page']['userpage']['class'],
|
||||
$content['vector-user-menu-overflow']['userpage']['class'],
|
||||
'User page link in user links overflow requires collapsible class'
|
||||
);
|
||||
$this->assertContains( 'mw-ui-button',
|
||||
$content['user-page']['userpage']['link-class'],
|
||||
$content['vector-user-menu-overflow']['userpage']['link-class'],
|
||||
'User page link in user links overflow requires button classes'
|
||||
);
|
||||
$this->assertContains( 'mw-ui-quiet',
|
||||
$content['user-page']['userpage']['link-class'],
|
||||
$content['vector-user-menu-overflow']['userpage']['link-class'],
|
||||
'User page link in user links overflow requires quiet button classes'
|
||||
);
|
||||
$this->assertNotContains( 'mw-ui-icon',
|
||||
$content['user-page']['userpage']['class'],
|
||||
$content['vector-user-menu-overflow']['userpage']['class'],
|
||||
'User page link in user links overflow does not have icon classes'
|
||||
);
|
||||
$this->assertContains( 'user-links-collapsible-item',
|
||||
|
|
Loading…
Reference in a new issue