Simplify how we generate icons and button classes in Vector
- Separate icon classes from button classes in user links/language - Upgrades the personal tools language button preference to a mw-ui-button with icon - Adds a generic selector for dropdown menus without an icon - Cleans up user links CSS now mw-list-item class is available - Removes icon hack CSS Bug: T289630 Bug: T283757 Change-Id: Ib518858e06549f252d73d57fd4768f446cc561b9
This commit is contained in:
parent
877e001ea9
commit
b88f2970f7
|
@ -220,6 +220,49 @@ class Hooks {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an icon
|
||||
*
|
||||
* @internal for use inside Vector skin.
|
||||
* @param string $name
|
||||
* @return string of HTML
|
||||
*/
|
||||
public static function makeButtonIcon( $name ) {
|
||||
// Html::makeLink will pass this through rawElement
|
||||
return '<span class="mw-ui-icon mw-ui-icon-' . $name . '"></span>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates user interface preferences for modern Vector to upgrade icon/button menu items.
|
||||
*
|
||||
* @param SkinTemplate $sk
|
||||
* @param array &$content_navigation
|
||||
* @param string $menu identifier
|
||||
*/
|
||||
private static function updateMenuItems( $sk, &$content_navigation, $menu ) {
|
||||
foreach ( $content_navigation[$menu] as $key => $item ) {
|
||||
$hasButton = $item['button'] ?? false;
|
||||
$hideText = $item['text-hidden'] ?? false;
|
||||
$icon = $item['icon'] ?? '';
|
||||
unset( $item['button'] );
|
||||
unset( $item['icon'] );
|
||||
unset( $item['text-hidden'] );
|
||||
|
||||
if ( $hasButton ) {
|
||||
$item['link-class'][] = 'mw-ui-button mw-ui-quiet';
|
||||
}
|
||||
|
||||
if ( $icon ) {
|
||||
if ( $hideText ) {
|
||||
$item['link-class'][] = 'mw-ui-icon mw-ui-icon-element mw-ui-icon-' . $icon;
|
||||
} else {
|
||||
$item['link-html'] = self::makeButtonIcon( $icon );
|
||||
}
|
||||
}
|
||||
$content_navigation[$menu][$key] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Upgrades Vector's watch action to a watchstar.
|
||||
* This is invoked inside SkinVector, not via skin registration, as skin hooks
|
||||
|
@ -251,6 +294,21 @@ class Hooks {
|
|||
self::updateUserLinksItems( $sk, $content_navigation );
|
||||
}
|
||||
}
|
||||
|
||||
if ( !self::isSkinVersionLegacy() ) {
|
||||
// Upgrade preferences and notifications to icon buttons
|
||||
// for extensions that have opted in.
|
||||
if ( isset( $content_navigation['user-interface-preferences'] ) ) {
|
||||
self::updateMenuItems(
|
||||
$sk, $content_navigation, 'user-interface-preferences'
|
||||
);
|
||||
}
|
||||
if ( isset( $content_navigation['notifications'] ) ) {
|
||||
self::updateMenuItems(
|
||||
$sk, $content_navigation, 'notifications'
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -514,12 +514,10 @@ class SkinVector extends SkinMustache {
|
|||
'label' => $label,
|
||||
// ext.uls.interface attaches click handler to this selector.
|
||||
'checkbox-class' => ' mw-interlanguage-selector ',
|
||||
'html-vector-heading-icon' => Hooks::makeButtonIcon( 'wikimedia-language' ),
|
||||
'heading-class' =>
|
||||
' vector-menu-heading ' .
|
||||
' mw-ui-icon ' .
|
||||
' mw-ui-icon-before ' .
|
||||
' mw-ui-icon-wikimedia-language ' .
|
||||
' mw-ui-button mw-ui-quiet '
|
||||
' mw-ui-button mw-ui-quiet'
|
||||
];
|
||||
|
||||
// Adds class to hide language button
|
||||
|
@ -533,6 +531,7 @@ class SkinVector extends SkinMustache {
|
|||
|
||||
/**
|
||||
* helper for applying Vector menu classes to portlets
|
||||
*
|
||||
* @param array $portletData returned by SkinMustache to decorate
|
||||
* @param int $type representing one of the menu types (see MENU_TYPE_* constants)
|
||||
* @return array modified version of portletData input
|
||||
|
@ -557,12 +556,21 @@ class SkinVector extends SkinMustache {
|
|||
$portletData['class'] .= $this->loggedin ?
|
||||
' vector-user-menu-logged-in' :
|
||||
' vector-user-menu-logged-out';
|
||||
$portletData['heading-class'] .= ' mw-ui-icon mw-ui-icon-element';
|
||||
$portletData['heading-class'] .= ' mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element';
|
||||
$portletData['heading-class'] .= $this->loggedin ?
|
||||
' mw-ui-icon-wikimedia-userAvatar' :
|
||||
' mw-ui-icon-wikimedia-ellipsis';
|
||||
}
|
||||
}
|
||||
switch ( $portletData['id'] ) {
|
||||
case 'p-variants':
|
||||
case 'p-cactions':
|
||||
$portletData['class'] .= ' vector-menu-dropdown-noicon';
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $portletData['id'] === 'p-lang' && $this->isLanguagesInHeader() ) {
|
||||
$portletData = $this->createULSLanguageButton( $portletData );
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<header class="mw-header">
|
||||
<label
|
||||
id="mw-sidebar-button"
|
||||
class="mw-checkbox-hack-button mw-ui-icon mw-ui-icon-element"
|
||||
class="mw-checkbox-hack-button mw-ui-icon mw-ui-button mw-ui-quiet mw-ui-icon-element"
|
||||
for="mw-sidebar-checkbox"
|
||||
role="button"
|
||||
aria-controls="mw-panel"
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
<div class="mw-ui-icon mw-ui-icon-element mw-ui-icon-{{icon}} {{class}}"></div>
|
||||
<a {{#href}}href="{{.}}"{{/href}} class="mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-element mw-ui-icon-{{icon}} {{class}}">
|
||||
{{#label}}<span>{{*}}</span>{{/label}}
|
||||
</a>
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
data-event-name="ui.dropdown-{{id}}"
|
||||
class="{{#checkbox-class}}{{.}}{{/checkbox-class}} vector-menu-checkbox" aria-labelledby="{{id}}-label" />
|
||||
{{/is-dropdown}}
|
||||
<h3 id="{{id}}-label" {{#heading-class}}class="{{.}}"{{/heading-class}}>
|
||||
<span>{{label}}</span>
|
||||
<h3 id="{{id}}-label" {{#heading-class}}class="{{.}}"{{/heading-class}}>{{!
|
||||
}}{{{html-vector-heading-icon}}} <span>{{label}}</span>
|
||||
{{#is-dropdown}}
|
||||
<span class="vector-menu-checkbox-expanded">{{msg-vector-menu-checkbox-expanded}}</span>
|
||||
<span class="vector-menu-checkbox-collapsed">{{msg-vector-menu-checkbox-collapsed}}</span>
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
</form>
|
||||
</div>
|
||||
{{#is-collapsible}}
|
||||
<a class="mw-ui-icon mw-ui-icon-wikimedia-search mw-ui-icon-element search-toggle"
|
||||
<a class="mw-ui-button mw-ui-quiet mw-ui-icon mw-ui-icon-wikimedia-search mw-ui-icon-element search-toggle"
|
||||
href="{{href-search}}">
|
||||
<span>{{msg-search}}</span>
|
||||
</a>
|
||||
|
|
|
@ -15,15 +15,6 @@
|
|||
display: block;
|
||||
.box-sizing( border-box );
|
||||
|
||||
&:not( .mw-ui-icon ) {
|
||||
// `padding-top` needs to scale with font-size.
|
||||
padding-top: 1.25em;
|
||||
padding-left: 8px;
|
||||
padding-right: unit( 24 / @font-size-tabs / @font-size-browser, em );
|
||||
font-size: @font-size-tabs;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
background-image: url( images/arrow-down.svg );
|
||||
|
@ -166,9 +157,23 @@
|
|||
// When the browser supports :checked, display it
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: `mw-portlet-` selectors are for cached HTML. Remove after 1 week. (T283757)
|
||||
.mw-portlet-variants,
|
||||
.mw-portlet-cactions,
|
||||
.vector-menu-dropdown-noicon {
|
||||
h3 {
|
||||
// `padding-top` needs to scale with font-size.
|
||||
padding-top: 1.25em;
|
||||
padding-left: 8px;
|
||||
padding-right: unit( 24 / @font-size-tabs / @font-size-browser, em );
|
||||
font-size: @font-size-tabs;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
// Add focus state to legacy menu dropdown buttons (i.e. p-variants, p-cactions)
|
||||
&:focus + h3 {
|
||||
.vector-menu-checkbox:focus + h3 {
|
||||
// Simulate browser focus ring
|
||||
outline: dotted 1px; // Firefox style
|
||||
outline: auto -webkit-focus-ring-color; // Webkit style
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
// TODO: `#p-lang-btn` Can be changed to `.mw-portlet-lang` when languages-in-header is the default.
|
||||
#p-lang-btn {
|
||||
// FIXME [review whether margin-top is needed] center vertically in heading.
|
||||
margin-top: 2px;
|
||||
.box-sizing( border-box );
|
||||
height: @height-lang-button;
|
||||
|
||||
|
@ -21,10 +23,6 @@
|
|||
user-select: none;
|
||||
// Remove opacity on language button (it applies to more menu because of label color).
|
||||
opacity: 1;
|
||||
// mw-ui-icon resets the button border.
|
||||
border: 1px solid transparent;
|
||||
// center vertically in heading.
|
||||
margin-top: 2px;
|
||||
|
||||
span {
|
||||
// Special treatment for language button, based on Vector font-size
|
||||
|
|
|
@ -33,13 +33,6 @@
|
|||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&:focus {
|
||||
// Next three rules from OOUI, frameless, icon-only button widget.
|
||||
border-color: @border-color-base--focus;
|
||||
outline: 0;
|
||||
box-shadow: @box-shadow-base--focus;
|
||||
}
|
||||
}
|
||||
|
||||
// Use the MediaWiki checkbox hack class from checkboxHack.less. This class exists on the
|
||||
|
|
|
@ -23,8 +23,12 @@
|
|||
white-space: nowrap;
|
||||
|
||||
a {
|
||||
color: #000;
|
||||
color: @color-base;
|
||||
text-decoration: none;
|
||||
|
||||
.mw-ui-icon {
|
||||
margin-right: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
// Below tablet threshold, all menu items except the notification icons will collapse into the user menu
|
||||
|
@ -63,9 +67,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// Overrides personal menu styles for consolidated user links.
|
||||
.vector-user-menu {
|
||||
height: 100%;
|
||||
|
||||
// Override ".emptyPortlet" class to ensure user menu isn't hidden
|
||||
&.emptyPortlet {
|
||||
|
@ -73,17 +75,13 @@
|
|||
}
|
||||
|
||||
.vector-menu-heading {
|
||||
color: transparent; // overrides MediaWiki UI icon
|
||||
height: 100%;
|
||||
line-height: 0; // T288540: Override language specific line height so user menu spacing is correct.
|
||||
}
|
||||
.mw-ui-icon ~ span {
|
||||
.mixin-screen-reader-text();
|
||||
}
|
||||
|
||||
.vector-menu-checkbox {
|
||||
// FIXME: This variable is currently not available in mediawiki core, but defined in the icons specification.
|
||||
@icon-background-color--selected: rgba( 0, 0, 0, 0.03 );
|
||||
// The mw-ui-icon hover effect does not work on the checkbox hack so must be applied explicitly.
|
||||
&:hover + h3 {
|
||||
background-color: @icon-background-color--selected;
|
||||
// FIXME: For cached HTML only.
|
||||
&.mw-ui-icon > span {
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,15 +103,16 @@
|
|||
}
|
||||
}
|
||||
|
||||
.vector-menu-content-list {
|
||||
li {
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
// FIXME: Remove `li` selector when T289163 is addressed.
|
||||
li,
|
||||
.mw-list-item {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
// FIXME: Remove `li > a` selector when T289163 is addressed.
|
||||
li > a,
|
||||
.vector-menu-content-item,
|
||||
li > a {
|
||||
.mw-list-item > a {
|
||||
// Overrides .mw-ui-icon's `min-height` property to have a computed
|
||||
// min-height of 32px. This matches the design spec of having an icon that
|
||||
// is 20px in height + 6px of top padding + 6px of bottom padding. Using
|
||||
|
@ -128,7 +127,7 @@
|
|||
// at the edge of the menu. Apply the padding on the link element instead
|
||||
// of the li element to maximize the click target.
|
||||
padding: 0 @padding-horizontal-user-links;
|
||||
color: #000;
|
||||
color: @color-base;
|
||||
text-decoration: none;
|
||||
|
||||
span {
|
||||
|
|
|
@ -109,11 +109,11 @@ class SkinVectorTest extends MediaWikiIntegrationTestCase {
|
|||
$namespaces['class']
|
||||
);
|
||||
$this->assertSame(
|
||||
'mw-portlet mw-portlet-variants vector-menu vector-menu-dropdown',
|
||||
'mw-portlet mw-portlet-variants vector-menu-dropdown-noicon vector-menu vector-menu-dropdown',
|
||||
$variants['class']
|
||||
);
|
||||
$this->assertSame(
|
||||
'mw-portlet mw-portlet-cactions vector-menu vector-menu-dropdown',
|
||||
'mw-portlet mw-portlet-cactions vector-menu-dropdown-noicon vector-menu vector-menu-dropdown',
|
||||
$actions['class']
|
||||
);
|
||||
$this->assertSame(
|
||||
|
|
Loading…
Reference in New Issue