Merge "Update user menu and watchstar buttons to be consistent with spec"

This commit is contained in:
jenkins-bot 2023-05-04 18:34:04 +00:00 committed by Gerrit Code Review
commit c069ada615
8 changed files with 66 additions and 56 deletions

View file

@ -177,7 +177,7 @@ class Hooks implements
// Force the item as a button with hidden text.
$item['button'] = true;
$item['text-hidden'] = true;
$item = self::updateMenuItemData( $item, true );
$item = self::updateMenuItemData( $item, true, false );
}
} elseif ( !$isLegacy ) {
// The vector-tab-noicon class is only used in Vector-22.
@ -436,11 +436,16 @@ class Hooks implements
*
* @internal for use inside Vector skin.
* @param string $name
* @param bool $isSmall
* @return string of HTML
*/
public static function makeIcon( $name ) {
public static function makeIcon( $name, $isSmall = false ) {
// Html::makeLink will pass this through rawElement
return '<span class="mw-ui-icon mw-ui-icon-' . $name . ' mw-ui-icon-wikimedia-' . $name . '"></span>';
$iconClasses = 'mw-ui-icon';
if ( $isSmall ) {
$iconClasses .= ' mw-ui-icon-small';
}
return '<span class="' . $iconClasses . ' mw-ui-icon-' . $name . ' mw-ui-icon-wikimedia-' . $name . '"></span>';
}
/**
@ -451,15 +456,20 @@ class Hooks implements
* @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
* @param bool $unsetIcon should the icon field be unset?
* @return array $item Updated data
*/
private static function updateItemData( $item, $buttonClassProp, $iconHtmlProp, $isSmallIcon = false ) {
private static function updateItemData(
$item, $buttonClassProp, $iconHtmlProp, $isSmallIcon = false, $unsetIcon = true
) {
$hasButton = $item['button'] ?? false;
$hideText = $item['text-hidden'] ?? false;
$isCollapsible = $item['collapsible'] ?? false;
$icon = $item['icon'] ?? '';
if ( $unsetIcon ) {
unset( $item['icon'] );
}
unset( $item['button'] );
unset( $item['icon'] );
unset( $item['text-hidden'] );
unset( $item['collapsible'] );
@ -471,20 +481,10 @@ class Hooks implements
}
if ( $icon ) {
if ( $hideText ) {
$iconElementClasses = [ 'mw-ui-icon', 'mw-ui-icon-element',
// Some extensions declare icons without the wikimedia- prefix. e.g. Echo
'mw-ui-icon-' . $icon,
// FIXME: Some icon names are prefixed with `wikimedia-`.
// We should seek to remove all these instances.
'mw-ui-icon-wikimedia-' . $icon
];
if ( $isSmallIcon ) {
$iconElementClasses[] = 'mw-ui-icon-small';
}
$iconElementClasses = [ 'mw-ui-icon-element' ];
self::appendClassToItem( $item[ $buttonClassProp ], $iconElementClasses );
} else {
$item[ $iconHtmlProp ] = self::makeIcon( $icon );
}
$item[ $iconHtmlProp ] = self::makeIcon( $icon, $isSmallIcon );
}
return $item;
}
@ -495,12 +495,13 @@ class Hooks implements
* @internal used inside Hooks::updateMenuItems ::updateViewsMenuIcons and ::updateUserLinksDropdownItems
* @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
* @param bool $unsetIcon should the icon field be unset?
* @return array $item Updated menu item data
*/
public static function updateMenuItemData( $item, $isSmallIcon = false ) {
public static function updateMenuItemData( $item, $isSmallIcon = false, $unsetIcon = true ) {
$buttonClassProp = 'link-class';
$iconHtmlProp = 'link-html';
return self::updateItemData( $item, $buttonClassProp, $iconHtmlProp, $isSmallIcon );
return self::updateItemData( $item, $buttonClassProp, $iconHtmlProp, $isSmallIcon, $unsetIcon );
}
/**

View file

@ -1,11 +1,12 @@
module.exports = function () {
mw.hook( 'wikipage.watchlistChange' ).add(
function ( /** @type {boolean} */ isWatched, /** @type {string} */ expiry ) {
const watchElement = document.querySelectorAll( '#ca-watch a, #ca-unwatch a' )[ 0 ];
if ( !watchElement ) {
const watchIcon = document.querySelectorAll( '#ca-watch .mw-ui-icon, #ca-unwatch .mw-ui-icon' )[ 0 ];
if ( !watchIcon ) {
return;
}
watchElement.classList.remove(
watchIcon.classList.remove(
// Vector attaches two icon classes to the element.
// Remove the mw-ui-icon one rather than managing both.
'mw-ui-icon-star',
@ -14,14 +15,15 @@ module.exports = function () {
'mw-ui-icon-wikimedia-star',
'mw-ui-icon-wikimedia-halfStar'
);
if ( isWatched ) {
if ( expiry === 'infinity' ) {
watchElement.classList.add( 'mw-ui-icon-wikimedia-unStar' );
watchIcon.classList.add( 'mw-ui-icon-wikimedia-unStar' );
} else {
watchElement.classList.add( 'mw-ui-icon-wikimedia-halfStar' );
watchIcon.classList.add( 'mw-ui-icon-wikimedia-halfStar' );
}
} else {
watchElement.classList.add( 'mw-ui-icon-wikimedia-star' );
watchIcon.classList.add( 'mw-ui-icon-wikimedia-star' );
}
}
);

View file

@ -11,11 +11,12 @@
// With mw-ui-icons, expand watchstar and wikilove links it to cover full touch area
.mw-list-item {
.mw-ui-icon {
.mw-ui-icon-element {
font-size: unit( 16 / @font-size-browser, rem );
// Align small icons with the bottom of the tabs.
// Height of tab is 32px, and small icon is 32px,
// With 2px border, 32 - 32 + 2
margin: 2px 0 0 0;
margin: 4px 2px 0 2px;
// Do not increase size at lower resolutions
padding: 0.3125em;
}
}

View file

@ -19,6 +19,23 @@
}
}
}
.mw-ui-icon-element {
// Override icon styles to apply .mw-ui-icon-small styles
// FIXME: To be replaced with Codex mixins
.mw-ui-icon {
min-width: 16px;
min-height: 16px;
width: 1em;
height: 1em;
&::before {
min-width: 100%;
min-height: 100%;
background-size: 100% 100%;
}
}
}
}
// ID Selectors outside of .vector-page-toolbar-container to avoid over-specificity.

View file

@ -7,19 +7,10 @@
* (in which case it is inside `.vector-menu-dropdown` instead of `.vector-menu-tabs`). */
// Note: there's no watchstar for anon users so no need to worry about cached HTML when changing this class
// Loading watchstar link class.
.mw-watchlink a::before {
.mw-watchlink .mw-ui-icon::before {
transition: transform 500ms;
}
.mw-watchlink .loading::before {
/* Suppress the hilarious rotating focus outline on Firefox */
outline: 0;
cursor: default;
pointer-events: none;
transform-origin: 50% 50%;
}
.mw-ui-icon-wikimedia-unStar::before,
.mw-ui-icon-wikimedia-star.loading::before {
.mw-ui-icon-wikimedia-unStar::before {
transform: rotate( 72deg );
}

View file

@ -57,6 +57,11 @@
.vector-user-links .mw-portlet-vector-user-menu-overflow {
font-size: @font-size-user-links;
// Ensure icon buttons have a base font of 16px
.mw-ui-icon-element {
font-size: unit( 16 / @font-size-browser, rem );
}
.vector-menu-content-list {
display: flex;
align-items: center;

View file

@ -1,11 +1,7 @@
@import '../resources/common/variables.less';
.mixin-notification-badge() {
// When 99+ allow counter so spill outside icon
// Overrides mw-ui-icon default.
&.mw-ui-icon {
overflow: visible;
}
position: relative;
&::after {
position: absolute;

View file

@ -721,23 +721,20 @@ class VectorHooksTest extends MediaWikiIntegrationTestCase {
[ 'class' => [], 'text-hidden' => true, 'icon' => 'userpage' ],
'link-class',
'link-html',
[ 'class' => [], 'link-class' => [
'mw-ui-icon',
'mw-ui-icon-element',
'mw-ui-icon-userpage',
'mw-ui-icon-wikimedia-userpage'
] ],
[
'class' => [],
'link-class' => [ 'mw-ui-icon-element' ],
'link-html' => '<span class="mw-ui-icon mw-ui-icon-userpage mw-ui-icon-wikimedia-userpage"></span>'
],
],
// Adds button and icon classes
[
[ 'class' => [], 'button' => true, 'icon' => 'userpage' ],
'class',
'link-html',
[ 'class' => [
'mw-ui-button',
'mw-ui-quiet'
], 'link-html' =>
'<span class="mw-ui-icon mw-ui-icon-userpage mw-ui-icon-wikimedia-userpage"></span>'
[
'class' => [ 'mw-ui-button', 'mw-ui-quiet' ],
'link-html' => '<span class="mw-ui-icon mw-ui-icon-userpage mw-ui-icon-wikimedia-userpage"></span>'
],
]
];