Compare commits

...

7 Commits

Author SHA1 Message Date
jenkins-bot c01c0cdcdc Merge "Fix bug in SkinVersionLookup" into wmf/1.38.0-wmf.18 2022-01-26 00:39:54 +00:00
Jon Robson e09a6d3b25 Do not load common.js twice
An error in both of these modules. This module is additive (it doesn't
replace the existing user module) so only needs to add new pages, not
append to existing pages.

Bug: T300070
Change-Id: I3ba2ce82ba924972d0f9fea763328510aef41f8e
2022-01-25 20:10:52 +00:00
Jon Robson a6f25034a9 Fix bug in SkinVersionLookup
Bug: T299971
Change-Id: Icd8874315bf3c5846b00e8c34eb1a739c4a0feba
(cherry picked from commit 435c903523)
2022-01-25 00:35:39 +00:00
Jon Robson 4f430a8c35 Respect useskin when operating in MigrationMode
Bug: T299171
Change-Id: I7c183949c358a5eb07c273044f63ac6474a62ad2
(cherry picked from commit 94bab9f45f)
2022-01-24 16:14:08 +00:00
Jon Robson 505d350c24 Do not try to make watchlist collapsible on wikis where watchlist is disabled
Bug: T299671
Change-Id: I9b44401ad753881ca986157dc06bb4402edc1017
(cherry picked from commit 6cd9cc5be0)
2022-01-20 18:08:14 +00:00
Jon Robson e060598359 Restore icons to user links dropdown
Follow up to
I62562969a00eb96c83af4519e0e34e4a77ed8b19

Bug: T289619
Change-Id: I88a2d4af97227bb69dc9a11ea7ceac54895d2376
2022-01-18 11:38:27 -08:00
Jon Robson 3793541149 Don't run Vector hook when menu absent from page
While editing I was seeing a fatal due to this error being null
Err on side of caution and check for existence of menu
Follow up to I8309492881142d47eec4da5cc4aa5c6febbd1b35

Bug: T289619
Bug: T299352
Change-Id: I62562969a00eb96c83af4519e0e34e4a77ed8b19
(cherry picked from commit 55bcce3cc0)
2022-01-18 19:37:50 +00:00
6 changed files with 191 additions and 20 deletions

View File

