ArticleTemplates/assets/js/modules/util.js (136 lines of code) (raw):
function isElementPartiallyInViewport(el) {
const rect = el.getBoundingClientRect();
const windowHeight = (window.innerHeight || document.documentElement.clientHeight);
const windowWidth = (window.innerWidth || document.documentElement.clientWidth);
const vertInView = (rect.top <= windowHeight) && ((rect.top + rect.height) >= 0);
const horInView = (rect.left <= windowWidth) && ((rect.left + rect.width) >= 0);
return (vertInView && horInView);
}
function getElementOffset(elem) {
const de = elem.ownerDocument.documentElement;
const bcr = elem.getBoundingClientRect();
const scroll = {
x: window.pageXOffset || document.documentElement.scrollLeft,
y: window.pageYOffset || document.documentElement.scrollTop
}
const width = elem.offsetWidth;
const height = elem.offsetHeight;
const top = bcr.top + scroll.y - Math.max(0, de && de.clientTop, document.body.clientTop);
const left = bcr.left + scroll.x - Math.max(0, de && de.clientLeft, document.body.clientLeft);
return { top, left, height, width }
}
function signalDevice(messageName) {
const path = 'x-gu://';
const url = path + messageName;
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = url;
document.documentElement.appendChild(iframe);
document.documentElement.removeChild(iframe);
}
function isOnline() {
return !GU.opts.isOffline && navigator.onLine;
}
function getClosestParentWithClass(elem, className) {
while (elem && (!elem.classList || !elem.classList.contains(className))) {
elem = elem.parentNode;
}
return elem;
}
function getClosestParentWithTag(elem, tagName) {
while (elem && (elem.tagName !== tagName.toUpperCase())) {
elem = elem.parentNode;
}
return elem;
}
function getClosestParentWithData(elem, dataKey, dataVals) {
if (typeof dataVals === 'string') {
dataVals = [dataVals];
}
while (elem && (!elem.dataset || !dataVals.includes(elem.dataset[dataKey]))) {
elem = elem.parentNode;
}
return elem;
}
function getStringFromUnicodeVal(unicodeVal) {
return String.fromCharCode(unicodeVal);
}
function debounce(func, wait, immediate) {
let args;
let callNow;
let context;
let later;
let timeout;
return function() {
context = this;
args = arguments;
later = () => {
timeout = null;
if (!immediate) {
func.apply(context, args);
}
}
callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) {
func.apply(context, args);
}
};
}
function getElemsFromHTML(html) {
let i;
const elems = [];
const div = document.createElement('div');
div.innerHTML = html;
for (i = 0; i < div.childNodes.length; i++) {
if (div.childNodes[i].nodeType === 1) {
elems.push(div.childNodes[i]);
}
}
return elems;
}
function append(scriptElement) {
document.body.appendChild(scriptElement);
}
function insertAfter(newNode, referenceNode) {
referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
}
function getAndroidVersion() {
const ua = navigator.userAgent.toLowerCase();
const match = ua.match(/android\s([0-9\.]*)/);
return match ? match[1] : undefined;
}
function scrollToElement(element) {
element.scrollIntoView()
}
function isAdvertising() {
return !!document.querySelector('body.is_advertising');
}
function isDarkMode() {
if (document.querySelector('.dark-mode-on')) {
return true;
}
if (window.matchMedia) {
return window.matchMedia('(prefers-color-scheme: dark)').matches;
}
return false;
}
export {
isElementPartiallyInViewport,
getElementOffset,
signalDevice,
isOnline,
getClosestParentWithClass,
getClosestParentWithTag,
getClosestParentWithData,
getStringFromUnicodeVal,
debounce,
getElemsFromHTML,
append,
insertAfter,
getAndroidVersion,
scrollToElement,
isAdvertising,
isDarkMode
};