ArticleTemplates/assets/js/bootstraps/atoms.js (114 lines of code) (raw):

import services from 'modules/atoms/services'; import { initPositionPoller } from 'modules/cards'; import { initMpuPoller } from 'modules/ads'; import { resetAndCheckForVideos } from 'modules/youtube'; function init() { const atomTypes = GU.opts.atoms; Object.keys(atomTypes).forEach(t => { const f = atomTypes[t]; if (t === 'chart' || typeof f.default !== 'function' || f.default.length !== 1) { return; } bootAtomType(t, atomTypes[t]); }); if ('chart' in atomTypes) { initCharts(); } if ('interactive' in atomTypes) { initInteractives(); } } function initCharts() { var iframes = Array.prototype.slice.call(document.querySelectorAll('.atom--chart > .atom__iframe')); window.addEventListener('message', function (event) { var message; var iframe = iframes.reduce(function (winner, candidate) { if (winner) { return winner; } try { return candidate.name === event.source.name ? candidate : null; } catch (e) { return null; } }, null); if (iframe) { try { message = JSON.parse(event.data); switch (message.type) { case 'set-height': iframe.height = message.value; break; default: } // eslint-disable-next-line no-empty } catch (e) {} } }); iframes.forEach(function (iframe) { const src = (iframe.getAttribute('srcdoc') || '') .replace(/<gu-script>/g, '<script>') // eslint-disable-next-line no-useless-concat .replace(/<\/gu-script>/g, '<' + '/script>'); iframe.setAttribute('srcdoc', src); }); } function bootAtomType(atomType, atomFactory) { const atomBuilder = atomFactory.default(services); const atoms = document.querySelectorAll(`.element-atom[data-atom-type="${atomType}"]`); for (let i = 0; i < atoms.length; i++) { const atom = atomBuilder(atoms[i]).runTry(); if (typeof atom === 'string') { console.log(`Failed to initialise atom [${atomType}/${atoms[i].getAttribute('data-atom-id')}]: ${atom}`); } else { initExpandables(atoms[i]); atom.start(); } } } function initExpandables(atom) { Array.prototype.slice.call(atom.getElementsByTagName('details')).forEach(function(d) { d.addEventListener('click', function() { initPositionPoller(0); initMpuPoller(0, false); resetAndCheckForVideos(); }); }); } function scrollListener() { const containers = [...document.querySelectorAll('figure[data-atom-type="interactive"]')].flatMap(element => element instanceof HTMLElement ? [element] : []); containers.forEach(function (container) { const rect = container.getBoundingClientRect(); const iframe = container.querySelector('iframe'); let scroll = -rect.top; if (rect.top > 0) { scroll = 0; } else if (rect.top < -rect.height) { scroll = rect.height; } iframe?.contentWindow?.postMessage({ kind: 'interactive:scroll', scroll }, '*'); }) } function initInteractives() { const iframes = [...document.querySelectorAll('figure[data-atom-type="interactive"] > iframe')].flatMap(element => element instanceof HTMLIFrameElement ? [element] : []); window.addEventListener('message', function (event) { var iframe = iframes.find(function({ name }) { return name === event.source.name; }); if (!iframe) return; try { const message = JSON.parse(event.data); switch (message.kind) { case 'interactive:height': iframe.height = message.height; break; case 'interactive:scroll': window.addEventListener('scroll', scrollListener) iframe.classList.add('scrolly'); break; default: } } catch (e) { // do nothing } }); } export { init };