@shopgate/pwa-common 6.23.4-beta.1 → 6.23.4-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- 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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}/* eslint-disable extra-rules/potential-point-free */ /**
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}/* eslint-disable extra-rules/potential-point-free */ /**
2
2
  * Class to maintain embedded media within DOM containers.
3
3
  */var EmbeddedMedia=/*#__PURE__*/function(){/**
4
4
  * Constructor
@@ -16,6 +16,16 @@ function _classCallCheck(instance,Constructor){if(!(instance instanceof Construc
16
16
  * embedded media is unmounted.
17
17
  * @param {ParentNode} container A DOM container.
18
18
  */},{key:"remove",value:function remove(container){this.providers.forEach(function(provider){provider.remove(container);});}/**
19
+ * Searches for embedded media and replaces it with a placeholder element when required cookie
20
+ * consent is not accepted.
21
+ * Should be invoked before container content is added to the DOM to fulfill all regulations.
22
+ * @param {ParentNode} container A DOM container.
23
+ * @param {Object} [cookieConsentSettings] Additional settings related to cookie consent.
24
+ * @param {boolean} [cookieConsentSettings.comfortCookiesAccepted] Whether comfort cookies
25
+ * are accepted.
26
+ * @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
27
+ * are accepted.
28
+ */},{key:"handleCookieConsent",value:function handleCookieConsent(container){var cookieConsentSettings=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var cookieConsent=_extends({comfortCookiesAccepted:false,statisticsCookiesAccepted:false},cookieConsentSettings);this.providers.forEach(function(provider){if(provider.handleCookieConsent){provider.handleCookieConsent(container,cookieConsent);}});}/**
19
29
  * Stops all playing media within the DOM containers.
20
30
  */},{key:"stop",value:function stop(){this.providers.forEach(function(provider){provider.stop();});}/**
21
31
  * Check if we have media providers with not-ready SDK
@@ -1,4 +1,4 @@
1
- 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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}import{logger}from'@shopgate/pwa-core/helpers';import{isRelativePosition,isAbsolutePosition}from"../../helpers/dom";import styles from"./style";/**
1
+ 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);Object.defineProperty(Constructor,"prototype",{writable:false});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 */ /**
2
2
  * The MediaProvider base class.
3
3
  */var MediaProvider=/*#__PURE__*/function(){/**
4
4
  * Constructor.
@@ -6,16 +6,44 @@ function _classCallCheck(instance,Constructor){if(!(instance instanceof Construc
6
6
  * Callback for when Provider script is loaded
7
7
  * @callback
8
8
  * @abstract
9
- */ /* eslint-disable-next-line class-methods-use-this, require-jsdoc */_createClass(MediaProvider,[{key:"onScriptLoaded",value:function onScriptLoaded(){logger.error('MediaProvider.onScriptLoaded() needs to be implemented within an inheriting class');}/**
9
+ */_createClass(MediaProvider,[{key:"onScriptLoaded",value:function onScriptLoaded(){logger.error('MediaProvider.onScriptLoaded() needs to be implemented within an inheriting class');}/**
10
+ * Callback to retrieve a list of media containers
11
+ * @callback
12
+ * @abstract
13
+ */},{key:"getMediaContainers",value:function getMediaContainers(){logger.error('MediaProvider.getMediaContainers() needs to be implemented within an inheriting class');}/**
10
14
  * Optimizes video container to make it responsive.
11
15
  * @param {Element} container A DOM container.
12
16
  * @returns {MediaProvider}
13
17
  */},{key:"responsify",value:function responsify(container){// Remove fixed dimensions from the container.
14
18
  container.removeAttribute('height');container.removeAttribute('width');if(isRelativePosition(container.parentNode)&&isAbsolutePosition(container)){// Assume responsive embed code
15
19
  container.parentNode.removeAttribute('style');}// Create the wrapper and apply styling.
16
- var wrapper=document.createElement('div');wrapper.className=styles;// Add the wrapper right before the container into the DOM.
20
+ var wrapper=document.createElement('div');wrapper.className=styles.responsiveContainer;// Add the wrapper right before the container into the DOM.
17
21
  container.parentNode.insertBefore(wrapper,container);// Move the container into the wrapper.
18
22
  wrapper.appendChild(container);return this;}/**
23
+ * Searches for embedded media and replaces it with a placeholder element when comfort cookie
24
+ * consent is not accepted.
25
+ *
26
+ * Should be called before media container / markup is mounted to the DOM.
27
+ * @param {ParentNode} container A DOM container.
28
+ * @param {Object} [cookieConsentSettings] Additional settings related to cookie consent.
29
+ * @param {boolean} [cookieConsentSettings.comfortCookiesAccepted] Whether comfort cookies
30
+ * are accepted.
31
+ * @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
32
+ * are accepted.
33
+ * @returns {MediaProvider}
34
+ */},{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
35
+ _this.responsify(iframe);// Select the container and clear its content
36
+ var responsiveContainer=iframe.parentNode;responsiveContainer.textContent=null;// Add the consent message element to the container
37
+ _this.injectCookieConsentMessage(responsiveContainer);});return this;}/**
38
+ * Injects a cookie consent message element into a container
39
+ * @param {Element} container A DOM container.
40
+ * @returns {MediaProvider}
41
+ */},{key:"injectCookieConsentMessage",value:function injectCookieConsentMessage(container){// Create the wrapper for the message element
42
+ 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)
43
+ messageWrapper.innerHTML=consentMessageIcon;// Create the main message and add it to the wrapper
44
+ 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
45
+ var link=document.createElement('a');link.classList.add(styles.consentLink,'common__media-provider_cookie-consent-message-container_link');link.href=PRIVACY_SETTINGS_PATTERN;link.innerHTML=i18n.text('htmlSanitizer.videoCookieConsent.link');messageWrapper.appendChild(link);// Add the wrapper to the container
46
+ container.appendChild(messageWrapper);return this;}/**
19
47
  * Add a DOM container with embedded videos.
20
48
  * @param {NodeList} container A DOM container.
21
49
  * @returns {MediaProvider}
@@ -26,4 +54,4 @@ wrapper.appendChild(container);return this;}/**
26
54
  */},{key:"remove",value:function remove(container){this.containers["delete"](container);return this;}/**
27
55
  * Stops all playing videos within the DOM containers.
28
56
  * @returns {MediaProvider}
29
- */},{key:"stop",value:function stop(){logger.error('MediaProvider.stop() needs to be implemented within an inheriting class');return this;}}]);return MediaProvider;}();export default MediaProvider;
57
+ */},{key:"stop",value:function stop(){logger.error('MediaProvider.stop() needs to be implemented within an inheriting class');return this;}}]);return MediaProvider;}();export default MediaProvider;/* eslint-enable class-methods-use-this */
@@ -1,11 +1,15 @@
1
- function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj;}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;},_typeof(obj);}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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});Object.defineProperty(subClass,"prototype",{writable:false});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return _possibleConstructorReturn(this,result);};}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}else if(call!==void 0){throw new TypeError("Derived constructors may only return object or undefined");}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}import MediaProvider from"./MediaProvider";var scriptUrl='https://player.vimeo.com/api/player.js';/**
1
+ function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj;}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;},_typeof(obj);}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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _get(){if(typeof Reflect!=="undefined"&&Reflect.get){_get=Reflect.get;}else{_get=function _get(target,property,receiver){var base=_superPropBase(target,property);if(!base)return;var desc=Object.getOwnPropertyDescriptor(base,property);if(desc.get){return desc.get.call(arguments.length<3?target:receiver);}return desc.value;};}return _get.apply(this,arguments);}function _superPropBase(object,property){while(!Object.prototype.hasOwnProperty.call(object,property)){object=_getPrototypeOf(object);if(object===null)break;}return object;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});Object.defineProperty(subClass,"prototype",{writable:false});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return _possibleConstructorReturn(this,result);};}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}else if(call!==void 0){throw new TypeError("Derived constructors may only return object or undefined");}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}import MediaProvider from"./MediaProvider";/* eslint-disable class-methods-use-this */var scriptUrl='https://player.vimeo.com/api/player.js';/**
2
2
  * The Vimeo media provider class.
3
3
  */var VimeoMediaProvider=/*#__PURE__*/function(_MediaProvider){_inherits(VimeoMediaProvider,_MediaProvider);var _super=_createSuper(VimeoMediaProvider);/**
4
4
  * Constructor.
5
5
  */function VimeoMediaProvider(){var _this;_classCallCheck(this,VimeoMediaProvider);_this=_super.call(this);// Need to check Vimeo.Player presence later
6
6
  _this.isPending=true;_this.remoteScriptUrl=scriptUrl;_this.deferred=[];return _this;}/**
7
+ * Retrieves a list of media containers for Vimeo.
8
+ * @param {ParentNode} container A DOM container that may contain Vimeo iframes.
9
+ * @returns {NodeListOf<Element>}
10
+ */_createClass(VimeoMediaProvider,[{key:"getMediaContainers",value:function getMediaContainers(container){return container.querySelectorAll('iframe[src*="vimeo.com"]');}/**
7
11
  * @inheritDoc
8
- */_createClass(VimeoMediaProvider,[{key:"onScriptLoaded",value:function onScriptLoaded(){var _this2=this;this.isPending=false;if(this.deferred.length){this.deferred.forEach(function(container){_this2.add(container);});this.deferred=[];}}/**
12
+ */},{key:"onScriptLoaded",value:function onScriptLoaded(){var _this2=this;this.isPending=false;if(this.deferred.length){this.deferred.forEach(function(container){_this2.add(container);});this.deferred=[];}}/**
9
13
  * Check if the Provider script to be loaded externally is finished loading
10
14
  * @returns {boolean}
11
15
  */},{key:"checkScriptLoadingStatus",value:function checkScriptLoadingStatus(){if(this.isPending&&typeof window.Vimeo!=='undefined'){this.isPending=false;}return!this.isPending;}/**
@@ -13,8 +17,22 @@ _this.isPending=true;_this.remoteScriptUrl=scriptUrl;_this.deferred=[];return _t
13
17
  * @override
14
18
  * @param {ParentNode} container A DOM container.
15
19
  * @returns {VimeoMediaProvider}
16
- */},{key:"add",value:function add(container){var _this3=this;if(!this.checkScriptLoadingStatus()){this.deferred.push(container);return this;}var iframes=container.querySelectorAll('iframe[src*="vimeo.com"]');if(!iframes.length){return this;}var players=[];iframes.forEach(function(iframe){_this3.responsify(iframe);players.push(new window.Vimeo.Player(iframe));});this.containers.set(container,players);return this;}/**
20
+ */},{key:"add",value:function add(container){var _this3=this;if(!this.checkScriptLoadingStatus()){this.deferred.push(container);return this;}var iframes=this.getMediaContainers(container);if(!iframes.length){return this;}var players=[];iframes.forEach(function(iframe){_this3.responsify(iframe);players.push(new window.Vimeo.Player(iframe));});this.containers.set(container,players);return this;}/**
17
21
  * Stops all playing videos within the DOM containers.
18
22
  * @override
19
23
  * @returns {VimeoMediaProvider}
20
- */},{key:"stop",value:function stop(){this.containers.forEach(function(players){players.forEach(function(player){player.pause();});});return this;}}]);return VimeoMediaProvider;}(MediaProvider);export default VimeoMediaProvider;
24
+ */},{key:"stop",value:function stop(){this.containers.forEach(function(players){players.forEach(function(player){player.pause();});});return this;}/**
25
+ * Searches for embedded media and replaces it with a placeholder element when comfort cookie
26
+ * consent is not accepted.
27
+ *
28
+ * Should be called before media container / markup is mounted to the DOM.
29
+ * @param {ParentNode} container A DOM container.
30
+ * @param {Object} [cookieConsentSettings] Additional settings related to cookie consent.
31
+ * @param {boolean} [cookieConsentSettings.comfortCookiesAccepted] Whether comfort cookies
32
+ * are accepted.
33
+ * @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
34
+ * are accepted.
35
+ * @override
36
+ * @returns {VimeoMediaProvider}
37
+ */},{key:"handleCookieConsent",value:function handleCookieConsent(container,cookieConsentSettings){// Remove Vimeo player scripts since the VimeoMediaProvider has custom logic for it
38
+ container.querySelectorAll('script[src*="vimeo.com"]').forEach(function(entry){entry.remove();});return _get(_getPrototypeOf(VimeoMediaProvider.prototype),"handleCookieConsent",this).call(this,container,cookieConsentSettings);}}]);return VimeoMediaProvider;}(MediaProvider);export default VimeoMediaProvider;/* eslint-enable class-methods-use-this */
@@ -1,15 +1,19 @@
1
- function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj;}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;},_typeof(obj);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_unsupportedIterableToArray(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen);}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i];}return arr2;}function _iterableToArrayLimit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});Object.defineProperty(subClass,"prototype",{writable:false});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return _possibleConstructorReturn(this,result);};}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}else if(call!==void 0){throw new TypeError("Derived constructors may only return object or undefined");}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}import URLSearchParams from'url-search-params';import MediaProvider from"./MediaProvider";/**
1
+ function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(obj){return typeof obj;}:function(obj){return obj&&"function"==typeof Symbol&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj;},_typeof(obj);}function _slicedToArray(arr,i){return _arrayWithHoles(arr)||_iterableToArrayLimit(arr,i)||_unsupportedIterableToArray(arr,i)||_nonIterableRest();}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");}function _unsupportedIterableToArray(o,minLen){if(!o)return;if(typeof o==="string")return _arrayLikeToArray(o,minLen);var n=Object.prototype.toString.call(o).slice(8,-1);if(n==="Object"&&o.constructor)n=o.constructor.name;if(n==="Map"||n==="Set")return Array.from(o);if(n==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return _arrayLikeToArray(o,minLen);}function _arrayLikeToArray(arr,len){if(len==null||len>arr.length)len=arr.length;for(var i=0,arr2=new Array(len);i<len;i++){arr2[i]=arr[i];}return arr2;}function _iterableToArrayLimit(arr,i){var _i=arr==null?null:typeof Symbol!=="undefined"&&arr[Symbol.iterator]||arr["@@iterator"];if(_i==null)return;var _arr=[];var _n=true;var _d=false;var _s,_e;try{for(_i=_i.call(arr);!(_n=(_s=_i.next()).done);_n=true){_arr.push(_s.value);if(i&&_arr.length===i)break;}}catch(err){_d=true;_e=err;}finally{try{if(!_n&&_i["return"]!=null)_i["return"]();}finally{if(_d)throw _e;}}return _arr;}function _arrayWithHoles(arr){if(Array.isArray(arr))return arr;}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);Object.defineProperty(Constructor,"prototype",{writable:false});return Constructor;}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function");}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});Object.defineProperty(subClass,"prototype",{writable:false});if(superClass)_setPrototypeOf(subClass,superClass);}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o;};return _setPrototypeOf(o,p);}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget);}else{result=Super.apply(this,arguments);}return _possibleConstructorReturn(this,result);};}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call;}else if(call!==void 0){throw new TypeError("Derived constructors may only return object or undefined");}return _assertThisInitialized(self);}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called");}return self;}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}));return true;}catch(e){return false;}}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o);};return _getPrototypeOf(o);}import URLSearchParams from'url-search-params';import MediaProvider from"./MediaProvider";/* eslint-disable class-methods-use-this */ /**
2
2
  * The YouTube media provider class.
3
- */var YouTubeMediaProvider=/*#__PURE__*/function(_MediaProvider){_inherits(YouTubeMediaProvider,_MediaProvider);var _super=_createSuper(YouTubeMediaProvider);function YouTubeMediaProvider(){_classCallCheck(this,YouTubeMediaProvider);return _super.apply(this,arguments);}_createClass(YouTubeMediaProvider,[{key:"add",value:/**
3
+ */var YouTubeMediaProvider=/*#__PURE__*/function(_MediaProvider){_inherits(YouTubeMediaProvider,_MediaProvider);var _super=_createSuper(YouTubeMediaProvider);function YouTubeMediaProvider(){_classCallCheck(this,YouTubeMediaProvider);return _super.apply(this,arguments);}_createClass(YouTubeMediaProvider,[{key:"getMediaContainers",value:/**
4
+ * Retrieves a list of media containers for YouTube.
5
+ * @param {ParentNode} container A DOM container that may contain YouTube iframes.
6
+ * @returns {NodeListOf<Element>}
7
+ */function getMediaContainers(container){return container.querySelectorAll('iframe[src*="youtube.com"], iframe[src*="youtube-nocookie.com"]');}/**
4
8
  * Add a DOM container with embedded videos.
5
9
  * @override
6
10
  * @param {ParentNode} container A DOM container.
7
11
  * @returns {YouTubeMediaProvider}
8
- */function add(container){var _this=this;var iframes=container.querySelectorAll('iframe[src*="youtube.com"], iframe[src*="youtube-nocookie.com"]');if(!iframes.length){return this;}// Update the video urls to enable stopping videos via the event API.
12
+ */},{key:"add",value:function add(container){var _this=this;var iframes=this.getMediaContainers(container);if(!iframes.length){return this;}// Update the video urls to enable stopping videos via the event API.
9
13
  iframes.forEach(function(iframe,index){_this.responsify(iframe);var src=iframe.src;var _src$split=src.split('?'),_src$split2=_slicedToArray(_src$split,2),url=_src$split2[0],query=_src$split2[1];var urlParams=new URLSearchParams(query);// Enable the js api to allow sending events to the iframe.
10
14
  urlParams.set('enablejsapi',1);// Enable controls to avoid the iframe not being resumable because of controls=0 param on ios.
11
15
  urlParams.set('controls',1);iframes[index].src="".concat(url,"?").concat(urlParams.toString());});this.containers.set(container,iframes);return this;}/**
12
16
  * Stops all playing videos within the DOM containers.
13
17
  * @override
14
18
  * @returns {YouTubeMediaProvider}
15
- */},{key:"stop",value:function stop(){this.containers.forEach(function(iframes){iframes.forEach(function(iframe){if(iframe.contentWindow&&iframe.contentWindow.postMessage){iframe.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}','*');}});});return this;}}]);return YouTubeMediaProvider;}(MediaProvider);export default YouTubeMediaProvider;
19
+ */},{key:"stop",value:function stop(){this.containers.forEach(function(iframes){iframes.forEach(function(iframe){if(iframe.contentWindow&&iframe.contentWindow.postMessage){iframe.contentWindow.postMessage('{"event":"command","func":"stopVideo","args":""}','*');}});});return this;}}]);return YouTubeMediaProvider;}(MediaProvider);export default YouTubeMediaProvider;/* eslint-enable class-methods-use-this */
@@ -1 +1,2 @@
1
- import{css}from'glamor';export default css({position:'relative',height:0,overflow:'hidden',padding:'56.25% 0 0 0',' iframe, object, embed':{position:'absolute',top:0,left:0,width:'100%',height:'100%',border:0}}).toString();
1
+ import{css}from'glamor';import{themeConfig}from'@shopgate/pwa-common/helpers/config';var colors=themeConfig.colors;var responsiveContainer=css({position:'relative',height:0,overflow:'hidden',padding:'56.25% 0 0 0',fontSize:'0.875rem',' iframe, object, embed':{position:'absolute',top:0,left:0,width:'100%',height:'100%',border:0}});var consentContainer=css({position:'absolute',height:'100%',width:'100%',padding:16,lineHeight:'1.2rem',display:'flex',flexDirection:'column',justifyContent:'center',textAlign:'center',gap:16,background:colors.shade10,border:"1px solid ".concat(colors.shade5),// Add a tiny little border radius to make the message container look nice with padding
2
+ borderRadius:4,top:0});var consentLink=css({textAlign:'center',color:colors.primary,fontWeight:500}).toString();var consentIcon=css({fill:colors.shade5,height:40});export default{responsiveContainer:responsiveContainer,consentContainer:consentContainer,consentLink:consentLink,consentIcon:consentIcon};
@@ -1,11 +1,11 @@
1
- import React,{Fragment}from'react';import PropTypes from'prop-types';import Helmet from'react-helmet';import{embeddedMedia}from'@shopgate/pwa-common/collections';/**
2
- * EmbeddedMedia component.
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import React,{Fragment,useMemo}from'react';import PropTypes from'prop-types';import Helmet from'react-helmet';import{embeddedMedia}from'@shopgate/pwa-common/collections';/**
2
+ * EmbeddedMedia component. Handles loading of media related scripts e.g. the Vimeo Player.
3
3
  * @returns {JSX}
4
- */var EmbeddedMedia=function EmbeddedMedia(_ref){var children=_ref.children;if(!embeddedMedia.getHasPendingProviders()){return children;}// Get all pending providers
5
- var pendingProviders=[].concat(embeddedMedia.providers).filter(function(p){return p.isPending;});/**
4
+ */var EmbeddedMedia=function EmbeddedMedia(_ref){var children=_ref.children,cookieConsentSettings=_ref.cookieConsentSettings;var cookieConsent=useMemo(function(){return _extends({comfortCookiesAccepted:false,statisticsCookiesAccepted:false},cookieConsentSettings);},[cookieConsentSettings]);if(!embeddedMedia.getHasPendingProviders()||!cookieConsent.comfortCookiesAccepted){return children;}// Get all pending providers
5
+ var pendingProviders=Array.from(embeddedMedia.providers).filter(function(p){return p.isPending;});/**
6
6
  * Inject onLoad cb to script tags
7
7
  * @param {Element[]} scriptTags script tags to listen for
8
8
  * @param {MediaProvider} provider Provider
9
9
  */var updateProviderScripts=function updateProviderScripts(_ref2){var scriptTags=_ref2.scriptTags;if(scriptTags){scriptTags.forEach(function(scriptTag){var provider=pendingProviders.find(function(p){return p.remoteScriptUrl===scriptTag.getAttribute('src');});// eslint-disable-next-line no-param-reassign
10
10
  scriptTag.onload=function(){provider.onScriptLoaded();};});}};var scripts=pendingProviders.map(function(provider){return{src:provider.remoteScriptUrl,type:'text/javascript'};});return/*#__PURE__*/React.createElement(Fragment,null,/*#__PURE__*/React.createElement(Helmet,{script:scripts// Helmet doesn't support `onload` in script objects so we have to hack in our own
11
- ,onChangeClientState:function onChangeClientState(newState,addedTags){return updateProviderScripts(addedTags);}}),children);};export default EmbeddedMedia;
11
+ ,onChangeClientState:function onChangeClientState(newState,addedTags){return updateProviderScripts(addedTags);}}),children);};EmbeddedMedia.defaultProps={cookieConsentSettings:{comfortCookiesAccepted:false,statisticsCookiesAccepted:false}};export default EmbeddedMedia;
@@ -1,5 +1,9 @@
1
- function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import{connect}from'react-redux';import{historyPush}from"../../actions/router";/**
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import{connect}from'react-redux';import{getAreComfortCookiesAccepted,getAreStatisticsCookiesAccepted}from'@shopgate/engage/tracking/selectors';import{historyPush}from"../../actions/router";/**
2
+ * Maps the current application state to the component props.
3
+ * @param {Object} state The current application state.
4
+ * @return {Object} The populated component props.
5
+ */var mapStateToProps=function mapStateToProps(state){return{comfortCookiesAccepted:getAreComfortCookiesAccepted(state),statisticsCookiesAccepted:getAreStatisticsCookiesAccepted(state)};};/**
2
6
  * Connects the dispatch function to a callable function in the props.
3
7
  * @param {Function} dispatch The redux dispatch function.
4
8
  * @return {Object} The extended component props.
5
- */var mapDispatchToProps=function mapDispatchToProps(dispatch){return{navigate:function navigate(pathname,target){return dispatch(historyPush(_extends({pathname:pathname},target&&{state:{target:target}})));}};};export default connect(null,mapDispatchToProps);
9
+ */var mapDispatchToProps=function mapDispatchToProps(dispatch){return{navigate:function navigate(pathname,target){return dispatch(historyPush(_extends({pathname:pathname},target&&{state:{target:target}})));}};};export default connect(mapStateToProps,mapDispatchToProps);
@@ -18,5 +18,5 @@ function _typeof(obj){"@babel/helpers - typeof";return _typeof="function"==typeo
18
18
  */},{key:"render",value:/**
19
19
  * Renders the component.
20
20
  * @returns {JSX}
21
- */function render(){var innerHTML={__html:parseHTML(this.props.children,this.props.decode,this.props.settings,this.props.processStyles)};var Wrapper=this.props.wrapper;return/*#__PURE__*/React.createElement(Wrapper,null,/*#__PURE__*/React.createElement("div",{// eslint-disable-next-line react/no-danger
22
- dangerouslySetInnerHTML:innerHTML,ref:this.htmlContainer,className:"".concat(this.props.className," common__html-sanitizer")}));}}]);return HtmlSanitizer;}(Component);_defineProperty(HtmlSanitizer,"defaultProps",{children:'',className:'',decode:false,processStyles:false,settings:{},wrapper:EmbeddedMedia});export default connect(HtmlSanitizer);
21
+ */function render(){var cookieConsentSettings={comfortCookiesAccepted:this.props.comfortCookiesAccepted,statisticsCookiesAccepted:this.props.statisticsCookiesAccepted};var innerHTML={__html:parseHTML(this.props.children,this.props.decode,this.props.settings,this.props.processStyles,cookieConsentSettings)};var Wrapper=this.props.wrapper;return/*#__PURE__*/React.createElement(Wrapper,{cookieConsentSettings:cookieConsentSettings},/*#__PURE__*/React.createElement("div",{// eslint-disable-next-line react/no-danger
22
+ dangerouslySetInnerHTML:innerHTML,ref:this.htmlContainer,className:"".concat(this.props.className," common__html-sanitizer")}));}}]);return HtmlSanitizer;}(Component);_defineProperty(HtmlSanitizer,"defaultProps",{children:'',className:'',decode:false,processStyles:false,settings:{},wrapper:EmbeddedMedia,comfortCookiesAccepted:false,statisticsCookiesAccepted:false});export default connect(HtmlSanitizer);
@@ -1,13 +1,13 @@
1
- function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import React from'react';import{mount}from'enzyme';import{JSDOM}from'jsdom';import{embeddedMedia}from'@shopgate/pwa-common/collections';import HtmlSanitizer from"./index";jest.mock('@shopgate/pwa-common/collections/EmbeddedMedia',function(){return{add:jest.fn(),remove:jest.fn()};});jest.mock("../EmbeddedMedia",function(){return function(_ref){var children=_ref.children;return children;};});jest.mock("./connector",function(){return function(Cmp){return Cmp;};});/**
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import React from'react';import{mount}from'enzyme';import{JSDOM}from'jsdom';import{embeddedMedia}from'@shopgate/pwa-common/collections';import HtmlSanitizer from"./index";jest.mock("../EmbeddedMedia",function(){return function(_ref){var children=_ref.children;return children;};});jest.mock("./connector",function(){return function(Cmp){return Cmp;};});/**
2
2
  * @param {string} html HTML markup.
3
3
  * @param {Object} props Component props.
4
4
  * @returns {JSX}
5
- */var createWrapper=function createWrapper(html){var props=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};return mount(/*#__PURE__*/React.createElement(HtmlSanitizer,_extends({navigate:function navigate(){}},props),html));};describe('<HtmlSanitizer />',function(){beforeEach(function(){jest.clearAllMocks();});it('should render the HtmlSanitizer',function(){/**
5
+ */var createWrapper=function createWrapper(html){var props=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};return mount(/*#__PURE__*/React.createElement(HtmlSanitizer,_extends({navigate:function navigate(){}},props),html));};describe('<HtmlSanitizer />',function(){var embeddedMediaAddSpy;var embeddedMediaRemoveSpy;var embeddedMediaHandleCookieConsentSpy;beforeEach(function(){jest.clearAllMocks();embeddedMediaAddSpy=jest.spyOn(embeddedMedia,'add');embeddedMediaRemoveSpy=jest.spyOn(embeddedMedia,'remove');embeddedMediaHandleCookieConsentSpy=jest.spyOn(embeddedMedia,'handleCookieConsent');});it('should render the HtmlSanitizer',function(){/**
6
6
  * The value for html is the HTML-escaped equivalent of the following:
7
7
  * <h1>Hello World!</h1>
8
8
  * @type {string}
9
9
  */var html='&lt;h1&gt;Hello World!&lt;/h1&gt;';var wrapper=createWrapper(html,{decode:true});// Test result of dangerouslySetInnerHTML.
10
- expect(wrapper.html()).toEqual('<div class=" common__html-sanitizer"><h1>Hello World!</h1></div>');expect(wrapper.render()).toMatchSnapshot();});it('should add and remove handlers for embedded media',function(){var wrapper=createWrapper('<div></div>',{decode:true});var ref=wrapper.instance().htmlContainer.current;expect(embeddedMedia.add).toHaveBeenCalledTimes(1);expect(embeddedMedia.add).toHaveBeenCalledWith(ref);expect(embeddedMedia.remove).toHaveBeenCalledTimes(0);wrapper.setProps({children:'<span></span>'});expect(embeddedMedia.add).toHaveBeenCalledTimes(2);expect(embeddedMedia.add).toHaveBeenCalledWith(ref);expect(embeddedMedia.remove).toHaveBeenCalledTimes(0);wrapper.unmount();expect(embeddedMedia.add).toHaveBeenCalledTimes(2);expect(embeddedMedia.remove).toHaveBeenCalledTimes(1);expect(embeddedMedia.remove).toHaveBeenCalledWith(ref);});it('strips out images with relative paths',function(){var html="\n <div>\n <style>a { color: red }</style>\n <a href=\"foo\">\n <img src=\"bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html);expect(wrapper.html()).not.toContain('<img');expect(wrapper.html()).toContain('<style>');expect(wrapper.render()).toMatchSnapshot();});it('should move style blocks out of the content',function(){var html="\n <div>\n <style>a { color: red }</style>\n <a href=\"foo\">\n <img src=\"bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html,{processStyles:true});expect(wrapper.html()).not.toContain('<style>');});it('does not strip out images with absolute paths',function(){var html="\n <div>\n <a href=\"foo\">\n <img src=\"http://google.de/bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html);expect(wrapper.html()).toContain('<img');expect(wrapper.render()).toMatchSnapshot();});it('strips out the script tags',function(){/**
10
+ expect(wrapper.html()).toEqual('<div class=" common__html-sanitizer"><h1>Hello World!</h1></div>');expect(wrapper.render()).toMatchSnapshot();});it('should add and remove handlers for embedded media',function(){var wrapper=createWrapper('<div></div>',{decode:true});var ref=wrapper.instance().htmlContainer.current;expect(embeddedMediaAddSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaAddSpy).toHaveBeenCalledWith(ref);expect(embeddedMediaRemoveSpy).toHaveBeenCalledTimes(0);wrapper.setProps({children:'<span></span>'});expect(embeddedMediaAddSpy).toHaveBeenCalledTimes(2);expect(embeddedMediaAddSpy).toHaveBeenCalledWith(ref);expect(embeddedMediaRemoveSpy).toHaveBeenCalledTimes(0);wrapper.unmount();expect(embeddedMediaAddSpy).toHaveBeenCalledTimes(2);expect(embeddedMediaRemoveSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaRemoveSpy).toHaveBeenCalledWith(ref);});it('strips out images with relative paths',function(){var html="\n <div>\n <style>a { color: red }</style>\n <a href=\"foo\">\n <img src=\"bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html);expect(wrapper.html()).not.toContain('<img');expect(wrapper.html()).toContain('<style>');expect(wrapper.render()).toMatchSnapshot();});it('should move style blocks out of the content',function(){var html="\n <div>\n <style>a { color: red }</style>\n <a href=\"foo\">\n <img src=\"bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html,{processStyles:true});expect(wrapper.html()).not.toContain('<style>');});it('does not strip out images with absolute paths',function(){var html="\n <div>\n <a href=\"foo\">\n <img src=\"http://google.de/bar.jpg\" />\n </a>\n </div>\n ";var wrapper=createWrapper(html);expect(wrapper.html()).toContain('<img');expect(wrapper.render()).toMatchSnapshot();});it('strips out the script tags',function(){/**
11
11
  * The value for html is the HTML-escaped equivalent of the following:
12
12
  * <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
13
13
  * <script type="text/javascript">var x = 42;</script>
@@ -15,4 +15,4 @@ expect(wrapper.html()).toEqual('<div class=" common__html-sanitizer"><h1>Hello W
15
15
  * <script>var y = 23;</script>
16
16
  * @type {string}
17
17
  */var html='&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js&quot;&gt;&lt;/script&gt; &lt;script type=&quot;text/javascript&quot;&gt;var x = 42;&lt;/script&gt; &lt;p&gt;Foo Bar&lt;/p&gt; &lt;script&gt;var y = 23;&lt;/script&gt;';var wrapper=createWrapper(html,{decode:true});// Test result of dangerouslySetInnerHTML.
18
- expect(wrapper.html()).toEqual('<div class=" common__html-sanitizer"> <p>Foo Bar</p> </div>');expect(wrapper).toMatchSnapshot();});describe('Link handling',function(){var mockedHandleClick=jest.fn();beforeEach(function(){mockedHandleClick.mockClear();});it('follows a link from a plain <a>',function(){var doc=new JSDOM('<!doctype html><html><body><div>/<div></body></html>').window.document;var html='&lt;a id=&quot;link&quot; href=&quot;#follow-me-and-everything-is-alright&quot;&gt;Plain Link&lt;/a&gt;';var wrapper=mount(/*#__PURE__*/React.createElement(HtmlSanitizer,{decode:true,settings:{handleClick:mockedHandleClick},navigate:function navigate(){}},html),{attachTo:doc.getElementsByTagName('div')[0]});var aTag=doc.getElementsByTagName('a')[0];aTag.closest=function(){return aTag;};var event={target:aTag,preventDefault:function preventDefault(){}};wrapper.instance().handleTap(event);expect(mockedHandleClick).toHaveBeenCalledTimes(1);expect(mockedHandleClick).toHaveBeenCalledWith('#follow-me-and-everything-is-alright','');});it('follows a link from a <a> with other HTML inside',function(){var doc=new JSDOM('<!doctype html><html><body><div>/<div></body></html>').window.document;var html='&lt;a id=&quot;link&quot; target=&quot;_blank&quot; href=&quot;#I-ll-be-the-one-to-tuck-you-in-at-night&quot;&gt;&lt;span&gt;Span Link&lt;/span&gt;&lt;/a&gt;';var wrapper=mount(/*#__PURE__*/React.createElement(HtmlSanitizer,{decode:true,settings:{handleClick:mockedHandleClick},navigate:function navigate(){}},html),{attachTo:doc.getElementsByTagName('div')[0]});var aTag=doc.getElementsByTagName('a')[0];var spanTag=doc.getElementsByTagName('span')[0];spanTag.closest=function(){return aTag;};var event={target:spanTag,preventDefault:function preventDefault(){}};wrapper.instance().handleTap(event);expect(mockedHandleClick).toHaveBeenCalledTimes(1);expect(mockedHandleClick).toHaveBeenCalledWith('#I-ll-be-the-one-to-tuck-you-in-at-night','_blank');});});});
18
+ expect(wrapper.html()).toEqual('<div class=" common__html-sanitizer"> <p>Foo Bar</p> </div>');expect(wrapper).toMatchSnapshot();});describe('Link handling',function(){var mockedHandleClick=jest.fn();beforeEach(function(){mockedHandleClick.mockClear();});it('follows a link from a plain <a>',function(){var doc=new JSDOM('<!doctype html><html><body><div>/<div></body></html>').window.document;var html='&lt;a id=&quot;link&quot; href=&quot;#follow-me-and-everything-is-alright&quot;&gt;Plain Link&lt;/a&gt;';var wrapper=mount(/*#__PURE__*/React.createElement(HtmlSanitizer,{decode:true,settings:{handleClick:mockedHandleClick},navigate:function navigate(){}},html),{attachTo:doc.getElementsByTagName('div')[0]});var aTag=doc.getElementsByTagName('a')[0];aTag.closest=function(){return aTag;};var event={target:aTag,preventDefault:function preventDefault(){}};wrapper.instance().handleTap(event);expect(mockedHandleClick).toHaveBeenCalledTimes(1);expect(mockedHandleClick).toHaveBeenCalledWith('#follow-me-and-everything-is-alright','');});it('follows a link from a <a> with other HTML inside',function(){var doc=new JSDOM('<!doctype html><html><body><div>/<div></body></html>').window.document;var html='&lt;a id=&quot;link&quot; target=&quot;_blank&quot; href=&quot;#I-ll-be-the-one-to-tuck-you-in-at-night&quot;&gt;&lt;span&gt;Span Link&lt;/span&gt;&lt;/a&gt;';var wrapper=mount(/*#__PURE__*/React.createElement(HtmlSanitizer,{decode:true,settings:{handleClick:mockedHandleClick},navigate:function navigate(){}},html),{attachTo:doc.getElementsByTagName('div')[0]});var aTag=doc.getElementsByTagName('a')[0];var spanTag=doc.getElementsByTagName('span')[0];spanTag.closest=function(){return aTag;};var event={target:spanTag,preventDefault:function preventDefault(){}};wrapper.instance().handleTap(event);expect(mockedHandleClick).toHaveBeenCalledTimes(1);expect(mockedHandleClick).toHaveBeenCalledWith('#I-ll-be-the-one-to-tuck-you-in-at-night','_blank');});});describe('Cookie consent handling',function(){it('should invoke handleCookieConsent method of embedded media with default cookie consent settings',function(){createWrapper('<div></div>',{decode:true});expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledWith(expect.any(Document),{comfortCookiesAccepted:false,statisticsCookiesAccepted:false});});it('should invoke handleCookieConsent method of embedded media with accepted comfort cookies',function(){createWrapper('<div></div>',{decode:true,comfortCookiesAccepted:true});expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledWith(expect.any(Document),{comfortCookiesAccepted:true,statisticsCookiesAccepted:false});});it('should invoke handleCookieConsent method of embedded media with accepted statistics cookies',function(){createWrapper('<div></div>',{decode:true,statisticsCookiesAccepted:true});expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledWith(expect.any(Document),{comfortCookiesAccepted:false,statisticsCookiesAccepted:true});});it('should invoke handleCookieConsent method of embedded media with all cookies accepted',function(){createWrapper('<div></div>',{decode:true,comfortCookiesAccepted:true,statisticsCookiesAccepted:true});expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledTimes(1);expect(embeddedMediaHandleCookieConsentSpy).toHaveBeenCalledWith(expect.any(Document),{comfortCookiesAccepted:true,statisticsCookiesAccepted:true});});});});
@@ -19,7 +19,8 @@ return Math.ceil(element.offsetHeight+margins);};/**
19
19
  * @param {HTMLElement} element The DOM element.
20
20
  * @param {string} property The style property in camel case
21
21
  * @returns {string}
22
- */export var getStyle=function getStyle(element,property){if(window.getComputedStyle){// getPropertyValue expects the property in kebab case.
22
+ */export var getStyle=function getStyle(element,property){// Use computed styles if possible - doesn't work with elements which are not mounted to the DOM
23
+ if(window.getComputedStyle&&document.body.contains(element)){// getPropertyValue expects the property in kebab case.
23
24
  return window.getComputedStyle(element,null).getPropertyValue(property.replace(/([a-z])([A-Z])/g,'$1-$2').toLowerCase());}return element.style[property];};/**
24
25
  * Check if element is relative.
25
26
  * @param {Element} element The DOM element.
@@ -1,13 +1,20 @@
1
- import{logger}from'@shopgate/pwa-core/helpers';import CryptoJs from'crypto-js';import{getExternalScripts,getInlineScripts,getHTMLContent,getDOMContainer,getStyles}from"./handleDOM";import decodeHTML from"./decodeHTML";/**
1
+ function _extends(){_extends=Object.assign||function(target){for(var i=1;i<arguments.length;i++){var source=arguments[i];for(var key in source){if(Object.prototype.hasOwnProperty.call(source,key)){target[key]=source[key];}}}return target;};return _extends.apply(this,arguments);}import{logger}from'@shopgate/pwa-core/helpers';import CryptoJs from'crypto-js';import{embeddedMedia}from"../../collections";import{getExternalScripts,getInlineScripts,getHTMLContent,getDOMContainer,getStyles}from"./handleDOM";import decodeHTML from"./decodeHTML";/**
2
2
  * Receives custom HTML from a widget configuration, parses possible
3
3
  * script tags and executes them after loading external scripts.
4
4
  * @param {string} html The HTML string. It might contain script tags.
5
5
  * @param {boolean} decode Whether the html must be decoded.
6
6
  * @param {Object} settings The settings are used to create a unique ID.
7
7
  * @param {boolean} [processStyles=false] When true, found styles are also added to the DOM.
8
+ * @param {Object} [cookieConsentSettings] Additional settings related to cookie consent.
9
+ * @param {boolean} [cookieConsentSettings.comfortCookiesAccepted] Whether comfort cookies
10
+ * are accepted.
11
+ * @param {boolean} [cookieConsentSettings.statisticsCookiesAccepted] Whether statistics cookies
12
+ * are accepted.
8
13
  * @returns {string} The HTML without any script tags.
9
- */var parseHTML=function parseHTML(html,decode,settings){var processStyles=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var id=CryptoJs.MD5(JSON.stringify(settings)).toString();var container=getDOMContainer("html-sanitizer-".concat(id));try{var parser=new DOMParser();var unparsedHTML=decode?decodeHTML(html):html;// Parse the html string to a DOM object.
10
- var dom=parser.parseFromString("<body>".concat(unparsedHTML,"</body>"),'text/html');// How many onloads have been processed.
14
+ */var parseHTML=function parseHTML(html,decode,settings){var processStyles=arguments.length>3&&arguments[3]!==undefined?arguments[3]:false;var cookieConsentSettings=arguments.length>4&&arguments[4]!==undefined?arguments[4]:{};var id=CryptoJs.MD5(JSON.stringify(settings)).toString();var container=getDOMContainer("html-sanitizer-".concat(id));var cookieConsent=_extends({comfortCookiesAccepted:false,statisticsCookiesAccepted:false},cookieConsentSettings);try{var parser=new DOMParser();var unparsedHTML=decode?decodeHTML(html):html;// Parse the html string to a DOM object.
15
+ var dom=parser.parseFromString("<body>".concat(unparsedHTML,"</body>"),'text/html');// Run cookie consent logic from embedded media to remove markup that's not supposed to run
16
+ // when consent is not accepted.
17
+ embeddedMedia.handleCookieConsent(dom,cookieConsent);// How many onloads have been processed.
11
18
  var onloads=0;var inlineScripts=[];var externalScripts=[];/**
12
19
  * Handles the onload events for external scripts.
13
20
  * @return {Array} The collection of external scripts.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shopgate/pwa-common",
3
- "version": "6.23.4-beta.1",
3
+ "version": "6.23.4-beta.2",
4
4
  "description": "Common library for the Shopgate Connect PWA.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Shopgate <support@shopgate.com>",
@@ -16,7 +16,7 @@
16
16
  ],
17
17
  "dependencies": {
18
18
  "@sentry/browser": "^4.6.3",
19
- "@shopgate/pwa-benchmark": "6.23.4-beta.1",
19
+ "@shopgate/pwa-benchmark": "6.23.4-beta.2",
20
20
  "@virtuous/conductor": "~2.4.0",
21
21
  "@virtuous/react-conductor": "~2.4.0",
22
22
  "@virtuous/redux-persister": "1.1.0-beta.7",
@@ -44,7 +44,7 @@
44
44
  "url-search-params": "^0.10.0"
45
45
  },
46
46
  "devDependencies": {
47
- "@shopgate/pwa-core": "6.23.4-beta.1",
47
+ "@shopgate/pwa-core": "6.23.4-beta.2",
48
48
  "lodash": "^4.17.4",
49
49
  "prop-types": "~15.7.2",
50
50
  "react": "~16.12.0",