@ -162,6 +162,12 @@ final class Constants {
*/
public const QUERY_PARAM_SKIN_VERSION = 'useskinversion';
/**
* Override the skin user preference and site Config. See readme.
* @var string
*/
public const QUERY_PARAM_SKIN = 'useskin';
/**
* @var string
*/

View File

@ -208,23 +208,28 @@ class Hooks {
}
/**
* Updates personal navigation menu (user links) for modern Vector wherein user page, create account and login links
* are removed from the dropdown to be handled separately. In legacy Vector, the custom "user-page" bucket is
* removed to preserve existing behavior.
* Updates personal navigation menu (user links) dropdown for modern Vector:
* - Adds icons
* - Makes user page and watchlist collapsible
*
* @param SkinTemplate $sk
* @param array &$content_navigation
*/
private static function updateUserLinksItems( $sk, &$content_navigation ) {
private static function updateUserLinksDropdownItems( $sk, &$content_navigation ) {
// For logged-in users in modern Vector, rearrange some links in the personal toolbar.
if ( $sk->getUser()->isRegistered() ) {
// Remove user page from personal menu dropdown for logged in users at higher resolutions.
// Remove user page from personal menu dropdown for logged in use
self::makeMenuItemCollapsible(
$content_navigation['user-menu']['userpage']
);
self::makeMenuItemCollapsible(
$content_navigation['user-menu']['watchlist']
);
// watchlist may be disabled if $wgGroupPermissions['*']['viewmywatchlist'] = false;
// See [[phab:T299671]]
$wlItem = $content_navigation['user-menu']['watchlist'] ?? false;
if ( $wlItem ) {
self::makeMenuItemCollapsible(
$wlItem
);
}
// Remove logout link from user-menu and recreate it in SkinVector,
unset( $content_navigation['user-menu']['logout'] );
// Don't show icons for anon menu items (besides login and create account).
@ -246,7 +251,21 @@ class Hooks {
// are set to false.
unset( $content_navigation['user-menu']['login-private'] );
}
}
/**
* Updates personal navigation menu (user links) for modern Vector wherein user page, create account and login links
* are removed from the dropdown to be handled separately. In legacy Vector, the custom "user-page" bucket is
* removed to preserve existing behavior.
*
* @param SkinTemplate $sk
* @param array &$content_navigation
*/
private static function updateUserLinksItems( $sk, &$content_navigation ) {
$hasUserMenu = $content_navigation['user-menu'] ?? false;
if ( $hasUserMenu ) {
self::updateUserLinksDropdownItems( $sk, $content_navigation );
}
// ULS and user page links are hidden at lower resolutions.
if ( $content_navigation['user-interface-preferences'] ) {
self::makeMenuItemCollapsible(

View File

@ -16,7 +16,6 @@ class VectorResourceLoaderUserModule extends ResourceLoaderUserModule {
$user = $context->getUserObj();
$pages = [];
if ( $config->get( 'AllowUserCss' ) && !$user->isAnon() && ( $skin === Constants::SKIN_NAME_MODERN ) ) {
$pages = parent::getPages( $context );
$userPage = $user->getUserPage()->getPrefixedDBkey();
$pages["$userPage/vector.js"] = [ 'type' => 'script' ];
}

View File

@ -16,7 +16,6 @@ class VectorResourceLoaderUserStylesModule extends ResourceLoaderUserStylesModul
$user = $context->getUserObj();
$pages = [];
if ( $config->get( 'AllowUserCss' ) && !$user->isAnon() && ( $skin === Constants::SKIN_NAME_MODERN ) ) {
$pages = parent::getPages( $context );
$userPage = $user->getUserPage()->getPrefixedDBkey();
$pages["$userPage/vector.css"] = [ 'type' => 'style' ];
}

View File

@ -107,6 +107,23 @@ final class SkinVersionLookup {
* @throws \ConfigException
*/
public function getVersion(): string {
$migrationMode = $this->config->get( 'VectorSkinMigrationMode' );
$useSkin = $this->request->getVal(
Constants::QUERY_PARAM_SKIN
);
// In migration mode, the useskin parameter is the source of truth.
if ( $migrationMode ) {
if ( $useSkin ) {
return $useSkin === Constants::SKIN_NAME_LEGACY ?
Constants::SKIN_VERSION_LEGACY :
Constants::SKIN_VERSION_LATEST;
}
}
// [[phab:T299971]]
if ( $useSkin === Constants::SKIN_NAME_MODERN ) {
return Constants::SKIN_VERSION_LATEST;
}
// If skin key is not vector, then version should be considered legacy.
// If skin is "Vector" invoke additional skin versioning detection.
@ -138,9 +155,12 @@ final class SkinVersionLookup {
)
);
// If we are in migration mode, we must check the skin version preference.
if ( $this->config->get( 'VectorSkinMigrationMode' ) ) {
// If we are in migration mode...
if ( $migrationMode ) {
// ... we must check the skin version preference for logged in users.
// No need to check for anons as wgDefaultSkin has already been consulted at this point.
if (
$this->user->isRegistered() &&
$skin === Constants::SKIN_NAME_LEGACY &&
$skinVersionPref === Constants::SKIN_VERSION_LATEST
) {

View File

@ -36,8 +36,13 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->with( $this->anything(), 'beta' )
->willReturn( 'alpha' );
->willReturnCallback( static function ( $key ) {
if ( $key === Constants::QUERY_PARAM_SKIN ) {
return null;
} else {
return 'alpha';
}
} );
$user = $this->createMock( \User::class );
$user
@ -76,8 +81,13 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->with( $this->anything(), 'beta' )
->willReturn( 'beta' );
->willReturnCallback( static function ( $key ) {
if ( $key === Constants::QUERY_PARAM_SKIN ) {
return null;
} else {
return 'beta';
}
} );
$user = $this->createMock( \User::class );
$user
@ -116,8 +126,13 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->with( $this->anything(), '1' )
->willReturn( '1' );
->willReturnCallback( static function ( $key ) {
if ( $key === Constants::QUERY_PARAM_SKIN ) {
return null;
} else {
return '1';
}
} );
$user = $this->createMock( \User::class );
$user
@ -148,6 +163,114 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
);
}
public function providerAnonUserMigrationMode() {
return [
// When no query string just return DefaultSkin version.
[
Constants::SKIN_NAME_LEGACY,
null,
Constants::SKIN_VERSION_LEGACY,
],
[
Constants::SKIN_NAME_MODERN,
null,
Constants::SKIN_VERSION_LATEST,
],
// When useskin=vector return legacy Vector version.
[
Constants::SKIN_NAME_LEGACY,
Constants::SKIN_NAME_LEGACY,
Constants::SKIN_VERSION_LEGACY,
],
[
Constants::SKIN_NAME_MODERN,
Constants::SKIN_NAME_LEGACY,
Constants::SKIN_VERSION_LEGACY,
],
// When useskin=vector-2022 return modern Vector.
[
Constants::SKIN_NAME_MODERN,
Constants::SKIN_NAME_MODERN,
Constants::SKIN_VERSION_LATEST,
],
[
Constants::SKIN_NAME_LEGACY,
Constants::SKIN_NAME_MODERN,
Constants::SKIN_VERSION_LATEST,
],
];
}
/**
* @covers ::getVersion
* @dataProvider providerAnonUserMigrationMode
*/
public function testVectorAnonUserMigrationModeWithUseSkinVector(
string $defaultSkin,
$useSkin,
$expectedVersion
) {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->with( 'useskin' )
->willReturn( $useSkin );
$user = $this->createMock( \User::class );
$user
->method( 'isRegistered' )
->willReturn( false );
$config = new HashConfig( [
'DefaultSkin' => $defaultSkin,
'VectorSkinMigrationMode' => true,
'VectorDefaultSkinVersion' => '2',
'VectorDefaultSkinVersionForExistingAccounts' => '2'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', [
'skin' => $defaultSkin,
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
$this->assertSame(
$expectedVersion,
$skinVersionLookup->getVersion(),
'useskin=vector query string yields legacy skin in migration mode'
);
}
/**
* @covers ::getVersion
*/
public function testVectorRegisteredUserMigrationMode() {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->willReturn( null );
$user = $this->createMock( \User::class );
$user
->method( 'isRegistered' )
->willReturn( true );
$config = new HashConfig( [
'DefaultSkin' => 'vector',
'VectorSkinMigrationMode' => true,
'VectorDefaultSkinVersion' => '1',
'VectorDefaultSkinVersionForExistingAccounts' => '1'
] );
$userOptionsLookup = $this->getUserOptionsLookupMock( $user, '2', [
'skin' => Constants::SKIN_NAME_LEGACY
] );
$skinVersionLookup = new SkinVersionLookup( $request, $user, $config, $userOptionsLookup );
$this->assertSame(
'2',
$skinVersionLookup->getVersion(),
'If legacy skin is set with skin version modern, then the user gets modern skin still'
);
}
/**
* @covers ::getVersion
*/
@ -188,8 +311,13 @@ class SkinVersionLookupTest extends \MediaWikiIntegrationTestCase {
$request = $this->getMockBuilder( \WebRequest::class )->getMock();
$request
->method( 'getVal' )
->with( $this->anything(), '2' )
->willReturn( '2' );
->willReturnCallback( static function ( $key ) {
if ( $key === Constants::QUERY_PARAM_SKIN ) {
return null;
} else {
return '2';
}
} );
$user = $this->createMock( \User::class );
$user