2021-10-26 23:37:56 +00:00
|
|
|
const
|
2022-03-24 20:49:22 +00:00
|
|
|
SCROLL_TITLE_HOOK = 'vector.page_title_scroll',
|
|
|
|
SCROLL_TITLE_CONTEXT_ABOVE = 'scrolled-above-page-title',
|
|
|
|
SCROLL_TITLE_CONTEXT_BELOW = 'scrolled-below-page-title',
|
|
|
|
SCROLL_TITLE_ACTION = 'scroll-to-top',
|
|
|
|
SCROLL_TOC_HOOK = 'vector.table_of_contents_scroll',
|
|
|
|
SCROLL_TOC_CONTEXT_ABOVE = 'scrolled-above-table-of-contents',
|
|
|
|
SCROLL_TOC_CONTEXT_BELOW = 'scrolled-below-table-of-contents',
|
2022-04-08 22:33:59 +00:00
|
|
|
SCROLL_TOC_ACTION = 'scroll-to-toc',
|
2022-05-05 20:01:51 +00:00
|
|
|
SCROLL_TOC_PARAMETER = 'table_of_contents';
|
2022-03-24 20:49:22 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @typedef {Object} scrollVariables
|
|
|
|
* @property {string} scrollHook
|
|
|
|
* @property {string} scrollContextBelow
|
|
|
|
* @property {string} scrollContextAbove
|
|
|
|
* @property {string} scrollAction
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return the correct variables based on hook type.
|
|
|
|
*
|
|
|
|
* @param {string} hook the type of hook
|
|
|
|
* @return {scrollVariables}
|
|
|
|
*/
|
|
|
|
function getScrollVariables( hook ) {
|
|
|
|
const scrollVariables = {};
|
|
|
|
if ( hook === 'page_title' ) {
|
|
|
|
scrollVariables.scrollHook = SCROLL_TITLE_HOOK;
|
|
|
|
scrollVariables.scrollContextBelow = SCROLL_TITLE_CONTEXT_BELOW;
|
|
|
|
scrollVariables.scrollContextAbove = SCROLL_TITLE_CONTEXT_ABOVE;
|
|
|
|
scrollVariables.scrollAction = SCROLL_TITLE_ACTION;
|
2022-04-08 22:33:59 +00:00
|
|
|
} else if ( hook === SCROLL_TOC_PARAMETER ) {
|
2022-03-24 20:49:22 +00:00
|
|
|
scrollVariables.scrollHook = SCROLL_TOC_HOOK;
|
|
|
|
scrollVariables.scrollContextBelow = SCROLL_TOC_CONTEXT_BELOW;
|
|
|
|
scrollVariables.scrollContextAbove = SCROLL_TOC_CONTEXT_ABOVE;
|
|
|
|
scrollVariables.scrollAction = SCROLL_TOC_ACTION;
|
|
|
|
}
|
|
|
|
return scrollVariables;
|
|
|
|
}
|
2021-10-26 23:37:56 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fire a hook to be captured by WikimediaEvents for scroll event logging.
|
|
|
|
*
|
|
|
|
* @param {string} direction the scroll direction
|
2022-03-24 20:49:22 +00:00
|
|
|
* @param {string} hook the hook to fire
|
2021-10-26 23:37:56 +00:00
|
|
|
*/
|
2022-03-24 20:49:22 +00:00
|
|
|
function fireScrollHook( direction, hook ) {
|
|
|
|
const scrollVariables = getScrollVariables( hook );
|
|
|
|
if ( Object.keys( scrollVariables ).length === 0 && scrollVariables.constructor === Object ) {
|
|
|
|
return;
|
|
|
|
}
|
2021-10-26 23:37:56 +00:00
|
|
|
if ( direction === 'down' ) {
|
2022-03-24 20:49:22 +00:00
|
|
|
mw.hook( scrollVariables.scrollHook ).fire( {
|
|
|
|
context: scrollVariables.scrollContextBelow
|
|
|
|
} );
|
2021-10-26 23:37:56 +00:00
|
|
|
} else {
|
2022-03-24 20:49:22 +00:00
|
|
|
mw.hook( scrollVariables.scrollHook ).fire( {
|
|
|
|
context: scrollVariables.scrollContextAbove,
|
|
|
|
action: scrollVariables.scrollAction
|
2021-10-26 23:37:56 +00:00
|
|
|
} );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Create an observer for showing/hiding feature and for firing scroll event hooks.
|
|
|
|
*
|
|
|
|
* @param {Function} show functionality for when feature is visible
|
|
|
|
* @param {Function} hide functionality for when feature is hidden
|
|
|
|
* @return {IntersectionObserver}
|
|
|
|
*/
|
|
|
|
function initScrollObserver( show, hide ) {
|
|
|
|
/* eslint-disable-next-line compat/compat */
|
|
|
|
return new IntersectionObserver( function ( entries ) {
|
|
|
|
if ( !entries[ 0 ].isIntersecting && entries[ 0 ].boundingClientRect.top < 0 ) {
|
|
|
|
// Viewport has crossed the bottom edge of the target element.
|
|
|
|
show();
|
|
|
|
} else {
|
|
|
|
// Viewport is above the bottom edge of the target element.
|
|
|
|
hide();
|
|
|
|
}
|
|
|
|
} );
|
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = {
|
|
|
|
initScrollObserver,
|
2021-12-03 19:19:27 +00:00
|
|
|
fireScrollHook
|
2021-10-26 23:37:56 +00:00
|
|
|
};
|