mirror of
https://gerrit.wikimedia.org/r/mediawiki/skins/Vector.git
synced 2024-11-25 08:05:51 +00:00
457dcfc472
- Pull IntersectionObserver into new file to share observer with different callbacks: - Wrap show/hide functionality of sticky header in conditionals based on user test group or by default. - Fire hooks for scroll event tracking in WME. - Add new js for A/B test functions and variables: - Fire hook to send data for A/B test initialization. - Update main js to include scrollObserver, A/B test init functionality. - Add A/B test config. - Update ResourceLoader package dependencies for sticky header. - Though not a strict dependency, see I42e3e7c2084c1e88363d5d1662630ed23a28c4d2 in WME repo which uses these hooks to log scroll events. - This patch includes changes from I56f40e706f8706fde1c0891a0561dd32c5e02bfc which were consolidated here for simplicity and ease of review - related to T292587 which calls for logging an init event for bucketing of users during A/B testing. Bug: T292586 Change-Id: If6446e1e84cea3649905808c4f0e9f6862255fa3
91 lines
2.5 KiB
JavaScript
91 lines
2.5 KiB
JavaScript
const
|
|
FEATURE_VISIBLE_CLASS = 'vector-sticky-header-visible',
|
|
FEATURE_TEST_GROUP = 'stickyHeaderEnabled',
|
|
SCROLL_HOOK = 'vector.page_title_scroll',
|
|
SCROLL_CONTEXT_ABOVE = 'scrolled-above-page-title',
|
|
SCROLL_CONTEXT_BELOW = 'scrolled-below-page-title',
|
|
SCROLL_ACTION = 'scroll-to-top';
|
|
|
|
/**
|
|
* Determine if user is in test group to experience feature.
|
|
*
|
|
* @param {string} bucket the bucket name the user is assigned
|
|
* @param {string} targetGroup the target test group to experience feature
|
|
* @return {boolean} true if the user should experience feature
|
|
*/
|
|
function isInTestGroup( bucket, targetGroup ) {
|
|
return bucket === targetGroup;
|
|
}
|
|
|
|
/**
|
|
* Show the feature based on test group.
|
|
*
|
|
* @param {HTMLElement} element target feature
|
|
* @param {string} group A/B test bucket of the user
|
|
*/
|
|
function onShowFeature( element, group ) {
|
|
if ( isInTestGroup( group, FEATURE_TEST_GROUP ) ) {
|
|
// eslint-disable-next-line mediawiki/class-doc
|
|
element.classList.add( FEATURE_VISIBLE_CLASS );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Hide the feature based on test group.
|
|
*
|
|
* @param {HTMLElement} element target feature
|
|
* @param {string} group A/B test bucket of the user
|
|
*/
|
|
function onHideFeature( element, group ) {
|
|
if ( isInTestGroup( group, FEATURE_TEST_GROUP ) ) {
|
|
// eslint-disable-next-line mediawiki/class-doc
|
|
element.classList.remove( FEATURE_VISIBLE_CLASS );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Fire a hook to be captured by WikimediaEvents for scroll event logging.
|
|
*
|
|
* @param {string} direction the scroll direction
|
|
*/
|
|
function logScrollEvent( direction ) {
|
|
if ( direction === 'down' ) {
|
|
// @ts-ignore
|
|
mw.hook( SCROLL_HOOK ).fire( { context: SCROLL_CONTEXT_BELOW } );
|
|
} else {
|
|
// @ts-ignore
|
|
mw.hook( SCROLL_HOOK ).fire( {
|
|
context: SCROLL_CONTEXT_ABOVE,
|
|
action: SCROLL_ACTION
|
|
} );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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,
|
|
onShowFeature,
|
|
onHideFeature,
|
|
logScrollEvent,
|
|
FEATURE_TEST_GROUP
|
|
};
|