mediawiki-skins-Vector/resources/skins.vector.legacy.js/portlets.js

97 lines
2.8 KiB
JavaScript
Raw Normal View History

/**
* 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
};