2021-01-16 22:01:58 +00:00
|
|
|
/**
|
2021-03-13 17:43:28 +00:00
|
|
|
* Based on Vector
|
|
|
|
* Wait for first paint before calling this function. That's its whole purpose.
|
|
|
|
*
|
|
|
|
* Some CSS animations and transitions are "disabled" by default as a workaround to this old Chrome
|
|
|
|
* bug, https://bugs.chromium.org/p/chromium/issues/detail?id=332189, which otherwise causes them to
|
|
|
|
* render in their terminal state on page load. By adding the `vector-animations-ready` class to the
|
|
|
|
* `html` root element **after** first paint, the animation selectors suddenly match causing the
|
|
|
|
* animations to become "enabled" when they will work properly. A similar pattern is used in Minerva
|
|
|
|
* (see T234570#5779890, T246419).
|
|
|
|
*
|
|
|
|
* Example usage in Less:
|
|
|
|
*
|
|
|
|
* ```less
|
|
|
|
* .foo {
|
|
|
|
* color: #f00;
|
|
|
|
* .transform( translateX( -100% ) );
|
|
|
|
* }
|
|
|
|
*
|
|
|
|
* // This transition will be disabled initially for JavaScript users. It will never be enabled for
|
|
|
|
* // no-JS users.
|
|
|
|
* .citizen-animations-ready .foo {
|
|
|
|
* .transition( transform 100ms ease-out; );
|
|
|
|
* }
|
|
|
|
* ```
|
|
|
|
*
|
|
|
|
* @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
|
|
|
/**
|
|
|
|
* Initialize checkboxHacks
|
|
|
|
* TODO: Maybe ToC should init checkboxHack in its own RL module?
|
|
|
|
*
|
|
|
|
* @param {Window} window
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function initCheckboxHack( window ) {
|
|
|
|
const checkboxHack = require( './checkboxHack.js' ),
|
|
|
|
drawer = {
|
|
|
|
button: document.getElementById( 'mw-drawer-button' ),
|
|
|
|
checkbox: document.getElementById( 'mw-drawer-checkbox' ),
|
|
|
|
target: document.getElementById( 'mw-drawer' )
|
|
|
|
},
|
|
|
|
personalMenu = {
|
|
|
|
button: document.getElementById( 'personalmenu-button' ),
|
|
|
|
checkbox: document.getElementById( 'personalmenu-checkbox' ),
|
|
|
|
target: document.getElementById( 'p-personal' )
|
|
|
|
},
|
|
|
|
checkboxObjs = [ drawer, personalMenu ];
|
|
|
|
|
|
|
|
// This should be in ToC script
|
|
|
|
// And the media query needs to be synced with the less variable
|
|
|
|
// Also this does not monitor screen size changes
|
|
|
|
if ( document.body.classList.contains( 'skin-citizen-has-toc' ) &&
|
|
|
|
window.matchMedia( 'screen and (max-width: 1300px)' ) ) {
|
|
|
|
const tocContainer = document.getElementById( 'toc' ),
|
|
|
|
toc = {
|
|
|
|
button: tocContainer.querySelector( '.toctogglelabel' ),
|
|
|
|
checkbox: document.getElementById( 'toctogglecheckbox' ),
|
|
|
|
target: tocContainer.querySelector( 'ul' )
|
|
|
|
};
|
|
|
|
|
|
|
|
checkboxObjs.push( toc );
|
|
|
|
}
|
|
|
|
|
|
|
|
checkboxObjs.forEach( ( checkboxObj ) => {
|
|
|
|
if ( checkboxObj.checkbox instanceof HTMLInputElement && checkboxObj.button ) {
|
|
|
|
checkboxHack.bindToggleOnClick( checkboxObj.checkbox, checkboxObj.button );
|
|
|
|
checkboxHack.bindUpdateAriaExpandedOnInput( checkboxObj.checkbox, checkboxObj.button );
|
|
|
|
checkboxHack.updateAriaExpanded( checkboxObj.checkbox, checkboxObj.button );
|
|
|
|
checkboxHack.bindToggleOnSpaceEnter( checkboxObj.checkbox, checkboxObj.button );
|
|
|
|
checkboxHack.bindDismissOnClickOutside(
|
|
|
|
window, checkboxObj.checkbox, checkboxObj.button, checkboxObj.target
|
|
|
|
);
|
|
|
|
checkboxHack.bindDismissOnEscape( window, checkboxObj.checkbox );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
2021-04-26 15:39:27 +00:00
|
|
|
/**
|
|
|
|
* Add a class to indicate that page title is outside of viewport
|
|
|
|
*
|
|
|
|
* @param {Document} document
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
function onTitleHidden( document ) {
|
|
|
|
const title = document.getElementById( 'firstHeading' );
|
|
|
|
|
|
|
|
if ( title ) {
|
|
|
|
const observer = new IntersectionObserver( ( entries ) => {
|
|
|
|
if ( !entries[ 0 ].isIntersecting ) {
|
|
|
|
document.body.classList.add( 'skin-citizen--titlehidden' );
|
|
|
|
} else {
|
|
|
|
document.body.classList.remove( 'skin-citizen--titlehidden' );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
observer.observe( title );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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 ) {
|
2021-04-21 17:44:28 +00:00
|
|
|
const theme = require( './theme.js' ),
|
2021-04-21 20:45:52 +00:00
|
|
|
search = require( './search.js' );
|
2021-04-21 17:44:28 +00:00
|
|
|
|
2021-03-13 17:43:28 +00:00
|
|
|
enableCssAnimations( window.document );
|
2021-04-21 03:42:45 +00:00
|
|
|
theme.init( window );
|
2021-04-21 22:47:03 +00:00
|
|
|
search.init( window );
|
2021-04-21 20:45:52 +00:00
|
|
|
initCheckboxHack( window );
|
2021-04-26 15:39:27 +00:00
|
|
|
onTitleHidden( window.document );
|
2021-01-16 22:01:58 +00:00
|
|
|
}
|
|
|
|
|
2021-03-13 17:43:28 +00:00
|
|
|
main( window );
|