mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-24 15:53:46 +00:00
64df4fde20
Remove JavaScript that collapses tabs and replace with an easier to maintain breakpoint based solution. Tabs will now collapse below the tablet breakpoint Note: In the case of mw.util.addPortletLink, to add items to the `views` menu, these will not be collapsed into the more menu and must now be explicitly added to both menus, ie. if the window is resized these will hide and not appear in the more menu. However, when mw.util.addPortletLink attempts to add to `views` menu when there is not available space, we will redirect those links to the more (`cactions`) dropdown menu. Bug: T306229 Change-Id: I34ace0aeb3e23d8f6a8c5a8680bb492f37e343ad
120 lines
3.9 KiB
JavaScript
120 lines
3.9 KiB
JavaScript
/** @interface CheckboxHack */
|
|
|
|
var
|
|
checkboxHack = /** @type {CheckboxHack} */ require( /** @type {string} */( 'mediawiki.page.ready' ) ).checkboxHack,
|
|
CHECKBOX_HACK_CONTAINER_SELECTOR = '.vector-menu-dropdown',
|
|
CHECKBOX_HACK_CHECKBOX_SELECTOR = '.vector-menu-checkbox',
|
|
CHECKBOX_HACK_BUTTON_SELECTOR = '.vector-menu-heading',
|
|
CHECKBOX_HACK_TARGET_SELECTOR = '.vector-menu-content';
|
|
|
|
/**
|
|
* Add the ability for users to toggle dropdown menus using the enter key (as
|
|
* well as space) using core's checkboxHack.
|
|
*/
|
|
function bind() {
|
|
// Search for all dropdown containers using the CHECKBOX_HACK_CONTAINER_SELECTOR.
|
|
var containers = document.querySelectorAll( CHECKBOX_HACK_CONTAINER_SELECTOR );
|
|
|
|
Array.prototype.forEach.call( containers, function ( container ) {
|
|
var
|
|
checkbox = container.querySelector( CHECKBOX_HACK_CHECKBOX_SELECTOR ),
|
|
button = container.querySelector( CHECKBOX_HACK_BUTTON_SELECTOR ),
|
|
target = container.querySelector( CHECKBOX_HACK_TARGET_SELECTOR );
|
|
|
|
if ( !( checkbox && button && target ) ) {
|
|
return;
|
|
}
|
|
|
|
checkboxHack.bind( window, checkbox, button, target );
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* T295085: Close all dropdown menus when page is unloaded to prevent them from
|
|
* being open when navigating back to a page.
|
|
*/
|
|
function bindCloseOnUnload() {
|
|
addEventListener( 'beforeunload', function () {
|
|
var checkboxes = document.querySelectorAll( CHECKBOX_HACK_CHECKBOX_SELECTOR + ':checked' );
|
|
Array.prototype.forEach.call( checkboxes, function ( checkbox ) {
|
|
/** @type {HTMLInputElement} */ ( checkbox ).checked = false;
|
|
} );
|
|
} );
|
|
}
|
|
|
|
/**
|
|
* Adds icon placeholder for gadgets to use.
|
|
*
|
|
* @typedef {Object} PortletLinkData
|
|
* @property {string|null} id
|
|
*/
|
|
/**
|
|
* @param {HTMLElement} item
|
|
* @param {PortletLinkData} data
|
|
*/
|
|
function addPortletLinkHandler( item, data ) {
|
|
var link = item.querySelector( 'a' );
|
|
var $menu = $( item ).parents( '.vector-menu' );
|
|
var menuElement = $menu.length && $menu.get( 0 ) || null;
|
|
// Dropdowns which have not got the noicon class are icon capable.
|
|
var isIconCapable = menuElement && menuElement.classList.contains(
|
|
'vector-menu-dropdown'
|
|
) && !menuElement.classList.contains(
|
|
'vector-menu-dropdown-noicon'
|
|
);
|
|
|
|
// The views menu has limited space so we need to decide whether there is space
|
|
// to accomodate the new item and if not to redirect to the more dropdown.
|
|
/* eslint-disable no-jquery/no-global-selector */
|
|
if ( $menu.prop( 'id' ) === 'p-views' ) {
|
|
// @ts-ignore if undefined as NaN will be ignored
|
|
var availableWidth = $( '.mw-article-toolbar-container' ).width() -
|
|
// @ts-ignore
|
|
$( '#p-namespaces' ).width() - $( '#p-variants' ).width() -
|
|
// @ts-ignore
|
|
$( '#p-views' ).width() - $( '#p-cactions' ).width();
|
|
var moreDropdown = document.querySelector( '#p-cactions ul' );
|
|
// If the screen width is less than 720px then the views menu is hidden
|
|
if ( moreDropdown && ( availableWidth < 0 || window.innerWidth < 720 ) ) {
|
|
moreDropdown.appendChild( item );
|
|
// reveal if hidden
|
|
mw.util.showPortlet( 'p-cactions' );
|
|
}
|
|
}
|
|
/* eslint-enable no-jquery/no-global-selector */
|
|
|
|
if ( isIconCapable && link ) {
|
|
// If class was previously added this will be a no-op so it is safe to call even
|
|
// if we've previously enhanced it.
|
|
link.classList.add(
|
|
'mw-ui-icon',
|
|
'mw-ui-icon-before'
|
|
);
|
|
|
|
if ( data.id ) {
|
|
// The following class allows gadgets developers to style or hide an icon.
|
|
// * mw-ui-icon-vector-gadget-<id>
|
|
// The class is considered stable and should not be removed without
|
|
// a #user-notice.
|
|
link.classList.add( 'mw-ui-icon-vector-gadget-' + data.id );
|
|
}
|
|
}
|
|
}
|
|
|
|
// Enhance previously added items.
|
|
Array.prototype.forEach.call(
|
|
document.querySelectorAll( '.mw-list-item-js' ),
|
|
function ( item ) {
|
|
addPortletLinkHandler( item, {
|
|
id: item.getAttribute( 'id' )
|
|
} );
|
|
}
|
|
);
|
|
|
|
mw.hook( 'util.addPortletLink' ).add( addPortletLinkHandler );
|
|
|
|
module.exports = function dropdownMenus() {
|
|
bind();
|
|
bindCloseOnUnload();
|
|
};
|