mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-12-01 02:37:05 +00:00
1c93d0514b
Bug: T345100 Change-Id: I51fdef33d517ce4f2f50930bc46dddb2f497677c
96 lines
2.8 KiB
JavaScript
96 lines
2.8 KiB
JavaScript
/**
|
|
* An object containing the data to help create a portlet.
|
|
*
|
|
* @typedef {Object} Hint
|
|
* @property {string} type
|
|
*/
|
|
|
|
/**
|
|
* Creates default portlet.
|
|
*
|
|
* @param {Element} portlet
|
|
* @return {Element}
|
|
*/
|
|
function addDefaultPortlet( portlet ) {
|
|
portlet.classList.add( 'vector-menu' );
|
|
const ul = portlet.querySelector( 'ul' );
|
|
if ( !ul ) {
|
|
return portlet;
|
|
}
|
|
ul.classList.add( 'vector-menu-content-list' );
|
|
const label = portlet.querySelector( 'label' );
|
|
const labelId = `${ portlet.id }-label`;
|
|
if ( label ) {
|
|
const labelDiv = document.createElement( 'div' );
|
|
labelDiv.id = labelId;
|
|
labelDiv.classList.add( 'vector-menu-heading' );
|
|
labelDiv.innerHTML = label.textContent || '';
|
|
portlet.insertBefore( labelDiv, label );
|
|
label.remove();
|
|
portlet.setAttribute( 'aria-labelledby', labelId );
|
|
portlet.setAttribute( 'role', 'navigation' );
|
|
}
|
|
let wrapper = portlet.querySelector( 'div:last-child' );
|
|
if ( wrapper ) {
|
|
ul.remove();
|
|
wrapper.appendChild( ul );
|
|
wrapper.classList.add( 'vector-menu-content' );
|
|
} else {
|
|
wrapper = document.createElement( 'div' );
|
|
wrapper.classList.add( 'vector-menu-content' );
|
|
ul.remove();
|
|
wrapper.appendChild( ul );
|
|
portlet.appendChild( wrapper );
|
|
}
|
|
// menus inside the legacy sidebar should have vector-menu-portal class.
|
|
if ( portlet.closest( '.vector-legacy-sidebar' ) ) {
|
|
portlet.classList.add( 'vector-menu-portal' );
|
|
}
|
|
|
|
return portlet;
|
|
}
|
|
|
|
/**
|
|
* A hook handler for util.addPortlet hook.
|
|
* It creates a portlet based on the hint, and adabt it to vector skin.
|
|
*
|
|
* @param {Element} portlet
|
|
* @return {Element}
|
|
*/
|
|
function addPortletHandler( portlet ) {
|
|
const parent = /** @type {HTMLElement} */( portlet.parentNode );
|
|
// Note if there is a parent, it's been appended to the DOM so we can determine
|
|
// its type.
|
|
if ( parent && parent.id === 'right-navigation' ) {
|
|
const id = portlet.id;
|
|
portlet.classList.add( 'vector-menu-dropdown' );
|
|
const checkbox = document.createElement( 'input' );
|
|
checkbox.type = 'checkbox';
|
|
checkbox.id = `${ id }-checkbox`;
|
|
checkbox.setAttribute( 'role', 'button' );
|
|
checkbox.setAttribute( 'aria-haspopup', 'true' );
|
|
checkbox.setAttribute( 'data-event-name', `ui.dropdown-${ id }` );
|
|
checkbox.setAttribute( 'class', 'vector-menu-checkbox' );
|
|
checkbox.setAttribute( 'aria-labelledby', `${ id }-label` );
|
|
portlet.prepend( checkbox );
|
|
}
|
|
portlet.classList.remove( 'mw-portlet-js' );
|
|
return addDefaultPortlet( portlet );
|
|
}
|
|
|
|
/**
|
|
* @return {{addPortletHandler: (function(Element): Element)}}
|
|
*/
|
|
function main() {
|
|
mw.hook( 'util.addPortlet' ).add( addPortletHandler );
|
|
// Update any portlets that were created prior to the hook being registered.
|
|
document.querySelectorAll( '.mw-portlet-js' ).forEach( addPortletHandler );
|
|
return {
|
|
addPortletHandler
|
|
};
|
|
}
|
|
|
|
module.exports = {
|
|
main, addPortletHandler
|
|
};
|