mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-11-24 06:24:22 +00:00
refactor(core): move intersection observer into a module
* We will likely use it for other things in the future * Based on Vector's implementation * Also do not get toc element twice
This commit is contained in:
parent
23795e05e3
commit
d59ca5c83a
24
resources/skins.citizen.scripts/scrollObserver.js
Normal file
24
resources/skins.citizen.scripts/scrollObserver.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
/**
|
||||
* Create an observer for showing/hiding feature and for firing scroll event hooks.
|
||||
* Based on Vector
|
||||
*
|
||||
* @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( ( 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
|
||||
};
|
|
@ -66,13 +66,16 @@ function onTitleHidden( document ) {
|
|||
const title = document.getElementById( 'firstHeading' );
|
||||
|
||||
if ( title ) {
|
||||
const observer = new IntersectionObserver( ( entries ) => {
|
||||
if ( !entries[ 0 ].isIntersecting ) {
|
||||
const scrollObserver = require( './scrollObserver.js' );
|
||||
|
||||
const observer = scrollObserver.initScrollObserver(
|
||||
() => {
|
||||
document.body.classList.add( 'skin-citizen--titlehidden' );
|
||||
} else {
|
||||
},
|
||||
() => {
|
||||
document.body.classList.remove( 'skin-citizen--titlehidden' );
|
||||
}
|
||||
} );
|
||||
);
|
||||
observer.observe( title );
|
||||
}
|
||||
}
|
||||
|
@ -82,9 +85,11 @@ function onTitleHidden( document ) {
|
|||
* @return {void}
|
||||
*/
|
||||
function main( window ) {
|
||||
const theme = require( './theme.js' ),
|
||||
search = require( './search.js' ),
|
||||
tocContainer = document.getElementById( 'toc' );
|
||||
const
|
||||
theme = require( './theme.js' ),
|
||||
search = require( './search.js' );
|
||||
|
||||
const tocContainer = document.getElementById( 'toc' );
|
||||
|
||||
enableCssAnimations( window.document );
|
||||
theme.init( window );
|
||||
|
@ -102,7 +107,7 @@ function main( window ) {
|
|||
// TODO: There must be a cleaner way to do this
|
||||
if ( tocContainer ) {
|
||||
const toc = require( './tableOfContents.js' );
|
||||
toc.init();
|
||||
toc.init( tocContainer );
|
||||
|
||||
checkboxHack.bind(
|
||||
window,
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
const ACTIVE_ITEM_CLASS = 'toc__item--active';
|
||||
|
||||
/**
|
||||
* Toggle active HTML class to items in table of content based on user viewport.
|
||||
*
|
||||
* @param {Element} toc TOC element
|
||||
* @return {void}
|
||||
*/
|
||||
function initToC() {
|
||||
const headlines = document.querySelectorAll( '.mw-headline' ),
|
||||
toc = document.getElementById( 'toc' ),
|
||||
function initToC( toc ) {
|
||||
const
|
||||
headlines = document.querySelectorAll( '.mw-headline' ),
|
||||
marginTop = '-' + window.getComputedStyle( document.documentElement ).getPropertyValue( 'scroll-padding-top' );
|
||||
|
||||
for ( let i = 0; i < headlines.length; i++ ) {
|
||||
|
@ -13,20 +16,21 @@ function initToC() {
|
|||
const observer = new IntersectionObserver( ( entry ) => {
|
||||
/* eslint-enable compat/compat */
|
||||
if ( entry[ 0 ].isIntersecting ) {
|
||||
const headlineId = headlines[ i ].id,
|
||||
const
|
||||
headlineId = headlines[ i ].id,
|
||||
// Get the decoded ID from the span before
|
||||
decodedId = ( headlines[ i ].previousSibling !== null ) ?
|
||||
headlines[ i ].previousSibling.id : '',
|
||||
links = toc.querySelector( "a[href='#" + headlineId + "']" ) ||
|
||||
toc.querySelector( "a[href='#" + decodedId + "']" ),
|
||||
targetLink = links.parentNode,
|
||||
activeLink = toc.querySelector( '.active' );
|
||||
activeLink = toc.querySelector( '.' + ACTIVE_ITEM_CLASS );
|
||||
|
||||
if ( activeLink !== null ) {
|
||||
activeLink.classList.remove( 'active' );
|
||||
activeLink.classList.remove( ACTIVE_ITEM_CLASS );
|
||||
}
|
||||
if ( targetLink !== null ) {
|
||||
targetLink.classList.add( 'active' );
|
||||
targetLink.classList.add( ACTIVE_ITEM_CLASS );
|
||||
}
|
||||
}
|
||||
}, {
|
||||
|
|
|
@ -52,7 +52,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
li.active {
|
||||
.toc__item--active {
|
||||
border-color: var( --color-primary );
|
||||
color: var( --color-primary );
|
||||
|
||||
|
|
|
@ -187,6 +187,7 @@
|
|||
"callback": "Citizen\\Hooks\\ResourceLoaderHooks::getCitizenResourceLoaderConfig"
|
||||
},
|
||||
"resources/skins.citizen.scripts/checkboxHack.js",
|
||||
"resources/skins.citizen.scripts/scrollObserver.js",
|
||||
"resources/skins.citizen.scripts/search.js",
|
||||
"resources/skins.citizen.scripts/tableOfContents.js",
|
||||
"resources/skins.citizen.scripts/theme.js"
|
||||
|
|
Loading…
Reference in a new issue