Icons: Watchstar and wikilove are upgraded
Can be tested by appending ?vectorvisualenhancementnext=1 to URL Bug: T310838 Bug: T234990 Bug: T234550 Depends-On: I76d0d94c9006cc5f5680849ecdd1c382c16e34ba Depends-On: Ib7c3021db014827b4b88cac855afc0b54a360f8c Change-Id: Ie2ffa5c3ecf270c1bb1f315937023ae7ace5ed30
This commit is contained in:
parent
e629775aff
commit
97cf735de2
|
@ -153,7 +153,7 @@ class Hooks implements
|
|||
}
|
||||
|
||||
/**
|
||||
* Transforms watch item inside the action navigation menu
|
||||
* Moves watch item from actions to views menu.
|
||||
*
|
||||
* @param array &$content_navigation
|
||||
*/
|
||||
|
@ -168,15 +168,60 @@ class Hooks implements
|
|||
|
||||
// Promote watch link from actions to views and add an icon
|
||||
if ( $key !== null ) {
|
||||
self::appendClassToItem(
|
||||
$content_navigation['actions'][$key]['class'],
|
||||
[ 'icon' ]
|
||||
);
|
||||
$content_navigation['views'][$key] = $content_navigation['actions'][$key];
|
||||
unset( $content_navigation['actions'][$key] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds icons to items in the "views" menu.
|
||||
*
|
||||
* @param array &$content_navigation
|
||||
* @param bool $isLegacy is this the legacy Vector skin?
|
||||
*/
|
||||
private static function updateViewsMenuIcons( &$content_navigation, $isLegacy ) {
|
||||
$featureManager = VectorServices::getFeatureManager();
|
||||
$visualEnhancements = $featureManager->isFeatureEnabled( Constants::FEATURE_VISUAL_ENHANCEMENTS );
|
||||
|
||||
foreach ( $content_navigation['views'] as $key => $item ) {
|
||||
$icon = $item['icon'] ?? null;
|
||||
if ( $icon ) {
|
||||
if ( $isLegacy || !$featureManager->isFeatureEnabled( Constants::FEATURE_VISUAL_ENHANCEMENTS ) ) {
|
||||
self::appendClassToItem(
|
||||
$item['class'],
|
||||
[ 'icon' ]
|
||||
);
|
||||
} else {
|
||||
// Force the item as a button with hidden text.
|
||||
$item['button'] = true;
|
||||
$item['text-hidden'] = true;
|
||||
$item = self::updateMenuItemData( $item, true );
|
||||
}
|
||||
} else {
|
||||
self::appendClassToItem(
|
||||
$item['class'],
|
||||
[ 'vector-tab-noicon' ]
|
||||
);
|
||||
}
|
||||
$content_navigation['views'][$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* All associated pages menu items do not have icons so are given the vector-tab-noicon class.
|
||||
*
|
||||
* @param array &$content_navigation
|
||||
*/
|
||||
private static function updateAssociatedPagesMenuIcons( &$content_navigation ) {
|
||||
foreach ( $content_navigation['associated-pages'] as $key => $item ) {
|
||||
self::appendClassToItem(
|
||||
$item['class'],
|
||||
[ 'vector-tab-noicon' ]
|
||||
);
|
||||
$content_navigation['associated-pages'][$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds class to a property
|
||||
*
|
||||
|
@ -376,9 +421,10 @@ class Hooks implements
|
|||
* @param array $item data to update
|
||||
* @param string $buttonClassProp property to append button classes
|
||||
* @param string $iconHtmlProp property to set icon HTML
|
||||
* @param bool $isSmallIcon when set a small icon will be applied rather than the standard icon size
|
||||
* @return array $item Updated data
|
||||
*/
|
||||
private static function updateItemData( $item, $buttonClassProp, $iconHtmlProp ) {
|
||||
private static function updateItemData( $item, $buttonClassProp, $iconHtmlProp, $isSmallIcon = false ) {
|
||||
$hasButton = $item['button'] ?? false;
|
||||
$hideText = $item['text-hidden'] ?? false;
|
||||
$isCollapsible = $item['collapsible'] ?? false;
|
||||
|
@ -403,6 +449,9 @@ class Hooks implements
|
|||
// We should seek to remove all these instances.
|
||||
'mw-ui-icon-wikimedia-' . $icon
|
||||
];
|
||||
if ( $isSmallIcon ) {
|
||||
$iconElementClasses[] = 'mw-ui-icon-small';
|
||||
}
|
||||
self::appendClassToItem( $item[ $buttonClassProp ], $iconElementClasses );
|
||||
} else {
|
||||
$item[ $iconHtmlProp ] = self::makeIcon( $icon );
|
||||
|
@ -439,12 +488,13 @@ class Hooks implements
|
|||
* Updates template data for Vector menu items.
|
||||
*
|
||||
* @param array $item menu item data to update
|
||||
* @param bool $isSmallIcon when set a small icon will be applied rather than the standard icon size
|
||||
* @return array $item Updated menu item data
|
||||
*/
|
||||
public static function updateMenuItemData( $item ) {
|
||||
public static function updateMenuItemData( $item, $isSmallIcon = false ) {
|
||||
$buttonClassProp = 'link-class';
|
||||
$iconHtmlProp = 'link-html';
|
||||
return self::updateItemData( $item, $buttonClassProp, $iconHtmlProp );
|
||||
return self::updateItemData( $item, $buttonClassProp, $iconHtmlProp, $isSmallIcon );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -500,7 +550,11 @@ class Hooks implements
|
|||
$title = $sk->getRelevantTitle();
|
||||
|
||||
$skinName = $sk->getSkinName();
|
||||
if ( self::isVectorSkin( $skinName ) ) {
|
||||
// These changes should only happen in Vector.
|
||||
if ( !$skinName || !self::isVectorSkin( $skinName ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
$sk->getConfig()->get( 'VectorUseIconWatch' ) &&
|
||||
$title && $title->canExist()
|
||||
|
@ -509,10 +563,14 @@ class Hooks implements
|
|||
}
|
||||
|
||||
self::updateUserLinksItems( $sk, $content_navigation );
|
||||
}
|
||||
if ( $skinName === Constants::SKIN_NAME_MODERN ) {
|
||||
self::createMoreOverflowMenu( $content_navigation );
|
||||
}
|
||||
|
||||
// The updating of the views menu happens /after/ the overflow menu has been created
|
||||
// this avoids icons showing in the more overflow menu.
|
||||
self::updateViewsMenuIcons( $content_navigation, self::isSkinVersionLegacy( $skinName ) );
|
||||
self::updateAssociatedPagesMenuIcons( $content_navigation );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,6 +2,7 @@ var languageButton = require( './languageButton.js' ),
|
|||
initSearchLoader = require( './searchLoader.js' ).initSearchLoader,
|
||||
dropdownMenus = require( './dropdownMenus.js' ).dropdownMenus,
|
||||
sidebarPersistence = require( './sidebarPersistence.js' ),
|
||||
watchstar = require( './watchstar.js' ),
|
||||
checkbox = require( './checkbox.js' );
|
||||
|
||||
/**
|
||||
|
@ -74,6 +75,9 @@ function main( window ) {
|
|||
languageButton();
|
||||
dropdownMenus();
|
||||
addNamespacesGadgetSupport();
|
||||
if ( document.body.classList.contains( 'vector-feature-visual-enhancement-next-enabled' ) ) {
|
||||
watchstar();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
module.exports = function () {
|
||||
mw.hook( 'wikipage.watchlistChange' ).add(
|
||||
function ( /** @type {boolean} */ isWatched, /** @type {string} */ expiry ) {
|
||||
var watchElement = document.querySelectorAll( '#ca-watch a, #ca-unwatch a' )[ 0 ];
|
||||
if ( !watchElement ) {
|
||||
return;
|
||||
}
|
||||
watchElement.classList.remove(
|
||||
'mw-ui-icon-wikimedia-unStar',
|
||||
'mw-ui-icon-wikimedia-star',
|
||||
'mw-ui-icon-wikimedia-halfStar'
|
||||
);
|
||||
if ( isWatched ) {
|
||||
if ( expiry === 'infinity' ) {
|
||||
watchElement.classList.add( 'mw-ui-icon-wikimedia-unStar' );
|
||||
} else {
|
||||
watchElement.classList.add( 'mw-ui-icon-wikimedia-halfStar' );
|
||||
}
|
||||
} else {
|
||||
watchElement.classList.add( 'mw-ui-icon-wikimedia-star' );
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
|
@ -15,8 +15,11 @@
|
|||
}
|
||||
|
||||
/* focus and hover have outlines. Text underline interferes with bottom border */
|
||||
.mw-list-item a:focus,
|
||||
.mw-list-item a:hover {
|
||||
/* FIXME: Remove 2 not selectors when cache has cleared for Ie2ffa5c3ecf270c1bb1f315937023ae7ace5ed30 */
|
||||
.mw-list-item a:not( .mw-ui-icon ):focus,
|
||||
.mw-list-item a:not( .mw-ui-icon ):hover,
|
||||
.mw-list-item.vector-tab-noicon a:focus,
|
||||
.mw-list-item.vector-tab-noicon a:hover {
|
||||
text-decoration: none;
|
||||
border-bottom: @border-width-base @border-style-base;
|
||||
}
|
||||
|
@ -37,11 +40,18 @@
|
|||
* Tab list item appearance. Applies to both <li>'s inside .vector-menu-tabs
|
||||
* and dropdown menus inside the article toolbar
|
||||
*/
|
||||
// FIXME: Remove the body selector once Ie2ffa5c3ecf270c1bb1f315937023ae7ace5ed30 is in production
|
||||
/* for cached HTML */ body:not( .vector-feature-visual-enhancement-next-enabled ) .vector-menu-tabs .mw-list-item,
|
||||
.vector-menu-tabs .mw-list-item.vector-tab-noicon,
|
||||
.mw-article-toolbar-container .vector-menu-dropdown {
|
||||
margin: 0 @padding-horizontal-tabs;
|
||||
}
|
||||
|
||||
.vector-menu-tabs .mw-list-item,
|
||||
.mw-article-toolbar-container .vector-menu-dropdown {
|
||||
float: left;
|
||||
white-space: nowrap;
|
||||
margin: 0 @padding-horizontal-tabs;
|
||||
margin-bottom: 0; /* overrides default `li` styling */
|
||||
|
||||
// target links inside of .vector-tab-menu
|
||||
// and dropdown menu headings inside the article toolbar.
|
||||
|
@ -51,19 +61,42 @@
|
|||
.vector-menu-heading {
|
||||
display: inline-flex;
|
||||
position: relative;
|
||||
// Top & bottom padding to increase clickable area.
|
||||
padding: 18px 0 7px 0;
|
||||
// bottom margin to overlap border with toolbar border.
|
||||
margin-bottom: -1px;
|
||||
cursor: pointer;
|
||||
border-bottom: @border-width-base @border-style-base transparent;
|
||||
// max-height & box-sizing to make link, watchstar & dropdown height consistent.
|
||||
// NOTE: Was 40px instead of 41, but changed to avoid visual regressions.
|
||||
max-height: unit( 41 / @font-size-tabs / @font-size-browser, em );
|
||||
box-sizing: border-box;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.vector-menu-heading {
|
||||
// For better compatibility with gadgets (like Twinkle) that append
|
||||
// <H3> elements as dropdown headings (which was the convention in legacy Vector).
|
||||
font-size: inherit;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
/* FIXME: Remove cached HTML selector (> a:not( .mw-ui-icon ))
|
||||
when Ie2ffa5c3ecf270c1bb1f315937023ae7ace5ed30 is in production */
|
||||
&.vector-tab-noicon > a,
|
||||
& > a:not( .mw-ui-icon ),
|
||||
.vector-menu-heading {
|
||||
// Top & bottom padding to increase clickable area.
|
||||
padding: 18px 0 7px 0;
|
||||
// bottom margin to overlap border with toolbar border.
|
||||
margin-bottom: -1px;
|
||||
}
|
||||
}
|
||||
|
||||
// With mw-ui-icons, expand watchstar and wikilove links it to cover full touch area
|
||||
.vector-feature-visual-enhancement-next-enabled {
|
||||
.vector-menu-tabs {
|
||||
.mw-list-item {
|
||||
.mw-ui-icon {
|
||||
// Align small icons with the bottom of the tabs.
|
||||
// Height of tab is 41px, and small icon is 36px,
|
||||
// With 1px border, 41 - 36 + 1;
|
||||
margin: 4px 0 0 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,8 @@
|
|||
/* Watch/Unwatch Icon Styling */
|
||||
/* Only use icon if the menu item is not collapsed into the "More" dropdown
|
||||
* (in which case it is inside `.vector-menu-dropdown` instead of `.vector-menu-tabs`). */
|
||||
.vector-menu-tabs {
|
||||
// Note: there's no watchstar for anon users so no need to worry about cached HTML when changing this class
|
||||
.vector-feature-visual-enhancement-next-disabled .vector-menu-tabs {
|
||||
@size-watchlink-icon: unit( 16 / @font-size-tabs / @font-size-browser, em );
|
||||
|
||||
.mw-watchlink.icon a {
|
||||
|
@ -59,3 +60,15 @@
|
|||
transform-origin: 50% 50%;
|
||||
}
|
||||
}
|
||||
|
||||
// Loading watchstar link class.
|
||||
.vector-feature-visual-enhancement-next-enabled {
|
||||
.mw-watchlink .loading:before {
|
||||
.rotation( 500ms );
|
||||
/* Suppress the hilarious rotating focus outline on Firefox */
|
||||
outline: 0;
|
||||
cursor: default;
|
||||
pointer-events: none;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -311,6 +311,7 @@
|
|||
}
|
||||
},
|
||||
"icons": [
|
||||
"heart",
|
||||
"language",
|
||||
"ellipsis",
|
||||
"userAvatar",
|
||||
|
@ -387,6 +388,7 @@
|
|||
"name": "resources/skins.vector.js/config.json",
|
||||
"callback": "MediaWiki\\Skins\\Vector\\Hooks::getVectorResourceLoaderConfig"
|
||||
},
|
||||
"resources/skins.vector.js/watchstar.js",
|
||||
"resources/skins.vector.js/dropdownMenus.js",
|
||||
"resources/skins.vector.js/checkbox.js",
|
||||
"resources/skins.vector.js/sidebarPersistence.js",
|
||||
|
|
|
@ -394,19 +394,24 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
*/
|
||||
public function testOnSkinTemplateNavigation() {
|
||||
$this->setMwGlobals( [
|
||||
'wgVectorUseIconWatch' => true
|
||||
'wgVectorUseIconWatch' => true,
|
||||
'wgVectorVisualEnhancementNext' => false,
|
||||
] );
|
||||
$skin = new SkinVector22( [ 'name' => 'vector' ] );
|
||||
$skin->getContext()->setTitle( Title::newFromText( 'Foo' ) );
|
||||
$contentNavWatch = [
|
||||
'associated-pages' => [],
|
||||
'views' => [],
|
||||
'actions' => [
|
||||
'watch' => [ 'class' => [ 'watch' ] ],
|
||||
'watch' => [ 'class' => [ 'watch' ], 'icon' => 'star' ],
|
||||
]
|
||||
];
|
||||
$contentNavUnWatch = [
|
||||
'associated-pages' => [],
|
||||
'views' => [],
|
||||
'actions' => [
|
||||
'move' => [ 'class' => [ 'move' ] ],
|
||||
'unwatch' => [],
|
||||
'unwatch' => [ 'icon' => 'unStar' ],
|
||||
],
|
||||
];
|
||||
|
||||
|
@ -433,6 +438,8 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
public function testUpdateUserLinksItems() {
|
||||
$vector2022Skin = new SkinVector22( [ 'name' => 'vector-2022' ] );
|
||||
$contentNav = [
|
||||
'associated-pages' => [],
|
||||
'views' => [],
|
||||
'user-page' => [
|
||||
'userpage' => [ 'class' => [], 'icon' => 'userpage' ],
|
||||
],
|
||||
|
@ -442,6 +449,8 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
|
|||
];
|
||||
$vectorLegacySkin = new SkinVectorLegacy( [ 'name' => 'vector' ] );
|
||||
$contentNavLegacy = [
|
||||
'associated-pages' => [],
|
||||
'views' => [],
|
||||
'user-page' => [
|
||||
'userpage' => [ 'class' => [], 'icon' => 'userpage' ],
|
||||
]
|
||||
|
|
Loading…
Reference in New Issue