@shopgate/pwa-common
Version:
Common library for the Shopgate Connect PWA.
54 lines • 5.89 kB
JavaScript
import event from'@shopgate/pwa-core/classes/Event/index';/**
* Parses a collection of DOM nodes for external script tags.
* @param {Array} nodes A collection of DOM nodes.
* @param {Function} callback Will be called when a single script is loaded.
* @param {boolean} isRoot Whether this is the root level of the given DOM tree.
* @return {Array} A collection of external script tags.
*/export var getExternalScripts=function getExternalScripts(nodes,callback){var isRoot=arguments.length>2&&arguments[2]!==undefined?arguments[2]:true;var nodesArray=[].slice.call(nodes);var externalScripts=nodesArray.reduce(function(result,node){// We only want external scripts.
if(node.tagName!=='SCRIPT'||!node.src){if(node.childNodes&&node.childNodes.length){return result.concat(getExternalScripts(node.childNodes,callback,false));}return result;}// Create a new script tag.
var script=document.createElement('script');script.type=node.type;script.src=node.src;script.async=node.async;script.onload=callback;script.onerror=callback;result.push(script);return result;},[]);if(!externalScripts.length&&isRoot){return callback();}return externalScripts;};/**
* Parses a collection of DOM nodes for inline script tags.
* @param {Array} nodes A collection of DOM nodes.
* @return {Array} A collection of inline script tags.
*/export var getInlineScripts=function getInlineScripts(nodes){var nodesArray=[].slice.call(nodes);return nodesArray.reduce(function(result,node){// We only want scripts.
if(node.tagName!=='SCRIPT'||node.src){if(node.childNodes&&node.childNodes.length){return result.concat(getInlineScripts(node.childNodes));}return result;}// Create a new script tag.
var script=document.createElement('script');script.type=node.type;script.textContent=node.innerText;result.push(script);return result;},[]);};/**
* Parses a collection of DOM nodes for non-script tags.
* @param {Array} nodes A collection of DOM nodes.
* @return {Object} A DOM node containing the HTML content.
*/export var getHTMLContent=function getHTMLContent(nodes){var contents=document.createElement('div');var nodesArray=[].slice.call(nodes);/**
* Filters out unwanted nodes.
* @param {Object} nodeList A node list.
* @returns {Object}
*/var filterBlacklistedNodes=function filterBlacklistedNodes(nodeList){return nodeList.map(function(node){// We don't care about script tags.
if(node.tagName==='SCRIPT'){return null;}if(node.tagName==='IMG'){// Images with a relative path won't work so we will remove them here.
if(!node.getAttribute('src').startsWith('http')){return null;}}if(node.childNodes.length>0){var filteredNodes=filterBlacklistedNodes(Array.from(node.childNodes));/* eslint-disable no-param-reassign */ // Resets / Clears all children so it can be replaced with the filtered ones.
node.innerHTML='';/* eslint-enable no-param-reassign */filteredNodes.forEach(function(child){return node.appendChild(child);});}return node;}).filter(function(node){return node!==null;});};filterBlacklistedNodes(nodesArray).forEach(function(node){contents.appendChild(node.cloneNode(true));});return contents;};/**
* Checks if a DOM container already exist and creates a new one if it doesn't exist.
* @param {string} containerID The HTML id attribute of the container.
* @return {Object} The container DOM node.
*/export var getDOMContainer=function getDOMContainer(containerID){var container=document.getElementById(containerID);if(container){container.innerHTML='';}else{container=document.createElement('div');container.id=containerID;document.body.appendChild(container);}return container;};/**
* Stops a NodeList of youtube players.
* @param {NodeList} players YouTube player iframes.
*/var stopPlayer=function stopPlayer(players){var cmdStop='{"event":"command","func":"stopVideo","args":""}';players.forEach(function(node,index){var yt=players[index];if(yt.contentWindow&&yt.contentWindow.postMessage){yt.contentWindow.postMessage(cmdStop,'*');}});};/**
* Handles YouTube iframes so that we are able to controll when the video should be stopped.
* It should not play in the background when a tab/page has changed.
* @param {NodeList} container HTML widget container.
* @deprecated Replaced by the EmbeddedVideos collection system.
*/export var handleYouTube=function handleYouTube(container){var youtubeIframes=container.querySelectorAll('iframe[src*="youtube.com"]');youtubeIframes.forEach(function(node,index){var src=node.src;// Is it really needed? We just queried for iframes WITH src attribute.
if(!src){return;}// Enable the js api
if(src.includes('enablejsapi=0')){src=src.replace('enablejsapi=0','enablejsapi=1');}if(!src.includes('enablejsapi')){var queryChar=src.includes('?')?'&':'?';src+="".concat(queryChar,"enablejsapi=1");}// Set controls to avoid the iframe not being resumable because of controls=0 param on ios.
if(!src.includes('controls')){src+='&controls=1';}else if(src.includes('controls=0')){src=src.replace('controls=0','controls=1');}youtubeIframes[index].src=src;});/**
* Stops the player when a native app event is triggered when a webview gets hidden or when the
* user navigated to some other page.
*/event.addCallback('routeDidChange',function(){stopPlayer(youtubeIframes);});event.addCallback('viewDidDisappear',function(){stopPlayer(youtubeIframes);});};/**
* Gets all styles from DOM.
* Important: DOM parser might and probably will add <style> tags into <head> while parsing
* the html string.
* @param {HTMLDocument} dom DOM.
* @returns {NodeList}
*/export var getStyles=function getStyles(dom){return dom.querySelectorAll('style');};/**
* Load image and notify on load.
* @param {string} src .
* @returns {Promise}
*/export var loadImage=function loadImage(src){return new Promise(function(resolve,reject){var image=new window.Image();image.onload=function(){return resolve(src);};image.onerror=reject;image.src=src;});};