2021-10-20 18:58:49 +00:00
|
|
|
// Enable Vector features limited to ES6 browse
|
2021-10-26 23:37:56 +00:00
|
|
|
const
|
|
|
|
searchToggle = require( './searchToggle.js' ),
|
|
|
|
stickyHeader = require( './stickyHeader.js' ),
|
|
|
|
scrollObserver = require( './scrollObserver.js' ),
|
2022-01-21 20:15:34 +00:00
|
|
|
AB = require( './AB.js' ),
|
|
|
|
initSectionObserver = require( './sectionObserver.js' ),
|
|
|
|
initTableOfContents = require( './tableOfContents.js' ),
|
|
|
|
TOC_ID = 'mw-panel-toc',
|
|
|
|
BODY_CONTENT_ID = 'bodyContent',
|
|
|
|
HEADLINE_SELECTOR = '.mw-headline',
|
|
|
|
TOC_SECTION_ID_PREFIX = 'toc-';
|
2021-10-20 18:58:49 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @return {void}
|
|
|
|
*/
|
|
|
|
const main = () => {
|
|
|
|
// Initialize the search toggle for the main header only. The sticky header
|
|
|
|
// toggle is initialized after wvui search loads.
|
2021-10-20 19:10:42 +00:00
|
|
|
const searchToggleElement = document.querySelector( '.mw-header .search-toggle' );
|
|
|
|
if ( searchToggleElement ) {
|
|
|
|
searchToggle( searchToggleElement );
|
|
|
|
}
|
2021-10-26 23:37:56 +00:00
|
|
|
|
|
|
|
// Get the A/B test config for sticky header if enabled.
|
|
|
|
const
|
2021-12-03 19:19:27 +00:00
|
|
|
FEATURE_TEST_GROUP = 'stickyHeaderEnabled',
|
2021-10-26 23:37:56 +00:00
|
|
|
testConfig = AB.getEnabledExperiment(),
|
|
|
|
stickyConfig = testConfig &&
|
|
|
|
// @ts-ignore
|
|
|
|
testConfig.experimentName === stickyHeader.STICKY_HEADER_EXPERIMENT_NAME ?
|
|
|
|
testConfig : null,
|
|
|
|
// Note that the default test group is set to experience the feature by default.
|
|
|
|
// @ts-ignore
|
2021-12-03 19:19:27 +00:00
|
|
|
testGroup = stickyConfig ? stickyConfig.group : FEATURE_TEST_GROUP,
|
2021-12-01 22:31:48 +00:00
|
|
|
targetElement = stickyHeader.header,
|
|
|
|
targetIntersection = stickyHeader.stickyIntersection,
|
2021-12-03 19:19:27 +00:00
|
|
|
isStickyHeaderAllowed = stickyHeader.isStickyHeaderAllowed() &&
|
|
|
|
testGroup !== 'unsampled' && AB.isInTestGroup( testGroup, FEATURE_TEST_GROUP );
|
2021-10-26 23:37:56 +00:00
|
|
|
|
|
|
|
// Fire the A/B test enrollment hook.
|
|
|
|
AB.initAB( testGroup );
|
|
|
|
|
|
|
|
// Set up intersection observer for sticky header functionality and firing scroll event hooks
|
|
|
|
// for event logging if AB test is enabled.
|
|
|
|
const observer = scrollObserver.initScrollObserver(
|
|
|
|
() => {
|
2021-12-01 22:31:48 +00:00
|
|
|
if ( targetElement && isStickyHeaderAllowed ) {
|
2021-12-03 19:19:27 +00:00
|
|
|
stickyHeader.show();
|
2021-12-01 22:31:48 +00:00
|
|
|
}
|
|
|
|
scrollObserver.fireScrollHook( 'down' );
|
2021-10-26 23:37:56 +00:00
|
|
|
},
|
|
|
|
() => {
|
2021-12-01 22:31:48 +00:00
|
|
|
if ( targetElement && isStickyHeaderAllowed ) {
|
2021-12-03 19:19:27 +00:00
|
|
|
stickyHeader.hide();
|
2021-12-01 22:31:48 +00:00
|
|
|
}
|
|
|
|
scrollObserver.fireScrollHook( 'up' );
|
2021-10-26 23:37:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
);
|
|
|
|
|
2021-12-01 22:31:48 +00:00
|
|
|
if ( isStickyHeaderAllowed ) {
|
|
|
|
stickyHeader.initStickyHeader( observer );
|
|
|
|
} else if ( targetIntersection ) {
|
|
|
|
observer.observe( targetIntersection );
|
|
|
|
}
|
2022-01-21 20:15:34 +00:00
|
|
|
|
|
|
|
// Table of contents
|
|
|
|
const tocElement = document.getElementById( TOC_ID );
|
|
|
|
const bodyContent = document.getElementById( BODY_CONTENT_ID );
|
|
|
|
|
|
|
|
if ( !(
|
|
|
|
tocElement &&
|
|
|
|
bodyContent &&
|
|
|
|
window.IntersectionObserver &&
|
|
|
|
window.requestAnimationFrame )
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// eslint-disable-next-line prefer-const
|
|
|
|
let /** @type {initSectionObserver.SectionObserver} */ sectionObserver;
|
|
|
|
const tableOfContents = initTableOfContents( {
|
|
|
|
container: tocElement,
|
|
|
|
onSectionClick: () => {
|
|
|
|
sectionObserver.pause();
|
|
|
|
|
|
|
|
// Ensure the browser has finished painting and has had enough time to
|
|
|
|
// scroll to the section before resuming section observer. One rAF should
|
|
|
|
// be sufficient in most browsers, but Firefox 96.0.2 seems to require two
|
|
|
|
// rAFs.
|
|
|
|
requestAnimationFrame( () => {
|
|
|
|
requestAnimationFrame( () => {
|
|
|
|
sectionObserver.resume();
|
|
|
|
} );
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
sectionObserver = initSectionObserver( {
|
|
|
|
container: bodyContent,
|
|
|
|
tagNames: [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ],
|
|
|
|
topMargin: targetElement ? targetElement.getBoundingClientRect().height : 0,
|
|
|
|
/**
|
|
|
|
* @param {HTMLElement} section
|
|
|
|
*/
|
|
|
|
onIntersection: ( section ) => {
|
|
|
|
const headline = section.querySelector( HEADLINE_SELECTOR );
|
|
|
|
|
|
|
|
if ( headline ) {
|
|
|
|
tableOfContents.activateSection( TOC_SECTION_ID_PREFIX + headline.id );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} );
|
2021-10-20 19:10:42 +00:00
|
|
|
};
|
2021-10-20 18:58:49 +00:00
|
|
|
|
2021-10-30 01:01:36 +00:00
|
|
|
module.exports = {
|
|
|
|
main: main
|
|
|
|
};
|