UNPKG

@shopgate/pwa-common

Version:

Common library for the Shopgate Connect PWA.

54 lines 5.89 kB
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;});};