@shopgate/pwa-common
Version:
Common library for the Shopgate Connect PWA.
67 lines • 7.69 kB
JavaScript
function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function");}}function _defineProperties(target,props){for(var i=0;i<props.length;i++){var descriptor=props[i];descriptor.enumerable=descriptor.enumerable||false;descriptor.configurable=true;if("value"in descriptor)descriptor.writable=true;Object.defineProperty(target,descriptor.key,descriptor);}}function _createClass(Constructor,protoProps,staticProps){if(protoProps)_defineProperties(Constructor.prototype,protoProps);if(staticProps)_defineProperties(Constructor,staticProps);return Constructor;}import{i18n,logger}from'@shopgate/engage/core/helpers';import{PRIVACY_SETTINGS_PATTERN}from'@shopgate/engage/tracking/constants';import{isRelativePosition,isAbsolutePosition}from"../../helpers/dom";import styles from"./style";var consentMessageIcon="\n <svg\n width=\"100%\"\n height=\"100%\"\n viewBox=\"0 0 110 84\"\n version=\"1.1\"\n class=\"".concat(styles.consentIcon,"\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <g transform=\"matrix(1,0,0,1,-24.6099,-41.8178)\">\n <path d=\"M50.303,68.639L104.088,98.668L56.288,125.172C55.039,125.865 53.518,125.845 52.288,125.12C51.058,124.396 50.303,123.075 50.303,121.648L50.303,68.639ZM50.303,54.702L50.303,45.855C50.303,44.425 51.059,43.102 52.292,42.376C53.524,41.651 55.048,41.631 56.298,42.324C71.141,50.554 109.492,71.82 124.676,80.239C125.95,80.945 126.741,82.288 126.741,83.745C126.741,85.203 125.95,86.545 124.676,87.252L116.612,91.724L50.303,54.702Z\" />\n <g transform=\"matrix(0.944597,0.527391,-0.487489,0.873129,45.7069,-42.8282)\">\n <path d=\"M139,89C139,87.344 137.757,86 136.227,86L26.773,86C25.243,86 24,87.344 24,89C24,90.656 25.243,92 26.773,92L136.227,92C137.757,92 139,90.656 139,89Z\" />\n </g>\n </g>\n </svg>");/* eslint-disable class-methods-use-this */ /**
* The MediaProvider base class.
*/var MediaProvider=/*#__PURE__*/function(){/**
* Constructor.
* @param {Object} options The provider options.
* @param {boolean} [options.responsify=true] Whether to responsify the video containers.
*/function MediaProvider(options){var _ref;_classCallCheck(this,MediaProvider);this.containers=new Map();this.isPending=false;this.remoteScriptUrl=null;this.options={responsify:(_ref=options===null||options===void 0?void 0:options.responsify)!==null&&_ref!==void 0?_ref:true};}/**
* Callback for when Provider script is loaded
* @callback
* @abstract
*/return _createClass(MediaProvider,[{key:"onScriptLoaded",value:function onScriptLoaded(){logger.error('MediaProvider.onScriptLoaded() needs to be implemented within an inheriting class');}/**
* Callback to retrieve a list of media containers
* @callback
* @abstract
*/},{key:"getMediaContainers",value:function getMediaContainers(){logger.error('MediaProvider.getMediaContainers() needs to be implemented within an inheriting class');}/**
* Applies optimizations to embedded media iframes within the given container.
* Common enhancements include adding responsive wrappers and appropriate
* sandbox attributes to improve security and layout behavior.
*
* @param {Document} document - The DOM document containing iframes to optimize.
* @returns {MediaProvider}
*/},{key:"applyIframeOptimizations",value:function applyIframeOptimizations(){return this;}/**
* Optimizes video container to make it responsive.
* @param {Element} container A DOM container.
* @returns {MediaProvider}
*/},{key:"responsify",value:function responsify(container){// Do not proceed when video responsify is disabled.
if(!this.options.responsify)return this;// Remove fixed dimensions from the container.
container.removeAttribute('height');container.removeAttribute('width');if(isRelativePosition(container.parentNode)&&isAbsolutePosition(container)){// Assume responsive embed code
container.parentNode.removeAttribute('style');}// Create the wrapper and apply styling.
var wrapper=document.createElement('div');wrapper.className=styles.responsiveContainer;// Add the wrapper right before the container into the DOM.
container.parentNode.insertBefore(wrapper,container);// Move the container into the wrapper.
wrapper.appendChild(container);return this;}/**
* Searches for embedded media and replaces it with a placeholder element when comfort cookie
* consent is not accepted.
*
* Should be called before media container / markup is mounted to the DOM.
* @param {ParentNode} container A DOM container.
* @param {Object} [cookieConsentSettings] Additional settings related to cookie consent.
* @param {boolean} [cookieConsentSettings.comfortCookiesAccepted] Whether comfort cookies
* are accepted.
* @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
* are accepted.
* @returns {MediaProvider}
*/},{key:"handleCookieConsent",value:function handleCookieConsent(container){var _this=this;var cookieConsentSettings=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var iframes=this.getMediaContainers(container);if(!iframes.length||cookieConsentSettings.comfortCookiesAccepted!==false){return this;}iframes.forEach(function(iframe){// Add responsive container around iframes
_this.responsify(iframe);// Select the container and clear its content
var responsiveContainer=iframe.parentNode;responsiveContainer.textContent=null;// Add the consent message element to the container
_this.injectCookieConsentMessage(responsiveContainer);});return this;}/**
* Injects a cookie consent message element into a container
* @param {Element} container A DOM container.
* @returns {MediaProvider}
*/},{key:"injectCookieConsentMessage",value:function injectCookieConsentMessage(container){// Create the wrapper for the message element
var messageWrapper=document.createElement('div');messageWrapper.classList.add(styles.consentContainer,'common__media-provider_cookie-consent-message-container');// Add an SVG icon (implemented this way, since there where issues with document.createElement)
messageWrapper.innerHTML=consentMessageIcon;// Create the main message and add it to the wrapper
var message=document.createElement('span');message.classList.add('common__media-provider_cookie-consent-message-container_message');message.innerHTML=i18n.text('htmlSanitizer.videoCookieConsent.message');messageWrapper.appendChild(message);// Create the link and add it to the wrapper
var link=document.createElement('a');link.classList.add(styles.consentLink,'common__media-provider_cookie-consent-message-container_link');link.href="".concat(PRIVACY_SETTINGS_PATTERN,"?source=video");link.innerHTML=i18n.text('htmlSanitizer.videoCookieConsent.link');messageWrapper.appendChild(link);// Add the wrapper to the container
container.appendChild(messageWrapper);return this;}/**
* Add a DOM container with embedded videos.
* @param {NodeList} container A DOM container.
* @returns {MediaProvider}
*/},{key:"add",value:function add(){logger.error('MediaProvider.add() needs to be implemented within an inheriting class');return this;}/**
* Remove a DOM container.
* @param {NodeList} container A DOM container.
* @returns {MediaProvider}
*/},{key:"remove",value:function remove(container){this.containers["delete"](container);return this;}/**
* Stops all playing videos within the DOM containers.
* @returns {MediaProvider}
*/},{key:"stop",value:function stop(){logger.error('MediaProvider.stop() needs to be implemented within an inheriting class');return this;}}]);}();export default MediaProvider;/* eslint-enable class-methods-use-this */