mediawiki-extensions-Relate.../resources/ext.relatedArticles.readMore.bootstrap/index.js
jdlrobson 923f594916 RelatedArticles should use IntersectionObserver rather than deprecated mediawiki.viewport module
Bug: T284251
Change-Id: Ia3139df0beb24268a1e37b85c755b0d0f62910b5
2021-10-29 14:53:20 -07:00

84 lines
2.4 KiB
JavaScript

/* eslint-disable no-jquery/no-global-selector */
( function () {
var data = require( './data.json' ),
relatedPages = new mw.relatedPages.RelatedPagesGateway(
new mw.Api(),
mw.config.get( 'wgPageName' ),
mw.config.get( 'wgRelatedArticles' ),
data.useCirrusSearch,
data.onlyUseCirrusSearch,
data.descriptionSource
),
// Make sure this is never undefined as I'm paranoid
LIMIT = mw.config.get( 'wgRelatedArticlesCardLimit', 3 );
/**
* Load related articles when the user scrolls past half of the window height.
*
* @ignore
*/
function loadRelatedArticles() {
var readMore = document.querySelector( '.read-more-container' ),
isSupported = 'IntersectionObserver' in window;
if ( !readMore || !isSupported ) {
// The container is not in the HTML for some reason and cannot be queried.
// See T281547
return;
}
/**
* @param {Element} container
*/
function initRelatedArticlesModule( container ) {
$.when(
// Note we load dependencies here rather than ResourceLoader
// to avoid PHP exceptions when Cards not installed
// which should never happen given the if statement.
mw.loader.using( [
'ext.relatedArticles.cards',
'ext.relatedArticles.readMore'
] ),
relatedPages.getForCurrentPage( LIMIT )
).then( function ( _, pages ) {
if ( pages.length ) {
mw.track( 'ext.relatedArticles.init', pages );
} else if ( container.parentNode ) {
container.parentNode.removeChild( container );
}
} );
}
var doc = document.documentElement;
// IntersectionObserver will not work if the component is already visible on the page.
// To handle this case, we compare scroll height to viewport height.
if ( ( doc.scrollHeight / 2 ) < doc.clientHeight ) {
// Load straight away. We are on a stub page.
initRelatedArticlesModule( readMore );
return;
}
// eslint-disable-next-line compat/compat
var observer = /** @type {IntersectionObserver} */( new IntersectionObserver( function ( entries ) {
if ( !entries[ 0 ].isIntersecting ) {
return;
}
// @ts-ignore
observer.unobserve( readMore );
observer.disconnect();
// @ts-ignore
initRelatedArticlesModule( readMore );
}, {
rootMargin: '-100% 0% 0% 0%'
} ) );
observer.observe( readMore );
}
function showReadMore() {
// try an initial load, in case of no scroll
loadRelatedArticles();
}
$( showReadMore );
}() );