Refactor: Simplify and standardize menu definitions
* Standardise the menu markup. This means all menus in Vector will now be wrapped in a div and will have a heading. * All menus now have the vector-menu class. Styles specific to personal tools are moved to layout since these are concerned with placement. * The ul class will always have menu class. * emptyPortal class is generalised into vector-menu-empty for consistency with other classes and moved from common.less into Menu.less * Standardise hooks - BaseTemplateAfterPortlet can now be run on any menu. Changes to HTML: * lang and dir attributes are moved from the h3 up to the div element .vectorTabs, .portal(s) and #p-personal now has hidden span element inside h3 * for non portals ul.menu" is now wrapped in a div.vector-menu-content This change does impact the following CSS selectors which will need to be updated: I see no matches for these selectors in code search. ``` #p-variants > ul #p-namespaces > ul #p-personal > ul #p-views > ul #p-cactions > ul ``` Using global-search.toolforge.org I see one match for p-variants, 26 for p-namespaces, 30 for p-personal, 36 for p-views and 7 for p-cactions. I see this as acceptable breakage provided a user notice is sent out which it has been (T252447) Bug: T249372 Change-Id: Id59234aa6b822a24848386bdc04d8d7ed37ca145
This commit is contained in:
parent
4e661112e8
commit
e048c2a729
|
@ -445,13 +445,11 @@ class VectorTemplate extends BaseTemplate {
|
|||
array $options = [],
|
||||
bool $setLabelToSelected = false
|
||||
) : array {
|
||||
$class = ( count( $urls ) == 0 ) ? 'emptyPortlet' : '';
|
||||
// FIXME: All menus should carry vector-menu, but this can only be done when
|
||||
// Menu.less CSS has been generalised to not include layout.
|
||||
$class = ( count( $urls ) == 0 ) ? 'vector-menu-empty emptyPortlet' : '';
|
||||
$extraClasses = [
|
||||
self::MENU_TYPE_DROPDOWN => 'vector-menu-dropdown vectorMenu',
|
||||
self::MENU_TYPE_TABS => 'vector-menu-tabs vectorTabs',
|
||||
self::MENU_TYPE_PORTAL => 'vector-menu-portal portal',
|
||||
self::MENU_TYPE_DROPDOWN => 'vector-menu vector-menu-dropdown vectorMenu',
|
||||
self::MENU_TYPE_TABS => 'vector-menu vector-menu-tabs vectorTabs',
|
||||
self::MENU_TYPE_PORTAL => 'vector-menu vector-menu-portal portal',
|
||||
self::MENU_TYPE_DEFAULT => 'vector-menu',
|
||||
];
|
||||
$isPortal = self::MENU_TYPE_PORTAL === $type;
|
||||
|
@ -467,7 +465,6 @@ class VectorTemplate extends BaseTemplate {
|
|||
'html-items' => '',
|
||||
'is-dropdown' => self::MENU_TYPE_DROPDOWN === $type,
|
||||
'html-tooltip' => Linker::tooltip( 'p-' . $label ),
|
||||
'is-portal' => $isPortal,
|
||||
];
|
||||
|
||||
foreach ( $urls as $key => $item ) {
|
||||
|
@ -483,7 +480,6 @@ class VectorTemplate extends BaseTemplate {
|
|||
}
|
||||
|
||||
$props['html-after-portal'] = $isPortal ? $this->getAfterPortlet( $label ) : '';
|
||||
|
||||
return $props;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
{{!
|
||||
See @typedef MenuDefinition
|
||||
}}
|
||||
<div id="{{id}}" role="navigation" class="{{class}}" aria-labelledby="{{label-id}}" {{{html-tooltip}}}>
|
||||
<div id="{{id}}" class="{{class}}" aria-labelledby="{{label-id}}" {{{html-tooltip}}}
|
||||
{{{html-userlangattributes}}}>
|
||||
{{#is-dropdown}}
|
||||
<input type="checkbox" class="vectorMenuCheckbox" aria-labelledby="{{label-id}}" />
|
||||
<h3 id="{{label-id}}" {{{html-userlangattributes}}}>
|
||||
{{/is-dropdown}}
|
||||
<h3 id="{{label-id}}">
|
||||
<span>{{label}}</span>
|
||||
</h3>
|
||||
{{/is-dropdown}}
|
||||
{{^is-dropdown}}
|
||||
<h3 id="{{label-id}}">{{label}}</h3>
|
||||
{{/is-dropdown}}
|
||||
{{#is-portal}}
|
||||
<div class="body">
|
||||
<ul>{{{html-items}}}</ul>
|
||||
{{! `body` class for backwards compatibility but let editors know not to use
|
||||
it via HTML comment below: }}
|
||||
<!-- Please do not use the .body class, it is deprecated. -->
|
||||
<div class="body vector-menu-content">
|
||||
<!-- Please do not use the .menu class, it is deprecated. -->
|
||||
<ul class="menu vector-menu-content-list">{{{html-items}}}</ul>
|
||||
{{{html-after-portal}}}
|
||||
</div>
|
||||
{{/is-portal}}
|
||||
{{^is-portal}}
|
||||
<ul class="menu" {{{html-userlangattributes}}}>
|
||||
{{{html-items}}}
|
||||
</ul>
|
||||
{{/is-portal}}
|
||||
</div>
|
||||
{{! Note: html-hook-vector-after-toolbox is deprecated. }}
|
||||
{{{html-hook-vector-after-toolbox}}}
|
||||
|
|
|
@ -28,8 +28,8 @@ function init() {
|
|||
var expandedWidth;
|
||||
// If the dropdown was hidden, show it
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
if ( $cactions.hasClass( 'emptyPortlet' ) ) {
|
||||
$cactions.removeClass( 'emptyPortlet' );
|
||||
if ( $cactions.hasClass( 'vector-menu-empty' ) ) {
|
||||
$cactions.removeClass( 'vector-menu-empty' );
|
||||
// Now that it is visible, force-render it virtually
|
||||
// to get its expanded width, then shrink it 1px before we
|
||||
// yield from JS (which means the expansion won't be visible).
|
||||
|
@ -47,7 +47,7 @@ function init() {
|
|||
// eslint-disable-next-line no-jquery/no-animate
|
||||
$cactions.find( 'h3' ).animate( { width: '1px' }, 'normal', function () {
|
||||
$( this ).attr( 'style', '' )
|
||||
.parent().addClass( 'emptyPortlet' );
|
||||
.parent().addClass( 'vector-menu-empty' );
|
||||
} );
|
||||
}
|
||||
} )
|
||||
|
@ -86,7 +86,7 @@ function init() {
|
|||
|
||||
// Always collapse if the "More" button is already shown.
|
||||
// eslint-disable-next-line no-jquery/no-class-state
|
||||
if ( !$cactions.hasClass( 'emptyPortlet' ) ) {
|
||||
if ( !$cactions.hasClass( 'vector-menu-empty' ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
@import 'mediawiki.mixins.less';
|
||||
|
||||
/* Hide empty portlets */
|
||||
.emptyPortlet {
|
||||
// FIXME: Remove when cache cleared.
|
||||
.emptyPortlet,
|
||||
.vector-menu-empty {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
@ -10,11 +12,8 @@
|
|||
.vector-menu,
|
||||
/* FIXME: Remove p-personal selector when cache has cleared. */
|
||||
#p-personal {
|
||||
position: absolute;
|
||||
top: @top-personal-tools;
|
||||
right: 0.75em;
|
||||
z-index: @z-index-personal;
|
||||
|
||||
// Hidden by default, but displayed by certain menus
|
||||
// e.g. MenuPortal
|
||||
h3 {
|
||||
display: none;
|
||||
}
|
||||
|
@ -22,16 +21,13 @@
|
|||
ul {
|
||||
list-style: none none;
|
||||
margin: 0;
|
||||
padding-left: 10em; /* Keep from overlapping logo */
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
margin-left: 0.75em;
|
||||
// `padding-top` instead of `margin-top` necessary for
|
||||
// anonymous user icon position below
|
||||
padding-top: 0.5em;
|
||||
font-size: @font-size-nav-personal;
|
||||
line-height: @line-height-nav-personal;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
direction: ltr;
|
||||
|
||||
h3 {
|
||||
display: block;
|
||||
background-image: url( images/portal-separator.png ); // Support: IE 8 & 9, Fx 3.6-15, Safari 5.1-6, Chrome 10-25
|
||||
background-image: linear-gradient( to right, transparent 0, #c8ccd1 35%, #c8ccd1 70%, transparent 100% ); // Standard (Firefox 16+, IE 10+, Safari 6.1+, Chrome 26+)
|
||||
background-position: center bottom;
|
||||
|
|
|
@ -48,3 +48,7 @@ body {
|
|||
font-size: @font-size-heading-1;
|
||||
}
|
||||
}
|
||||
|
||||
#p-personal li {
|
||||
font-size: @font-size-nav-personal;
|
||||
}
|
||||
|
|
|
@ -131,6 +131,24 @@ body {
|
|||
margin-top: @height-header;
|
||||
}
|
||||
|
||||
#p-personal {
|
||||
position: absolute;
|
||||
top: @top-personal-tools;
|
||||
right: 0.75em;
|
||||
z-index: @z-index-personal;
|
||||
|
||||
ul {
|
||||
// Keep from spilling out into the first column
|
||||
// For completeness this should also include the width of the logo.
|
||||
// As a result it is possible for the personal tools to overlap the logo.
|
||||
padding-left: @width-grid-column-one;
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
#mw-panel {
|
||||
position: absolute;
|
||||
top: @height-header;
|
||||
|
|
|
@ -25,6 +25,21 @@ body {
|
|||
padding: @padding-content;
|
||||
}
|
||||
|
||||
#p-personal {
|
||||
position: absolute;
|
||||
top: @top-personal-tools;
|
||||
right: 0.75em;
|
||||
z-index: @z-index-personal;
|
||||
|
||||
ul {
|
||||
padding-left: 10em; /* Keep from overlapping logo */
|
||||
}
|
||||
|
||||
li {
|
||||
float: left;
|
||||
}
|
||||
}
|
||||
|
||||
.mw-body,
|
||||
#mw-data-after-content {
|
||||
margin-left: 10em;
|
||||
|
|
|
@ -34,7 +34,6 @@ export const PORTALS = {
|
|||
label: 'Portal title',
|
||||
'label-id': 'p-example-label',
|
||||
'html-userlangattributes': htmluserlangattributes,
|
||||
'is-portal': true,
|
||||
'html-items': `
|
||||
<li><a href='#'>A list of links</a></li>
|
||||
<li><a href='#'>with ids</a></li>
|
||||
|
@ -51,7 +50,6 @@ export const PORTALS = {
|
|||
label: 'Navigation',
|
||||
'label-id': 'p-navigation-label',
|
||||
'html-userlangattributes': htmluserlangattributes,
|
||||
'is-portal': true,
|
||||
'html-items': `
|
||||
<li id="n-mainpage-description"><a href="/wiki/Main_Page" title="Visit the main page [⌃⌥z]" accesskey="z">Main page</a></li><li id="n-contents"><a href="/wiki/Wikipedia:Contents" title="Guides to browsing Wikipedia">Contents</a></li><li id="n-featuredcontent"><a href="/wiki/Wikipedia:Featured_content" title="Featured content – the best of Wikipedia">Featured content</a></li><li id="n-currentevents"><a href="/wiki/Portal:Current_events" title="Find background information on current events">Current events</a></li><li id="n-randompage"><a href="/wiki/Special:Random" title="Load a random page [⌃⌥x]" accesskey="x">Random page</a></li><li id="n-sitesupport"><a href="https://donate.wikimedia.org/wiki/Special:FundraiserRedirector?utm_source=donate&utm_medium=sidebar&utm_campaign=C13_en.wikipedia.org&uselang=en" title="Support us">Donate</a></li><li id="n-shoplink"><a href="//shop.wikimedia.org" title="Visit the Wikipedia store">Wikipedia store</a></li>
|
||||
`,
|
||||
|
@ -64,7 +62,6 @@ export const PORTALS = {
|
|||
label: 'Tools',
|
||||
'label-id': 'p-tb-label',
|
||||
'html-userlangattributes': htmluserlangattributes,
|
||||
'is-portal': true,
|
||||
'html-items': `
|
||||
<li id="t-whatlinkshere"><a href="/wiki/Special:WhatLinksHere/Spain" title="A list of all wiki pages that link here [⌃⌥j]" accesskey="j">What links here</a></li><li id="t-recentchangeslinked"><a href="/wiki/Special:RecentChangesLinked/Spain" rel="nofollow" title="Recent changes in pages linked from this page [⌃⌥k]" accesskey="k">Related changes</a></li><li id="t-upload"><a href="/wiki/Wikipedia:File_Upload_Wizard" title="Upload files [⌃⌥u]" accesskey="u">Upload file</a></li><li id="t-specialpages"><a href="/wiki/Special:SpecialPages" title="A list of all special pages [⌃⌥q]" accesskey="q">Special pages</a></li><li id="t-permalink"><a href="/w/index.php?title=Spain&oldid=935087243" title="Permanent link to this revision of the page">Permanent link</a></li><li id="t-info"><a href="/w/index.php?title=Spain&action=info" title="More information about this page">Page information</a></li><li id="t-wikibase"><a href="https://www.wikidata.org/wiki/Special:EntityPage/Q29" title="Link to connected data repository item [⌃⌥g]" accesskey="g">Wikidata item</a></li><li id="t-cite"><a href="/w/index.php?title=Special:CiteThisPage&page=Spain&id=935087243" title="Information on how to cite this page">Cite this page</a></li>
|
||||
`,
|
||||
|
@ -77,7 +74,6 @@ export const PORTALS = {
|
|||
label: 'In other languages',
|
||||
'label-id': 'p-lang-label',
|
||||
'html-userlangattributes': htmluserlangattributes,
|
||||
'is-portal': true,
|
||||
'html-items': `
|
||||
<li class="interlanguage-link interwiki-ace">
|
||||
<a href="https://ace.wikipedia.org/wiki/Seupanyo"
|
||||
|
@ -97,7 +93,6 @@ ${placeholder( `<p>Further hook output possible (lang)</p>`, 60 )}`
|
|||
'label-id': 'p-wikibase-otherprojects-label',
|
||||
'html-userlangattributes': htmluserlangattributes,
|
||||
|
||||
'is-portal': true,
|
||||
'html-items': `
|
||||
<li class="wb-otherproject-link wb-otherproject-commons"><a href="https://commons.wikimedia.org/wiki/Category:Spain" hreflang="en">Wikimedia Commons</a></li><li class="wb-otherproject-link wb-otherproject-wikinews"><a href="https://en.wikinews.org/wiki/Category:Spain" hreflang="en">Wikinews</a></li><li class="wb-otherproject-link wb-otherproject-wikiquote"><a href="https://en.wikiquote.org/wiki/Spain" hreflang="en">Wikiquote</a></li><li class="wb-otherproject-link wb-otherproject-wikivoyage"><a href="https://en.wikivoyage.org/wiki/Spain" hreflang="en">Wikivoyage</a></li>`,
|
||||
'html-after-portal': ''
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
* @prop {string} [class] of menu
|
||||
* @prop {string} [html-userlangattributes]
|
||||
* @prop {boolean} [is-dropdown]
|
||||
* @prop {boolean} [is-portal]
|
||||
* @prop {string} [html-hook-vector-after-toolbox] Deprecated and used by the toolbox portal menu.
|
||||
* @prop {string} [html-after-portal] Additional HTML specific to portal menus.
|
||||
*/
|
||||
|
|
|
@ -154,28 +154,27 @@ class VectorTemplateTest extends MediaWikiIntegrationTestCase {
|
|||
|
||||
$this->assertSame( $views, [
|
||||
'id' => 'p-views',
|
||||
'class' => 'emptyPortlet vector-menu-tabs vectorTabs',
|
||||
'class' => 'vector-menu-empty emptyPortlet vector-menu vector-menu-tabs vectorTabs',
|
||||
'label-id' => 'p-views-label',
|
||||
'label' => 'Views',
|
||||
'html-userlangattributes' => $langAttrs,
|
||||
'html-items' => '',
|
||||
'class' => 'emptyPortlet vector-menu-tabs vectorTabs',
|
||||
'class' => 'vector-menu-empty emptyPortlet vector-menu vector-menu-tabs vectorTabs',
|
||||
'is-dropdown' => false,
|
||||
'html-tooltip' => '',
|
||||
'is-portal' => false,
|
||||
'html-after-portal' => ''
|
||||
] );
|
||||
|
||||
$variants = $props['data-variants'];
|
||||
$actions = $props['data-page-actions-more'];
|
||||
$this->assertSame( $namespaces['class'],
|
||||
'emptyPortlet vector-menu-tabs vectorTabs' );
|
||||
'vector-menu-empty emptyPortlet vector-menu vector-menu-tabs vectorTabs' );
|
||||
$this->assertSame( $variants['class'],
|
||||
'emptyPortlet vector-menu-dropdown vectorMenu' );
|
||||
'vector-menu-empty emptyPortlet vector-menu vector-menu-dropdown vectorMenu' );
|
||||
$this->assertSame( $actions['class'],
|
||||
'emptyPortlet vector-menu-dropdown vectorMenu' );
|
||||
'vector-menu-empty emptyPortlet vector-menu vector-menu-dropdown vectorMenu' );
|
||||
$this->assertSame( $props['data-personal-menu']['class'],
|
||||
'emptyPortlet vector-menu' );
|
||||
'vector-menu-empty emptyPortlet vector-menu' );
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue