@abtasty/widget-quality 0.4.22 → 0.4.23
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.
- package/dist/form.js +2222 -1
- package/dist/main.js +2699 -1
- package/package.json +3 -4
package/dist/main.js
CHANGED
|
@@ -1 +1,2699 @@
|
|
|
1
|
-
!function(){"use strict";const e=()=>Object.prototype.hasOwnProperty.call(top,"ABTastyEditor"),t=()=>{const e=!!document.getElementById("ABTastyPreviewBar"),t=location.href.includes("ab_project=preview");return e||t},n=e=>new Function(`try {\n\t\t${e}\n\t} catch (error) {\n\t\treturn null;\n\t}`)(),i=()=>encodeURIComponent(DATA.spNoTrim?window.location.href.replace(window.location.origin,""):`${window.location.pathname}`),s=()=>!e()&&(t()||!!window.ABTasty.getTestsOnPage()[TEST_ID]),r=()=>window.ABTasty&&!0===window.ABTasty.consentReady,o=()=>{const{type:e}=DATA;return`${PACKAGE.replace("@abtasty/","")}${e?`_${e}`:""}`},a=()=>{const e=o();return`${e.charAt(0).toUpperCase()}${e.slice(1)}`.split("-").join(" ")},c=()=>`${PLUGIN_ID.split("-")[0]}_${TEST_ID}`,l=n=>{const i=(()=>{if(e()||t())return!1;const n=ABTasty.getTestsOnPage()[TEST_ID];return!!n&&Object.keys(n.targetings.qaParameters).length>0})(),s=window.document.cookie.includes("abTastyDebug=")||!0===window.abTastyDebug;if(i||s){const e=a();window.console.log(`%c${e} - ${i?"QA":"Debug"} Mode for campaign ${TEST_ID} %c ${n}`,"background-color: #D6FF01; color: #3100be; padding: 3px 0 3px 10px; border-radius: 5px 0 0 5px; font-weight: bold;","background-color: #3100be; color: white; padding: 3px 10px 3px 0; border-radius: 0 5px 5px 0;")}},h=e=>{const t={promise:null,resolve:null,reject:null,name:e};return t.promise=new Promise((e,n)=>{t.resolve=e,t.reject=n}),t},d=(e,t)=>{const n=t?[]:null;if("string"!=typeof e||!e.trim().length)return n;const[i,s,r]=e.split("[]").map(e=>e.trim()),o=Boolean(r)?r:e,a=s?document.querySelector(i)?.[s]:document;return a?t?[...a.querySelectorAll(o)]:a.querySelector(o):n},u=e=>d(e,!1),g=e=>d(e,!0),m=(e,t)=>{const n={childList:!0,subtree:!0,attributes:!0},i=()=>s.disconnect(),s=new MutationObserver(()=>{const n=u(t);return n&&!i()&&e(n)});return{clear:i,observe:e=>{const t=document.querySelector("body")||document.documentElement,i=e??t;s.observe(i,n)}}},p=()=>{},v=(t,n)=>{const i=u(t),s={selector:t,clear:p,observe:p};if(i)return setTimeout(()=>n(i),0),s;if(e())return setTimeout(()=>v(t,n),1e3),s;if(t.includes("[]"))return((e,t)=>{const[n,i]=t.split("[]").map(e=>e.trim()),s=u(n),r=s?.[i],{clear:o,observe:a}=m(e,t),c=()=>{const n=u(t);return n&&!l()&&e(n)},l=()=>{o(),s?.removeEventListener("load",c)},h=()=>{a(r),"iframe"===s?.localName&&s.addEventListener("load",c)};return h(),{selector:t,clear:l,observe:h}})(n,t);const{clear:r,observe:o}=m(n,t);return o(),{selector:t,clear:r,observe:o}};function f(e,t){const n=e.parentElement||e.getRootNode().host;return t(e)||!n?e:f(n,t)}const y=t=>{e()||(t.preventDefault(),t.stopPropagation(),t.stopImmediatePropagation())},b=(e,t)=>[...g(t)].some(n=>{const[i,,s]=t.split("[]"),r=s??i;return n===e||!!e.closest(r)});let w=!1;class T{constructor(){this.targets=[],this.existingTargets=[],this.inViewportTargets=[],this.visibilityObserver=null,this.mutationObserver=null,this.mouseOverEvent=null,this.scrollEvent=null,this.onTransitionEnd=null,this.onIframeLoad=null}transitionOverHandler(e){const t=[e,"transitionend",this.checkElements.bind(this),!0];return this.getEvents(...t)}intersectionHandler(e){e.forEach(e=>{e.isIntersecting?(this.existingTargets.forEach(t=>{t.element.isSameNode(e.target)&&(this.inViewportTargets.push(t),this.mouseOverEvent.start(),this.scrollEvent.start(),this.onTransitionEnd.start())}),this.checkElements()):this.inViewportTargets=this.inViewportTargets.filter(t=>!t.element.isSameNode(e.target)||(this.mouseOverEvent.clear(),this.scrollEvent.clear(),this.onTransitionEnd.clear(),!1))})}startVisibilityObserver(e){const t={root:e,rootMargin:"0px",threshold:.01};return this.visibilityObserver??=new IntersectionObserver(this.intersectionHandler.bind(this),t),this.visibilityObserver}startMutationObserver(e){return this.mutationObserver??=new MutationObserver(this.checkElements.bind(this)),this.mutationObserver.observe(e,{attributes:!0,childList:!0,subtree:!0}),this.mutationObserver}onMouseOver({target:e,path:t}){const n=this.inViewportTargets.find(({element:n,selector:i})=>{if(n.isSameNode(e))return!0;const[s,,r]=i.split("[]"),o=r??s,a=[...e.querySelectorAll(o)];if(a.length&&a.includes(n))return!0;if(t.includes(n))return!0;if(!e.parentElement?.children?.length)return;const c=[...e.parentElement.children],l=c.findIndex(t=>t.isSameNode(e)),h=c.filter((e,t)=>t>l);if(h.length){if(h.includes(n))return!0;if(h.some(e=>[...e.querySelectorAll(o)].includes(n)))return!0}return!1});if(n&&this.isElementVisible(n.element)){const{selector:e,element:t,uniqueId:i}=n,s=this.targets.find(t=>t.selector===e&&t.uniqueId===i);s&&s.resolve(t),this.clear(e,i)}}getEvents(e,...t){return{start:()=>e?.addEventListener(...t),clear:()=>e?.removeEventListener(...t)}}mouseOverHandler(e){const t=[e,"ontouchstart"in window||navigator.maxTouchPoints>0||navigator.msMaxTouchPoints>0?"touchmove":"mouseover",e=>{const t=e.composedPath(),{target:n}=e;setTimeout(()=>this.onMouseOver({target:n,path:t}),50)},!0];return this.getEvents(...t)}scrollEventHandler(e){const t=[e,"scroll",(n=this.checkElements.bind(this),()=>{w||(w=!0,setTimeout(()=>{n(),w=!1},100))}),{passive:!0}];var n;return this.getEvents(...t)}isElementVisible(e){return this.isElementOpaque(e)&&this.isElementTopmost(e)}isElementOpaque(e){return"HTML"===f(e,e=>"0"===window.getComputedStyle(e).opacity).nodeName}isElementTopmost(e){const t=e.getBoundingClientRect(),n=[[t.left,t.top],[t.right,t.top],[t.left,t.bottom],[t.right,t.bottom],[t.left+t.width/2,t.top],[t.left+t.width/2,t.bottom],[t.left,t.height/2],[t.right,t.height/2],[t.left+t.left/2,t.height/2]];let i=!1,s=0;for(;!i&&s<n.length;){const t=e.getRootNode()?.elementFromPoint(...n[s]);i=e===t||t?.contains(e)||e.contains(t),s+=1}return i}checkElements(){this.targets.forEach(({selector:e,uniqueId:t})=>{const n=u(e),[i,,s]=e.split("[]"),r=s??i;n&&!this.existingTargets.find(e=>e.element.matches(r)&&e.uniqueId===t)&&(this.existingTargets.push({element:n,selector:e,uniqueId:t}),this.visibilityObserver.observe(n))}),this.existingTargets=this.existingTargets.filter(({selector:e,element:t})=>!(!u(e)||!t.isConnected)||(t&&this.visibilityObserver.unobserve(t),!1)),this.inViewportTargets=this.inViewportTargets.filter(({selector:e,element:t,uniqueId:n})=>{const[i,,s]=e.split("[]"),r=s??i;if(t.matches(r)&&this.isElementVisible(t)){const i=this.targets.find(t=>t.selector===e&&t.uniqueId===n);return i&&i.resolve(t),this.clear(e,n),!1}return!0})}onLoadIframe(e){const t=[e.defaultView.frameElement,"load",()=>this.watch(selector,resolve,uniqueId).bind(this),{passive:!0}];return this.getEvents(...t)}watch(e,t,n){this.targets.push({selector:e,resolve:t,uniqueId:n});const{clear:i}=v(e,e=>{i();const t=e.getRootNode({composed:!0}),n="body"in t?t.body:document;this.mouseOverEvent=this.mouseOverHandler(t),this.scrollEvent=this.scrollEventHandler(t),this.onTransitionEnd=this.transitionOverHandler(t),t.defaultView?.frameElement&&(this.onIframeLoad=this.onLoadIframe(t),this.onIframeLoad.start()),this.startVisibilityObserver(t),this.startMutationObserver(n),this.checkElements()})}clear(e,t){[this.targets,this.existingTargets,this.inViewportTargets]=[this.targets,this.existingTargets,this.inViewportTargets].map(n=>n.filter(({selector:n,uniqueId:i})=>n!==e&&i!==t));const n=u(e);n&&this.visibilityObserver?.unobserve(n),0===this.targets.length&&(this.mutationObserver?.disconnect(),this.onIframeLoad?.clear()),0===this.inViewportTargets.length&&(this.mouseOverEvent?.clear(),this.scrollEvent?.clear(),this.onTransitionEnd?.clear())}}const E="remove",C="rebuild",S="update",A="ABTastyData";class x{constructor({triggerEvent:e,triggerSelector:t,triggerDelay:n,triggerTarget:i}){this.event=e,this.selector=Boolean(t)?t:"body",this.target="string"==typeof i?u(t):i,this.delay=1e3*n,this.triggerElements=[],this.eventsListeners=[],this.timeouts=[],this.intervals=[],this.promises=[],this.visibilityObservers=[],this.socialProofStore={},this.elementWaiters=[]}async onElementVisible({promise:e,resolve:t}){const n=h(`${this.event}DomReady`);this.promises.push(n);const{clear:i}=v(this.selector,()=>{const e=new T;this.visibilityObservers.push(e),e.watch(this.selector,t,c())});return this.elementWaiters.push(i),e}onPageLoad({promise:e,resolve:t}){const n=()=>"complete"===document.readyState;if(!n()){const i=["readystatechange",()=>n()&&t(!0),{passive:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}return t(!0),e}onClick({promise:e,resolve:t}){const n=({isTrusted:e,target:n})=>{if(e)return(n.isEqualNode(this.target)||b(n,this.selector))&&t(!0)},{clear:i}=v(this.selector,e=>{i();const t=document.createElement("style");t.id=`Click_${c()}`;const[s,,r]=this.selector.split("[]"),o=r??s;t.innerHTML=`${o} {\n\t\t\t\tcursor: pointer !important;\n\t\t\t\tpointer-events: all !important;\n\t\t\t}`;const a=e.getRootNode();("head"in a?a.head:a).appendChild(t),this.triggerElements.push(t);const l=["click",n,{passive:!0,capture:!0}];this.eventsListeners.push([a,...l]),a.addEventListener(...l)});return this.elementWaiters.push(i),e}onHover({promise:e,resolve:t}){const n=({isTrusted:e,target:n})=>{if(e)return(this.target?n.isEqualNode(this.target):b(n,this.selector))&&t(!0)},{clear:i}=v(this.selector,e=>{const t=e.getRootNode(),i="body"in t?t.body:[...t.childNodes].find(t=>t.contains(e)),s=["mouseenter",n,{passive:!0,capture:!0}];this.eventsListeners.push([i,...s]),i.addEventListener(...s)});return this.elementWaiters.push(i),e}onExitIntent({promise:e,resolve:t}){const n=["mouseleave",({isTrusted:e,clientY:n})=>{e&&n<=0&&t(!0)},{passive:!0}],{clear:i}=v("html",e=>{i(),this.eventsListeners.push([e,...n]),e.addEventListener(...n)});return e}onReengage({promise:e,resolve:t}){const n=this.delay;let i=n;const s=[...document.querySelectorAll("*:empty")].map(e=>e.contentDocument||e.shadowRoot).filter(e=>e),r=[({isTrusted:e})=>{e&&(i=n)},{passive:!0}];["click","mousemove","scroll","keypress"].forEach(e=>{[document,...s].forEach(t=>{this.eventsListeners.push([t,e,...r]),t.addEventListener(e,...r)})});const o=setInterval(()=>{i<=0?t(!0):i-=100},100);return this.intervals.push(o),e}onCustomTrigger({promise:e,resolve:t}){const{triggerEventCustomScript:n}=DATA,i="undefined"!=typeof DATA_JS&&DATA_JS?.triggerEventCustomScript,s="function"==typeof i?()=>new Promise(e=>i(e)):new Function(`return new Promise(async resolve => {${n}})`);return s().then(e=>e&&t(!0)),e}onScrollUp({promise:e,resolve:t}){let n=0;const i=["scroll",({isTrusted:e})=>{e&&(window.scrollY<n?t(!0):n=window.scrollY)},{passive:!0,capture:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}onScrollPercentReached({promise:e,resolve:t}){const{triggerEventScrollPercent:n}=DATA,i=["scroll",({isTrusted:e})=>{if(!e)return;const i=(()=>{const{documentElement:e,body:t}=document,n=e.scrollTop||t.scrollTop,i=e.scrollHeight||t.scrollHeight;return Math.trunc(n/(i-e.clientHeight)*100,10)})();n<i&&t(!0)},{passive:!0,capture:!0}];return this.eventsListeners.push([document,...i]),document.addEventListener(...i),e}checkSocialProofConditions(e,t,n,i){const s=(()=>{let e;return window.ABTasty||window.ABTASTY_S?(window.ABTASTY_S?.USER?.accountIdentifier?.length?e=window.ABTASTY_S.USER.accountIdentifier:"function"==typeof window.ABTasty?.getAccountSettings?e=window.ABTasty.getAccountSettings().identifier:window.ABTasty?.accountSettings&&(e=window.ABTasty.accountSettings.identifier),e):e})(),{viewInterval:r,spNoTrim:o}=DATA;if(this.socialProofStore.hasOwnProperty(e))n(this.socialProofStore[e])?i(`${this.socialProofStore[e][r]}`):i(!1);else if(e&&s){const a=t=>(this.socialProofStore[e]=t,i(!!n(t)&&`${t[r]}`));fetch(`https://api-social-proof.abtasty.com/clients/${s}/metrics/${t}?key=${e}${o?"&noTrim=true":""}`).then(e=>e.ok&&e.json()).then(a).catch(()=>l("Failed to fetch datas from server."))}else i(!1)}getSocialProofDatas({promise:e,resolve:t},s,r=!1){const{productKey:o,keyType:a}=(()=>{const{socialProofContentType:e,productKeyProvider:t,pathToProductKey:s,customJSProductKey:r,productSKU:o}=DATA,{pathToProductKey:a,customJSProductKey:c}="undefined"!=typeof DATA_JS?DATA_JS:{};if(2===e)return{productKey:i(),keyType:"url"};{let l=null,h="sku";switch(t){case"ABTastyProductKey":l=window.ABTastyProductKey;break;case"pathToProductKey":l="function"==typeof a?a():n(`return ${s};`);break;case"customJSProductKey":l="function"==typeof c?c():n(r);break;case"productSKU":l=o}return l||3!==e||(l=i(),h="url"),{productKey:l,keyType:h}}})(),{viewInterval:c,triggerSocialProofMinVisitors:h,triggerSocialProofMinPurchases:d,triggerSocialProofMinPageViews:u}=DATA,g={pv:u,i:d,"v-pv":h}[s];return[typeof c,typeof g].includes("undefined")&&t(!1),r&&!o&&(l("Not able to find ABTastyProductKey, impossible to call the API, read documentation for more informations:\n\t\t\t\thttps://support.abtasty.com/hc/en-us/articles/4710919241628-Widgets-List#h_84c04344-c655-4e5e-b9ab-d26a798ad9b0"),t(!1)),this.checkSocialProofConditions(o,"v-pv"===s&&"sku"===a?"v-i":s,e=>{const t=void 0!==e[c]&&e[c]>=g;return t||l(`Widget will not be shown, Social Proof API returned ${e[c]} while ${g} are required`),t},t),e}onConsent({promise:e,resolve:t}){if(!r()){const n=["abtasty_consentValid",()=>t(!0)];return this.eventsListeners.push(n),window.addEventListener(...n),e}return t(!0),e}onTrackingSent({promise:e,resolve:t}){const{triggerEventTrackingSent:n}=DATA;let i=localStorage.getItem(A);const s=()=>JSON.parse(i)?.ActionTracking?.some(({name:e})=>e===n),r=["storage",({key:e,newValue:n})=>{e===A&&(i=n,s()&&t(!0))},{passive:!0,capture:!0}];return i&&s()?t(!0):(()=>{this.eventsListeners.push([window,...r]),window.addEventListener(...r)})(),e}onMinPagesViewed({promise:e,resolve:t}){const{triggerEventMinPagesViewed:n}=DATA;let i=localStorage.getItem(A);const s=()=>n<=(i?JSON.parse(i)?.VisitedPages?.length:0),r=["storage",({key:e,newValue:n})=>{e===A&&(i=n,s()&&t(!0))},{passive:!0,capture:!0}];return i&&s()?t(!0):(()=>{this.eventsListeners.push([window,...r]),window.addEventListener(...r)})(),e}onRageClick({promise:e,resolve:t}){const{triggerEventRageClickQuantity:n,triggerEventRageClickDelay:i}=DATA;let s=0,r=!1;const o=["click",({isTrusted:e})=>{if(e&&(s+=1,s>=n&&t(!0),!r)){r=!0;const e=setTimeout(()=>{s=0,r=!1},i);this.timeouts.push(e)}},{passive:!0,capture:!0}],a=e=>{this.eventsListeners.push([e,...o]),e.addEventListener(...o)},{clear:c}=v("iframe []contentDocument[] body > *",()=>{const e=document.getElementsByTagName("iframe");for(const t of e){"contentDocument"in t&&"body"in t.contentDocument&&a(t.contentDocument);const e=()=>a(t.contentDocument);t.addEventListener("load",e),this.eventsListeners.push([t,"onIframeLoad",e])}});return this.elementWaiters.push(c),a(document),e}clear(){this.triggerElements=this.triggerElements.filter(e=>(e.remove(),!1)),this.eventsListeners=this.eventsListeners.filter(e=>{const[t,...n]=e;return t&&n.length>1&&t.removeEventListener(...n),!1}),this.timeouts=this.timeouts.filter(e=>(clearTimeout(e),!1)),this.intervals=this.intervals.filter(e=>(clearInterval(e),!1));const e=c();return this.visibilityObservers=this.visibilityObservers.filter(t=>(t.clear(this.selector,e),!1)),this.promises=this.promises.filter(e=>(e.resolve(!1),!1)),this.elementWaiters=this.elementWaiters.filter(e=>(e(),!1)),this}async isTriggered(){this.clear();const e=h(this.event);this.promises.push(e);const t={consent:()=>this.onConsent(e),direct:()=>!0,pageLoad:()=>this.onPageLoad(e),click:()=>this.onClick(e),exitIntent:()=>this.onExitIntent(e),reengage:()=>this.onReengage(e),elementVisible:()=>this.onElementVisible(e),script:()=>this.onCustomTrigger(e),hover:()=>this.onHover(e),scrollUp:()=>this.onScrollUp(e),scrollPercent:()=>this.onScrollPercentReached(e),rageClick:()=>this.onRageClick(e),minPagesViewed:()=>this.onMinPagesViewed(e),trackingSent:()=>this.onTrackingSent(e),socialProofPurchases:()=>this.getSocialProofDatas(e,"i",!0),socialProofPageViews:()=>this.getSocialProofDatas(e,"pv"),socialProofVisitors:()=>this.getSocialProofDatas(e,"v-pv")},n=!Object.prototype.hasOwnProperty.call(t,this.event)||await t[this.event]();return n&&this.clear(),"reengage"!==this.event&&this.delay?n&&await(async()=>{const e=h(`${this.event}Delay`);this.promises.push(e);const t=setTimeout(()=>{e.resolve(!0),this.clear()},this.delay);return this.timeouts.push(t),e.promise})():n}}const k="display",P="closing",I="validation",N="ABTastyWidgets",L=`${N}Temporary`;class R{constructor({displayRecurrence:e,closingRecurrence:t,validationRecurrence:n},i){this.displayRecurrence=parseFloat(e),this.closingRecurrence=parseFloat(t),this.validationRecurrence=parseFloat(n),this.onSetCallback=i,this.widgetName=o(),this.uniqueId=c(),this.recurrenceKey=`${this.widgetName}_${this.uniqueId}`,this.isListeningStorageEvent=this.listenStorageEvent(),this.pendingRecurrence=!1,this.pendingRecurrenceValue={}}onStorage({key:e}){const t=localStorage.getItem(L),n=sessionStorage.getItem(N);"ABTastyData"===e&&!t&&n&&localStorage.setItem(L,n)}listenStorageEvent(){return this.isListeningStorageEvent||window.addEventListener("storage",this.onStorage.bind(this)),!0}getGivenRecurrenceStorageParsed(e){try{const t=e.getItem(N);return JSON.parse(t)}catch(t){return e.removeItem(N),!1}}getSessionRecurrenceStorageParsed(){return this.getGivenRecurrenceStorageParsed(window.sessionStorage)}getLocalRecurrenceStorageParsed(){return this.getGivenRecurrenceStorageParsed(window.localStorage)}removeGivenStorage(e,t){const{[this.recurrenceKey]:n,...i}=t;return Object.entries(i).length?(e.setItem(N,JSON.stringify(i)),i):(e.removeItem(N),!1)}removeSessionRecurrenceStorage(){const e=this.getSessionRecurrenceStorageParsed();return!!e&&this.removeGivenStorage(window.sessionStorage,e)}removeLocalRecurrenceStorage(){const e=this.getLocalRecurrenceStorageParsed();return!!e&&this.removeGivenStorage(window.localStorage,e)}getSessionRecurrence(){const e=this.getSessionRecurrenceStorageParsed();return!!e&&e[this.recurrenceKey]}getLocalRecurrence(){const e=this.getLocalRecurrenceStorageParsed();return!!e&&e[this.recurrenceKey]}getCurrentRecurrence(){if(this.pendingRecurrence)return this.pendingRecurrenceValue;const e=this.getSessionRecurrence(),t=this.getLocalRecurrence();return e||t||{type:!1}}isOver(){const e=localStorage.getItem(L),t=!(!e||!e.includes(this.recurrenceKey))||this.getSessionRecurrence();e&&(sessionStorage.setItem(N,e),localStorage.removeItem(L));const n=this.getLocalRecurrence(),i=(n?parseFloat(n.stamp):0)<(new Date).getTime();return i&&this.removeLocalRecurrenceStorage(),!this.pendingRecurrence&&i&&!this.getLocalRecurrence()&&!t}setRecurrence(e,n){0!==e&&(window.removeEventListener("storage",this.onStorage.bind(this)),this.isListeningStorageEvent=!1);const i=this.getTypeOfStorage(e);if(t()||!i&&"object"!=typeof i)return!1;const{storageString:s,storageMethod:o}=i,a=this.getStamp(e),c={type:n,stamp:a},{type:l}=this.getCurrentRecurrence(),h=async()=>{if(!r()){this.pendingRecurrence=!0,this.pendingRecurrenceValue=c;const e=new x({triggerEvent:"consent"});await e.isTriggered(),this.pendingRecurrence=!1,this.pendingRecurrenceValue={}}const e=this.getSessionRecurrence(),t=this.getLocalRecurrence();let n;"session"===s?e?n=this.removeSessionRecurrenceStorage():(this.removeLocalRecurrenceStorage(),n=this.getSessionRecurrenceStorageParsed()):"local"===s&&(t?n=this.removeLocalRecurrenceStorage():(this.removeSessionRecurrenceStorage(),n=this.getLocalRecurrenceStorageParsed()));const i=n?{[this.recurrenceKey]:c,...n}:{[this.recurrenceKey]:c};o.setItem(N,JSON.stringify(i)),this.onSetCallback&&"function"==typeof this.onSetCallback&&this.onSetCallback()};if(!o)return!1;if(l&&n!==I)if(n===P&&l!==I)h();else{if(n!==k||l===I||l===P)return!1;h()}else h();return a}setDisplayRecurrence(){const e=k;this.setRecurrence(this.displayRecurrence,e)}setClosingRecurrence(){const e=P;this.setRecurrence(this.closingRecurrence,e)}setValidationRecurrence(){const e=I;this.setRecurrence(this.validationRecurrence,e)}getStamp(e){return(new Date).getTime()+864e5*e}getTypeOfStorage(e){return!(isNaN(e)||e<0||0!==e&&!e)&&(e>0?{storageString:"local",storageMethod:window.localStorage}:0===e&&{storageString:"session",storageMethod:window.sessionStorage})}}class D{constructor(e,t,n){this.isWidgetApplied=e,this.callback=t,this.shouldUpdate=n,this.triggerIframeTarget=null,this.observer=new MutationObserver(this.observerHandler.bind(this)),this.tagRollbackEventParams=["abtasty_resetActionTracking",this.onTagRollback.bind(this)],this.onCampaignLaunchedEventParams=["abtasty_executedCampaign",this.onCampaignLaunched.bind(this)]}decisionHandler(e){const t=!e&&this.isWidgetApplied(),n=t?this.shouldUpdate&&S:C;return n?(this.clearWatcher(),this.callback(n,!e,t),this.watch(),this):this}onCampaignLaunched({detail:{campaignId:e}}){e===TEST_ID&&(this.callback(C,!1),this.watch())}onTagRollback({target:e}){return this.clearWatcher(e),this.callback(E,!1,!0),window.addEventListener(...this.onCampaignLaunchedEventParams),this}observerHandler(e){return s()?e.some(e=>["removedNodes","addedNodes"].some(t=>e[t]&&e[t].length))?this.decisionHandler():this:this.callback(E,!1)}watch(t,n){if(e())return this;if(this.clearWatcher(t),window.removeEventListener(...this.onCampaignLaunchedEventParams),document.addEventListener(...this.tagRollbackEventParams),n?.includes("[]contentDocument[]")){const e=n.split("[]")[0].trim(),{clear:t}=v(e,e=>{t(),this.triggerIframeTarget=e,e.addEventListener("load",this.decisionHandler.bind(this))})}const i=t?.defaultView?.frameElement;i&&this.triggerIframeTarget!==i&&i.addEventListener("load",this.decisionHandler.bind(this));const{clear:s}=v("body",e=>{s();const n=t?.body||t||e;this.observer.observe(n,{childList:!0,subtree:!0})});return this}clearTriggerElementWatcher(){this.triggerIframeTarget?.removeEventListener("load",this.decisionHandler.bind(this))}clearWatcher(e){return document.removeEventListener(...this.tagRollbackEventParams),this.observer.disconnect(),this.clearTriggerElementWatcher(),e?.defaultView?.frameElement?.removeEventListener("load",this.decisionHandler.bind(this)),this}}const B=/.+\/([^.]+)\.(otf|ttf)$/,O=["socialProofPurchases","socialProofPageViews","socialProofVisitors"];class _{constructor(t,n){this.children=void 0,this.uniqueId=`${c()}${n?`_${n}`:""}`,this.widgetName=o(),this.prettyName=a(),this.recurrenceParams=(()=>{const{displayRecurrence:t,closingRecurrence:n,validationRecurrence:i}=DATA,s=!t&&!n&&!i;if(e()||s)return!1;const r={everytime:()=>-1,session:()=>0,once:()=>395,day:e=>DATA[`${e}_day`],week:e=>7*DATA[`${e}_week`],month:e=>30.5*DATA[`${e}_month`]},o={};return t&&(o.displayRecurrence=r[t]("displayRecurrence")),n&&(o.closingRecurrence=r[n]("closingRecurrence")),i&&(o.validationRecurrence=r[i]("validationRecurrence")),o})(),this.triggerParams=(t=>{let{triggerEvent:n}=DATA;const{triggerEventClick:i,triggerEventHover:s,triggerEventReengageDelay:r,socialProofContentType:o,triggerEventElementVisible:a,triggerEventDelay:c}=DATA;if(e()||!n&&!o)return!1;const l={click:()=>i,hover:()=>s,elementVisible:()=>a},h=Object.prototype.hasOwnProperty.call(l,n)?l[n]():"body",d="reengage"===n?r:c;return o&&(n=[,"socialProofPurchases","socialProofPageViews","socialProofVisitors"][o]),{triggerEvent:n,triggerSelector:h,triggerDelay:d,triggerTarget:t}})(t),this.recurrence=!!this.recurrenceParams&&new R(this.recurrenceParams,this.clearGivenClearables.bind(this)),this.trigger=!!this.triggerParams&&new x(this.triggerParams),this.shouldUpdate=!!this.triggerParams&&O.includes(this.triggerParams.triggerEvent),this.pageWatcher=new D(this.isWidgetApplied.bind(this),this.onPageChange.bind(this)),this.hasOncePerPageTrigger=(()=>{const{isOncePerPageTrigger:e,triggerEvent:t}=DATA;return!t||!["click","hover","scrollUp","script"].includes(t)||e})(),this.basicClassName=`ab_widget_container_${this.widgetName}`,this.widgetContainerId=`${this.basicClassName}_${this.uniqueId}`,this.contentClassName=`${this.basicClassName}_content`,this.overlayClassName=`${this.basicClassName}_overlay`,this.closeButtonClassName=`${this.basicClassName}_close_button`,this.hideClassName=`ab_hide_${this.uniqueId}`,this.rootElement=null,this.domElement=this.getDom(),this.hasBeenShown=!1,this.closedByUser=!1,this.websiteFocusedElement=null,this.elementsWaiters=[]}clearGivenClearables(){for(const e of this.elementsWaiters)e.clear();this.elementsWaiters=[]}isWidgetApplied(){return this.domElement?.isConnected&&this.domElement.ownerDocument?.defaultView}removeOldDomElement(){const e=this.rootElement?.getElementById(this.widgetContainerId);return e?.remove(),this}async insert(){if(this.isWidgetApplied())return!1;const e=["free"];"drawer"===DATA.layout&&DATA.customTarget&&e.push("drawer");const t=e.includes(DATA.layout);return new Promise(e=>{const{elementReferrer:n="body",referrerInsertType:i="beforeend"}=t?DATA:{},s=v(n,t=>{this.elementsWaiters=this.elementsWaiters.filter(e=>e.selector!==n),this.rootElement=t.getRootNode(),this.removeOldDomElement(),this.domElement.appendChild(this.styleElement),e(t.insertAdjacentElement(i,this.domElement))});this.elementsWaiters.push(s)}).then(()=>this)}remove(){this.trigger&&this.trigger.clear(),this.pageWatcher.clearWatcher(this.rootElement);for(const e of this.elementsWaiters)[DATA.elementReferrer,"body"].includes(e.selector)&&e.clear();return this.domElement?.isConnected&&this.domElement.remove(),this.hasOncePerPageTrigger?this.pageWatcher.watch(this.rootElement):e()||this.init().then(({response:e})=>e?this.show():this),this}show(){const{layout:t,overlay:n=!0}=DATA;return e()||this.hasBeenShown&&this.hasOncePerPageTrigger||window.ABTastyEvent(`${this.prettyName} displayed`,null,TEST_ID),this.closedByUser=!1,this.websiteFocusedElement=document.activeElement,setTimeout(()=>{this.domElement.classList.remove(this.hideClassName),e()||"popin"!==t||!0!==n||this.domElement.querySelector('input[type="text"], textarea, a, button')?.focus()},50),this.recurrence&&this.recurrence.setDisplayRecurrence(),this.hasBeenShown=!0,this.pageWatcher.watch(this.rootElement),this}hide(t=!0){return!e()&&this.hasBeenShown&&t&&window.ABTastyEvent(`${this.prettyName} closed`,null,TEST_ID),t&&(this.pageWatcher.clearWatcher(this.rootElement),this.closedByUser=!0),this.domElement.classList.add(this.hideClassName),!e()&&this.websiteFocusedElement?.isConnected&&this.websiteFocusedElement.focus(),this}async init(t){const n=e(),i=s(),r=this.trigger?.promises?.length,o=!this.recurrence||this.recurrence.isOver();if(!n&&!i||r||!o)return{container:this,response:!1};this.pageWatcher.watch(this.rootElement||document,this.triggerParams.triggerSelector);const a=n||!this.trigger||this.trigger&&await this.trigger.isTriggered();this.pageWatcher.clearTriggerElementWatcher();const c={container:this,response:a};return a?(await this.insert(),this.addCloseEvent(),n||t||this.hasBeenShown||void 0===this.children||"function"!=typeof this.children.refreshContent||this.children.refreshContent(a),c):c}onPageChange(e,t,n){const i=()=>this.init().then(({response:e})=>{e?this.show():this.hide(!1)});t||(this.hasBeenShown=!1,n&&this.domElement.remove(),this.trigger&&this.trigger.clear());const s={[E]:()=>n?this.remove():this.pageWatcher.watch(this.rootElement),[C]:()=>{this.hasBeenShown?this.closedByUser?this.pageWatcher.watch(this.rootElement):n||this.insert().then(e=>e.show()).catch(this.pageWatcher.watch):i()},[S]:()=>{this.hasBeenShown?this.pageWatcher.watch():i()}};"function"==typeof s[e]&&s[e]()}addCloseEvent(...t){const{closeButton:n,overlay:i,overlayClickable:s,layout:r,animationDuration:o=1e3}=DATA,a=[];if(void 0!==i&&!0!==i||!0!==s||"popin"!==r||a.push(`.${this.overlayClassName}`),void 0!==n&&n&&a.push(`.${this.closeButtonClassName}`),!a.length)return this;const c=this.domElement.querySelectorAll(a.join(", "));if(!c.length)return this;const l=e=>{const t="click"===e.type,n="keyup"===e.type&&"Escape"===e.code&&e.isTrusted;(t||n)&&(y(e),this.recurrence&&this.recurrence.setClosingRecurrence(),this.hide(!0),setTimeout(()=>this.remove(),1.05*o))},h=["click",l,{once:!0,capture:!0}];t.push(...c);for(const n of t)e()&&(n.dataset.abtastyActionnable="true"),n.removeEventListener(...h),n.addEventListener(...h);return window.removeEventListener("keyup",l,{once:!0}),window.addEventListener("keyup",l,{once:!0}),this}getDom(){const{closeButton:e,layout:t,overlayClickable:n,overlay:i=!0}=DATA,s=document.createElement("div");return s.className=`${this.basicClassName} ${this.hideClassName}`,s.id=this.widgetContainerId,["popin","bannerTop","bannerBottom"].includes(t)&&(s.role="dialog","popin"===t&&!0===i&&(s.ariaModal="true")),s.innerHTML=`\n\t\t\t${"popin"===t&&!0===i?`<div ${n?'aria-label="Close dialog"':""} class="${this.overlayClassName}"></div>`:""}\n\t\t\t<div class="${this.contentClassName}">\n\t\t\t${e?`<button class="${this.closeButtonClassName}" aria-label="Close dialog"><svg viewBox="0 0 16 16">\n\t<defs><path id="prefix__a" d="M12 4.991L11.009 4 8 7.009 4.991 4 4 4.991 7.009 8 4 11.009 4.991 12 8 8.991 11.009 12 12 11.009 8.991 8z"></path></defs>\n\t<g><use xlink:href="#prefix__a"></use></g>\n</svg></button>`:""}\n\t\t\t</div>`,s}loadFont(e,t){if(!e||"inherit"===e||!/otf|ttf/g.test(t))return;const n=document.createElement("style"),i=t.match(B)?t.match(B)[1]:"";n.innerHTML=`@font-face { font-family: '${e}_${i}'; src: url('${t}'); font-display: swap; }`;const s=this.rootElement?.head||document.head;s?.appendChild(n)}getStyleTag(t="",n=DATA){const{noStyles:i,layout:s}=n,{backgroundColor:r,isBackgroundImage:o,backgroundImage:a,backgroundSize:c,backgroundPosition:l,backgroundRepeat:h,borderColor:d,borderRadius:u,borderWidth:g,textColor:m,textAlign:p,fontName:v,fontStyle:f,fontSize:y,isTitle:b,titleTextAlign:w,titleTextColor:T,titleFontName:E,titleFontStyle:C,titleFontSize:S,overlay:A,overlayColor:x,dropShadow:k,dropShadowColor:P,dropShadowBlur:I,containerMargin:N,containerPadding:L,closeButton:R,closeButtonPosition:D,closeButtonSize:O,closeButtonBorderRadius:_,closeButtonBorderWidth:V,closeButtonBorderColor:W,closeButtonColor:j,closeButtonBackgroundColor:H,buttonsAlign:q,buttonsBorderWidth:M,buttonsBorderColor:F,buttonsBorderRadius:z,buttonsBackgroundColor:K,buttonsTextColor:U,buttonsFontName:J,buttonsFontStyle:G,buttonsFontSize:Y,secondLink:Q,secondLinkBorderWidth:X,secondLinkBorderColor:Z,secondLinkBorderRadius:ee,secondLinkBackgroundColor:te,secondLinkTextColor:ne,secondLinkFontName:ie,secondLinkFontStyle:se,secondLinkFontSize:re,animation:oe,animationDuration:ae,animationBehaviour:ce,animationSlideDirection:le}=i?{}:n,he=document.createElement("style");e()&&he.setAttribute("abtasty-script-added","true"),this.loadFont(v,f),this.loadFont(E,C),this.loadFont(J,G),this.loadFont(ie,se);const de=`background: ${["string"==typeof r?r:"rgba(255, 255, 255, 1)",o&&"string"==typeof a&&a.length?`url(${a})`:"",o&&"string"==typeof l&&"100% 100%"!==c?l:"0 0",o&&"string"==typeof c?`/ ${c}`:"/ auto",o&&h&&!["cover","100% 100%"].includes(c)?"repeat":"no-repeat"].join(" ").trim()};`,ue="number"==typeof g&&g>0,ge=`border: ${[ue?`${g}px`:"unset",ue?"solid":"",ue&&"string"==typeof d&&d.length?d:""].join(" ").trim()};`,me=void 0!==u?`border-radius: ${u}px;`:"",pe=void 0!==m?`color: ${m}; fill: ${m}; -webkit-text-fill-color: ${m};`:"",ve=void 0!==p?`text-align: ${p};`:"",fe=v&&"inherit"!==v?`font-family:${v}_${f.match(B)?f.match(B)[1]:""};`:f||"",ye=y?`font-size: ${y}px;`:"",be=void 0!==k&&k?`box-shadow: 0 5px ${I}px 0 ${P};`:"",we=N instanceof Array&&1===N.length&&N[0],$e=we?`margin: ${we.top}px ${we.right}px ${we.bottom}px ${we.left}px;`:"",Te=we?`margin: calc(${we.top}px * 0.5) calc(${we.right}px * 0.5) calc(${we.bottom}px * 0.5) calc(${we.left}px * 0.5);`:"",Ee=L instanceof Array&&1===L.length&&L[0],Ce=Ee?`padding: ${Ee.top}px ${Ee.right}px ${Ee.bottom}px ${Ee.left}px;`:"",Se=Ee?`padding: calc(${Ee.top}px * 0.5) calc(${Ee.right}px * 0.5) calc(${Ee.bottom}px * 0.5) calc(${Ee.left}px * 0.5);`:"",Ae=void 0!==M&&M?`border-width: ${M}px; border-style: solid;`:"",xe=[F,M].every(e=>void 0!==e)&&M?`border-color: ${F};`:"",ke=void 0!==z?`border-radius: ${z}px;`:"",Pe=void 0!==K?`background-color: ${K};`:"",Ie=void 0!==U?`color: ${U}; fill: ${U}; -webkit-text-fill-color: ${U};`:"",Ne=J&&"inherit"!==J?`font-family:${J}_${G.match(B)?G.match(B)[1]:""};`:G||"",Le=Y?`font-size: ${Y}px;`:"",Re="number"==typeof X?`border-width: ${X}px; border-style: solid;`:"",De=[Z,X].every(e=>void 0!==e)&&X?`border-color: ${Z};`:"",Be=void 0!==ee?`border-radius: ${ee}px;`:"",Oe=void 0!==te?`background-color: ${te};`:"",_e=void 0!==ne?`color: ${ne}; fill: ${ne}; -webkit-text-fill-color: ${ne};`:"",Ve=ie&&"inherit"!==ie?`font-family:${ie}_${se.match(B)?se.match(B)[1]:""};`:se||"",We=re?`font-size: ${re}px;`:"",je="popin"!==s||void 0!==A&&!0!==A?"":[`#${this.widgetContainerId} .${this.overlayClassName} {`,`background-color: ${void 0!==x?x:"rgba(0, 0, 0, 0.6)"};`,"}"].join(""),He="number"==typeof O?O:16,qe=He/2,Me=i||void 0!==R&&R?[`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} {`,"position: absolute;",("out"===D?`bottom: calc(100% + ${qe}px)`:`top: ${qe}px`)+";",`right: ${qe}px;`,"width: auto;","height: auto;","background: none;","border: none;","cursor: pointer;","padding: 0;","margin: 0;","line-height: 0;","z-index: 9;","number"==typeof _?`border-radius: ${_}px;`:"","number"==typeof V&&V>0?`border: ${V}px solid ${void 0!==W?W:"rgba(57, 57, 57, 1)"};`:"","string"==typeof H?`background-color: ${H};`:"","}",`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} svg {`,"pointer-events: none;",`width: ${He}px;`,`height: ${He}px;`,"string"==typeof j?`fill: ${j};`:"","}"].join(""):"",Fe=b&&"string"==typeof T?[`#${this.widgetContainerId} .${this.contentClassName} > * h1, `,`#${this.widgetContainerId} .${this.contentClassName} > * h2, `,`#${this.widgetContainerId} .${this.contentClassName} > * h3, `,`#${this.widgetContainerId} .${this.contentClassName} > * h4, `,`#${this.widgetContainerId} .${this.contentClassName} > * h5, `,`#${this.widgetContainerId} .${this.contentClassName} > * h6 {`,`color: ${T}; fill: ${T}; -webkit-text-fill-color: ${T};`,void 0!==w?`text-align: ${w};`:"",E&&"inherit"!==E?`font-family:${E}_${C.match(B)?C.match(B)[1]:""};`:C||"",S?`font-size: ${S}px;`:"","}"].join(""):"";let ze="";if("string"==typeof oe){const t=(ae/1e3).toFixed(2),n=["top","bottom"].includes(le),i=Number(n),s=[(["top","left"].includes(le)?"-":"")+"100vmax",this.translateValues?this.translateValues[i]:"0"];n&&s.reverse(),ze={none:[`.${this.hideClassName} {`,"opacity: 0 !important;","}"],fade:[`.${this.hideClassName} {`,"opacity: 0 !important;","}",`#${this.widgetContainerId} {`,`transition: opacity ${t}s ${ce};`,"}","@media (prefers-reduced-motion: reduce) {",`#${this.widgetContainerId} {`,"transition: unset;","}","}"],slide:[`.${this.hideClassName} .${this.overlayClassName} {`,"opacity: 0 !important;","}",`#${this.widgetContainerId} .${this.overlayClassName} {`,`transition: opacity ${t}s ${ce};`,"}",`.${this.hideClassName} .${this.contentClassName} {`,`transform: translate(${s.join(", ")}) !important;`,"}",`#${this.widgetContainerId} .${this.contentClassName} {`,`transition: transform ${t}s ${ce};`,"}","@media (prefers-reduced-motion: reduce) {",`#${this.widgetContainerId} .${this.overlayClassName},`,`.${this.hideClassName} .${this.contentClassName},`,`#${this.widgetContainerId} .${this.contentClassName} {`,"transition: unset;","}","}"]}[e()&&!ABTASTY_S.WIDGETS.animationChanged?"none":oe].join("")}const Ke=[`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,`margin-${"fill"===q?"top":"left"}: 8px;`,Re,De,Be,Oe,_e,Ve,We,"}",`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,_e,Ve,We,"}"];return he.textContent=[`#${this.widgetContainerId} style { display: none; }`,`.${this.hideClassName} {`,"pointer-events: none;","}",`#${this.widgetContainerId} {`,"opacity: 1;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,de,me,ge,pe,ve,be,$e,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} p {`,pe,ve,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} > * {`,"display: block;","line-height: 1;","text-indent: unset;",Ce,fe,ye,"}",`#${this.widgetContainerId} .${this.contentClassName} a {`,"text-decoration: underline;","}",`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a, `,`#${this.widgetContainerId} .${this.contentClassName} button {`,"text-decoration: none;","box-sizing: border-box;","display: inline-block;",Ae,xe,ke,Pe,Ie,Ne,Le,"}",`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a *:not(.second_link span), `,`#${this.widgetContainerId} .${this.contentClassName} button:not([class*="close_button"], [class*="csatEmojiButton"]) * {`,Ie,Ne,Le,"}",...Q?Ke:[],"@media screen and (max-width: 579px) {",`#${this.widgetContainerId} .${this.contentClassName} {`,Te,"}",`#${this.widgetContainerId} .${this.contentClassName} > * {`,Se,"}","}",je,Me,Fe,ze,`${t}`].join(""),he}}const V=["top: 0;","top: 50%;","bottom: 0;"],W=["left: 0;","left: 50%;","right: 0;"],j=e=>1===e?"-50%":0,H=()=>{if(Array.isArray(DATA.popinPosition)){const{popinPosition:[{x:e,y:t}]}=DATA,n=`translate(${j(t)}, ${j(e)});`;return`${V[e]}${W[t]}transform: ${n}`}return"left: 50%;top: 50%;transform: translate(-50%, -50%);"},q=()=>"autoWidth"in DATA&&!0===DATA.autoWidth,M=()=>{if(q())return"width: auto; height: auto; min-width: fit-content;";const{popinPercentWidth:e,popinPixelsWidth:t,widthUnit:n,autoHeight:i,popinPercentHeight:s,popinPixelsHeight:r,heightUnit:o}=DATA;return`width: ${"px"===n?t:e}${n};height: ${i?"auto":`${"px"===o?r:s}${o}`};`};class F extends _{constructor(){super(),this.translateValues=Object.values(DATA.popinPosition[0]).map(e=>j(e)),this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){const{zindex:e,zindexCustom:t,widthUnit:n}=DATA,i="string"!=typeof DATA.overlay&&DATA.overlay;return[`#${this.widgetContainerId} {`,"position: fixed;","top: 0;","left: 0;","width: 100%;","height: 100%;",`z-index: ${"custom"===e?t:e};`,"background: none;","pointer-events: "+(i?"all":"none"),"}",`#${this.widgetContainerId} .${this.overlayClassName} {`,"position: absolute;","z-index: -1;","top: 0;","left: 0;","width: 100%;","height: 100%;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: absolute;",H(),M(),"pointer-events: all","}",`${q()?"":[`#${this.widgetContainerId} .${this.contentClassName} > div {`,"height: 100%;","overflow: auto;","box-sizing: border-box;","}"].join("")}`,`${!q()&&["px","em"].includes(n)?["@media screen and (max-width: 579px) {",`#${this.widgetContainerId} .${this.contentClassName} {`,"max-width: 94vw;","}","}"].join(""):""}`].join("")}}class z extends _{constructor(){super(),this.position="string"==typeof DATA.layout&&"bannerTop"===DATA.layout?"top":"bottom",this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){const{zindex:e,zindexCustom:t}=DATA;return[`#${this.widgetContainerId} {`,"position: fixed;",`${this.position}: 0;`,"left: 0;","width: 100%;","height: auto;",`z-index: ${"custom"===e?t:e};`,"background: none;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: relative;","}"].join("")}}class K extends _{constructor(e,t){super(e,t),this.stringStyles=this.getStyles(),this.styleElement=this.getStyleTag(this.stringStyles)}getStyles(){return[`#${this.widgetContainerId} {`,"width: auto;","height: auto;","margin: 0;","padding: 0;","background: none;","}",`#${this.widgetContainerId} .${this.contentClassName} {`,"position: relative;","}"].join("")}}function U(e){return U="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},U(e)}function J(e,t){for(var n=0;n<t.length;n++){var i=t[n];i.enumerable=i.enumerable||!1,i.configurable=!0,"value"in i&&(i.writable=!0),Object.defineProperty(e,G(i.key),i)}}function G(e){var t=function(e){if("object"!=U(e)||!e)return e;var t=e[Symbol.toPrimitive];if(void 0!==t){var n=t.call(e,"string");if("object"!=U(n))return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e);return"symbol"==U(t)?t:t+""}var Y=function(){function t(e){var n=e.parentContainer;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,t),this.parentContainer=n,this.baseClassName="qualitywidget_container",this.className="".concat(this.baseClassName,"_").concat(n.uniqueId),this.contentElement=this.getContentElement()}return n=t,s=[{key:"getVariableText",value:function(){var e=DATA,t=e.textVariables,n=e.date,i=e.time,s=e.datetime,r=e.datetimeTimezone,o=new Date(n),a=new Date(s),c="".concat(o.getDate()),l="".concat(o.getMonth()+1),h="".concat(o.getFullYear()),d="".concat(a.getHours()),u="".concat(a.getMinutes()),g="".concat(a.getDate()),m="".concat(a.getMonth()+1),p="".concat(a.getFullYear()),v="".concat(c.length<2?"0".concat(c):c,"/").concat(l.length<2?"0".concat(l):l,"/").concat(h),f="".concat(d.length<2?"0".concat(d):d,":").concat(u.length<2?"0".concat(u):u),y="".concat(g.length<2?"0".concat(g):g,"/").concat(m.length<2?"0".concat(m):m,"/").concat(p),b=r.raw,w=b.followTheSun,T=b.timezone,E=b.previewTimezone,C=b.timedef,S=C.minute,A=C.hour,x=C.day,k=C.month,P=C.year,I="".concat("".concat(A).length<2?"0".concat(A):A,":").concat("".concat(S).length<2?"0".concat(S):S),N="".concat("".concat(x).length<2?"0".concat(x):x,"/").concat("".concat(k).length<2?"0".concat(k):k,"/").concat(P);return t.replace("!time!",'<code class="time">'.concat(JSON.stringify(i,null,0),"</code>")).replace("!date!",'<span class="date">'.concat(v,"</span>")).replace("!timedate!",'<span class="timedate">'.concat(f,"</span>")).replace("!datetime!",'<span class="datetime">'.concat(y,"</span>")).replace("!timeTimezone!",'<span class="timeTimezone">'.concat(I,"</span>")).replace("!dateTimezone!",'<span class="dateTimezone">'.concat(N,"</span>")).replace("!timezone!",'<span class="timezone">'.concat(w?E:T,"</span>"))}}],(i=[{key:"insertIn",value:function(e,t){return this.setStyles(),e.insertAdjacentElement(t,this.contentElement),this}},{key:"addCloseEvent",value:function(t){var n=this;t&&t.addEventListener("click",function(t){y(t),e()||n.parentContainer.recurrence.setClosingRecurrence(),n.parentContainer.hide(),setTimeout(function(){return n.parentContainer.remove()},1e3)},{capture:!0,passive:!1})}},{key:"addRedirectionEvent",value:function(t){var n=this;!e()&&t&&t.addEventListener("click",function(){var t=DATA,i=t.autoHide,s=t.timeHide;i&&setTimeout(function(){return n.parentContainer.hide()},1e3*s),e()||n.parentContainer.recurrence.setValidationRecurrence()},{capture:!0,passive:!0})}},{key:"getButton",value:function(){var e=DATA,t=e.linkType,n=e.buttonText,i=e.redirectionUrl,s=e.openInNewTab,r=document.createElement("a");return r.ariaLabel=n,r.className="popin_link",r.innerHTML="<span>".concat(n,"</span>"),"button"===t?(r.href=i,r.target=s?"_blank":"_self",this.addRedirectionEvent(r)):(r.href="#",r.dataset.abtastyActionnable="true",this.addCloseEvent(r)),r}},{key:"getContentElement",value:function(){var e=DATA,n=e.isTitle,i=e.isText,s=e.linkType,r=e.buttonText,o=e.iconPicker,a="string"==typeof s&&s.includes("widget")?"a":"div",c=document.createElement(a);if(c.className=this.className,""!==(null==o?void 0:o.src)){var l=document.createElement("img");l.setAttribute("src",o.src),l.setAttribute("alt",o.alt),l.classList.add("iconPicker"),c.appendChild(l)}if("widget"===s){var h=DATA,d=h.redirectionUrl,u=h.openInNewTab;c.href=d,c.target=u?"_blank":"_self",this.addRedirectionEvent(c)}else"widgetClose"===s&&(c.href="#",c.dataset.abtastyActionnable="true",this.addCloseEvent(c));if(n){var g=DATA.title,m=document.createElement("h4");m.textContent=g,c.appendChild(m)}if(i){var p=DATA,v=p.text,f=p.includeVariables,y=document.createElement("p"),b=f?t.getVariableText():v;y.innerHTML=b,c.appendChild(y)}if([s,r].every(function(e){return"string"==typeof e})&&s.includes("button")&&r.length){var w=this.getButton(),T=document.createElement("div");T.className="buttons_container",T.appendChild(w),c.appendChild(T)}return c}},{key:"setStyles",value:function(){var e=this.parentContainer,t=e.styleElement,n=e.widgetContainerId,i=DATA,s=i.textColor,r=i.textAlign,o=i.buttonsAlign,a="#".concat(n," .").concat(this.className),c=void 0!==s?"color: ".concat(s,";"):"",l=void 0!==r?"text-align: ".concat(r,";"):"",h=void 0!==o&&"fill"!==o?"text-align: ".concat(o,";"):"",d=["".concat(a," > * {"),"display: inline-block;","vertical-align: middle;","}","".concat(a," .iconPicker {"),"width: 26px;","height: 26px;","}","".concat(a," h4 {"),"margin-bottom: 24px;","display: inline-block;","width: 100%","}","".concat(a," p {"),"width: 100%;","margin: 0;","white-space: pre-line;",c,l,"}","".concat(a," .buttons_container {"),"display: inline-block;","width: 100%;",h,"}","".concat(a," a {"),"margin-top: 24px;","padding: 6px 16px;","width: ".concat("fill"===o?"100%":"auto",";"),"}","@media screen and (min-width: 1024px) {","}","@media screen and (max-width: 1023px) {","}"].join("");return t.insertAdjacentText("beforeend",d),t}}])&&J(n.prototype,i),s&&J(n,s),Object.defineProperty(n,"prototype",{writable:!1}),n;var n,i,s}();!function(){l("Widget launch");var e=(()=>{const{layout:e}=DATA;let t;switch(e){case"popin":t=new F;break;case"bannerTop":case"bannerBottom":t=new z;break;case"free":t=new K;break;default:t=new _}return t})(),t=e.domElement.querySelector(".".concat(e.contentClassName)),n=new Y({parentContainer:e});e.children=n,n.insertIn(t,"beforeend"),e.init(!0).then(function(t){t.response&&e.show()})}()}();
|
|
1
|
+
(function () {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const getAccountIdentifier = () => {
|
|
5
|
+
let identifier;
|
|
6
|
+
if (!window.ABTasty && !window.ABTASTY_S) return identifier;
|
|
7
|
+
|
|
8
|
+
if (
|
|
9
|
+
window.ABTASTY_S?.USER?.accountIdentifier?.length
|
|
10
|
+
) {
|
|
11
|
+
identifier = window.ABTASTY_S.USER.accountIdentifier;
|
|
12
|
+
} else if (
|
|
13
|
+
typeof window.ABTasty?.getAccountSettings === 'function'
|
|
14
|
+
) {
|
|
15
|
+
identifier = window.ABTasty.getAccountSettings().identifier;
|
|
16
|
+
} else if (window.ABTasty?.accountSettings) {
|
|
17
|
+
identifier = window.ABTasty.accountSettings.identifier;
|
|
18
|
+
}
|
|
19
|
+
return identifier;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const isOnEditor = () => Object.prototype.hasOwnProperty.call(top, 'ABTastyEditor');
|
|
23
|
+
|
|
24
|
+
const isOnPreview = () => {
|
|
25
|
+
const previewBarExist = !!document.getElementById('ABTastyPreviewBar');
|
|
26
|
+
const urlContainsPreview = location.href.includes('ab_project=preview');
|
|
27
|
+
return previewBarExist || urlContainsPreview;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const getCustomSKU = (code) => {
|
|
31
|
+
return new Function(`try {
|
|
32
|
+
${code}
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return null;
|
|
35
|
+
}`)();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
const getSKUWithPath = (path) => getCustomSKU(`return ${path};`);
|
|
39
|
+
|
|
40
|
+
const getSKUWithCustomJS = (code) => getCustomSKU(code);
|
|
41
|
+
|
|
42
|
+
const getEncodedUrl = () => encodeURIComponent(
|
|
43
|
+
DATA.spNoTrim
|
|
44
|
+
? window.location.href.replace(window.location.origin, "")
|
|
45
|
+
: `${window.location.pathname}`
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
const getProductKey = () => {
|
|
49
|
+
const {
|
|
50
|
+
socialProofContentType,
|
|
51
|
+
productKeyProvider,
|
|
52
|
+
pathToProductKey,
|
|
53
|
+
customJSProductKey,
|
|
54
|
+
productSKU,
|
|
55
|
+
} = DATA;
|
|
56
|
+
|
|
57
|
+
const {
|
|
58
|
+
pathToProductKey: pathToProductKeyFunction,
|
|
59
|
+
customJSProductKey: customJSProductKeyFunction,
|
|
60
|
+
} = typeof DATA_JS !== 'undefined' ? DATA_JS : {};
|
|
61
|
+
|
|
62
|
+
if (socialProofContentType === 2) {
|
|
63
|
+
return {
|
|
64
|
+
productKey: getEncodedUrl(),
|
|
65
|
+
keyType: 'url',
|
|
66
|
+
};
|
|
67
|
+
} else {
|
|
68
|
+
let productKey = null;
|
|
69
|
+
let keyType = 'sku';
|
|
70
|
+
switch (productKeyProvider) {
|
|
71
|
+
case "ABTastyProductKey":
|
|
72
|
+
productKey = window.ABTastyProductKey;
|
|
73
|
+
break;
|
|
74
|
+
case "pathToProductKey":
|
|
75
|
+
productKey = typeof pathToProductKeyFunction === 'function'
|
|
76
|
+
? pathToProductKeyFunction()
|
|
77
|
+
: getSKUWithPath(pathToProductKey);
|
|
78
|
+
break;
|
|
79
|
+
case "customJSProductKey":
|
|
80
|
+
productKey =
|
|
81
|
+
typeof customJSProductKeyFunction === 'function'
|
|
82
|
+
? customJSProductKeyFunction()
|
|
83
|
+
: getSKUWithCustomJS(customJSProductKey);
|
|
84
|
+
break;
|
|
85
|
+
case "productSKU":
|
|
86
|
+
productKey = productSKU;
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
if (!productKey && socialProofContentType === 3) {
|
|
90
|
+
productKey = getEncodedUrl();
|
|
91
|
+
keyType = 'url';
|
|
92
|
+
}
|
|
93
|
+
return { productKey, keyType };
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
const isAffected = () => !isOnEditor() && (isOnPreview() || !!window.ABTasty.getTestsOnPage()[TEST_ID]);
|
|
98
|
+
|
|
99
|
+
const isInQaMode = () => {
|
|
100
|
+
if (isOnEditor() || isOnPreview()) return false;
|
|
101
|
+
const campaign = ABTasty.getTestsOnPage()[TEST_ID];
|
|
102
|
+
if (campaign) return Object.keys(campaign.targetings.qaParameters).length > 0;
|
|
103
|
+
return false;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const isConsentReady = () => window.ABTasty && window.ABTasty.consentReady === true;
|
|
107
|
+
|
|
108
|
+
const getWidgetName = () => {
|
|
109
|
+
const { type } = DATA;
|
|
110
|
+
return `${PACKAGE.replace('@abtasty/', '')}${type ? `_${type}` : ''}`;
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
const getPrettyWidgetName = () => {
|
|
114
|
+
const name = getWidgetName();
|
|
115
|
+
const prettyName = `${name.charAt(0).toUpperCase()}${name.slice(1)}`;
|
|
116
|
+
return prettyName.split('-').join(' ');
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const getUniqueId = () => `${PLUGIN_ID.split('-')[0]}_${TEST_ID}`;
|
|
120
|
+
|
|
121
|
+
const getRecurrenceParams = () => {
|
|
122
|
+
const { displayRecurrence, closingRecurrence, validationRecurrence } = DATA;
|
|
123
|
+
const noRecurrence = !displayRecurrence && !closingRecurrence && !validationRecurrence;
|
|
124
|
+
|
|
125
|
+
if (isOnEditor() || noRecurrence) return false;
|
|
126
|
+
|
|
127
|
+
const recurrenceGetters = {
|
|
128
|
+
everytime: () => -1,
|
|
129
|
+
session: () => 0,
|
|
130
|
+
once: () => 395,
|
|
131
|
+
day: (key) => DATA[`${key}_day`],
|
|
132
|
+
week: (key) => (DATA[`${key}_week`] * 7),
|
|
133
|
+
month: (key) => (DATA[`${key}_month`] * 30.5),
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const recurrenceParams = {};
|
|
137
|
+
|
|
138
|
+
if (displayRecurrence) recurrenceParams.displayRecurrence = recurrenceGetters[displayRecurrence]('displayRecurrence');
|
|
139
|
+
|
|
140
|
+
if (closingRecurrence) recurrenceParams.closingRecurrence = recurrenceGetters[closingRecurrence]('closingRecurrence');
|
|
141
|
+
|
|
142
|
+
if (validationRecurrence) recurrenceParams.validationRecurrence = recurrenceGetters[validationRecurrence]('validationRecurrence');
|
|
143
|
+
|
|
144
|
+
return recurrenceParams;
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
const getTriggerParams = (target) => {
|
|
148
|
+
let { triggerEvent } = DATA;
|
|
149
|
+
|
|
150
|
+
const {
|
|
151
|
+
triggerEventClick,
|
|
152
|
+
triggerEventHover,
|
|
153
|
+
triggerEventReengageDelay,
|
|
154
|
+
socialProofContentType,
|
|
155
|
+
triggerEventElementVisible,
|
|
156
|
+
triggerEventDelay,
|
|
157
|
+
} = DATA;
|
|
158
|
+
|
|
159
|
+
if (isOnEditor() || (!triggerEvent && !socialProofContentType)) return false;
|
|
160
|
+
|
|
161
|
+
const triggerSelectorGetters = {
|
|
162
|
+
click: () => triggerEventClick,
|
|
163
|
+
hover: () => triggerEventHover,
|
|
164
|
+
elementVisible: () => triggerEventElementVisible,
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
const triggerSelector = Object.prototype.hasOwnProperty.call(triggerSelectorGetters, triggerEvent)
|
|
168
|
+
? triggerSelectorGetters[triggerEvent]()
|
|
169
|
+
: 'body';
|
|
170
|
+
|
|
171
|
+
const triggerDelay = triggerEvent === 'reengage' ? triggerEventReengageDelay : triggerEventDelay;
|
|
172
|
+
|
|
173
|
+
if (socialProofContentType) {
|
|
174
|
+
triggerEvent = [, 'socialProofPurchases', 'socialProofPageViews', 'socialProofVisitors'][socialProofContentType];
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const triggerParams = { triggerEvent, triggerSelector, triggerDelay, triggerTarget: target };
|
|
178
|
+
return triggerParams;
|
|
179
|
+
};
|
|
180
|
+
|
|
181
|
+
const isTriggerOncePerPage = () => {
|
|
182
|
+
const { isOncePerPageTrigger, triggerEvent } = DATA;
|
|
183
|
+
|
|
184
|
+
if (!triggerEvent) return true;
|
|
185
|
+
|
|
186
|
+
const canBeTriggeredMoreThanOnce = ['click', 'hover', 'scrollUp', 'script'].includes(triggerEvent);
|
|
187
|
+
return canBeTriggeredMoreThanOnce ? isOncePerPageTrigger : true;
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
const isInDebugMode = () => window.document.cookie.includes('abTastyDebug=') || window.abTastyDebug === true;
|
|
191
|
+
|
|
192
|
+
const widgetLog = message => {
|
|
193
|
+
const inQaMode = isInQaMode();
|
|
194
|
+
const inDebugMode = isInDebugMode();
|
|
195
|
+
if (inQaMode || inDebugMode) {
|
|
196
|
+
const widgetName = getPrettyWidgetName();
|
|
197
|
+
window.console.log(
|
|
198
|
+
`%c${widgetName} - ${inQaMode ? 'QA' : 'Debug'} Mode for campaign ${TEST_ID} %c ${message}`,
|
|
199
|
+
`background-color: #D6FF01; color: #3100be; padding: 3px 0 3px 10px; border-radius: 5px 0 0 5px; font-weight: bold;`,
|
|
200
|
+
`background-color: #3100be; color: white; padding: 3px 10px 3px 0; border-radius: 0 5px 5px 0;`
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
const promiseDeferrer = name => {
|
|
206
|
+
const deferred = {
|
|
207
|
+
promise: null,
|
|
208
|
+
resolve: null,
|
|
209
|
+
reject: null,
|
|
210
|
+
name
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
deferred.promise = new Promise((resolve, reject) => {
|
|
214
|
+
deferred.resolve = resolve;
|
|
215
|
+
deferred.reject = reject;
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
return deferred;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
*
|
|
223
|
+
* @param {string} selector
|
|
224
|
+
* @param {boolean} all
|
|
225
|
+
* @returns {null | Element | NodeListOf<Element> | Element[]}
|
|
226
|
+
*/
|
|
227
|
+
const getElementBySelector = (selector, all) => {
|
|
228
|
+
const defaultReturn = all ? [] : null;
|
|
229
|
+
if (typeof selector !== 'string' || !selector.trim().length)
|
|
230
|
+
return defaultReturn;
|
|
231
|
+
|
|
232
|
+
const [outerSelector, accessMethod, innerSelector] = selector.split('[]').map(s => s.trim());
|
|
233
|
+
const contextSelector = Boolean(innerSelector) ? innerSelector : selector;
|
|
234
|
+
|
|
235
|
+
const rootElement = accessMethod
|
|
236
|
+
? document.querySelector(outerSelector)?.[accessMethod]
|
|
237
|
+
: document;
|
|
238
|
+
|
|
239
|
+
if (!rootElement) return defaultReturn;
|
|
240
|
+
|
|
241
|
+
return all
|
|
242
|
+
? [...rootElement.querySelectorAll(contextSelector)]
|
|
243
|
+
: rootElement.querySelector(contextSelector);
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
*
|
|
248
|
+
* @param {string} selector
|
|
249
|
+
* @returns {Element | null}
|
|
250
|
+
*/
|
|
251
|
+
const getElement = (selector) => getElementBySelector(selector, false);
|
|
252
|
+
/**
|
|
253
|
+
*
|
|
254
|
+
* @param {string} selector
|
|
255
|
+
* @returns {Element[]}
|
|
256
|
+
*/
|
|
257
|
+
const getElements = (selector) => getElementBySelector(selector, true);
|
|
258
|
+
|
|
259
|
+
const observers = {};
|
|
260
|
+
|
|
261
|
+
const setObserver = (callback, selector) => {
|
|
262
|
+
const observerParams = {
|
|
263
|
+
childList: true,
|
|
264
|
+
subtree: true,
|
|
265
|
+
attributes: true,
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
const clear = () => observer.disconnect();
|
|
269
|
+
const observe = (target) => {
|
|
270
|
+
const defaultObserverTarget = document.querySelector('body') || document.documentElement;
|
|
271
|
+
const currentTarget = target ?? defaultObserverTarget;
|
|
272
|
+
observer.observe(currentTarget, observerParams);
|
|
273
|
+
};
|
|
274
|
+
const observerCallback = () => {
|
|
275
|
+
const element = getElement(selector);
|
|
276
|
+
return element && !clear() && callback(element);
|
|
277
|
+
};
|
|
278
|
+
const observer = observers[selector] ?? new MutationObserver(observerCallback);
|
|
279
|
+
observers[selector] ??= observer;
|
|
280
|
+
return { clear, observe };
|
|
281
|
+
};
|
|
282
|
+
|
|
283
|
+
const fakeReturn = () => {};
|
|
284
|
+
|
|
285
|
+
const watchForNestedElement = (callback, selector) => {
|
|
286
|
+
const [outerSelector, accessMethod] = selector.split('[]').map((s) => s.trim());
|
|
287
|
+
const outerElement = getElement(outerSelector);
|
|
288
|
+
const rootElement = outerElement?.[accessMethod];
|
|
289
|
+
|
|
290
|
+
const { clear: clearObserver, observe: launchObserver } = setObserver(callback, selector);
|
|
291
|
+
|
|
292
|
+
const onIframeLoad = () => {
|
|
293
|
+
const element = getElement(selector);
|
|
294
|
+
return element && !clear() && callback(element);
|
|
295
|
+
};
|
|
296
|
+
|
|
297
|
+
const clear = () => {
|
|
298
|
+
clearObserver();
|
|
299
|
+
outerElement?.removeEventListener('load', onIframeLoad);
|
|
300
|
+
};
|
|
301
|
+
|
|
302
|
+
const observe = () => {
|
|
303
|
+
launchObserver(rootElement);
|
|
304
|
+
if (outerElement?.localName === 'iframe') {
|
|
305
|
+
outerElement.addEventListener('load', onIframeLoad);
|
|
306
|
+
}
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
observe();
|
|
310
|
+
return { selector, clear, observe };
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
const waitForElement = (selector, callback) => {
|
|
314
|
+
const element = getElement(selector);
|
|
315
|
+
|
|
316
|
+
const defaultReturn = {
|
|
317
|
+
selector,
|
|
318
|
+
clear: fakeReturn,
|
|
319
|
+
observe: fakeReturn,
|
|
320
|
+
};
|
|
321
|
+
|
|
322
|
+
if (element) {
|
|
323
|
+
setTimeout(() => callback(element), 0);
|
|
324
|
+
return defaultReturn;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
if (isOnEditor()) {
|
|
328
|
+
setTimeout(() => waitForElement(selector, callback), 1000);
|
|
329
|
+
return defaultReturn;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
const isNestedRootTarget = selector.includes('[]');
|
|
333
|
+
if (isNestedRootTarget) return watchForNestedElement(callback, selector);
|
|
334
|
+
|
|
335
|
+
const { clear, observe } = setObserver(callback, selector);
|
|
336
|
+
observe();
|
|
337
|
+
return { selector, clear, observe };
|
|
338
|
+
};
|
|
339
|
+
|
|
340
|
+
function findParent(element, cb) {
|
|
341
|
+
const parentElement = element.parentElement || element.getRootNode().host;
|
|
342
|
+
if (cb(element) || !parentElement) {
|
|
343
|
+
return element;
|
|
344
|
+
}
|
|
345
|
+
return findParent(parentElement, cb);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const avoidEventDetection = event => {
|
|
349
|
+
if (isOnEditor()) return;
|
|
350
|
+
event.preventDefault();
|
|
351
|
+
event.stopPropagation();
|
|
352
|
+
event.stopImmediatePropagation();
|
|
353
|
+
};
|
|
354
|
+
|
|
355
|
+
const isTargetValid = (eventTarget, selector) => {
|
|
356
|
+
const userTargets = [...getElements(selector)];
|
|
357
|
+
return userTargets.some(element => {
|
|
358
|
+
const [outerSelector, , innerSelector] = selector.split('[]');
|
|
359
|
+
const closestSelector = innerSelector ?? outerSelector;
|
|
360
|
+
const isTarget = element === eventTarget || !!eventTarget.closest(closestSelector);
|
|
361
|
+
return isTarget;
|
|
362
|
+
});
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
let throttleInProgress = false;
|
|
366
|
+
const throttle = (fn, delay) => {
|
|
367
|
+
return () => {
|
|
368
|
+
if (throttleInProgress) return;
|
|
369
|
+
throttleInProgress = true;
|
|
370
|
+
setTimeout(() => {
|
|
371
|
+
fn();
|
|
372
|
+
throttleInProgress = false;
|
|
373
|
+
}, delay);
|
|
374
|
+
}
|
|
375
|
+
};
|
|
376
|
+
|
|
377
|
+
// VisibilityTrigger
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
class VisibilityObserver {
|
|
381
|
+
constructor() {
|
|
382
|
+
// step 1. targets we want to watch:
|
|
383
|
+
this.targets = [];
|
|
384
|
+
// step 2. targets that exist in the DOM:
|
|
385
|
+
this.existingTargets = [];
|
|
386
|
+
// step 3. targets that are in the viewport:
|
|
387
|
+
this.inViewportTargets = [];
|
|
388
|
+
|
|
389
|
+
this.visibilityObserver = null;
|
|
390
|
+
this.mutationObserver = null;
|
|
391
|
+
this.mouseOverEvent = null;
|
|
392
|
+
this.scrollEvent = null;
|
|
393
|
+
this.onTransitionEnd = null;
|
|
394
|
+
this.onIframeLoad = null;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
transitionOverHandler(root) {
|
|
398
|
+
const listenerParams = [
|
|
399
|
+
root,
|
|
400
|
+
'transitionend',
|
|
401
|
+
this.checkElements.bind(this),
|
|
402
|
+
true
|
|
403
|
+
];
|
|
404
|
+
return this.getEvents(...listenerParams);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
intersectionHandler(entries) {
|
|
408
|
+
entries.forEach(entry => {
|
|
409
|
+
if (entry.isIntersecting) {
|
|
410
|
+
this.existingTargets.forEach(target => {
|
|
411
|
+
if (target.element.isSameNode(entry.target)) {
|
|
412
|
+
this.inViewportTargets.push(target);
|
|
413
|
+
this.mouseOverEvent.start();
|
|
414
|
+
this.scrollEvent.start();
|
|
415
|
+
this.onTransitionEnd.start();
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
this.checkElements();
|
|
419
|
+
} else {
|
|
420
|
+
this.inViewportTargets = this.inViewportTargets.filter(target => {
|
|
421
|
+
if (target.element.isSameNode(entry.target)) {
|
|
422
|
+
this.mouseOverEvent.clear();
|
|
423
|
+
this.scrollEvent.clear();
|
|
424
|
+
this.onTransitionEnd.clear();
|
|
425
|
+
return false;
|
|
426
|
+
}
|
|
427
|
+
return true;
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
startVisibilityObserver(rootElement) {
|
|
434
|
+
const options = {
|
|
435
|
+
root: rootElement,
|
|
436
|
+
rootMargin: '0px',
|
|
437
|
+
threshold: 0.01
|
|
438
|
+
};
|
|
439
|
+
this.visibilityObserver ??= new IntersectionObserver(this.intersectionHandler.bind(this), options);
|
|
440
|
+
return this.visibilityObserver;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
startMutationObserver(rootElement) {
|
|
444
|
+
this.mutationObserver ??= new MutationObserver(this.checkElements.bind(this));
|
|
445
|
+
this.mutationObserver.observe(rootElement, {
|
|
446
|
+
attributes: true,
|
|
447
|
+
childList: true,
|
|
448
|
+
subtree: true,
|
|
449
|
+
});
|
|
450
|
+
return this.mutationObserver;
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
onMouseOver({ target: eventTarget, path }) {
|
|
454
|
+
const inViewportEventTarget = this.inViewportTargets.find(({ element, selector }) => {
|
|
455
|
+
if (element.isSameNode(eventTarget)) {
|
|
456
|
+
// Check if the target is the viewport element we're looking for (cover case for css "eventTarget:hover")
|
|
457
|
+
return true;
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const [outerSelector, , innerSelector] = selector.split('[]');
|
|
461
|
+
const toTestSelector = innerSelector ?? outerSelector;
|
|
462
|
+
|
|
463
|
+
// Find matching children of event target (cover case for css "eventTarget:hover *")
|
|
464
|
+
const eventTargetMatchingChildren = [...eventTarget.querySelectorAll(toTestSelector)];
|
|
465
|
+
if (eventTargetMatchingChildren.length) {
|
|
466
|
+
// Check if one matching children of event target is the viewport element we're looking for
|
|
467
|
+
const visibleTargetElementIsChild = eventTargetMatchingChildren.includes(element);
|
|
468
|
+
if (visibleTargetElementIsChild) return true;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
if (path.includes(element)) {
|
|
472
|
+
// (cover case for css "eventTarget:hover *")
|
|
473
|
+
// Check if one parent of event target is the viewport element we're looking for
|
|
474
|
+
return true;
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
// (cover case for css "eventTarget:hover ~ *")
|
|
478
|
+
if (!eventTarget.parentElement?.children?.length) return;
|
|
479
|
+
|
|
480
|
+
const eventTargetParentChildren = [...eventTarget.parentElement.children];
|
|
481
|
+
const eventTargetIndex = eventTargetParentChildren.findIndex(child =>
|
|
482
|
+
child.isSameNode(eventTarget)
|
|
483
|
+
);
|
|
484
|
+
const eventTargetNextBrothers = eventTargetParentChildren.filter(
|
|
485
|
+
(children, index) => index > eventTargetIndex
|
|
486
|
+
);
|
|
487
|
+
|
|
488
|
+
if (eventTargetNextBrothers.length) {
|
|
489
|
+
// Check if one of the following event target brother is the viewport element we're looking for
|
|
490
|
+
const visibleTargetElementIsBrother = eventTargetNextBrothers.includes(element);
|
|
491
|
+
if (visibleTargetElementIsBrother) return true;
|
|
492
|
+
// Check if one of the following event target brother children is the viewport element we're looking for
|
|
493
|
+
const visibleTargetElementIsBrotherChildren = eventTargetNextBrothers.some(brother =>
|
|
494
|
+
[...brother.querySelectorAll(toTestSelector)].includes(element)
|
|
495
|
+
);
|
|
496
|
+
if (visibleTargetElementIsBrotherChildren) return true;
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
return false;
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
if (inViewportEventTarget && this.isElementVisible(inViewportEventTarget.element)) {
|
|
503
|
+
const { selector, element, uniqueId } = inViewportEventTarget;
|
|
504
|
+
const currentTarget = this.targets.find(
|
|
505
|
+
target => target.selector === selector && target.uniqueId === uniqueId
|
|
506
|
+
);
|
|
507
|
+
if (currentTarget) currentTarget.resolve(element);
|
|
508
|
+
this.clear(selector, uniqueId);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
getEvents(root, ...listenerParams) {
|
|
513
|
+
const start = () => root?.addEventListener(...listenerParams);
|
|
514
|
+
const clear = () => root?.removeEventListener(...listenerParams);
|
|
515
|
+
return { start, clear };
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
mouseOverHandler(root) {
|
|
519
|
+
const isTouchDevice = 'ontouchstart' in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0;
|
|
520
|
+
const eventType = isTouchDevice ? 'touchmove' : 'mouseover';
|
|
521
|
+
|
|
522
|
+
const listenerParams = [
|
|
523
|
+
root,
|
|
524
|
+
eventType,
|
|
525
|
+
event => {
|
|
526
|
+
const path = event.composedPath();
|
|
527
|
+
const { target } = event;
|
|
528
|
+
setTimeout(() => this.onMouseOver({ target, path }), 50);
|
|
529
|
+
},
|
|
530
|
+
true
|
|
531
|
+
];
|
|
532
|
+
return this.getEvents(...listenerParams);
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
scrollEventHandler(root) {
|
|
536
|
+
const listenerParams = [
|
|
537
|
+
root,
|
|
538
|
+
'scroll',
|
|
539
|
+
throttle(this.checkElements.bind(this), 100),
|
|
540
|
+
{ passive: true },
|
|
541
|
+
];
|
|
542
|
+
return this.getEvents(...listenerParams);
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
isElementVisible(element) {
|
|
546
|
+
return this.isElementOpaque(element) && this.isElementTopmost(element);
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
isElementOpaque(element) {
|
|
550
|
+
const transparencyRoot = findParent(
|
|
551
|
+
element,
|
|
552
|
+
elem => window.getComputedStyle(elem).opacity === '0'
|
|
553
|
+
);
|
|
554
|
+
return transparencyRoot.nodeName === 'HTML';
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
isElementTopmost(element) {
|
|
558
|
+
const elementCorners = element.getBoundingClientRect();
|
|
559
|
+
const corners = [
|
|
560
|
+
[elementCorners.left, elementCorners.top],
|
|
561
|
+
[elementCorners.right, elementCorners.top],
|
|
562
|
+
[elementCorners.left, elementCorners.bottom],
|
|
563
|
+
[elementCorners.right, elementCorners.bottom],
|
|
564
|
+
[elementCorners.left + elementCorners.width / 2, elementCorners.top],
|
|
565
|
+
[elementCorners.left + elementCorners.width / 2, elementCorners.bottom],
|
|
566
|
+
[elementCorners.left, elementCorners.height / 2],
|
|
567
|
+
[elementCorners.right, elementCorners.height / 2],
|
|
568
|
+
[elementCorners.left + elementCorners.left / 2, elementCorners.height / 2]
|
|
569
|
+
];
|
|
570
|
+
let istopmost = false;
|
|
571
|
+
let i = 0;
|
|
572
|
+
while (!istopmost && i < corners.length) {
|
|
573
|
+
const topmostelem = element.getRootNode()?.elementFromPoint(...corners[i]);
|
|
574
|
+
istopmost =
|
|
575
|
+
element === topmostelem ||
|
|
576
|
+
topmostelem?.contains(element) ||
|
|
577
|
+
element.contains(topmostelem);
|
|
578
|
+
i += 1;
|
|
579
|
+
}
|
|
580
|
+
return istopmost;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
checkElements() {
|
|
584
|
+
this.targets.forEach(({ selector, uniqueId }) => {
|
|
585
|
+
const element = getElement(selector);
|
|
586
|
+
|
|
587
|
+
const [outerSelector, , innerSelector] = selector.split('[]');
|
|
588
|
+
const toMatchSelector = innerSelector ?? outerSelector;
|
|
589
|
+
|
|
590
|
+
if (
|
|
591
|
+
element &&
|
|
592
|
+
!this.existingTargets.find(
|
|
593
|
+
existingTarget =>
|
|
594
|
+
existingTarget.element.matches(toMatchSelector) && existingTarget.uniqueId === uniqueId
|
|
595
|
+
)
|
|
596
|
+
) {
|
|
597
|
+
this.existingTargets.push({ element, selector, uniqueId });
|
|
598
|
+
this.visibilityObserver.observe(element);
|
|
599
|
+
}
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
this.existingTargets = this.existingTargets.filter(({ selector, element }) => {
|
|
603
|
+
if (getElement(selector) && element.isConnected) return true;
|
|
604
|
+
|
|
605
|
+
if (element) this.visibilityObserver.unobserve(element);
|
|
606
|
+
return false;
|
|
607
|
+
});
|
|
608
|
+
|
|
609
|
+
this.inViewportTargets = this.inViewportTargets.filter(({ selector, element, uniqueId }) => {
|
|
610
|
+
const [outerSelector, , innerSelector] = selector.split('[]');
|
|
611
|
+
const toMatchSelector = innerSelector ?? outerSelector;
|
|
612
|
+
const elementMatchesSelector = element.matches(toMatchSelector);
|
|
613
|
+
const elementIsVisible = elementMatchesSelector && this.isElementVisible(element);
|
|
614
|
+
if (elementIsVisible) {
|
|
615
|
+
const currentTarget = this.targets.find(
|
|
616
|
+
target => target.selector === selector && target.uniqueId === uniqueId
|
|
617
|
+
);
|
|
618
|
+
if (currentTarget) currentTarget.resolve(element);
|
|
619
|
+
this.clear(selector, uniqueId);
|
|
620
|
+
return false;
|
|
621
|
+
}
|
|
622
|
+
return true;
|
|
623
|
+
});
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
onLoadIframe(root) {
|
|
627
|
+
const listenerParams = [
|
|
628
|
+
root.defaultView.frameElement,
|
|
629
|
+
'load',
|
|
630
|
+
() => this.watch(selector, resolve, uniqueId).bind(this),
|
|
631
|
+
{ passive: true },
|
|
632
|
+
];
|
|
633
|
+
return this.getEvents(...listenerParams);
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
watch(selector, resolve, uniqueId) {
|
|
637
|
+
this.targets.push({ selector, resolve, uniqueId });
|
|
638
|
+
const { clear } = waitForElement(selector, (target) => {
|
|
639
|
+
clear();
|
|
640
|
+
const rootNode = target.getRootNode({ composed: true });
|
|
641
|
+
const rootElement = 'body' in rootNode ? rootNode.body : document;
|
|
642
|
+
|
|
643
|
+
this.mouseOverEvent = this.mouseOverHandler(rootNode);
|
|
644
|
+
this.scrollEvent = this.scrollEventHandler(rootNode);
|
|
645
|
+
this.onTransitionEnd = this.transitionOverHandler(rootNode);
|
|
646
|
+
|
|
647
|
+
if (rootNode.defaultView?.frameElement) {
|
|
648
|
+
this.onIframeLoad = this.onLoadIframe(rootNode);
|
|
649
|
+
this.onIframeLoad.start();
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
this.startVisibilityObserver(rootNode);
|
|
653
|
+
this.startMutationObserver(rootElement);
|
|
654
|
+
this.checkElements();
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
clear(toClearSelector, id) {
|
|
659
|
+
[this.targets, this.existingTargets, this.inViewportTargets] = [
|
|
660
|
+
this.targets,
|
|
661
|
+
this.existingTargets,
|
|
662
|
+
this.inViewportTargets
|
|
663
|
+
].map(targetsList =>
|
|
664
|
+
targetsList.filter(
|
|
665
|
+
({ selector, uniqueId }) => selector !== toClearSelector && uniqueId !== id
|
|
666
|
+
)
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
const clearElement = getElement(toClearSelector);
|
|
670
|
+
|
|
671
|
+
if (clearElement) this.visibilityObserver?.unobserve(clearElement);
|
|
672
|
+
|
|
673
|
+
if (this.targets.length === 0) {
|
|
674
|
+
this.mutationObserver?.disconnect();
|
|
675
|
+
this.onIframeLoad?.clear();
|
|
676
|
+
}
|
|
677
|
+
if (this.inViewportTargets.length === 0) {
|
|
678
|
+
this.mouseOverEvent?.clear();
|
|
679
|
+
this.scrollEvent?.clear();
|
|
680
|
+
this.onTransitionEnd?.clear();
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
// Categories
|
|
686
|
+
const TAG_RESET_EVENT = 'abtasty_resetActionTracking';
|
|
687
|
+
const TAG_CAMPAIGN_LAUNCHED_EVENT = 'abtasty_executedCampaign';
|
|
688
|
+
|
|
689
|
+
// PAGE WATCHER ACTIONS
|
|
690
|
+
const REMOVE_WIDGET = 'remove';
|
|
691
|
+
const REBUILD_WIDGET = 'rebuild';
|
|
692
|
+
const UPDATE_WIDGET = 'update';
|
|
693
|
+
|
|
694
|
+
// COLORS
|
|
695
|
+
const WHITE = 'rgba(255, 255, 255, 1)'; // #FFF
|
|
696
|
+
const DARK_GRAY = 'rgba(57, 57, 57, 1)'; // #393939
|
|
697
|
+
|
|
698
|
+
const SOCIAL_PROOF_API_BASE = 'https://api-social-proof.abtasty.com/clients/';
|
|
699
|
+
|
|
700
|
+
const abtastyDataStorageName = 'ABTastyData';
|
|
701
|
+
|
|
702
|
+
class Trigger {
|
|
703
|
+
constructor({ triggerEvent, triggerSelector, triggerDelay, triggerTarget }) {
|
|
704
|
+
this.event = triggerEvent;
|
|
705
|
+
this.selector = Boolean(triggerSelector) ? triggerSelector : 'body';
|
|
706
|
+
this.target = typeof triggerTarget === 'string' ? getElement(triggerSelector) : triggerTarget;
|
|
707
|
+
this.delay = triggerDelay * 1000;
|
|
708
|
+
this.triggerElements = []; // [Element, Element]
|
|
709
|
+
this.eventsListeners =
|
|
710
|
+
[]; /* [['event1', callback, params], [element, 'event2', callback, params]]
|
|
711
|
+
It can have 3 or 4 items depending on target is document or not
|
|
712
|
+
No given element means target is document */
|
|
713
|
+
this.timeouts = []; // [timeout1, timeout2]
|
|
714
|
+
this.intervals = []; // [interval1, interval2]
|
|
715
|
+
this.promises = []; // [promise1, promise2]
|
|
716
|
+
this.visibilityObservers = []; // [visibilityObserver1, visibilityObserver2]
|
|
717
|
+
this.socialProofStore = {};
|
|
718
|
+
this.elementWaiters = [];
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
async onElementVisible({ promise, resolve }) {
|
|
722
|
+
const defferedPromise = promiseDeferrer(`${this.event}DomReady`);
|
|
723
|
+
this.promises.push(defferedPromise);
|
|
724
|
+
|
|
725
|
+
const { clear } = waitForElement(this.selector, () => {
|
|
726
|
+
const visibilityObserver = new VisibilityObserver();
|
|
727
|
+
this.visibilityObservers.push(visibilityObserver);
|
|
728
|
+
visibilityObserver.watch(this.selector, resolve, getUniqueId());
|
|
729
|
+
});
|
|
730
|
+
|
|
731
|
+
this.elementWaiters.push(clear);
|
|
732
|
+
return promise;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
onPageLoad({ promise, resolve }) {
|
|
736
|
+
const isDomLoadComplete = () => document.readyState === 'complete';
|
|
737
|
+
|
|
738
|
+
if (!isDomLoadComplete()) {
|
|
739
|
+
const onDomStateChange = () => isDomLoadComplete() && resolve(true);
|
|
740
|
+
const listenerParams = ['readystatechange', onDomStateChange, { passive: true }];
|
|
741
|
+
|
|
742
|
+
this.eventsListeners.push([document, ...listenerParams]);
|
|
743
|
+
document.addEventListener(...listenerParams);
|
|
744
|
+
return promise;
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
resolve(true);
|
|
748
|
+
return promise;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
onClick({ promise, resolve }) {
|
|
752
|
+
const onClickTarget = ({ isTrusted, target }) => {
|
|
753
|
+
if (!isTrusted) return;
|
|
754
|
+
const targetValid = target.isEqualNode(this.target) || isTargetValid(target, this.selector);
|
|
755
|
+
return targetValid && resolve(true);
|
|
756
|
+
};
|
|
757
|
+
|
|
758
|
+
const { clear } = waitForElement(this.selector, (target) => {
|
|
759
|
+
clear();
|
|
760
|
+
const styleElement = document.createElement('style');
|
|
761
|
+
styleElement.id = `Click_${getUniqueId()}`;
|
|
762
|
+
const [outerSelector, , innerSelector] = this.selector.split('[]');
|
|
763
|
+
const modificationSelector = innerSelector ?? outerSelector;
|
|
764
|
+
styleElement.innerHTML = `${modificationSelector} {
|
|
765
|
+
cursor: pointer !important;
|
|
766
|
+
pointer-events: all !important;
|
|
767
|
+
}`;
|
|
768
|
+
|
|
769
|
+
const rootElement = target.getRootNode();
|
|
770
|
+
const stylesTarget = 'head' in rootElement ? rootElement.head : rootElement;
|
|
771
|
+
|
|
772
|
+
stylesTarget.appendChild(styleElement);
|
|
773
|
+
this.triggerElements.push(styleElement);
|
|
774
|
+
|
|
775
|
+
const listenerParams = ['click', onClickTarget, { passive: true, capture: true }];
|
|
776
|
+
this.eventsListeners.push([rootElement, ...listenerParams]);
|
|
777
|
+
rootElement.addEventListener(...listenerParams);
|
|
778
|
+
});
|
|
779
|
+
|
|
780
|
+
this.elementWaiters.push(clear);
|
|
781
|
+
|
|
782
|
+
return promise;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
onHover({ promise, resolve }) {
|
|
786
|
+
const onHoverTarget = ({ isTrusted, target }) => {
|
|
787
|
+
if (!isTrusted) return;
|
|
788
|
+
const targetValid = this.target ? target.isEqualNode(this.target) : isTargetValid(target, this.selector);
|
|
789
|
+
return targetValid && resolve(true);
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
const { clear } = waitForElement(this.selector, (target) => {
|
|
793
|
+
const rootElement = target.getRootNode();
|
|
794
|
+
const eventTarget =
|
|
795
|
+
'body' in rootElement
|
|
796
|
+
? rootElement.body
|
|
797
|
+
: [...rootElement.childNodes].find((child) => child.contains(target));
|
|
798
|
+
const listenerParams = ['mouseenter', onHoverTarget, { passive: true, capture: true }];
|
|
799
|
+
this.eventsListeners.push([eventTarget, ...listenerParams]);
|
|
800
|
+
eventTarget.addEventListener(...listenerParams);
|
|
801
|
+
});
|
|
802
|
+
|
|
803
|
+
this.elementWaiters.push(clear);
|
|
804
|
+
|
|
805
|
+
return promise;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
onExitIntent({ promise, resolve }) {
|
|
809
|
+
const onMouseLeave = ({ isTrusted, clientY }) => {
|
|
810
|
+
if (isTrusted && clientY <= 0) resolve(true);
|
|
811
|
+
};
|
|
812
|
+
|
|
813
|
+
const listenerParams = ['mouseleave', onMouseLeave, { passive: true }];
|
|
814
|
+
const { clear } = waitForElement('html', (documentElement) => {
|
|
815
|
+
clear();
|
|
816
|
+
this.eventsListeners.push([documentElement, ...listenerParams]);
|
|
817
|
+
documentElement.addEventListener(...listenerParams);
|
|
818
|
+
});
|
|
819
|
+
return promise;
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
onReengage({ promise, resolve }) {
|
|
823
|
+
const originalTimer = this.delay;
|
|
824
|
+
let timer = originalTimer;
|
|
825
|
+
const onUserActivity = ({ isTrusted }) => {
|
|
826
|
+
if (isTrusted) timer = originalTimer;
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
const trackActivityTargets = [...document.querySelectorAll('*:empty')]
|
|
830
|
+
.map((element) => element.contentDocument || element.shadowRoot)
|
|
831
|
+
.filter((element) => element);
|
|
832
|
+
const eventsType = ['click', 'mousemove', 'scroll', 'keypress'];
|
|
833
|
+
const listenerParams = [onUserActivity, { passive: true }];
|
|
834
|
+
eventsType.forEach((event) => {
|
|
835
|
+
[document, ...trackActivityTargets].forEach(rootElement => {
|
|
836
|
+
this.eventsListeners.push([rootElement, event, ...listenerParams]);
|
|
837
|
+
rootElement.addEventListener(event, ...listenerParams);
|
|
838
|
+
});
|
|
839
|
+
});
|
|
840
|
+
|
|
841
|
+
const interval = setInterval(() => {
|
|
842
|
+
if (timer <= 0) {
|
|
843
|
+
resolve(true);
|
|
844
|
+
} else {
|
|
845
|
+
timer -= 100;
|
|
846
|
+
}
|
|
847
|
+
}, 100);
|
|
848
|
+
this.intervals.push(interval);
|
|
849
|
+
|
|
850
|
+
return promise;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
onCustomTrigger({ promise, resolve }) {
|
|
854
|
+
const { triggerEventCustomScript } = DATA;
|
|
855
|
+
const triggerEventCustomScriptFunction =
|
|
856
|
+
typeof DATA_JS !== 'undefined' && DATA_JS?.triggerEventCustomScript;
|
|
857
|
+
/* eslint-disable no-new-func */
|
|
858
|
+
const customFunction =
|
|
859
|
+
typeof triggerEventCustomScriptFunction === 'function'
|
|
860
|
+
? () =>
|
|
861
|
+
new Promise((resolve) => triggerEventCustomScriptFunction(resolve))
|
|
862
|
+
: new Function(
|
|
863
|
+
`return new Promise(async resolve => {${triggerEventCustomScript}})`
|
|
864
|
+
);
|
|
865
|
+
/* eslint-enable no-new-func */
|
|
866
|
+
customFunction().then((response) => response && resolve(true));
|
|
867
|
+
return promise;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
onScrollUp({ promise, resolve }) {
|
|
871
|
+
let scrollPosition = 0;
|
|
872
|
+
const onScroll = ({ isTrusted }) => {
|
|
873
|
+
if (!isTrusted) return;
|
|
874
|
+
if (window.scrollY < scrollPosition) resolve(true);
|
|
875
|
+
else scrollPosition = window.scrollY;
|
|
876
|
+
};
|
|
877
|
+
const listenerParams = ['scroll', onScroll, { passive: true, capture: true }];
|
|
878
|
+
this.eventsListeners.push([document, ...listenerParams]);
|
|
879
|
+
document.addEventListener(...listenerParams);
|
|
880
|
+
return promise;
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
onScrollPercentReached({ promise, resolve }) {
|
|
884
|
+
const { triggerEventScrollPercent } = DATA;
|
|
885
|
+
|
|
886
|
+
const getScrollPercent = () => {
|
|
887
|
+
const { documentElement, body } = document;
|
|
888
|
+
const scrollTop = documentElement.scrollTop || body.scrollTop;
|
|
889
|
+
const scrollHeight = documentElement.scrollHeight || body.scrollHeight;
|
|
890
|
+
return Math.trunc((scrollTop / (scrollHeight - documentElement.clientHeight)) * 100, 10);
|
|
891
|
+
};
|
|
892
|
+
|
|
893
|
+
const onScroll = ({ isTrusted }) => {
|
|
894
|
+
if (!isTrusted) return;
|
|
895
|
+
const scrollPercent = getScrollPercent();
|
|
896
|
+
if (triggerEventScrollPercent < scrollPercent) resolve(true);
|
|
897
|
+
};
|
|
898
|
+
|
|
899
|
+
const listenerParams = ['scroll', onScroll, { passive: true, capture: true }];
|
|
900
|
+
this.eventsListeners.push([document, ...listenerParams]);
|
|
901
|
+
document.addEventListener(...listenerParams);
|
|
902
|
+
return promise;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
checkSocialProofConditions(key, urlKey, compareFunction, resolve) {
|
|
906
|
+
const accountId = getAccountIdentifier();
|
|
907
|
+
const { viewInterval, spNoTrim } = DATA;
|
|
908
|
+
|
|
909
|
+
if (this.socialProofStore.hasOwnProperty(key)) {
|
|
910
|
+
if (compareFunction(this.socialProofStore[key])) {
|
|
911
|
+
resolve(`${this.socialProofStore[key][viewInterval]}`);
|
|
912
|
+
} else {
|
|
913
|
+
resolve(false);
|
|
914
|
+
}
|
|
915
|
+
} else if (key && accountId) {
|
|
916
|
+
const url = `${SOCIAL_PROOF_API_BASE}${accountId}/metrics/${urlKey}?key=${key}${
|
|
917
|
+
spNoTrim ? '&noTrim=true' : ''
|
|
918
|
+
}`;
|
|
919
|
+
|
|
920
|
+
const onJsonResponse = (response) => {
|
|
921
|
+
this.socialProofStore[key] = response;
|
|
922
|
+
return resolve(compareFunction(response) ? `${response[viewInterval]}` : false);
|
|
923
|
+
};
|
|
924
|
+
|
|
925
|
+
fetch(url)
|
|
926
|
+
.then((response) => response.ok && response.json())
|
|
927
|
+
.then(onJsonResponse)
|
|
928
|
+
.catch(() => widgetLog('Failed to fetch datas from server.'));
|
|
929
|
+
} else {
|
|
930
|
+
resolve(false);
|
|
931
|
+
}
|
|
932
|
+
};
|
|
933
|
+
|
|
934
|
+
getSocialProofDatas({ promise, resolve }, metric, requiresProductKey = false) {
|
|
935
|
+
const { productKey, keyType } = getProductKey();
|
|
936
|
+
const { viewInterval, triggerSocialProofMinVisitors, triggerSocialProofMinPurchases, triggerSocialProofMinPageViews } = DATA;
|
|
937
|
+
|
|
938
|
+
const metricValue = {
|
|
939
|
+
pv: triggerSocialProofMinPageViews,
|
|
940
|
+
i: triggerSocialProofMinPurchases,
|
|
941
|
+
'v-pv': triggerSocialProofMinVisitors,
|
|
942
|
+
}[metric];
|
|
943
|
+
|
|
944
|
+
const cannotCheck = [
|
|
945
|
+
typeof viewInterval,
|
|
946
|
+
typeof metricValue,
|
|
947
|
+
].includes("undefined");
|
|
948
|
+
|
|
949
|
+
if (cannotCheck) resolve(false);
|
|
950
|
+
|
|
951
|
+
const isMetricHigherThanValue = (response) => {
|
|
952
|
+
const metricHigherThanValue =
|
|
953
|
+
typeof response[viewInterval] !== 'undefined' &&
|
|
954
|
+
response[viewInterval] >= metricValue;
|
|
955
|
+
|
|
956
|
+
if (!metricHigherThanValue)
|
|
957
|
+
widgetLog(
|
|
958
|
+
`Widget will not be shown, Social Proof API returned ${response[viewInterval]} while ${metricValue} are required`
|
|
959
|
+
);
|
|
960
|
+
|
|
961
|
+
return metricHigherThanValue;
|
|
962
|
+
};
|
|
963
|
+
|
|
964
|
+
if (requiresProductKey && !productKey) {
|
|
965
|
+
widgetLog(
|
|
966
|
+
`Not able to find ABTastyProductKey, impossible to call the API, read documentation for more informations:
|
|
967
|
+
https://support.abtasty.com/hc/en-us/articles/4710919241628-Widgets-List#h_84c04344-c655-4e5e-b9ab-d26a798ad9b0`
|
|
968
|
+
);
|
|
969
|
+
resolve(false);
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
this.checkSocialProofConditions(productKey, metric === 'v-pv' && keyType === 'sku' ? 'v-i' : metric, isMetricHigherThanValue, resolve);
|
|
973
|
+
return promise;
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
onConsent({ promise, resolve }) {
|
|
977
|
+
if (!isConsentReady()) {
|
|
978
|
+
const onConsentValid = () => resolve(true);
|
|
979
|
+
const listenerParams = ['abtasty_consentValid', onConsentValid];
|
|
980
|
+
this.eventsListeners.push(listenerParams);
|
|
981
|
+
window.addEventListener(...listenerParams);
|
|
982
|
+
return promise;
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
resolve(true);
|
|
986
|
+
return promise;
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
onTrackingSent({ promise, resolve }) {
|
|
990
|
+
const { triggerEventTrackingSent } = DATA;
|
|
991
|
+
let ABTastyData = localStorage.getItem(abtastyDataStorageName);
|
|
992
|
+
|
|
993
|
+
const isActionTrackingSent = () =>
|
|
994
|
+
JSON.parse(ABTastyData)?.ActionTracking?.some(
|
|
995
|
+
({ name }) => name === triggerEventTrackingSent
|
|
996
|
+
);
|
|
997
|
+
|
|
998
|
+
const onStorage = ({ key, newValue }) => {
|
|
999
|
+
if (key !== abtastyDataStorageName) return;
|
|
1000
|
+
ABTastyData = newValue;
|
|
1001
|
+
if (isActionTrackingSent()) resolve(true);
|
|
1002
|
+
};
|
|
1003
|
+
|
|
1004
|
+
const listenerParams = ['storage', onStorage, { passive: true, capture: true }];
|
|
1005
|
+
const setEvent = () => {
|
|
1006
|
+
this.eventsListeners.push([window, ...listenerParams]);
|
|
1007
|
+
window.addEventListener(...listenerParams);
|
|
1008
|
+
};
|
|
1009
|
+
|
|
1010
|
+
if (!ABTastyData || !isActionTrackingSent()) setEvent();
|
|
1011
|
+
else resolve(true);
|
|
1012
|
+
|
|
1013
|
+
return promise;
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
onMinPagesViewed({ promise, resolve }) {
|
|
1017
|
+
const { triggerEventMinPagesViewed } = DATA;
|
|
1018
|
+
let ABTastyData = localStorage.getItem(abtastyDataStorageName);
|
|
1019
|
+
|
|
1020
|
+
const getNumberOfPagesViewed = () =>
|
|
1021
|
+
ABTastyData ? JSON.parse(ABTastyData)?.VisitedPages?.length : 0;
|
|
1022
|
+
|
|
1023
|
+
const isGoalReached = () => triggerEventMinPagesViewed <= getNumberOfPagesViewed();
|
|
1024
|
+
|
|
1025
|
+
const onStorage = ({ key, newValue }) => {
|
|
1026
|
+
if (key !== abtastyDataStorageName) return;
|
|
1027
|
+
ABTastyData = newValue;
|
|
1028
|
+
if (isGoalReached()) resolve(true);
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
const listenerParams = ['storage', onStorage, { passive: true, capture: true }];
|
|
1032
|
+
const setEvent = () => {
|
|
1033
|
+
this.eventsListeners.push([window, ...listenerParams]);
|
|
1034
|
+
window.addEventListener(...listenerParams);
|
|
1035
|
+
};
|
|
1036
|
+
|
|
1037
|
+
if (!ABTastyData || !isGoalReached()) setEvent();
|
|
1038
|
+
else resolve(true);
|
|
1039
|
+
|
|
1040
|
+
return promise;
|
|
1041
|
+
}
|
|
1042
|
+
|
|
1043
|
+
onRageClick({ promise, resolve }) {
|
|
1044
|
+
const { triggerEventRageClickQuantity, triggerEventRageClickDelay } = DATA;
|
|
1045
|
+
let clicksCount = 0;
|
|
1046
|
+
let countInProgress = false;
|
|
1047
|
+
|
|
1048
|
+
const onClick = ({ isTrusted }) => {
|
|
1049
|
+
if (!isTrusted) return;
|
|
1050
|
+
|
|
1051
|
+
clicksCount += 1;
|
|
1052
|
+
|
|
1053
|
+
if (clicksCount >= triggerEventRageClickQuantity) resolve(true);
|
|
1054
|
+
|
|
1055
|
+
if (!countInProgress) {
|
|
1056
|
+
countInProgress = true;
|
|
1057
|
+
const rageClickTimeout = setTimeout(() => {
|
|
1058
|
+
clicksCount = 0;
|
|
1059
|
+
countInProgress = false;
|
|
1060
|
+
}, triggerEventRageClickDelay);
|
|
1061
|
+
this.timeouts.push(rageClickTimeout);
|
|
1062
|
+
}
|
|
1063
|
+
};
|
|
1064
|
+
|
|
1065
|
+
const listenerParams = ['click', onClick, { passive: true, capture: true }];
|
|
1066
|
+
|
|
1067
|
+
const setRageCLickListener = (target) => {
|
|
1068
|
+
this.eventsListeners.push([target, ...listenerParams]);
|
|
1069
|
+
target.addEventListener(...listenerParams);
|
|
1070
|
+
};
|
|
1071
|
+
|
|
1072
|
+
const { clear } = waitForElement('iframe []contentDocument[] body > *', () => {
|
|
1073
|
+
const iframes = document.getElementsByTagName('iframe');
|
|
1074
|
+
for (const iframe of iframes) {
|
|
1075
|
+
if ('contentDocument' in iframe && 'body' in iframe.contentDocument) {
|
|
1076
|
+
setRageCLickListener(iframe.contentDocument);
|
|
1077
|
+
}
|
|
1078
|
+
const onIframeLoad = () => setRageCLickListener(iframe.contentDocument);
|
|
1079
|
+
iframe.addEventListener('load', onIframeLoad);
|
|
1080
|
+
this.eventsListeners.push([iframe, 'onIframeLoad', onIframeLoad]);
|
|
1081
|
+
}
|
|
1082
|
+
});
|
|
1083
|
+
|
|
1084
|
+
this.elementWaiters.push(clear);
|
|
1085
|
+
setRageCLickListener(document);
|
|
1086
|
+
|
|
1087
|
+
return promise;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
clear() {
|
|
1091
|
+
this.triggerElements = this.triggerElements.filter((element) => {
|
|
1092
|
+
element.remove();
|
|
1093
|
+
return false;
|
|
1094
|
+
});
|
|
1095
|
+
|
|
1096
|
+
this.eventsListeners = this.eventsListeners.filter((event) => {
|
|
1097
|
+
const [target, ...eventParams] = event;
|
|
1098
|
+
if (target && eventParams.length > 1) target.removeEventListener(...eventParams);
|
|
1099
|
+
return false;
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
this.timeouts = this.timeouts.filter((timeout) => {
|
|
1103
|
+
clearTimeout(timeout);
|
|
1104
|
+
return false;
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
this.intervals = this.intervals.filter((interval) => {
|
|
1108
|
+
clearInterval(interval);
|
|
1109
|
+
return false
|
|
1110
|
+
});
|
|
1111
|
+
|
|
1112
|
+
const uniqueId = getUniqueId();
|
|
1113
|
+
this.visibilityObservers = this.visibilityObservers.filter((visibilityObserver) => {
|
|
1114
|
+
visibilityObserver.clear(this.selector, uniqueId);
|
|
1115
|
+
return false;
|
|
1116
|
+
});
|
|
1117
|
+
|
|
1118
|
+
this.promises = this.promises.filter((promise) => {
|
|
1119
|
+
promise.resolve(false);
|
|
1120
|
+
return false;
|
|
1121
|
+
});
|
|
1122
|
+
|
|
1123
|
+
this.elementWaiters = this.elementWaiters.filter((clearElementWaiter) => {
|
|
1124
|
+
clearElementWaiter();
|
|
1125
|
+
return false;
|
|
1126
|
+
});
|
|
1127
|
+
|
|
1128
|
+
return this;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
async isTriggered() {
|
|
1132
|
+
this.clear();
|
|
1133
|
+
|
|
1134
|
+
const defferedPromise = promiseDeferrer(this.event);
|
|
1135
|
+
this.promises.push(defferedPromise);
|
|
1136
|
+
|
|
1137
|
+
const triggersLauncher = {
|
|
1138
|
+
consent: () => this.onConsent(defferedPromise),
|
|
1139
|
+
direct: () => true,
|
|
1140
|
+
pageLoad: () => this.onPageLoad(defferedPromise),
|
|
1141
|
+
click: () => this.onClick(defferedPromise),
|
|
1142
|
+
exitIntent: () => this.onExitIntent(defferedPromise),
|
|
1143
|
+
reengage: () => this.onReengage(defferedPromise),
|
|
1144
|
+
elementVisible: () => this.onElementVisible(defferedPromise),
|
|
1145
|
+
script: () => this.onCustomTrigger(defferedPromise),
|
|
1146
|
+
hover: () => this.onHover(defferedPromise),
|
|
1147
|
+
scrollUp: () => this.onScrollUp(defferedPromise),
|
|
1148
|
+
scrollPercent: () => this.onScrollPercentReached(defferedPromise),
|
|
1149
|
+
rageClick: () => this.onRageClick(defferedPromise),
|
|
1150
|
+
minPagesViewed: () => this.onMinPagesViewed(defferedPromise),
|
|
1151
|
+
trackingSent: () => this.onTrackingSent(defferedPromise),
|
|
1152
|
+
socialProofPurchases: () => this.getSocialProofDatas(defferedPromise, 'i', true),
|
|
1153
|
+
socialProofPageViews: () => this.getSocialProofDatas(defferedPromise, 'pv'),
|
|
1154
|
+
socialProofVisitors: () => this.getSocialProofDatas(defferedPromise, 'v-pv'),
|
|
1155
|
+
};
|
|
1156
|
+
|
|
1157
|
+
const eventTrigered = Object.prototype.hasOwnProperty.call(triggersLauncher, this.event)
|
|
1158
|
+
? await triggersLauncher[this.event]()
|
|
1159
|
+
: true;
|
|
1160
|
+
|
|
1161
|
+
if (eventTrigered) this.clear();
|
|
1162
|
+
|
|
1163
|
+
const waitDelay = async () => {
|
|
1164
|
+
const defferedDelayPromise = promiseDeferrer(`${this.event}Delay`);
|
|
1165
|
+
this.promises.push(defferedDelayPromise);
|
|
1166
|
+
const delayTimeout = setTimeout(() => {
|
|
1167
|
+
defferedDelayPromise.resolve(true);
|
|
1168
|
+
this.clear();
|
|
1169
|
+
}, this.delay);
|
|
1170
|
+
this.timeouts.push(delayTimeout);
|
|
1171
|
+
return defferedDelayPromise.promise;
|
|
1172
|
+
};
|
|
1173
|
+
|
|
1174
|
+
const isTrigger =
|
|
1175
|
+
this.event !== 'reengage' && this.delay
|
|
1176
|
+
? eventTrigered && (await waitDelay())
|
|
1177
|
+
: eventTrigered;
|
|
1178
|
+
return isTrigger;
|
|
1179
|
+
}
|
|
1180
|
+
}
|
|
1181
|
+
|
|
1182
|
+
const DISPLAY = 'display';
|
|
1183
|
+
const CLOSING = 'closing';
|
|
1184
|
+
const VALIDATION = 'validation';
|
|
1185
|
+
const WIDGETS_STORAGE = 'ABTastyWidgets';
|
|
1186
|
+
const TEMPORARY_STORAGE = `${WIDGETS_STORAGE}Temporary`;
|
|
1187
|
+
|
|
1188
|
+
class Recurrence {
|
|
1189
|
+
constructor({ displayRecurrence, closingRecurrence, validationRecurrence }, onSetCallback) {
|
|
1190
|
+
this.displayRecurrence = parseFloat(displayRecurrence);
|
|
1191
|
+
this.closingRecurrence = parseFloat(closingRecurrence);
|
|
1192
|
+
this.validationRecurrence = parseFloat(validationRecurrence);
|
|
1193
|
+
this.onSetCallback = onSetCallback;
|
|
1194
|
+
this.widgetName = getWidgetName();
|
|
1195
|
+
this.uniqueId = getUniqueId();
|
|
1196
|
+
this.recurrenceKey = `${this.widgetName}_${this.uniqueId}`;
|
|
1197
|
+
this.isListeningStorageEvent = this.listenStorageEvent();
|
|
1198
|
+
this.pendingRecurrence = false;
|
|
1199
|
+
this.pendingRecurrenceValue = {};
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
onStorage({ key }) {
|
|
1203
|
+
const temporaryStorage = localStorage.getItem(TEMPORARY_STORAGE);
|
|
1204
|
+
const sessionStoredRecurrence = sessionStorage.getItem(WIDGETS_STORAGE);
|
|
1205
|
+
|
|
1206
|
+
if (key === 'ABTastyData' && !temporaryStorage && sessionStoredRecurrence)
|
|
1207
|
+
localStorage.setItem(TEMPORARY_STORAGE, sessionStoredRecurrence);
|
|
1208
|
+
}
|
|
1209
|
+
|
|
1210
|
+
listenStorageEvent() {
|
|
1211
|
+
if (!this.isListeningStorageEvent)
|
|
1212
|
+
window.addEventListener('storage', this.onStorage.bind(this));
|
|
1213
|
+
return true;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
getGivenRecurrenceStorageParsed(storageType) {
|
|
1217
|
+
try {
|
|
1218
|
+
const storage = storageType.getItem(WIDGETS_STORAGE);
|
|
1219
|
+
return JSON.parse(storage);
|
|
1220
|
+
} catch (error) {
|
|
1221
|
+
storageType.removeItem(WIDGETS_STORAGE);
|
|
1222
|
+
return false;
|
|
1223
|
+
}
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
getSessionRecurrenceStorageParsed() {
|
|
1227
|
+
return this.getGivenRecurrenceStorageParsed(window.sessionStorage);
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
getLocalRecurrenceStorageParsed() {
|
|
1231
|
+
return this.getGivenRecurrenceStorageParsed(window.localStorage);
|
|
1232
|
+
}
|
|
1233
|
+
|
|
1234
|
+
removeGivenStorage(storageType, currentParsedStorage) {
|
|
1235
|
+
const { [this.recurrenceKey]: removedStorage, ...newStorage } = currentParsedStorage;
|
|
1236
|
+
|
|
1237
|
+
if (!Object.entries(newStorage).length) {
|
|
1238
|
+
storageType.removeItem(WIDGETS_STORAGE);
|
|
1239
|
+
return false;
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
storageType.setItem(WIDGETS_STORAGE, JSON.stringify(newStorage));
|
|
1243
|
+
return newStorage;
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
removeSessionRecurrenceStorage() {
|
|
1247
|
+
const sessionWidgetsRecurrence = this.getSessionRecurrenceStorageParsed();
|
|
1248
|
+
if (!sessionWidgetsRecurrence) return false;
|
|
1249
|
+
return this.removeGivenStorage(window.sessionStorage, sessionWidgetsRecurrence);
|
|
1250
|
+
}
|
|
1251
|
+
|
|
1252
|
+
removeLocalRecurrenceStorage() {
|
|
1253
|
+
const localWidgetsRecurrence = this.getLocalRecurrenceStorageParsed();
|
|
1254
|
+
if (!localWidgetsRecurrence) return false;
|
|
1255
|
+
return this.removeGivenStorage(window.localStorage, localWidgetsRecurrence);
|
|
1256
|
+
}
|
|
1257
|
+
|
|
1258
|
+
getSessionRecurrence() {
|
|
1259
|
+
const sessionRecurrence = this.getSessionRecurrenceStorageParsed();
|
|
1260
|
+
return !!sessionRecurrence && sessionRecurrence[this.recurrenceKey];
|
|
1261
|
+
}
|
|
1262
|
+
|
|
1263
|
+
getLocalRecurrence() {
|
|
1264
|
+
const localRecurrence = this.getLocalRecurrenceStorageParsed();
|
|
1265
|
+
return !!localRecurrence && localRecurrence[this.recurrenceKey];
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
getCurrentRecurrence() {
|
|
1269
|
+
if (this.pendingRecurrence) return this.pendingRecurrenceValue;
|
|
1270
|
+
|
|
1271
|
+
const sessionRecurrence = this.getSessionRecurrence();
|
|
1272
|
+
const localRecurrence = this.getLocalRecurrence();
|
|
1273
|
+
return sessionRecurrence || localRecurrence || { type: false };
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1276
|
+
isOver() {
|
|
1277
|
+
const temporaryStorage = localStorage.getItem(TEMPORARY_STORAGE);
|
|
1278
|
+
const sessionRecurrence =
|
|
1279
|
+
temporaryStorage && temporaryStorage.includes(this.recurrenceKey)
|
|
1280
|
+
? true
|
|
1281
|
+
: this.getSessionRecurrence();
|
|
1282
|
+
|
|
1283
|
+
if (temporaryStorage) {
|
|
1284
|
+
sessionStorage.setItem(WIDGETS_STORAGE, temporaryStorage);
|
|
1285
|
+
localStorage.removeItem(TEMPORARY_STORAGE);
|
|
1286
|
+
}
|
|
1287
|
+
|
|
1288
|
+
const localRecurrence = this.getLocalRecurrence();
|
|
1289
|
+
const localRecurrenceStamp = localRecurrence ? parseFloat(localRecurrence.stamp) : 0;
|
|
1290
|
+
const now = new Date().getTime();
|
|
1291
|
+
const stampIsDone = localRecurrenceStamp < now;
|
|
1292
|
+
|
|
1293
|
+
if (stampIsDone) {
|
|
1294
|
+
this.removeLocalRecurrenceStorage();
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
return (
|
|
1298
|
+
!this.pendingRecurrence && stampIsDone && !this.getLocalRecurrence() && !sessionRecurrence
|
|
1299
|
+
);
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
setRecurrence(recurrence, type) {
|
|
1303
|
+
if (recurrence !== 0) {
|
|
1304
|
+
window.removeEventListener('storage', this.onStorage.bind(this));
|
|
1305
|
+
this.isListeningStorageEvent = false;
|
|
1306
|
+
}
|
|
1307
|
+
|
|
1308
|
+
const neededStorageInfos = this.getTypeOfStorage(recurrence);
|
|
1309
|
+
if (isOnPreview() || (!neededStorageInfos && typeof neededStorageInfos !== 'object'))
|
|
1310
|
+
return false;
|
|
1311
|
+
|
|
1312
|
+
const { storageString, storageMethod } = neededStorageInfos;
|
|
1313
|
+
const stamp = this.getStamp(recurrence);
|
|
1314
|
+
const storeObject = { type, stamp };
|
|
1315
|
+
const { type: currentType } = this.getCurrentRecurrence();
|
|
1316
|
+
|
|
1317
|
+
const store = async () => {
|
|
1318
|
+
if (!isConsentReady()) {
|
|
1319
|
+
this.pendingRecurrence = true;
|
|
1320
|
+
this.pendingRecurrenceValue = storeObject;
|
|
1321
|
+
const waitForConsent = new Trigger({ triggerEvent: 'consent' });
|
|
1322
|
+
await waitForConsent.isTriggered();
|
|
1323
|
+
this.pendingRecurrence = false;
|
|
1324
|
+
this.pendingRecurrenceValue = {};
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
const sessionRecurrence = this.getSessionRecurrence();
|
|
1328
|
+
const localRecurrence = this.getLocalRecurrence();
|
|
1329
|
+
let storageWithoutCurrent;
|
|
1330
|
+
|
|
1331
|
+
if (storageString === 'session') {
|
|
1332
|
+
if (sessionRecurrence) {
|
|
1333
|
+
storageWithoutCurrent = this.removeSessionRecurrenceStorage();
|
|
1334
|
+
} else {
|
|
1335
|
+
this.removeLocalRecurrenceStorage();
|
|
1336
|
+
storageWithoutCurrent = this.getSessionRecurrenceStorageParsed();
|
|
1337
|
+
}
|
|
1338
|
+
} else if (storageString === 'local') {
|
|
1339
|
+
if (localRecurrence) {
|
|
1340
|
+
storageWithoutCurrent = this.removeLocalRecurrenceStorage();
|
|
1341
|
+
} else {
|
|
1342
|
+
this.removeSessionRecurrenceStorage();
|
|
1343
|
+
storageWithoutCurrent = this.getLocalRecurrenceStorageParsed();
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
|
|
1347
|
+
const newStorage = storageWithoutCurrent
|
|
1348
|
+
? { [this.recurrenceKey]: storeObject, ...storageWithoutCurrent }
|
|
1349
|
+
: { [this.recurrenceKey]: storeObject };
|
|
1350
|
+
|
|
1351
|
+
storageMethod.setItem(WIDGETS_STORAGE, JSON.stringify(newStorage));
|
|
1352
|
+
if (this.onSetCallback && typeof this.onSetCallback === 'function') this.onSetCallback();
|
|
1353
|
+
};
|
|
1354
|
+
|
|
1355
|
+
if (!storageMethod) return false;
|
|
1356
|
+
|
|
1357
|
+
if (!currentType || type === VALIDATION) {
|
|
1358
|
+
store();
|
|
1359
|
+
} else if (type === CLOSING && currentType !== VALIDATION) {
|
|
1360
|
+
store();
|
|
1361
|
+
} else if (type === DISPLAY && currentType !== VALIDATION && currentType !== CLOSING) {
|
|
1362
|
+
store();
|
|
1363
|
+
} else {
|
|
1364
|
+
return false;
|
|
1365
|
+
}
|
|
1366
|
+
|
|
1367
|
+
return stamp;
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
setDisplayRecurrence() {
|
|
1371
|
+
const type = DISPLAY;
|
|
1372
|
+
this.setRecurrence(this.displayRecurrence, type);
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
setClosingRecurrence() {
|
|
1376
|
+
const type = CLOSING;
|
|
1377
|
+
this.setRecurrence(this.closingRecurrence, type);
|
|
1378
|
+
}
|
|
1379
|
+
|
|
1380
|
+
setValidationRecurrence() {
|
|
1381
|
+
const type = VALIDATION;
|
|
1382
|
+
this.setRecurrence(this.validationRecurrence, type);
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1385
|
+
getStamp(recurrence) {
|
|
1386
|
+
const day = 86400000;
|
|
1387
|
+
const now = new Date().getTime();
|
|
1388
|
+
return now + day * recurrence;
|
|
1389
|
+
}
|
|
1390
|
+
|
|
1391
|
+
getTypeOfStorage(recurrence) {
|
|
1392
|
+
if (isNaN(recurrence) || recurrence < 0 || (recurrence !== 0 && !recurrence)) {
|
|
1393
|
+
return false;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
if (recurrence > 0) {
|
|
1397
|
+
return { storageString: 'local', storageMethod: window.localStorage };
|
|
1398
|
+
}
|
|
1399
|
+
if (recurrence === 0) {
|
|
1400
|
+
return { storageString: 'session', storageMethod: window.sessionStorage };
|
|
1401
|
+
}
|
|
1402
|
+
return false;
|
|
1403
|
+
}
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
/* Params :
|
|
1407
|
+
recurrence : as initiated recurrence
|
|
1408
|
+
isWidgetApplied : as a function that return true or false depending on widget specificities and allow us to callback or not in case all other native actions are true
|
|
1409
|
+
callback : as a function that is called when you need to do any action to your widget / params : as a string 'remove' or 'rebuild'
|
|
1410
|
+
*/
|
|
1411
|
+
|
|
1412
|
+
class PageWatcher {
|
|
1413
|
+
constructor(isWidgetApplied, callback, shouldUpdate) {
|
|
1414
|
+
this.isWidgetApplied = isWidgetApplied;
|
|
1415
|
+
this.callback = callback;
|
|
1416
|
+
this.shouldUpdate = shouldUpdate;
|
|
1417
|
+
this.triggerIframeTarget = null;
|
|
1418
|
+
this.observer = new MutationObserver(this.observerHandler.bind(this));
|
|
1419
|
+
this.tagRollbackEventParams = [TAG_RESET_EVENT, this.onTagRollback.bind(this)];
|
|
1420
|
+
this.onCampaignLaunchedEventParams = [TAG_CAMPAIGN_LAUNCHED_EVENT, this.onCampaignLaunched.bind(this)];
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
decisionHandler(event) {
|
|
1424
|
+
const widgetApplied = !event && this.isWidgetApplied();
|
|
1425
|
+
const action = widgetApplied ? this.shouldUpdate && UPDATE_WIDGET : REBUILD_WIDGET;
|
|
1426
|
+
if (!action) return this;
|
|
1427
|
+
|
|
1428
|
+
this.clearWatcher();
|
|
1429
|
+
this.callback(action, !event, widgetApplied);
|
|
1430
|
+
this.watch();
|
|
1431
|
+
|
|
1432
|
+
return this;
|
|
1433
|
+
}
|
|
1434
|
+
|
|
1435
|
+
onCampaignLaunched({ detail: { campaignId } }) {
|
|
1436
|
+
if (campaignId !== TEST_ID) return;
|
|
1437
|
+
this.callback(REBUILD_WIDGET, false);
|
|
1438
|
+
this.watch();
|
|
1439
|
+
}
|
|
1440
|
+
|
|
1441
|
+
onTagRollback({ target }) {
|
|
1442
|
+
this.clearWatcher(target);
|
|
1443
|
+
this.callback(REMOVE_WIDGET, false, true);
|
|
1444
|
+
window.addEventListener(...this.onCampaignLaunchedEventParams);
|
|
1445
|
+
return this;
|
|
1446
|
+
}
|
|
1447
|
+
|
|
1448
|
+
observerHandler(mutations) {
|
|
1449
|
+
if (!isAffected()) return this.callback(REMOVE_WIDGET, false);
|
|
1450
|
+
|
|
1451
|
+
const domChanges = mutations.some(mutation => ['removedNodes', 'addedNodes'].some(prop => mutation[prop] && mutation[prop].length));
|
|
1452
|
+
if (domChanges) return this.decisionHandler();
|
|
1453
|
+
|
|
1454
|
+
return this;
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1457
|
+
watch(rootElement, triggerSelector) {
|
|
1458
|
+
if (isOnEditor()) return this;
|
|
1459
|
+
this.clearWatcher(rootElement);
|
|
1460
|
+
|
|
1461
|
+
window.removeEventListener(...this.onCampaignLaunchedEventParams);
|
|
1462
|
+
document.addEventListener(...this.tagRollbackEventParams);
|
|
1463
|
+
|
|
1464
|
+
if (triggerSelector?.includes('[]contentDocument[]')) {
|
|
1465
|
+
const iframeSelector = triggerSelector.split('[]')[0].trim();
|
|
1466
|
+
const { clear } = waitForElement(iframeSelector, (iframeTargetElement) => {
|
|
1467
|
+
clear();
|
|
1468
|
+
this.triggerIframeTarget = iframeTargetElement;
|
|
1469
|
+
iframeTargetElement.addEventListener('load', this.decisionHandler.bind(this));
|
|
1470
|
+
});
|
|
1471
|
+
}
|
|
1472
|
+
|
|
1473
|
+
const iframeContainer = rootElement?.defaultView?.frameElement;
|
|
1474
|
+
if (iframeContainer && this.triggerIframeTarget !== iframeContainer) {
|
|
1475
|
+
iframeContainer.addEventListener('load', this.decisionHandler.bind(this));
|
|
1476
|
+
}
|
|
1477
|
+
|
|
1478
|
+
const { clear } = waitForElement('body', (body) => {
|
|
1479
|
+
clear();
|
|
1480
|
+
const observerTarget = rootElement?.body || rootElement || body;
|
|
1481
|
+
this.observer.observe(observerTarget, { childList: true, subtree: true });
|
|
1482
|
+
});
|
|
1483
|
+
|
|
1484
|
+
return this;
|
|
1485
|
+
}
|
|
1486
|
+
|
|
1487
|
+
clearTriggerElementWatcher() {
|
|
1488
|
+
this.triggerIframeTarget?.removeEventListener('load', this.decisionHandler.bind(this));
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
clearWatcher(rootElement) {
|
|
1492
|
+
document.removeEventListener(...this.tagRollbackEventParams);
|
|
1493
|
+
this.observer.disconnect();
|
|
1494
|
+
this.clearTriggerElementWatcher();
|
|
1495
|
+
rootElement?.defaultView?.frameElement?.removeEventListener('load', this.decisionHandler.bind(this));
|
|
1496
|
+
return this;
|
|
1497
|
+
}
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
const fontHashRegex = /.+\/([^.]+)\.(otf|ttf)$/;
|
|
1501
|
+
const svgClosingCross = `<svg viewBox="0 0 16 16">
|
|
1502
|
+
<defs><path id="prefix__a" d="M12 4.991L11.009 4 8 7.009 4.991 4 4 4.991 7.009 8 4 11.009 4.991 12 8 8.991 11.009 12 12 11.009 8.991 8z"></path></defs>
|
|
1503
|
+
<g><use xlink:href="#prefix__a"></use></g>
|
|
1504
|
+
</svg>`;
|
|
1505
|
+
|
|
1506
|
+
const shouldUpdateOnPageChange = [
|
|
1507
|
+
'socialProofPurchases',
|
|
1508
|
+
'socialProofPageViews',
|
|
1509
|
+
'socialProofVisitors',
|
|
1510
|
+
];
|
|
1511
|
+
|
|
1512
|
+
class WidgetContainer {
|
|
1513
|
+
constructor(target, index) {
|
|
1514
|
+
this.children = undefined;
|
|
1515
|
+
this.uniqueId = `${getUniqueId()}${index ? `_${index}` : ''}`;
|
|
1516
|
+
this.widgetName = getWidgetName();
|
|
1517
|
+
this.prettyName = getPrettyWidgetName();
|
|
1518
|
+
this.recurrenceParams = getRecurrenceParams();
|
|
1519
|
+
this.triggerParams = getTriggerParams(target);
|
|
1520
|
+
this.recurrence = this.recurrenceParams
|
|
1521
|
+
? new Recurrence(
|
|
1522
|
+
this.recurrenceParams,
|
|
1523
|
+
this.clearGivenClearables.bind(this)
|
|
1524
|
+
)
|
|
1525
|
+
: false;
|
|
1526
|
+
this.trigger = this.triggerParams ? new Trigger(this.triggerParams) : false;
|
|
1527
|
+
this.shouldUpdate = this.triggerParams
|
|
1528
|
+
? shouldUpdateOnPageChange.includes(this.triggerParams.triggerEvent)
|
|
1529
|
+
: false;
|
|
1530
|
+
this.pageWatcher = new PageWatcher(
|
|
1531
|
+
this.isWidgetApplied.bind(this),
|
|
1532
|
+
this.onPageChange.bind(this)
|
|
1533
|
+
);
|
|
1534
|
+
this.hasOncePerPageTrigger = isTriggerOncePerPage();
|
|
1535
|
+
this.basicClassName = `ab_widget_container_${this.widgetName}`;
|
|
1536
|
+
this.widgetContainerId = `${this.basicClassName}_${this.uniqueId}`;
|
|
1537
|
+
this.contentClassName = `${this.basicClassName}_content`;
|
|
1538
|
+
this.overlayClassName = `${this.basicClassName}_overlay`;
|
|
1539
|
+
this.closeButtonClassName = `${this.basicClassName}_close_button`;
|
|
1540
|
+
this.hideClassName = `ab_hide_${this.uniqueId}`;
|
|
1541
|
+
|
|
1542
|
+
this.rootElement = null;
|
|
1543
|
+
this.domElement = this.getDom();
|
|
1544
|
+
this.hasBeenShown = false;
|
|
1545
|
+
this.closedByUser = false;
|
|
1546
|
+
this.websiteFocusedElement = null;
|
|
1547
|
+
this.elementsWaiters = [];
|
|
1548
|
+
}
|
|
1549
|
+
|
|
1550
|
+
clearGivenClearables() {
|
|
1551
|
+
for (const elementWaiter of this.elementsWaiters) {
|
|
1552
|
+
elementWaiter.clear();
|
|
1553
|
+
}
|
|
1554
|
+
this.elementsWaiters = [];
|
|
1555
|
+
}
|
|
1556
|
+
|
|
1557
|
+
isWidgetApplied() {
|
|
1558
|
+
return (
|
|
1559
|
+
this.domElement?.isConnected && this.domElement.ownerDocument?.defaultView
|
|
1560
|
+
);
|
|
1561
|
+
}
|
|
1562
|
+
|
|
1563
|
+
removeOldDomElement() {
|
|
1564
|
+
const oldElement = this.rootElement?.getElementById(this.widgetContainerId);
|
|
1565
|
+
oldElement?.remove();
|
|
1566
|
+
return this;
|
|
1567
|
+
}
|
|
1568
|
+
|
|
1569
|
+
async insert() {
|
|
1570
|
+
if (this.isWidgetApplied()) return false;
|
|
1571
|
+
|
|
1572
|
+
const inElementLayouts = ['free'];
|
|
1573
|
+
if (DATA.layout === 'drawer' && DATA.customTarget)
|
|
1574
|
+
inElementLayouts.push('drawer');
|
|
1575
|
+
|
|
1576
|
+
const widgetHaveTargetLayout = inElementLayouts.includes(DATA.layout);
|
|
1577
|
+
|
|
1578
|
+
const waitForReferrenceElementPromise = new Promise((resolve) => {
|
|
1579
|
+
const { elementReferrer = 'body', referrerInsertType = 'beforeend' } =
|
|
1580
|
+
widgetHaveTargetLayout ? DATA : {};
|
|
1581
|
+
|
|
1582
|
+
const waitForReferrenceElement = waitForElement(
|
|
1583
|
+
elementReferrer,
|
|
1584
|
+
(element) => {
|
|
1585
|
+
this.elementsWaiters = this.elementsWaiters.filter(
|
|
1586
|
+
(waiter) => waiter.selector !== elementReferrer
|
|
1587
|
+
);
|
|
1588
|
+
this.rootElement = element.getRootNode();
|
|
1589
|
+
this.removeOldDomElement();
|
|
1590
|
+
this.domElement.appendChild(this.styleElement);
|
|
1591
|
+
resolve(
|
|
1592
|
+
element.insertAdjacentElement(referrerInsertType, this.domElement)
|
|
1593
|
+
);
|
|
1594
|
+
}
|
|
1595
|
+
);
|
|
1596
|
+
this.elementsWaiters.push(waitForReferrenceElement);
|
|
1597
|
+
});
|
|
1598
|
+
|
|
1599
|
+
return waitForReferrenceElementPromise.then(() => this);
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1602
|
+
remove() {
|
|
1603
|
+
if (this.trigger) this.trigger.clear();
|
|
1604
|
+
this.pageWatcher.clearWatcher(this.rootElement);
|
|
1605
|
+
for (const elementWaiter of this.elementsWaiters) {
|
|
1606
|
+
if (![DATA.elementReferrer, 'body'].includes(elementWaiter.selector))
|
|
1607
|
+
continue;
|
|
1608
|
+
elementWaiter.clear();
|
|
1609
|
+
}
|
|
1610
|
+
this.domElement?.isConnected && this.domElement.remove();
|
|
1611
|
+
|
|
1612
|
+
if (this.hasOncePerPageTrigger) {
|
|
1613
|
+
this.pageWatcher.watch(this.rootElement);
|
|
1614
|
+
} else if (!isOnEditor()) {
|
|
1615
|
+
this.init().then(({ response }) => (response ? this.show() : this));
|
|
1616
|
+
}
|
|
1617
|
+
return this;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
show() {
|
|
1621
|
+
const { layout, overlay = true } = DATA;
|
|
1622
|
+
if (!isOnEditor() && (!this.hasBeenShown || !this.hasOncePerPageTrigger)) {
|
|
1623
|
+
window.ABTastyEvent(`${this.prettyName} displayed`, null, TEST_ID);
|
|
1624
|
+
}
|
|
1625
|
+
this.closedByUser = false;
|
|
1626
|
+
this.websiteFocusedElement = document.activeElement;
|
|
1627
|
+
setTimeout(() => {
|
|
1628
|
+
this.domElement.classList.remove(this.hideClassName);
|
|
1629
|
+
if (!isOnEditor() && layout === 'popin' && overlay === true) {
|
|
1630
|
+
this.domElement
|
|
1631
|
+
.querySelector('input[type="text"], textarea, a, button')
|
|
1632
|
+
?.focus();
|
|
1633
|
+
}
|
|
1634
|
+
}, 50);
|
|
1635
|
+
if (this.recurrence) this.recurrence.setDisplayRecurrence();
|
|
1636
|
+
this.hasBeenShown = true;
|
|
1637
|
+
this.pageWatcher.watch(this.rootElement);
|
|
1638
|
+
return this;
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1641
|
+
hide(hideByUser = true) {
|
|
1642
|
+
if (!isOnEditor() && this.hasBeenShown && hideByUser) {
|
|
1643
|
+
window.ABTastyEvent(`${this.prettyName} closed`, null, TEST_ID);
|
|
1644
|
+
}
|
|
1645
|
+
if (hideByUser) {
|
|
1646
|
+
this.pageWatcher.clearWatcher(this.rootElement);
|
|
1647
|
+
this.closedByUser = true;
|
|
1648
|
+
}
|
|
1649
|
+
this.domElement.classList.add(this.hideClassName);
|
|
1650
|
+
if (!isOnEditor() && this.websiteFocusedElement?.isConnected) {
|
|
1651
|
+
this.websiteFocusedElement.focus();
|
|
1652
|
+
}
|
|
1653
|
+
return this;
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
async init(firstInit) {
|
|
1657
|
+
const onEditor = isOnEditor();
|
|
1658
|
+
const affected = isAffected();
|
|
1659
|
+
|
|
1660
|
+
const alreadyAwaitingTrigger = this.trigger?.promises?.length;
|
|
1661
|
+
const recurrenceDone = this.recurrence ? this.recurrence.isOver() : true;
|
|
1662
|
+
|
|
1663
|
+
if ((!onEditor && !affected) || alreadyAwaitingTrigger || !recurrenceDone) {
|
|
1664
|
+
return { container: this, response: false };
|
|
1665
|
+
}
|
|
1666
|
+
|
|
1667
|
+
this.pageWatcher.watch(
|
|
1668
|
+
this.rootElement || document,
|
|
1669
|
+
this.triggerParams.triggerSelector
|
|
1670
|
+
);
|
|
1671
|
+
|
|
1672
|
+
const canLaunch =
|
|
1673
|
+
onEditor ||
|
|
1674
|
+
!this.trigger ||
|
|
1675
|
+
(this.trigger && (await this.trigger.isTriggered()));
|
|
1676
|
+
this.pageWatcher.clearTriggerElementWatcher();
|
|
1677
|
+
const returnValue = { container: this, response: canLaunch };
|
|
1678
|
+
|
|
1679
|
+
if (!canLaunch) return returnValue;
|
|
1680
|
+
|
|
1681
|
+
await this.insert();
|
|
1682
|
+
this.addCloseEvent();
|
|
1683
|
+
|
|
1684
|
+
if (
|
|
1685
|
+
!onEditor &&
|
|
1686
|
+
!firstInit &&
|
|
1687
|
+
!this.hasBeenShown &&
|
|
1688
|
+
typeof this.children !== 'undefined' &&
|
|
1689
|
+
typeof this.children.refreshContent === 'function'
|
|
1690
|
+
) {
|
|
1691
|
+
this.children.refreshContent(canLaunch);
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
return returnValue;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1697
|
+
onPageChange(changeType, isDomModif, widgetApplied) {
|
|
1698
|
+
const relaunch = () =>
|
|
1699
|
+
this.init().then(({ response }) => {
|
|
1700
|
+
response ? this.show() : this.hide(false);
|
|
1701
|
+
});
|
|
1702
|
+
|
|
1703
|
+
if (!isDomModif) {
|
|
1704
|
+
this.hasBeenShown = false;
|
|
1705
|
+
if (widgetApplied) this.domElement.remove();
|
|
1706
|
+
if (this.trigger) this.trigger.clear();
|
|
1707
|
+
}
|
|
1708
|
+
|
|
1709
|
+
const cases = {
|
|
1710
|
+
[REMOVE_WIDGET]: () =>
|
|
1711
|
+
widgetApplied
|
|
1712
|
+
? this.remove()
|
|
1713
|
+
: this.pageWatcher.watch(this.rootElement),
|
|
1714
|
+
[REBUILD_WIDGET]: () => {
|
|
1715
|
+
if (this.hasBeenShown) {
|
|
1716
|
+
if (this.closedByUser) {
|
|
1717
|
+
this.pageWatcher.watch(this.rootElement);
|
|
1718
|
+
} else if (!widgetApplied) {
|
|
1719
|
+
this.insert()
|
|
1720
|
+
.then((self) => self.show())
|
|
1721
|
+
.catch(this.pageWatcher.watch);
|
|
1722
|
+
}
|
|
1723
|
+
} else {
|
|
1724
|
+
relaunch();
|
|
1725
|
+
}
|
|
1726
|
+
},
|
|
1727
|
+
[UPDATE_WIDGET]: () => {
|
|
1728
|
+
if (this.hasBeenShown) {
|
|
1729
|
+
this.pageWatcher.watch();
|
|
1730
|
+
return;
|
|
1731
|
+
}
|
|
1732
|
+
relaunch();
|
|
1733
|
+
},
|
|
1734
|
+
};
|
|
1735
|
+
|
|
1736
|
+
if (typeof cases[changeType] === 'function') cases[changeType]();
|
|
1737
|
+
}
|
|
1738
|
+
|
|
1739
|
+
addCloseEvent(...closeElements) {
|
|
1740
|
+
const {
|
|
1741
|
+
closeButton,
|
|
1742
|
+
overlay,
|
|
1743
|
+
overlayClickable,
|
|
1744
|
+
layout,
|
|
1745
|
+
animationDuration = 1000,
|
|
1746
|
+
} = DATA;
|
|
1747
|
+
|
|
1748
|
+
const closeElementsSelectors = [];
|
|
1749
|
+
if (
|
|
1750
|
+
(typeof overlay === 'undefined' || overlay === true) &&
|
|
1751
|
+
overlayClickable === true &&
|
|
1752
|
+
layout === 'popin'
|
|
1753
|
+
) {
|
|
1754
|
+
closeElementsSelectors.push(`.${this.overlayClassName}`);
|
|
1755
|
+
}
|
|
1756
|
+
if (typeof closeButton !== 'undefined' && closeButton) {
|
|
1757
|
+
closeElementsSelectors.push(`.${this.closeButtonClassName}`);
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
if (!closeElementsSelectors.length) return this;
|
|
1761
|
+
|
|
1762
|
+
const nativeCloseElements = this.domElement.querySelectorAll(
|
|
1763
|
+
closeElementsSelectors.join(', ')
|
|
1764
|
+
);
|
|
1765
|
+
|
|
1766
|
+
if (!nativeCloseElements.length) return this;
|
|
1767
|
+
|
|
1768
|
+
const onUserClose = (event) => {
|
|
1769
|
+
const isClick = event.type === 'click';
|
|
1770
|
+
const isEscape = event.type === 'keyup' && event.code === 'Escape' && event.isTrusted;
|
|
1771
|
+
|
|
1772
|
+
if (!isClick && !isEscape) return;
|
|
1773
|
+
|
|
1774
|
+
avoidEventDetection(event);
|
|
1775
|
+
if (this.recurrence) this.recurrence.setClosingRecurrence();
|
|
1776
|
+
this.hide(true);
|
|
1777
|
+
setTimeout(() => this.remove(), animationDuration * 1.05);
|
|
1778
|
+
};
|
|
1779
|
+
|
|
1780
|
+
const onCloseParams = [
|
|
1781
|
+
'click',
|
|
1782
|
+
onUserClose,
|
|
1783
|
+
{ once: true, capture: true },
|
|
1784
|
+
];
|
|
1785
|
+
|
|
1786
|
+
closeElements.push(...nativeCloseElements);
|
|
1787
|
+
|
|
1788
|
+
for (const closeElement of closeElements) {
|
|
1789
|
+
if (isOnEditor()) {
|
|
1790
|
+
// eslint-disable-next-line no-param-reassign
|
|
1791
|
+
closeElement.dataset.abtastyActionnable = 'true';
|
|
1792
|
+
}
|
|
1793
|
+
closeElement.removeEventListener(...onCloseParams);
|
|
1794
|
+
closeElement.addEventListener(...onCloseParams);
|
|
1795
|
+
}
|
|
1796
|
+
|
|
1797
|
+
window.removeEventListener('keyup', onUserClose, { once: true });
|
|
1798
|
+
window.addEventListener('keyup', onUserClose, { once: true });
|
|
1799
|
+
return this;
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
getDom() {
|
|
1803
|
+
const { closeButton, layout, overlayClickable, overlay = true } = DATA;
|
|
1804
|
+
const widgetContainerElement = document.createElement('div');
|
|
1805
|
+
widgetContainerElement.className = `${this.basicClassName} ${this.hideClassName}`;
|
|
1806
|
+
widgetContainerElement.id = this.widgetContainerId;
|
|
1807
|
+
|
|
1808
|
+
if (['popin', 'bannerTop', 'bannerBottom'].includes(layout)){
|
|
1809
|
+
widgetContainerElement.role = 'dialog';
|
|
1810
|
+
if (layout === 'popin' && overlay === true) widgetContainerElement.ariaModal = "true";
|
|
1811
|
+
}
|
|
1812
|
+
|
|
1813
|
+
widgetContainerElement.innerHTML = `
|
|
1814
|
+
${
|
|
1815
|
+
layout === 'popin' && overlay === true
|
|
1816
|
+
? `<div ${
|
|
1817
|
+
overlayClickable ? 'aria-label="Close dialog"' : ''
|
|
1818
|
+
} class="${this.overlayClassName}"></div>`
|
|
1819
|
+
: ''
|
|
1820
|
+
}
|
|
1821
|
+
<div class="${this.contentClassName}">
|
|
1822
|
+
${
|
|
1823
|
+
closeButton
|
|
1824
|
+
? `<button class="${this.closeButtonClassName}" aria-label="Close dialog">${svgClosingCross}</button>`
|
|
1825
|
+
: ''
|
|
1826
|
+
}
|
|
1827
|
+
</div>`;
|
|
1828
|
+
return widgetContainerElement;
|
|
1829
|
+
}
|
|
1830
|
+
|
|
1831
|
+
loadFont(name, styleSrc) {
|
|
1832
|
+
if (!name || name === 'inherit' || !/otf|ttf/g.test(styleSrc)) return;
|
|
1833
|
+
const newStyle = document.createElement('style');
|
|
1834
|
+
const styleHash = styleSrc.match(fontHashRegex)
|
|
1835
|
+
? styleSrc.match(fontHashRegex)[1]
|
|
1836
|
+
: '';
|
|
1837
|
+
newStyle.innerHTML = `@font-face { font-family: '${name}_${styleHash}'; src: url('${styleSrc}'); font-display: swap; }`;
|
|
1838
|
+
|
|
1839
|
+
const stylesContainer = this.rootElement?.head || document.head;
|
|
1840
|
+
stylesContainer?.appendChild(newStyle);
|
|
1841
|
+
}
|
|
1842
|
+
|
|
1843
|
+
getStyleTag(uniqueStyles = '', widgetData = DATA) {
|
|
1844
|
+
const { noStyles, layout } = widgetData;
|
|
1845
|
+
const {
|
|
1846
|
+
backgroundColor,
|
|
1847
|
+
isBackgroundImage,
|
|
1848
|
+
backgroundImage,
|
|
1849
|
+
backgroundSize,
|
|
1850
|
+
backgroundPosition,
|
|
1851
|
+
backgroundRepeat,
|
|
1852
|
+
borderColor,
|
|
1853
|
+
borderRadius,
|
|
1854
|
+
borderWidth,
|
|
1855
|
+
textColor,
|
|
1856
|
+
textAlign,
|
|
1857
|
+
fontName,
|
|
1858
|
+
fontStyle,
|
|
1859
|
+
fontSize,
|
|
1860
|
+
isTitle,
|
|
1861
|
+
titleTextAlign,
|
|
1862
|
+
titleTextColor,
|
|
1863
|
+
titleFontName,
|
|
1864
|
+
titleFontStyle,
|
|
1865
|
+
titleFontSize,
|
|
1866
|
+
overlay,
|
|
1867
|
+
overlayColor,
|
|
1868
|
+
dropShadow,
|
|
1869
|
+
dropShadowColor,
|
|
1870
|
+
dropShadowBlur,
|
|
1871
|
+
containerMargin,
|
|
1872
|
+
containerPadding,
|
|
1873
|
+
closeButton,
|
|
1874
|
+
closeButtonPosition,
|
|
1875
|
+
closeButtonSize,
|
|
1876
|
+
closeButtonBorderRadius,
|
|
1877
|
+
closeButtonBorderWidth,
|
|
1878
|
+
closeButtonBorderColor,
|
|
1879
|
+
closeButtonColor,
|
|
1880
|
+
closeButtonBackgroundColor,
|
|
1881
|
+
buttonsAlign,
|
|
1882
|
+
buttonsBorderWidth,
|
|
1883
|
+
buttonsBorderColor,
|
|
1884
|
+
buttonsBorderRadius,
|
|
1885
|
+
buttonsBackgroundColor,
|
|
1886
|
+
buttonsTextColor,
|
|
1887
|
+
buttonsFontName,
|
|
1888
|
+
buttonsFontStyle,
|
|
1889
|
+
buttonsFontSize,
|
|
1890
|
+
secondLink: hasSecondLink,
|
|
1891
|
+
secondLinkBorderWidth,
|
|
1892
|
+
secondLinkBorderColor,
|
|
1893
|
+
secondLinkBorderRadius,
|
|
1894
|
+
secondLinkBackgroundColor,
|
|
1895
|
+
secondLinkTextColor,
|
|
1896
|
+
secondLinkFontName,
|
|
1897
|
+
secondLinkFontStyle,
|
|
1898
|
+
secondLinkFontSize,
|
|
1899
|
+
animation,
|
|
1900
|
+
animationDuration,
|
|
1901
|
+
animationBehaviour,
|
|
1902
|
+
animationSlideDirection,
|
|
1903
|
+
} = noStyles ? {} : widgetData;
|
|
1904
|
+
const styleDomElement = document.createElement('style');
|
|
1905
|
+
if (isOnEditor())
|
|
1906
|
+
styleDomElement.setAttribute('abtasty-script-added', 'true');
|
|
1907
|
+
this.loadFont(fontName, fontStyle);
|
|
1908
|
+
this.loadFont(titleFontName, titleFontStyle);
|
|
1909
|
+
this.loadFont(buttonsFontName, buttonsFontStyle);
|
|
1910
|
+
this.loadFont(secondLinkFontName, secondLinkFontStyle);
|
|
1911
|
+
|
|
1912
|
+
const backgroundProps = [
|
|
1913
|
+
typeof backgroundColor === 'string' ? backgroundColor : WHITE,
|
|
1914
|
+
isBackgroundImage &&
|
|
1915
|
+
typeof backgroundImage === 'string' &&
|
|
1916
|
+
backgroundImage.length
|
|
1917
|
+
? `url(${backgroundImage})`
|
|
1918
|
+
: '',
|
|
1919
|
+
isBackgroundImage &&
|
|
1920
|
+
typeof backgroundPosition === 'string' &&
|
|
1921
|
+
backgroundSize !== '100% 100%'
|
|
1922
|
+
? backgroundPosition
|
|
1923
|
+
: '0 0',
|
|
1924
|
+
isBackgroundImage && typeof backgroundSize === 'string'
|
|
1925
|
+
? `/ ${backgroundSize}`
|
|
1926
|
+
: '/ auto',
|
|
1927
|
+
isBackgroundImage &&
|
|
1928
|
+
backgroundRepeat &&
|
|
1929
|
+
!['cover', '100% 100%'].includes(backgroundSize)
|
|
1930
|
+
? 'repeat'
|
|
1931
|
+
: 'no-repeat',
|
|
1932
|
+
];
|
|
1933
|
+
const backgroundStyle = `background: ${backgroundProps.join(' ').trim()};`;
|
|
1934
|
+
|
|
1935
|
+
const isBorderWithMoreThanZero =
|
|
1936
|
+
typeof borderWidth === 'number' && borderWidth > 0;
|
|
1937
|
+
const borderProps = [
|
|
1938
|
+
isBorderWithMoreThanZero ? `${borderWidth}px` : 'unset',
|
|
1939
|
+
isBorderWithMoreThanZero ? `solid` : '',
|
|
1940
|
+
isBorderWithMoreThanZero &&
|
|
1941
|
+
typeof borderColor === 'string' &&
|
|
1942
|
+
borderColor.length
|
|
1943
|
+
? borderColor
|
|
1944
|
+
: '',
|
|
1945
|
+
];
|
|
1946
|
+
const borderStyle = `border: ${borderProps.join(' ').trim()};`;
|
|
1947
|
+
const borderRadiusStyle =
|
|
1948
|
+
typeof borderRadius !== 'undefined'
|
|
1949
|
+
? `border-radius: ${borderRadius}px;`
|
|
1950
|
+
: '';
|
|
1951
|
+
|
|
1952
|
+
const textColorStyle =
|
|
1953
|
+
typeof textColor !== 'undefined'
|
|
1954
|
+
? `color: ${textColor}; fill: ${textColor}; -webkit-text-fill-color: ${textColor};`
|
|
1955
|
+
: '';
|
|
1956
|
+
const textAlignStyle =
|
|
1957
|
+
typeof textAlign !== 'undefined' ? `text-align: ${textAlign};` : '';
|
|
1958
|
+
const fontNameStyle =
|
|
1959
|
+
fontName && fontName !== 'inherit'
|
|
1960
|
+
? `font-family:${fontName}_${
|
|
1961
|
+
fontStyle.match(fontHashRegex)
|
|
1962
|
+
? fontStyle.match(fontHashRegex)[1]
|
|
1963
|
+
: ''
|
|
1964
|
+
};`
|
|
1965
|
+
: fontStyle || '';
|
|
1966
|
+
const fontSizeStyle = fontSize ? `font-size: ${fontSize}px;` : '';
|
|
1967
|
+
|
|
1968
|
+
const dropShadowStyle =
|
|
1969
|
+
typeof dropShadow !== 'undefined' && dropShadow
|
|
1970
|
+
? `box-shadow: 0 5px ${dropShadowBlur}px 0 ${dropShadowColor};`
|
|
1971
|
+
: '';
|
|
1972
|
+
|
|
1973
|
+
const margin =
|
|
1974
|
+
containerMargin instanceof Array &&
|
|
1975
|
+
containerMargin.length === 1 &&
|
|
1976
|
+
containerMargin[0];
|
|
1977
|
+
const marginsStyle = margin
|
|
1978
|
+
? `margin: ${margin.top}px ${margin.right}px ${margin.bottom}px ${margin.left}px;`
|
|
1979
|
+
: '';
|
|
1980
|
+
const marginSmallScreens = margin
|
|
1981
|
+
? `margin: calc(${margin.top}px * 0.5) calc(${margin.right}px * 0.5) calc(${margin.bottom}px * 0.5) calc(${margin.left}px * 0.5);`
|
|
1982
|
+
: '';
|
|
1983
|
+
const padding =
|
|
1984
|
+
containerPadding instanceof Array &&
|
|
1985
|
+
containerPadding.length === 1 &&
|
|
1986
|
+
containerPadding[0];
|
|
1987
|
+
const paddingsStyle = padding
|
|
1988
|
+
? `padding: ${padding.top}px ${padding.right}px ${padding.bottom}px ${padding.left}px;`
|
|
1989
|
+
: '';
|
|
1990
|
+
const paddingSmallScreens = padding
|
|
1991
|
+
? `padding: calc(${padding.top}px * 0.5) calc(${padding.right}px * 0.5) calc(${padding.bottom}px * 0.5) calc(${padding.left}px * 0.5);`
|
|
1992
|
+
: '';
|
|
1993
|
+
|
|
1994
|
+
const buttonsBorderWidthStyle =
|
|
1995
|
+
typeof buttonsBorderWidth !== 'undefined' && buttonsBorderWidth
|
|
1996
|
+
? `border-width: ${buttonsBorderWidth}px; border-style: solid;`
|
|
1997
|
+
: '';
|
|
1998
|
+
const buttonsBorderColorStyle =
|
|
1999
|
+
[buttonsBorderColor, buttonsBorderWidth].every(
|
|
2000
|
+
(prop) => typeof prop !== 'undefined'
|
|
2001
|
+
) && buttonsBorderWidth
|
|
2002
|
+
? `border-color: ${buttonsBorderColor};`
|
|
2003
|
+
: '';
|
|
2004
|
+
const buttonsBorderRadiusStyle =
|
|
2005
|
+
typeof buttonsBorderRadius !== 'undefined'
|
|
2006
|
+
? `border-radius: ${buttonsBorderRadius}px;`
|
|
2007
|
+
: '';
|
|
2008
|
+
const buttonsBackgroundColorStyle =
|
|
2009
|
+
typeof buttonsBackgroundColor !== 'undefined'
|
|
2010
|
+
? `background-color: ${buttonsBackgroundColor};`
|
|
2011
|
+
: '';
|
|
2012
|
+
const buttonsTextColorStyle =
|
|
2013
|
+
typeof buttonsTextColor !== 'undefined'
|
|
2014
|
+
? `color: ${buttonsTextColor}; fill: ${buttonsTextColor}; -webkit-text-fill-color: ${buttonsTextColor};`
|
|
2015
|
+
: '';
|
|
2016
|
+
const buttonsFontNameStyle =
|
|
2017
|
+
buttonsFontName && buttonsFontName !== 'inherit'
|
|
2018
|
+
? `font-family:${buttonsFontName}_${
|
|
2019
|
+
buttonsFontStyle.match(fontHashRegex)
|
|
2020
|
+
? buttonsFontStyle.match(fontHashRegex)[1]
|
|
2021
|
+
: ''
|
|
2022
|
+
};`
|
|
2023
|
+
: buttonsFontStyle || '';
|
|
2024
|
+
const buttonsFontSizeStyle = buttonsFontSize
|
|
2025
|
+
? `font-size: ${buttonsFontSize}px;`
|
|
2026
|
+
: '';
|
|
2027
|
+
|
|
2028
|
+
const secondLinkBorderWidthStyle =
|
|
2029
|
+
typeof secondLinkBorderWidth === 'number'
|
|
2030
|
+
? `border-width: ${secondLinkBorderWidth}px; border-style: solid;`
|
|
2031
|
+
: '';
|
|
2032
|
+
const secondLinkBorderColorStyle =
|
|
2033
|
+
[secondLinkBorderColor, secondLinkBorderWidth].every(
|
|
2034
|
+
(prop) => typeof prop !== 'undefined'
|
|
2035
|
+
) && secondLinkBorderWidth
|
|
2036
|
+
? `border-color: ${secondLinkBorderColor};`
|
|
2037
|
+
: '';
|
|
2038
|
+
const secondLinkBorderRadiusStyle =
|
|
2039
|
+
typeof secondLinkBorderRadius !== 'undefined'
|
|
2040
|
+
? `border-radius: ${secondLinkBorderRadius}px;`
|
|
2041
|
+
: '';
|
|
2042
|
+
const secondLinkBackgroundColorStyle =
|
|
2043
|
+
typeof secondLinkBackgroundColor !== 'undefined'
|
|
2044
|
+
? `background-color: ${secondLinkBackgroundColor};`
|
|
2045
|
+
: '';
|
|
2046
|
+
const secondLinkTextColorStyle =
|
|
2047
|
+
typeof secondLinkTextColor !== 'undefined'
|
|
2048
|
+
? `color: ${secondLinkTextColor}; fill: ${secondLinkTextColor}; -webkit-text-fill-color: ${secondLinkTextColor};`
|
|
2049
|
+
: '';
|
|
2050
|
+
const secondLinkFontNameStyle =
|
|
2051
|
+
secondLinkFontName && secondLinkFontName !== 'inherit'
|
|
2052
|
+
? `font-family:${secondLinkFontName}_${
|
|
2053
|
+
secondLinkFontStyle.match(fontHashRegex)
|
|
2054
|
+
? secondLinkFontStyle.match(fontHashRegex)[1]
|
|
2055
|
+
: ''
|
|
2056
|
+
};`
|
|
2057
|
+
: secondLinkFontStyle || '';
|
|
2058
|
+
const secondLinkFontSizeStyle = secondLinkFontSize
|
|
2059
|
+
? `font-size: ${secondLinkFontSize}px;`
|
|
2060
|
+
: '';
|
|
2061
|
+
|
|
2062
|
+
const overlayRules =
|
|
2063
|
+
layout === 'popin' && (typeof overlay === 'undefined' || overlay === true)
|
|
2064
|
+
? [
|
|
2065
|
+
`#${this.widgetContainerId} .${this.overlayClassName} {`,
|
|
2066
|
+
`background-color: ${
|
|
2067
|
+
typeof overlayColor !== 'undefined'
|
|
2068
|
+
? overlayColor
|
|
2069
|
+
: 'rgba(0, 0, 0, 0.6)'
|
|
2070
|
+
};`,
|
|
2071
|
+
'}',
|
|
2072
|
+
].join('')
|
|
2073
|
+
: '';
|
|
2074
|
+
|
|
2075
|
+
const closeButtonSizeNumber =
|
|
2076
|
+
typeof closeButtonSize === 'number' ? closeButtonSize : 16;
|
|
2077
|
+
const halfCloseButtonSize = closeButtonSizeNumber / 2;
|
|
2078
|
+
const closeButtonRules =
|
|
2079
|
+
noStyles || (typeof closeButton !== 'undefined' && closeButton)
|
|
2080
|
+
? [
|
|
2081
|
+
`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} {`,
|
|
2082
|
+
'position: absolute;',
|
|
2083
|
+
`${
|
|
2084
|
+
closeButtonPosition === 'out'
|
|
2085
|
+
? `bottom: calc(100% + ${halfCloseButtonSize}px)`
|
|
2086
|
+
: `top: ${halfCloseButtonSize}px`
|
|
2087
|
+
};`,
|
|
2088
|
+
`right: ${halfCloseButtonSize}px;`,
|
|
2089
|
+
'width: auto;',
|
|
2090
|
+
'height: auto;',
|
|
2091
|
+
'background: none;',
|
|
2092
|
+
'border: none;',
|
|
2093
|
+
'cursor: pointer;',
|
|
2094
|
+
'padding: 0;',
|
|
2095
|
+
'margin: 0;',
|
|
2096
|
+
'line-height: 0;',
|
|
2097
|
+
'z-index: 9;',
|
|
2098
|
+
`${
|
|
2099
|
+
typeof closeButtonBorderRadius === 'number'
|
|
2100
|
+
? `border-radius: ${closeButtonBorderRadius}px;`
|
|
2101
|
+
: ''
|
|
2102
|
+
}`,
|
|
2103
|
+
`${
|
|
2104
|
+
typeof closeButtonBorderWidth === 'number' &&
|
|
2105
|
+
closeButtonBorderWidth > 0
|
|
2106
|
+
? `border: ${closeButtonBorderWidth}px solid ${
|
|
2107
|
+
typeof closeButtonBorderColor !== 'undefined'
|
|
2108
|
+
? closeButtonBorderColor
|
|
2109
|
+
: DARK_GRAY
|
|
2110
|
+
};`
|
|
2111
|
+
: ''
|
|
2112
|
+
}`,
|
|
2113
|
+
`${
|
|
2114
|
+
typeof closeButtonBackgroundColor === 'string'
|
|
2115
|
+
? `background-color: ${closeButtonBackgroundColor};`
|
|
2116
|
+
: ''
|
|
2117
|
+
}`,
|
|
2118
|
+
'}',
|
|
2119
|
+
`#${this.widgetContainerId} .${this.contentClassName} .${this.closeButtonClassName} svg {`,
|
|
2120
|
+
'pointer-events: none;',
|
|
2121
|
+
`width: ${closeButtonSizeNumber}px;`,
|
|
2122
|
+
`height: ${closeButtonSizeNumber}px;`,
|
|
2123
|
+
`${
|
|
2124
|
+
typeof closeButtonColor === 'string'
|
|
2125
|
+
? `fill: ${closeButtonColor};`
|
|
2126
|
+
: ''
|
|
2127
|
+
}`,
|
|
2128
|
+
'}',
|
|
2129
|
+
].join('')
|
|
2130
|
+
: '';
|
|
2131
|
+
|
|
2132
|
+
const titleRules =
|
|
2133
|
+
isTitle && typeof titleTextColor === 'string'
|
|
2134
|
+
? [
|
|
2135
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h1, `,
|
|
2136
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h2, `,
|
|
2137
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h3, `,
|
|
2138
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h4, `,
|
|
2139
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h5, `,
|
|
2140
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * h6 {`,
|
|
2141
|
+
`color: ${titleTextColor}; fill: ${titleTextColor}; -webkit-text-fill-color: ${titleTextColor};`,
|
|
2142
|
+
typeof titleTextAlign !== 'undefined'
|
|
2143
|
+
? `text-align: ${titleTextAlign};`
|
|
2144
|
+
: '',
|
|
2145
|
+
titleFontName && titleFontName !== 'inherit'
|
|
2146
|
+
? `font-family:${titleFontName}_${
|
|
2147
|
+
titleFontStyle.match(fontHashRegex)
|
|
2148
|
+
? titleFontStyle.match(fontHashRegex)[1]
|
|
2149
|
+
: ''
|
|
2150
|
+
};`
|
|
2151
|
+
: titleFontStyle || '',
|
|
2152
|
+
titleFontSize ? `font-size: ${titleFontSize}px;` : '',
|
|
2153
|
+
'}',
|
|
2154
|
+
].join('')
|
|
2155
|
+
: '';
|
|
2156
|
+
|
|
2157
|
+
let animationRules = '';
|
|
2158
|
+
|
|
2159
|
+
if (typeof animation === 'string') {
|
|
2160
|
+
const millisecondsDuration = (animationDuration / 1000).toFixed(2);
|
|
2161
|
+
const slideFromTopOrBottom = ['top', 'bottom'].includes(
|
|
2162
|
+
animationSlideDirection
|
|
2163
|
+
);
|
|
2164
|
+
const translateAxisPopin = Number(slideFromTopOrBottom);
|
|
2165
|
+
const translateParams = [
|
|
2166
|
+
`${
|
|
2167
|
+
['top', 'left'].includes(animationSlideDirection) ? '-' : ''
|
|
2168
|
+
}100vmax`,
|
|
2169
|
+
this.translateValues ? this.translateValues[translateAxisPopin] : '0',
|
|
2170
|
+
];
|
|
2171
|
+
|
|
2172
|
+
if (slideFromTopOrBottom) translateParams.reverse();
|
|
2173
|
+
|
|
2174
|
+
animationRules = {
|
|
2175
|
+
none: [`.${this.hideClassName} {`, 'opacity: 0 !important;', '}'],
|
|
2176
|
+
fade: [
|
|
2177
|
+
`.${this.hideClassName} {`,
|
|
2178
|
+
'opacity: 0 !important;',
|
|
2179
|
+
'}',
|
|
2180
|
+
`#${this.widgetContainerId} {`,
|
|
2181
|
+
`transition: opacity ${millisecondsDuration}s ${animationBehaviour};`,
|
|
2182
|
+
'}',
|
|
2183
|
+
`@media (prefers-reduced-motion: reduce) {`,
|
|
2184
|
+
`#${this.widgetContainerId} {`,
|
|
2185
|
+
'transition: unset;',
|
|
2186
|
+
'}',
|
|
2187
|
+
'}',
|
|
2188
|
+
],
|
|
2189
|
+
slide: [
|
|
2190
|
+
`.${this.hideClassName} .${this.overlayClassName} {`,
|
|
2191
|
+
'opacity: 0 !important;',
|
|
2192
|
+
'}',
|
|
2193
|
+
`#${this.widgetContainerId} .${this.overlayClassName} {`,
|
|
2194
|
+
`transition: opacity ${millisecondsDuration}s ${animationBehaviour};`,
|
|
2195
|
+
'}',
|
|
2196
|
+
`.${this.hideClassName} .${this.contentClassName} {`,
|
|
2197
|
+
`transform: translate(${translateParams.join(', ')}) !important;`,
|
|
2198
|
+
'}',
|
|
2199
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2200
|
+
`transition: transform ${millisecondsDuration}s ${animationBehaviour};`,
|
|
2201
|
+
'}',
|
|
2202
|
+
`@media (prefers-reduced-motion: reduce) {`,
|
|
2203
|
+
`#${this.widgetContainerId} .${this.overlayClassName},`,
|
|
2204
|
+
`.${this.hideClassName} .${this.contentClassName},`,
|
|
2205
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2206
|
+
'transition: unset;',
|
|
2207
|
+
'}',
|
|
2208
|
+
'}',
|
|
2209
|
+
],
|
|
2210
|
+
}[
|
|
2211
|
+
isOnEditor() && !ABTASTY_S.WIDGETS.animationChanged ? 'none' : animation
|
|
2212
|
+
].join('');
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
const secondLinkStyles = [
|
|
2216
|
+
`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,
|
|
2217
|
+
`margin-${buttonsAlign === 'fill' ? 'top' : 'left'}: 8px;`,
|
|
2218
|
+
secondLinkBorderWidthStyle,
|
|
2219
|
+
secondLinkBorderColorStyle,
|
|
2220
|
+
secondLinkBorderRadiusStyle,
|
|
2221
|
+
secondLinkBackgroundColorStyle,
|
|
2222
|
+
secondLinkTextColorStyle,
|
|
2223
|
+
secondLinkFontNameStyle,
|
|
2224
|
+
secondLinkFontSizeStyle,
|
|
2225
|
+
'}',
|
|
2226
|
+
`#${this.widgetContainerId} .${this.contentClassName} .buttons_container .second_link {`,
|
|
2227
|
+
secondLinkTextColorStyle,
|
|
2228
|
+
secondLinkFontNameStyle,
|
|
2229
|
+
secondLinkFontSizeStyle,
|
|
2230
|
+
'}',
|
|
2231
|
+
];
|
|
2232
|
+
|
|
2233
|
+
styleDomElement.textContent = [
|
|
2234
|
+
`#${this.widgetContainerId} style { display: none; }`,
|
|
2235
|
+
`.${this.hideClassName} {`,
|
|
2236
|
+
'pointer-events: none;',
|
|
2237
|
+
'}',
|
|
2238
|
+
`#${this.widgetContainerId} {`,
|
|
2239
|
+
'opacity: 1;',
|
|
2240
|
+
'}',
|
|
2241
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2242
|
+
backgroundStyle,
|
|
2243
|
+
borderRadiusStyle,
|
|
2244
|
+
borderStyle,
|
|
2245
|
+
textColorStyle,
|
|
2246
|
+
textAlignStyle,
|
|
2247
|
+
dropShadowStyle,
|
|
2248
|
+
marginsStyle,
|
|
2249
|
+
fontNameStyle,
|
|
2250
|
+
fontSizeStyle,
|
|
2251
|
+
'}',
|
|
2252
|
+
`#${this.widgetContainerId} .${this.contentClassName} p {`,
|
|
2253
|
+
textColorStyle,
|
|
2254
|
+
textAlignStyle,
|
|
2255
|
+
fontNameStyle,
|
|
2256
|
+
fontSizeStyle,
|
|
2257
|
+
'}',
|
|
2258
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * {`,
|
|
2259
|
+
'display: block;',
|
|
2260
|
+
'line-height: 1;',
|
|
2261
|
+
'text-indent: unset;',
|
|
2262
|
+
paddingsStyle,
|
|
2263
|
+
fontNameStyle,
|
|
2264
|
+
fontSizeStyle,
|
|
2265
|
+
'}',
|
|
2266
|
+
`#${this.widgetContainerId} .${this.contentClassName} a {`,
|
|
2267
|
+
'text-decoration: underline;',
|
|
2268
|
+
'}',
|
|
2269
|
+
`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a, `,
|
|
2270
|
+
`#${this.widgetContainerId} .${this.contentClassName} button {`,
|
|
2271
|
+
'text-decoration: none;',
|
|
2272
|
+
'box-sizing: border-box;',
|
|
2273
|
+
'display: inline-block;',
|
|
2274
|
+
buttonsBorderWidthStyle,
|
|
2275
|
+
buttonsBorderColorStyle,
|
|
2276
|
+
buttonsBorderRadiusStyle,
|
|
2277
|
+
buttonsBackgroundColorStyle,
|
|
2278
|
+
buttonsTextColorStyle,
|
|
2279
|
+
buttonsFontNameStyle,
|
|
2280
|
+
buttonsFontSizeStyle,
|
|
2281
|
+
'}',
|
|
2282
|
+
`#${this.widgetContainerId} .${this.contentClassName} div.buttons_container a *:not(.second_link span), `,
|
|
2283
|
+
`#${this.widgetContainerId} .${this.contentClassName} button:not([class*="close_button"], [class*="csatEmojiButton"]) * {`,
|
|
2284
|
+
buttonsTextColorStyle,
|
|
2285
|
+
buttonsFontNameStyle,
|
|
2286
|
+
buttonsFontSizeStyle,
|
|
2287
|
+
'}',
|
|
2288
|
+
...(hasSecondLink ? secondLinkStyles : []),
|
|
2289
|
+
'@media screen and (max-width: 579px) {',
|
|
2290
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2291
|
+
marginSmallScreens,
|
|
2292
|
+
'}',
|
|
2293
|
+
`#${this.widgetContainerId} .${this.contentClassName} > * {`,
|
|
2294
|
+
paddingSmallScreens,
|
|
2295
|
+
'}',
|
|
2296
|
+
'}',
|
|
2297
|
+
overlayRules,
|
|
2298
|
+
closeButtonRules,
|
|
2299
|
+
titleRules,
|
|
2300
|
+
animationRules,
|
|
2301
|
+
`${uniqueStyles}`,
|
|
2302
|
+
].join('');
|
|
2303
|
+
|
|
2304
|
+
return styleDomElement;
|
|
2305
|
+
}
|
|
2306
|
+
}
|
|
2307
|
+
|
|
2308
|
+
const xPosition = ['top: 0;', 'top: 50%;', 'bottom: 0;'];
|
|
2309
|
+
const yPosition = ['left: 0;', 'left: 50%;', 'right: 0;'];
|
|
2310
|
+
const getTranslatePercent = (axis) => (axis === 1 ? '-50%' : 0);
|
|
2311
|
+
|
|
2312
|
+
const getPopinPosition = () => {
|
|
2313
|
+
if (Array.isArray(DATA.popinPosition)) {
|
|
2314
|
+
const {
|
|
2315
|
+
popinPosition: [{ x, y }],
|
|
2316
|
+
} = DATA;
|
|
2317
|
+
const translateValue = `translate(${getTranslatePercent(y)}, ${getTranslatePercent(x)});`;
|
|
2318
|
+
return `${xPosition[x]}${yPosition[y]}transform: ${translateValue}`;
|
|
2319
|
+
}
|
|
2320
|
+
return 'left: 50%;top: 50%;transform: translate(-50%, -50%);';
|
|
2321
|
+
};
|
|
2322
|
+
|
|
2323
|
+
const useDimensionsAuto = () => 'autoWidth' in DATA && DATA.autoWidth === true;
|
|
2324
|
+
|
|
2325
|
+
const getPopinDimensions = () => {
|
|
2326
|
+
if (useDimensionsAuto()) return `width: auto; height: auto; min-width: fit-content;`;
|
|
2327
|
+
|
|
2328
|
+
const {
|
|
2329
|
+
popinPercentWidth,
|
|
2330
|
+
popinPixelsWidth,
|
|
2331
|
+
widthUnit,
|
|
2332
|
+
autoHeight,
|
|
2333
|
+
popinPercentHeight,
|
|
2334
|
+
popinPixelsHeight,
|
|
2335
|
+
heightUnit,
|
|
2336
|
+
} = DATA;
|
|
2337
|
+
const width = widthUnit === 'px' ? popinPixelsWidth : popinPercentWidth;
|
|
2338
|
+
const height = heightUnit === 'px' ? popinPixelsHeight : popinPercentHeight;
|
|
2339
|
+
return `width: ${width}${widthUnit};height: ${autoHeight ? 'auto' : `${height}${heightUnit}`};`;
|
|
2340
|
+
};
|
|
2341
|
+
|
|
2342
|
+
class Popin extends WidgetContainer {
|
|
2343
|
+
constructor() {
|
|
2344
|
+
super();
|
|
2345
|
+
this.translateValues = Object.values(DATA.popinPosition[0]).map(value => getTranslatePercent(value));
|
|
2346
|
+
this.stringStyles = this.getStyles();
|
|
2347
|
+
this.styleElement = this.getStyleTag(this.stringStyles);
|
|
2348
|
+
}
|
|
2349
|
+
|
|
2350
|
+
getStyles() {
|
|
2351
|
+
const { zindex, zindexCustom, widthUnit } = DATA;
|
|
2352
|
+
const overlay = typeof DATA.overlay === 'string' ? false : DATA.overlay;
|
|
2353
|
+
|
|
2354
|
+
return [
|
|
2355
|
+
`#${this.widgetContainerId} {`,
|
|
2356
|
+
'position: fixed;',
|
|
2357
|
+
'top: 0;',
|
|
2358
|
+
'left: 0;',
|
|
2359
|
+
'width: 100%;',
|
|
2360
|
+
'height: 100%;',
|
|
2361
|
+
`z-index: ${zindex === 'custom' ? zindexCustom : zindex};`,
|
|
2362
|
+
'background: none;',
|
|
2363
|
+
`pointer-events: ${overlay ? 'all' : 'none'}`,
|
|
2364
|
+
'}',
|
|
2365
|
+
`#${this.widgetContainerId} .${this.overlayClassName} {`,
|
|
2366
|
+
'position: absolute;',
|
|
2367
|
+
'z-index: -1;',
|
|
2368
|
+
'top: 0;',
|
|
2369
|
+
'left: 0;',
|
|
2370
|
+
'width: 100%;',
|
|
2371
|
+
'height: 100%;',
|
|
2372
|
+
'}',
|
|
2373
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2374
|
+
'position: absolute;',
|
|
2375
|
+
getPopinPosition(),
|
|
2376
|
+
getPopinDimensions(),
|
|
2377
|
+
'pointer-events: all',
|
|
2378
|
+
'}',
|
|
2379
|
+
`${
|
|
2380
|
+
!useDimensionsAuto()
|
|
2381
|
+
? [
|
|
2382
|
+
`#${this.widgetContainerId} .${this.contentClassName} > div {`,
|
|
2383
|
+
'height: 100%;',
|
|
2384
|
+
'overflow: auto;',
|
|
2385
|
+
'box-sizing: border-box;',
|
|
2386
|
+
'}',
|
|
2387
|
+
].join('')
|
|
2388
|
+
: ''
|
|
2389
|
+
}`,
|
|
2390
|
+
`${
|
|
2391
|
+
!useDimensionsAuto() && ['px', 'em'].includes(widthUnit)
|
|
2392
|
+
? [
|
|
2393
|
+
'@media screen and (max-width: 579px) {',
|
|
2394
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2395
|
+
'max-width: 94vw;',
|
|
2396
|
+
'}',
|
|
2397
|
+
'}',
|
|
2398
|
+
].join('')
|
|
2399
|
+
: ''
|
|
2400
|
+
}`,
|
|
2401
|
+
].join('');
|
|
2402
|
+
}
|
|
2403
|
+
}
|
|
2404
|
+
|
|
2405
|
+
class Banner extends WidgetContainer {
|
|
2406
|
+
constructor() {
|
|
2407
|
+
super();
|
|
2408
|
+
this.position =
|
|
2409
|
+
typeof DATA.layout === 'string' && DATA.layout === 'bannerTop' ? 'top' : 'bottom';
|
|
2410
|
+
this.stringStyles = this.getStyles();
|
|
2411
|
+
this.styleElement = this.getStyleTag(this.stringStyles);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
getStyles() {
|
|
2415
|
+
const { zindex, zindexCustom } = DATA;
|
|
2416
|
+
return [
|
|
2417
|
+
`#${this.widgetContainerId} {`,
|
|
2418
|
+
'position: fixed;',
|
|
2419
|
+
`${this.position}: 0;`,
|
|
2420
|
+
'left: 0;',
|
|
2421
|
+
'width: 100%;',
|
|
2422
|
+
'height: auto;',
|
|
2423
|
+
`z-index: ${zindex === 'custom' ? zindexCustom : zindex};`,
|
|
2424
|
+
'background: none;',
|
|
2425
|
+
'}',
|
|
2426
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2427
|
+
'position: relative;',
|
|
2428
|
+
'}'
|
|
2429
|
+
].join('');
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
class Free extends WidgetContainer {
|
|
2434
|
+
constructor(target, index) {
|
|
2435
|
+
super(target, index);
|
|
2436
|
+
this.stringStyles = this.getStyles();
|
|
2437
|
+
this.styleElement = this.getStyleTag(this.stringStyles);
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
getStyles() {
|
|
2441
|
+
return [
|
|
2442
|
+
`#${this.widgetContainerId} {`,
|
|
2443
|
+
'width: auto;',
|
|
2444
|
+
'height: auto;',
|
|
2445
|
+
'margin: 0;',
|
|
2446
|
+
'padding: 0;',
|
|
2447
|
+
'background: none;',
|
|
2448
|
+
'}',
|
|
2449
|
+
`#${this.widgetContainerId} .${this.contentClassName} {`,
|
|
2450
|
+
'position: relative;',
|
|
2451
|
+
'}'
|
|
2452
|
+
].join('');
|
|
2453
|
+
}
|
|
2454
|
+
}
|
|
2455
|
+
|
|
2456
|
+
const getWidgetContainer = () => {
|
|
2457
|
+
const { layout } = DATA;
|
|
2458
|
+
|
|
2459
|
+
let parentContainer;
|
|
2460
|
+
|
|
2461
|
+
switch (layout) {
|
|
2462
|
+
case 'popin':
|
|
2463
|
+
parentContainer = new Popin();
|
|
2464
|
+
break;
|
|
2465
|
+
case 'bannerTop':
|
|
2466
|
+
case 'bannerBottom':
|
|
2467
|
+
parentContainer = new Banner();
|
|
2468
|
+
break;
|
|
2469
|
+
case 'free':
|
|
2470
|
+
parentContainer = new Free();
|
|
2471
|
+
break;
|
|
2472
|
+
default:
|
|
2473
|
+
parentContainer = new WidgetContainer();
|
|
2474
|
+
break;
|
|
2475
|
+
}
|
|
2476
|
+
|
|
2477
|
+
return parentContainer;
|
|
2478
|
+
};
|
|
2479
|
+
|
|
2480
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
2481
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
2482
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || false, o.configurable = true, "value" in o && (o.writable = true), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
2483
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: false }), e; }
|
|
2484
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
2485
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return (String )(t); }
|
|
2486
|
+
var Widget = /*#__PURE__*/function () {
|
|
2487
|
+
function Widget(_ref) {
|
|
2488
|
+
var parentContainer = _ref.parentContainer;
|
|
2489
|
+
_classCallCheck(this, Widget);
|
|
2490
|
+
this.parentContainer = parentContainer;
|
|
2491
|
+
this.baseClassName = "qualitywidget_container";
|
|
2492
|
+
this.className = "".concat(this.baseClassName, "_").concat(parentContainer.uniqueId);
|
|
2493
|
+
this.contentElement = this.getContentElement();
|
|
2494
|
+
}
|
|
2495
|
+
return _createClass(Widget, [{
|
|
2496
|
+
key: "insertIn",
|
|
2497
|
+
value: function insertIn(element, position) {
|
|
2498
|
+
this.setStyles();
|
|
2499
|
+
element.insertAdjacentElement(position, this.contentElement);
|
|
2500
|
+
return this;
|
|
2501
|
+
}
|
|
2502
|
+
}, {
|
|
2503
|
+
key: "addCloseEvent",
|
|
2504
|
+
value: function addCloseEvent(closeElement) {
|
|
2505
|
+
var _this = this;
|
|
2506
|
+
if (closeElement) closeElement.addEventListener('click', function onClose(event) {
|
|
2507
|
+
avoidEventDetection(event);
|
|
2508
|
+
if (!isOnEditor()) _this.parentContainer.recurrence.setClosingRecurrence();
|
|
2509
|
+
_this.parentContainer.hide();
|
|
2510
|
+
setTimeout(function () {
|
|
2511
|
+
return _this.parentContainer.remove();
|
|
2512
|
+
}, 1000);
|
|
2513
|
+
}, {
|
|
2514
|
+
capture: true,
|
|
2515
|
+
passive: false
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
}, {
|
|
2519
|
+
key: "addRedirectionEvent",
|
|
2520
|
+
value: function addRedirectionEvent(element) {
|
|
2521
|
+
var _this2 = this;
|
|
2522
|
+
if (!isOnEditor() && element) element.addEventListener('click', function onRedirect() {
|
|
2523
|
+
var _DATA = DATA,
|
|
2524
|
+
autoHide = _DATA.autoHide,
|
|
2525
|
+
timeHide = _DATA.timeHide;
|
|
2526
|
+
if (autoHide) setTimeout(function () {
|
|
2527
|
+
return _this2.parentContainer.hide();
|
|
2528
|
+
}, timeHide * 1000);
|
|
2529
|
+
if (!isOnEditor()) _this2.parentContainer.recurrence.setValidationRecurrence();
|
|
2530
|
+
}, {
|
|
2531
|
+
capture: true,
|
|
2532
|
+
passive: true
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2535
|
+
}, {
|
|
2536
|
+
key: "getButton",
|
|
2537
|
+
value: function getButton() {
|
|
2538
|
+
var _DATA2 = DATA,
|
|
2539
|
+
linkType = _DATA2.linkType,
|
|
2540
|
+
buttonText = _DATA2.buttonText,
|
|
2541
|
+
redirectionUrl = _DATA2.redirectionUrl,
|
|
2542
|
+
openInNewTab = _DATA2.openInNewTab;
|
|
2543
|
+
var button = document.createElement('a');
|
|
2544
|
+
button.ariaLabel = buttonText;
|
|
2545
|
+
button.className = 'popin_link';
|
|
2546
|
+
button.innerHTML = "<span>".concat(buttonText, "</span>");
|
|
2547
|
+
if (linkType === 'button') {
|
|
2548
|
+
button.href = redirectionUrl;
|
|
2549
|
+
button.target = openInNewTab ? '_blank' : '_self';
|
|
2550
|
+
this.addRedirectionEvent(button);
|
|
2551
|
+
} else {
|
|
2552
|
+
button.href = '#';
|
|
2553
|
+
button.dataset.abtastyActionnable = 'true';
|
|
2554
|
+
this.addCloseEvent(button);
|
|
2555
|
+
}
|
|
2556
|
+
return button;
|
|
2557
|
+
}
|
|
2558
|
+
}, {
|
|
2559
|
+
key: "getContentElement",
|
|
2560
|
+
value: function getContentElement() {
|
|
2561
|
+
var _DATA3 = DATA,
|
|
2562
|
+
isTitle = _DATA3.isTitle,
|
|
2563
|
+
isText = _DATA3.isText,
|
|
2564
|
+
linkType = _DATA3.linkType,
|
|
2565
|
+
buttonText = _DATA3.buttonText,
|
|
2566
|
+
iconPicker = _DATA3.iconPicker;
|
|
2567
|
+
var elementType = typeof linkType === 'string' && linkType.includes('widget') ? 'a' : 'div';
|
|
2568
|
+
var contentElement = document.createElement(elementType);
|
|
2569
|
+
contentElement.className = this.className;
|
|
2570
|
+
if ((iconPicker === null || iconPicker === void 0 ? void 0 : iconPicker.src) !== '') {
|
|
2571
|
+
var imgElement = document.createElement('img');
|
|
2572
|
+
imgElement.setAttribute('src', iconPicker.src);
|
|
2573
|
+
imgElement.setAttribute('alt', iconPicker.alt);
|
|
2574
|
+
imgElement.classList.add('iconPicker');
|
|
2575
|
+
contentElement.appendChild(imgElement);
|
|
2576
|
+
}
|
|
2577
|
+
if (linkType === 'widget') {
|
|
2578
|
+
var _DATA4 = DATA,
|
|
2579
|
+
redirectionUrl = _DATA4.redirectionUrl,
|
|
2580
|
+
openInNewTab = _DATA4.openInNewTab;
|
|
2581
|
+
contentElement.href = redirectionUrl;
|
|
2582
|
+
contentElement.target = openInNewTab ? '_blank' : '_self';
|
|
2583
|
+
this.addRedirectionEvent(contentElement);
|
|
2584
|
+
} else if (linkType === 'widgetClose') {
|
|
2585
|
+
contentElement.href = '#';
|
|
2586
|
+
contentElement.dataset.abtastyActionnable = 'true';
|
|
2587
|
+
this.addCloseEvent(contentElement);
|
|
2588
|
+
}
|
|
2589
|
+
if (isTitle) {
|
|
2590
|
+
var _DATA5 = DATA,
|
|
2591
|
+
title = _DATA5.title;
|
|
2592
|
+
var titleElement = document.createElement('h4');
|
|
2593
|
+
titleElement.textContent = title;
|
|
2594
|
+
contentElement.appendChild(titleElement);
|
|
2595
|
+
}
|
|
2596
|
+
if (isText) {
|
|
2597
|
+
var _DATA6 = DATA,
|
|
2598
|
+
text = _DATA6.text,
|
|
2599
|
+
includeVariables = _DATA6.includeVariables;
|
|
2600
|
+
var textElement = document.createElement('p');
|
|
2601
|
+
var textContent = includeVariables ? Widget.getVariableText() : text;
|
|
2602
|
+
textElement.innerHTML = textContent;
|
|
2603
|
+
contentElement.appendChild(textElement);
|
|
2604
|
+
}
|
|
2605
|
+
if ([linkType, buttonText].every(function (prop) {
|
|
2606
|
+
return typeof prop === 'string';
|
|
2607
|
+
}) && linkType.includes('button') && buttonText.length) {
|
|
2608
|
+
var button = this.getButton();
|
|
2609
|
+
var buttonsContainer = document.createElement('div');
|
|
2610
|
+
buttonsContainer.className = 'buttons_container';
|
|
2611
|
+
buttonsContainer.appendChild(button);
|
|
2612
|
+
contentElement.appendChild(buttonsContainer);
|
|
2613
|
+
}
|
|
2614
|
+
return contentElement;
|
|
2615
|
+
}
|
|
2616
|
+
}, {
|
|
2617
|
+
key: "setStyles",
|
|
2618
|
+
value: function setStyles() {
|
|
2619
|
+
var _this$parentContainer = this.parentContainer,
|
|
2620
|
+
styleElement = _this$parentContainer.styleElement,
|
|
2621
|
+
widgetContainerId = _this$parentContainer.widgetContainerId;
|
|
2622
|
+
var _DATA7 = DATA,
|
|
2623
|
+
textColor = _DATA7.textColor,
|
|
2624
|
+
textAlign = _DATA7.textAlign,
|
|
2625
|
+
buttonsAlign = _DATA7.buttonsAlign;
|
|
2626
|
+
var baseSelector = "#".concat(widgetContainerId, " .").concat(this.className);
|
|
2627
|
+
var textColorValue = typeof textColor !== 'undefined' ? "color: ".concat(textColor, ";") : '';
|
|
2628
|
+
var textAlignValue = typeof textAlign !== 'undefined' ? "text-align: ".concat(textAlign, ";") : '';
|
|
2629
|
+
var buttonsAlignValue = typeof buttonsAlign !== 'undefined' && buttonsAlign !== 'fill' ? "text-align: ".concat(buttonsAlign, ";") : '';
|
|
2630
|
+
var stylesTextContent = ["".concat(baseSelector, " > * {"), 'display: inline-block;', 'vertical-align: middle;', '}', "".concat(baseSelector, " .iconPicker {"), 'width: 26px;', 'height: 26px;', '}', "".concat(baseSelector, " h4 {"), 'margin-bottom: 24px;', 'display: inline-block;', 'width: 100%', '}', "".concat(baseSelector, " p {"), 'width: 100%;', 'margin: 0;', 'white-space: pre-line;', textColorValue, textAlignValue, '}', "".concat(baseSelector, " .buttons_container {"), 'display: inline-block;', 'width: 100%;', buttonsAlignValue, '}', "".concat(baseSelector, " a {"), 'margin-top: 24px;', 'padding: 6px 16px;', "width: ".concat(buttonsAlign === 'fill' ? '100%' : 'auto', ";"), '}', '@media screen and (min-width: 1024px) {', '}', '@media screen and (max-width: 1023px) {', '}'].join('');
|
|
2631
|
+
styleElement.insertAdjacentText('beforeend', stylesTextContent);
|
|
2632
|
+
return styleElement;
|
|
2633
|
+
}
|
|
2634
|
+
}], [{
|
|
2635
|
+
key: "getVariableText",
|
|
2636
|
+
value: function getVariableText() {
|
|
2637
|
+
var _DATA8 = DATA,
|
|
2638
|
+
textVariables = _DATA8.textVariables,
|
|
2639
|
+
date = _DATA8.date,
|
|
2640
|
+
time = _DATA8.time,
|
|
2641
|
+
datetime = _DATA8.datetime,
|
|
2642
|
+
datetimeTimezone = _DATA8.datetimeTimezone;
|
|
2643
|
+
|
|
2644
|
+
// const jsTime = new Date(datetime);
|
|
2645
|
+
var jsDate = new Date(date);
|
|
2646
|
+
var jsDateTime = new Date(datetime);
|
|
2647
|
+
|
|
2648
|
+
// const hours = `${jsTime.getHours()}`;
|
|
2649
|
+
// const minutes = `${jsTime.getMinutes()}`;
|
|
2650
|
+
var jsDateDay = "".concat(jsDate.getDate());
|
|
2651
|
+
var jsDateMonth = "".concat(jsDate.getMonth() + 1);
|
|
2652
|
+
var jsDateYear = "".concat(jsDate.getFullYear());
|
|
2653
|
+
var jsDateTimeHours = "".concat(jsDateTime.getHours());
|
|
2654
|
+
var jsDateTimeMinutes = "".concat(jsDateTime.getMinutes());
|
|
2655
|
+
var jsDateTimeDay = "".concat(jsDateTime.getDate());
|
|
2656
|
+
var jsDateTimeMonth = "".concat(jsDateTime.getMonth() + 1);
|
|
2657
|
+
var jsDateTimeYear = "".concat(jsDateTime.getFullYear());
|
|
2658
|
+
var formatedDate = "".concat(jsDateDay.length < 2 ? "0".concat(jsDateDay) : jsDateDay, "/").concat(jsDateMonth.length < 2 ? "0".concat(jsDateMonth) : jsDateMonth, "/").concat(jsDateYear);
|
|
2659
|
+
var formatedTimeDate = "".concat(jsDateTimeHours.length < 2 ? "0".concat(jsDateTimeHours) : jsDateTimeHours, ":").concat(jsDateTimeMinutes.length < 2 ? "0".concat(jsDateTimeMinutes) : jsDateTimeMinutes);
|
|
2660
|
+
var formatedDateTime = "".concat(jsDateTimeDay.length < 2 ? "0".concat(jsDateTimeDay) : jsDateTimeDay, "/").concat(jsDateTimeMonth.length < 2 ? "0".concat(jsDateTimeMonth) : jsDateTimeMonth, "/").concat(jsDateTimeYear);
|
|
2661
|
+
var _datetimeTimezone$raw = datetimeTimezone.raw,
|
|
2662
|
+
followTheSun = _datetimeTimezone$raw.followTheSun,
|
|
2663
|
+
timezone = _datetimeTimezone$raw.timezone,
|
|
2664
|
+
previewTimezone = _datetimeTimezone$raw.previewTimezone,
|
|
2665
|
+
_datetimeTimezone$raw2 = _datetimeTimezone$raw.timedef,
|
|
2666
|
+
minute = _datetimeTimezone$raw2.minute,
|
|
2667
|
+
hour = _datetimeTimezone$raw2.hour,
|
|
2668
|
+
day = _datetimeTimezone$raw2.day,
|
|
2669
|
+
month = _datetimeTimezone$raw2.month,
|
|
2670
|
+
year = _datetimeTimezone$raw2.year;
|
|
2671
|
+
var formatedTimeTimezone = "".concat("".concat(hour).length < 2 ? "0".concat(hour) : hour, ":").concat("".concat(minute).length < 2 ? "0".concat(minute) : minute);
|
|
2672
|
+
var formatedDateTimezone = "".concat("".concat(day).length < 2 ? "0".concat(day) : day, "/").concat("".concat(month).length < 2 ? "0".concat(month) : month, "/").concat(year);
|
|
2673
|
+
var outputText = textVariables.replace('!time!', "<code class=\"time\">".concat(JSON.stringify(time, null, 0), "</code>")).replace('!date!', "<span class=\"date\">".concat(formatedDate, "</span>")).replace('!timedate!', "<span class=\"timedate\">".concat(formatedTimeDate, "</span>")).replace('!datetime!', "<span class=\"datetime\">".concat(formatedDateTime, "</span>")).replace('!timeTimezone!', "<span class=\"timeTimezone\">".concat(formatedTimeTimezone, "</span>")).replace('!dateTimezone!', "<span class=\"dateTimezone\">".concat(formatedDateTimezone, "</span>")).replace('!timezone!', "<span class=\"timezone\">".concat(followTheSun ? previewTimezone : timezone, "</span>"));
|
|
2674
|
+
return outputText;
|
|
2675
|
+
}
|
|
2676
|
+
}]);
|
|
2677
|
+
}();
|
|
2678
|
+
|
|
2679
|
+
function start() {
|
|
2680
|
+
widgetLog('Widget launch');
|
|
2681
|
+
var parentContainer = getWidgetContainer();
|
|
2682
|
+
var containerElement = parentContainer.domElement.querySelector(".".concat(parentContainer.contentClassName));
|
|
2683
|
+
var widget = new Widget({
|
|
2684
|
+
parentContainer: parentContainer
|
|
2685
|
+
});
|
|
2686
|
+
parentContainer.children = widget;
|
|
2687
|
+
widget.insertIn(containerElement, 'beforeend');
|
|
2688
|
+
parentContainer.init(true).then(function (_ref) {
|
|
2689
|
+
var response = _ref.response;
|
|
2690
|
+
if (response) parentContainer.show();
|
|
2691
|
+
});
|
|
2692
|
+
return {
|
|
2693
|
+
parentContainer: parentContainer,
|
|
2694
|
+
widget: widget
|
|
2695
|
+
};
|
|
2696
|
+
}
|
|
2697
|
+
start();
|
|
2698
|
+
|
|
2699
|
+
})();
|