2022-05-13 02:37:28 +00:00
|
|
|
const
|
|
|
|
checkboxHack = require( './checkboxHack.js' ),
|
|
|
|
CHECKBOX_HACK_CONTAINER_SELECTOR = '.mw-checkbox-hack-container',
|
|
|
|
CHECKBOX_HACK_CHECKBOX_SELECTOR = '.mw-checkbox-hack-checkbox',
|
|
|
|
CHECKBOX_HACK_BUTTON_SELECTOR = '.mw-checkbox-hack-button',
|
|
|
|
CHECKBOX_HACK_TARGET_SELECTOR = '.mw-checkbox-hack-target';
|
|
|
|
|
2021-01-16 22:01:58 +00:00
|
|
|
/**
|
2022-05-13 02:37:28 +00:00
|
|
|
* Wait for first paint before calling this function.
|
2021-03-13 17:43:28 +00:00
|
|
|
* (see T234570#5779890, T246419).
|
|
|
|
*
|
|
|
|
* @param {Document} document
|
2021-01-16 22:01:58 +00:00
|
|
|
* @return {void}
|
|
|
|
*/
|
2021-03-13 17:43:28 +00:00
|
|
|
function enableCssAnimations( document ) {
|
|
|
|
document.documentElement.classList.add( 'citizen-animations-ready' );
|
|
|
|
}
|
|
|
|
|
2021-04-21 20:45:52 +00:00
|
|
|
/**
|
2022-05-13 02:37:28 +00:00
|
|
|
* Add the ability for users to toggle dropdown menus using the enter key (as
|
|
|
|
* well as space) using core's checkboxHack.
|
2021-04-21 20:45:52 +00:00
|
|
|
*
|
2022-05-13 02:37:28 +00:00
|
|
|
* Based on Vector
|
2022-11-09 22:46:55 +00:00
|
|
|
*
|
|
|
|
* @return {void}
|
2021-04-21 20:45:52 +00:00
|
|
|
*/
|
2022-05-13 02:37:28 +00:00
|
|
|
function bind() {
|
|
|
|
// Search for all dropdown containers using the CHECKBOX_HACK_CONTAINER_SELECTOR.
|
|
|
|
const containers = document.querySelectorAll( CHECKBOX_HACK_CONTAINER_SELECTOR );
|
|
|
|
|
|
|
|
containers.forEach( ( container ) => {
|
|
|
|
const
|
|
|
|
checkbox = container.querySelector( CHECKBOX_HACK_CHECKBOX_SELECTOR ),
|
|
|
|
button = container.querySelector( CHECKBOX_HACK_BUTTON_SELECTOR ),
|
|
|
|
target = container.querySelector( CHECKBOX_HACK_TARGET_SELECTOR );
|
2021-04-21 20:45:52 +00:00
|
|
|
|
2022-05-13 02:37:28 +00:00
|
|
|
if ( !( checkbox && button && target ) ) {
|
|
|
|
return;
|
2021-04-21 20:45:52 +00:00
|
|
|
}
|
2022-05-13 02:37:28 +00:00
|
|
|
|
|
|
|
checkboxHack.bind( window, checkbox, button, target );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2022-11-09 22:46:55 +00:00
|
|
|
* Close all menus through unchecking all checkbox hacks
|
2022-05-13 02:37:28 +00:00
|
|
|
*
|
2022-11-09 22:46:55 +00:00
|
|
|
* @return {void}
|
2022-05-13 02:37:28 +00:00
|
|
|
*/
|
2022-11-09 22:46:55 +00:00
|
|
|
function uncheckCheckboxHacks() {
|
|
|
|
const checkboxes = document.querySelectorAll( CHECKBOX_HACK_CHECKBOX_SELECTOR + ':checked' );
|
2022-05-13 02:37:28 +00:00
|
|
|
|
2022-11-09 22:46:55 +00:00
|
|
|
checkboxes.forEach( ( checkbox ) => {
|
|
|
|
/** @type {HTMLInputElement} */ ( checkbox ).checked = false;
|
2021-04-21 20:45:52 +00:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2021-04-26 15:39:27 +00:00
|
|
|
/**
|
2022-10-22 23:58:54 +00:00
|
|
|
* Add a class to indicate that sticky header is active
|
2021-04-26 15:39:27 +00:00
|
|
|
*
|
|
|
|
* @param {Document} document
|
|
|
|
* @return {void}
|
|
|
|
*/
|
2022-10-22 23:58:54 +00:00
|
|
|
function initStickyHeader( document ) {
|
2022-11-10 01:02:21 +00:00
|
|
|
const scrollObserver = require( './scrollObserver.js' );
|
|
|
|
|
|
|
|
// Detect scroll direction and add the right class
|
|
|
|
scrollObserver.initDirectionObserver(
|
|
|
|
() => {
|
|
|
|
document.body.classList.remove( 'citizen-scroll--up' );
|
|
|
|
document.body.classList.add( 'citizen-scroll--down' );
|
|
|
|
},
|
|
|
|
() => {
|
|
|
|
document.body.classList.remove( 'citizen-scroll--down' );
|
|
|
|
document.body.classList.add( 'citizen-scroll--up' );
|
|
|
|
},
|
2022-11-23 19:11:48 +00:00
|
|
|
10
|
2022-11-10 01:02:21 +00:00
|
|
|
);
|
|
|
|
|
2022-10-22 23:58:54 +00:00
|
|
|
const sentinel = document.getElementById( 'citizen-body-header-sticky-sentinel' );
|
2021-04-26 15:39:27 +00:00
|
|
|
|
2022-11-09 22:34:40 +00:00
|
|
|
// In some pages we use display:none to disable the sticky header
|
|
|
|
// Do not start observer if it is set to display:none
|
|
|
|
if ( sentinel && getComputedStyle( sentinel ).getPropertyValue( 'display' ) !== 'none' ) {
|
2022-11-10 01:02:21 +00:00
|
|
|
const observer = scrollObserver.initIntersectionObserver(
|
2022-05-13 04:21:08 +00:00
|
|
|
() => {
|
2022-09-30 02:33:06 +00:00
|
|
|
document.body.classList.add( 'citizen-body-header--sticky' );
|
2022-05-13 04:21:08 +00:00
|
|
|
},
|
|
|
|
() => {
|
2022-09-30 02:33:06 +00:00
|
|
|
document.body.classList.remove( 'citizen-body-header--sticky' );
|
2021-04-26 15:39:27 +00:00
|
|
|
}
|
2022-05-13 04:21:08 +00:00
|
|
|
);
|
2022-10-22 23:58:54 +00:00
|
|
|
|
|
|
|
observer.observe( sentinel );
|
2021-04-26 15:39:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-10-23 20:37:43 +00:00
|
|
|
/**
|
|
|
|
* Register service worker
|
|
|
|
*
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function registerServiceWorker() {
|
|
|
|
const scriptPath = mw.config.get( 'wgScriptPath' );
|
|
|
|
|
|
|
|
// Only allow serviceWorker when the scriptPath is at root because of its scope
|
2022-11-09 22:40:31 +00:00
|
|
|
// I can't figure out how to add the Service-Worker-Allowed HTTP header
|
|
|
|
// to change the default scope
|
2022-10-23 20:37:43 +00:00
|
|
|
if ( scriptPath === '' ) {
|
|
|
|
if ( 'serviceWorker' in navigator ) {
|
|
|
|
const SW_MODULE_NAME = 'skins.citizen.serviceWorker',
|
|
|
|
version = mw.loader.moduleRegistry[ SW_MODULE_NAME ].version,
|
|
|
|
// HACK: Faking a RL link
|
|
|
|
swUrl = scriptPath +
|
|
|
|
'/load.php?modules=' + SW_MODULE_NAME +
|
|
|
|
'&only=scripts&raw=true&skin=citizen&version=' + version;
|
|
|
|
|
|
|
|
navigator.serviceWorker.register( swUrl, { scope: '/' } );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-13 17:43:28 +00:00
|
|
|
/**
|
2021-03-13 17:45:03 +00:00
|
|
|
* @param {Window} window
|
2021-03-13 17:43:28 +00:00
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function main( window ) {
|
2022-05-20 21:33:10 +00:00
|
|
|
const search = require( './search.js' );
|
2022-05-13 04:21:08 +00:00
|
|
|
|
2021-03-13 17:43:28 +00:00
|
|
|
enableCssAnimations( window.document );
|
2021-04-21 22:47:03 +00:00
|
|
|
search.init( window );
|
2022-10-22 23:58:54 +00:00
|
|
|
initStickyHeader( window.document );
|
2021-04-27 16:57:54 +00:00
|
|
|
|
2022-10-23 20:37:43 +00:00
|
|
|
// Set up checkbox hacks
|
2022-05-13 02:37:28 +00:00
|
|
|
bind();
|
|
|
|
|
2022-10-23 23:40:19 +00:00
|
|
|
// Table of Contents
|
|
|
|
const tocContainer = document.getElementById( 'mw-panel-toc' );
|
|
|
|
if ( tocContainer ) {
|
|
|
|
const toc = require( './tableOfContents.js' );
|
|
|
|
toc.init();
|
2022-10-25 17:55:07 +00:00
|
|
|
}
|
2022-10-23 23:40:19 +00:00
|
|
|
|
2022-12-09 19:48:17 +00:00
|
|
|
// Collapsible sections
|
|
|
|
if ( document.body.classList.contains( 'citizen-sections-enabled' ) ) {
|
|
|
|
const sections = require( './sections.js' );
|
|
|
|
sections.init();
|
|
|
|
}
|
|
|
|
|
2021-04-27 16:57:54 +00:00
|
|
|
mw.loader.load( 'skins.citizen.preferences' );
|
2022-11-09 22:46:55 +00:00
|
|
|
registerServiceWorker();
|
2022-10-23 20:37:43 +00:00
|
|
|
|
|
|
|
window.addEventListener( 'beforeunload', () => {
|
2022-11-09 22:46:55 +00:00
|
|
|
// T295085: Close all dropdown menus when page is unloaded to prevent them
|
|
|
|
// from being open when navigating back to a page.
|
|
|
|
uncheckCheckboxHacks();
|
|
|
|
// Set up loading indicator
|
2022-10-23 20:37:43 +00:00
|
|
|
document.documentElement.classList.add( 'citizen-loading' );
|
|
|
|
}, false );
|
2021-01-16 22:01:58 +00:00
|
|
|
}
|
|
|
|
|
2022-06-04 21:42:06 +00:00
|
|
|
if ( document.readyState === 'interactive' || document.readyState === 'complete' ) {
|
|
|
|
main( window );
|
|
|
|
} else {
|
|
|
|
document.addEventListener( 'DOMContentLoaded', function () {
|
|
|
|
main( window );
|
|
|
|
} );
|
|
|
|
}
|