UNPKG

@nosto/autocomplete

Version:

Library designed to simplify the implementation of search autocomplete functionality

96 lines (92 loc) 25.6 kB
/*! * mustache.js - Logic-less {{mustache}} templates with JavaScript * http://github.com/janl/mustache.js */var Se=Object.prototype.toString,L=Array.isArray||function(t){return Se.call(t)==="[object Array]"};function z(e){return typeof e=="function"}function ke(e){return L(e)?"array":typeof e}function G(e){return e.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function ee(e,t){return e!=null&&typeof e=="object"&&t in e}function Ce(e,t){return e!=null&&typeof e!="object"&&e.hasOwnProperty&&e.hasOwnProperty(t)}var Ee=RegExp.prototype.test;function Pe(e,t){return Ee.call(e,t)}var Ae=/\S/;function Te(e){return!Pe(Ae,e)}var Ie={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;","/":"&#x2F;","`":"&#x60;","=":"&#x3D;"};function Ue(e){return String(e).replace(/[&<>"'`=\/]/g,function(n){return Ie[n]})}var Le=/\s*/,De=/\s+/,te=/\s*=/,Oe=/\s*\}/,qe=/#|\^|\/|>|\{|&|=|!/;function Ne(e,t){if(!e)return[];var n=!1,r=[],o=[],i=[],c=!1,a=!1,u="",l=0;function s(){if(c&&!a)for(;i.length;)delete o[i.pop()];else i=[];c=!1,a=!1}var d,h,A;function I(S){if(typeof S=="string"&&(S=S.split(De,2)),!L(S)||S.length!==2)throw new Error("Invalid tags: "+S);d=new RegExp(G(S[0])+"\\s*"),h=new RegExp("\\s*"+G(S[1])),A=new RegExp("\\s*"+G("}"+S[1]))}I(t||b.tags);for(var p=new q(e),m,y,g,T,U,E;!p.eos();){if(m=p.pos,g=p.scanUntil(d),g)for(var O=0,J=g.length;O<J;++O)T=g.charAt(O),Te(T)?(i.push(o.length),u+=T):(a=!0,n=!0,u+=" "),o.push(["text",T,m,m+1]),m+=1,T===` `&&(s(),u="",l=0,n=!1);if(!p.scan(d))break;if(c=!0,y=p.scan(qe)||"name",p.scan(Le),y==="="?(g=p.scanUntil(te),p.scan(te),p.scanUntil(h)):y==="{"?(g=p.scanUntil(A),p.scan(Oe),p.scanUntil(h),y="&"):g=p.scanUntil(h),!p.scan(h))throw new Error("Unclosed tag at "+p.pos);if(y==">"?U=[y,g,m,p.pos,u,l,n]:U=[y,g,m,p.pos],l++,o.push(U),y==="#"||y==="^")r.push(U);else if(y==="/"){if(E=r.pop(),!E)throw new Error('Unopened section "'+g+'" at '+m);if(E[1]!==g)throw new Error('Unclosed section "'+E[1]+'" at '+m)}else y==="name"||y==="{"||y==="&"?a=!0:y==="="&&I(g)}if(s(),E=r.pop(),E)throw new Error('Unclosed section "'+E[1]+'" at '+p.pos);return He(je(o))}function je(e){for(var t=[],n,r,o=0,i=e.length;o<i;++o)n=e[o],n&&(n[0]==="text"&&r&&r[0]==="text"?(r[1]+=n[1],r[3]=n[3]):(t.push(n),r=n));return t}function He(e){for(var t=[],n=t,r=[],o,i,c=0,a=e.length;c<a;++c)switch(o=e[c],o[0]){case"#":case"^":n.push(o),r.push(o),n=o[4]=[];break;case"/":i=r.pop(),i[5]=o[2],n=r.length>0?r[r.length-1][4]:t;break;default:n.push(o)}return t}function q(e){this.string=e,this.tail=e,this.pos=0}q.prototype.eos=function(){return this.tail===""},q.prototype.scan=function(t){var n=this.tail.match(t);if(!n||n.index!==0)return"";var r=n[0];return this.tail=this.tail.substring(r.length),this.pos+=r.length,r},q.prototype.scanUntil=function(t){var n=this.tail.search(t),r;switch(n){case-1:r=this.tail,this.tail="";break;case 0:r="";break;default:r=this.tail.substring(0,n),this.tail=this.tail.substring(n)}return this.pos+=r.length,r};function D(e,t){this.view=e,this.cache={".":this.view},this.parent=t}D.prototype.push=function(t){return new D(t,this)},D.prototype.lookup=function(t){var n=this.cache,r;if(n.hasOwnProperty(t))r=n[t];else{for(var o=this,i,c,a,u=!1;o;){if(t.indexOf(".")>0)for(i=o.view,c=t.split("."),a=0;i!=null&&a<c.length;)a===c.length-1&&(u=ee(i,c[a])||Ce(i,c[a])),i=i[c[a++]];else i=o.view[t],u=ee(o.view,t);if(u){r=i;break}o=o.parent}n[t]=r}return z(r)&&(r=r.call(this.view)),r};function v(){this.templateCache={_cache:{},set:function(t,n){this._cache[t]=n},get:function(t){return this._cache[t]},clear:function(){this._cache={}}}}v.prototype.clearCache=function(){typeof this.templateCache<"u"&&this.templateCache.clear()},v.prototype.parse=function(t,n){var r=this.templateCache,o=t+":"+(n||b.tags).join(":"),i=typeof r<"u",c=i?r.get(o):void 0;return c==null&&(c=Ne(t,n),i&&r.set(o,c)),c},v.prototype.render=function(t,n,r,o){var i=this.getConfigTags(o),c=this.parse(t,i),a=n instanceof D?n:new D(n,void 0);return this.renderTokens(c,a,r,t,o)},v.prototype.renderTokens=function(t,n,r,o,i){for(var c="",a,u,l,s=0,d=t.length;s<d;++s)l=void 0,a=t[s],u=a[0],u==="#"?l=this.renderSection(a,n,r,o,i):u==="^"?l=this.renderInverted(a,n,r,o,i):u===">"?l=this.renderPartial(a,n,r,i):u==="&"?l=this.unescapedValue(a,n):u==="name"?l=this.escapedValue(a,n,i):u==="text"&&(l=this.rawValue(a)),l!==void 0&&(c+=l);return c},v.prototype.renderSection=function(t,n,r,o,i){var c=this,a="",u=n.lookup(t[1]);function l(h){return c.render(h,n,r,i)}if(u){if(L(u))for(var s=0,d=u.length;s<d;++s)a+=this.renderTokens(t[4],n.push(u[s]),r,o,i);else if(typeof u=="object"||typeof u=="string"||typeof u=="number")a+=this.renderTokens(t[4],n.push(u),r,o,i);else if(z(u)){if(typeof o!="string")throw new Error("Cannot use higher-order sections without the original template");u=u.call(n.view,o.slice(t[3],t[5]),l),u!=null&&(a+=u)}else a+=this.renderTokens(t[4],n,r,o,i);return a}},v.prototype.renderInverted=function(t,n,r,o,i){var c=n.lookup(t[1]);if(!c||L(c)&&c.length===0)return this.renderTokens(t[4],n,r,o,i)},v.prototype.indentPartial=function(t,n,r){for(var o=n.replace(/[^ \t]/g,""),i=t.split(` `),c=0;c<i.length;c++)i[c].length&&(c>0||!r)&&(i[c]=o+i[c]);return i.join(` `)},v.prototype.renderPartial=function(t,n,r,o){if(r){var i=this.getConfigTags(o),c=z(r)?r(t[1]):r[t[1]];if(c!=null){var a=t[6],u=t[5],l=t[4],s=c;u==0&&l&&(s=this.indentPartial(c,l,a));var d=this.parse(s,i);return this.renderTokens(d,n,r,s,o)}}},v.prototype.unescapedValue=function(t,n){var r=n.lookup(t[1]);if(r!=null)return r},v.prototype.escapedValue=function(t,n,r){var o=this.getConfigEscape(r)||b.escape,i=n.lookup(t[1]);if(i!=null)return typeof i=="number"&&o===b.escape?String(i):o(i)},v.prototype.rawValue=function(t){return t[1]},v.prototype.getConfigTags=function(t){return L(t)?t:t&&typeof t=="object"?t.tags:void 0},v.prototype.getConfigEscape=function(t){if(t&&typeof t=="object"&&!L(t))return t.escape};var b={name:"mustache.js",version:"4.2.0",tags:["{{","}}"],clearCache:void 0,escape:void 0,parse:void 0,render:void 0,Scanner:void 0,Context:void 0,Writer:void 0,set templateCache(e){N.templateCache=e},get templateCache(){return N.templateCache}},N=new v;b.clearCache=function(){return N.clearCache()},b.parse=function(t,n){return N.parse(t,n)},b.render=function(t,n,r,o){if(typeof t!="string")throw new TypeError('Invalid template! Template should be a "string" but "'+ke(t)+'" was given as the first argument for mustache#render(template, view, partials)');return N.render(t,n,r,o)},b.escape=Ue,b.Scanner=q,b.Context=D,b.Writer=v;var ne=`<div class="ns-autocomplete-results"> {{#response.keywords.hits.length}} <div class="ns-autocomplete-keywords"> <div class="ns-autocomplete-header"> Keywords </div> {{#response.keywords.hits}} <div class="ns-autocomplete-keyword" data-ns-hit="{{toJson}}" data-testid="keyword"> {{#_highlight.keyword}} <span>{{{.}}}</span> {{/_highlight.keyword}} {{^_highlight.keyword}} <span>{{keyword}}</span> {{/_highlight.keyword}} </div> {{/response.keywords.hits}} </div> {{/response.keywords.hits.length}} {{#response.products.hits.length}} <div class="ns-autocomplete-products"> <div class="ns-autocomplete-header"> Products </div> {{#response.products.hits}} <a class="ns-autocomplete-product" href="{{url}}" data-ns-hit="{{toJson}}" data-testid="product"> <img class="ns-autocomplete-product-image" src="{{#imageUrl}}{{ imageUrl }}{{/imageUrl}}{{^imageUrl}}{{ imagePlaceholder }}{{/imageUrl}}" alt="{{name}}" width="60" height="40" /> <div class="ns-autocomplete-product-info"> {{#brand}} <div class="ns-autocomplete-product-brand"> {{.}} </div> {{/brand}} <div class="ns-autocomplete-product-name"> {{name}} </div> <div> <span> {{price}}&euro; </span> {{#showListPrice}} <span class="ns-autocomplete-product-list-price"> {{listPrice}}&euro; </span> {{/showListPrice}} </div> </div> </a> {{/response.products.hits}} </div> {{/response.products.hits.length}} {{#history.length}} <div class="ns-autocomplete-history"> <div class="ns-autocomplete-header"> Recently searched </div> {{#history}} <div class="ns-autocomplete-history-item" data-ns-hit="{{toJson}}" data-testid="history"> {{item}} <a href="#" class="ns-autocomplete-history-item-remove" data-ns-remove-history="{{item}}"> &#x2715; </a> </div> {{/history}} </div> <div class="ns-autocomplete-history-clear"> <button type="button" class="ns-autocomplete-button" data-ns-remove-history="all"> Clear history </button> </div> {{/history.length}} {{#response.keywords.hits.length}}{{#response.products.hits.length}} <div class="ns-autocomplete-submit"> <button type="submit" class="ns-autocomplete-button"> See all search results </button> </div> {{/response.products.hits.length}}{{/response.keywords.hits.length}} </div> `;function re(e,t){if(b===void 0)throw new Error("Mustache is not defined. Please include the Mustache dependency or library in your page.");const{helpers:n}=t||{};return(r,o)=>(r.innerHTML=b.render(e,{...o,imagePlaceholder:"https://cdn.nosto.com/nosto/9/mock",toJson:function(){return JSON.stringify(this)},showListPrice:function(){return this.listPrice!==this.price},...n}),Promise.resolve())}function oe(){window.nostojs=window.nostojs??function(e){(window.nostojs.q=window.nostojs.q??[]).push(e)}}async function K(e){return window.nostojs(e)}typeof window<"u"&&(oe(),K(e=>{e.internal.getSettings()})),typeof window<"u"&&oe();function $e(e){K(t=>t.recordSearchClick("autocomplete",e))}function Re(e){K(t=>t.recordSearchSubmit(e))}function ie(){window.nostojs=window.nostojs??function(e){(window.nostojs.q=window.nostojs.q??[]).push(e)}}async function H(e){return window.nostojs(e)}typeof window<"u"&&(ie(),H(e=>{e.internal.getSettings()})),typeof window<"u"&&ie();const se=e=>String(e)==="[object Object]";function ae(e){if(!se(e))return!1;const t=e.constructor;if(t===void 0)return!0;const n=t.prototype;return!(!se(n)||!n.hasOwnProperty("isPrototypeOf"))}function $(e,t){if(e===t)return!0;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length!==t.length?!1:e.every((n,r)=>$(n,t[r]));if(ae(e)&&ae(t)){const n=Object.entries(e);return n.length!==Object.keys(t).length?!1:n.every(([r,o])=>$(o,t[r]))}return!1}function R(e){return(...t)=>{H(n=>{(n.internal.context.mode.isPreview()?console[e]:n.internal.logger[e])(...t)})}}const C={debug:R("debug"),info:R("info"),warn:R("warn"),error:R("error")};async function _e(e,{hitDecorators:t,...n},r){var o,i;const c=await r(e,n);if(!((i=(o=c.products)==null?void 0:o.hits)!=null&&i.length)||!(t!=null&&t.length))return c;const a=u=>t.reduce((l,s)=>s(l),u);return{...c,products:{...c.products,hits:c.products.hits.map(a)}}}function Me(e,t,n){const r=JSON.stringify(t);try{n.setItem(e,r)}catch(o){C.warn(o)}}function xe(e,t){try{const n=t.getItem(e);if(n)return JSON.parse(n)}catch(n){C.warn(n)}}function Je(e,t){Me(e,t,sessionStorage)}function Fe(e){return xe(e,sessionStorage)}const ce="nosto:search-js:cache",ze=60*1e3;function Ge(e,t){Je(ce,{query:e,result:t,created:Date.now()})}function Ke(e){const t=Fe(ce);if(!t||!Be(t))return null;const n=ue(t.query);return!$(ue(e),n)||Date.now()-t.created>ze?null:t.result}function ue(e){const t={...e,time:void 0,products:{...e.products,size:void 0}};return JSON.parse(JSON.stringify(t))}function Be(e){return typeof e=="object"&&e!==null&&"query"in e&&"result"in e&&"created"in e}async function We(e,{usePersistentCache:t,...n},r){if(!t)return r(e,n);const o=await Qe(e,n,r);return Ge(e,o),o}async function Qe(e,t,n){var r,o,i,c,a,u;const{from:l=0,size:s=0}=e.products||{},d=Ke(e);if(!d)return await n(e,t);const h=((r=d?.products)==null?void 0:r.size)??0,A=((o=d?.products)==null?void 0:o.hits)??[];if(s===h)return d;if(s<h)return{...d,products:{...d.products,size:s,hits:A.slice(0,s),total:((i=d.products)==null?void 0:i.total)||0}};const I=s-A.length,p=l>0?l+1:s-I,m={...e,products:{...e.products,from:p,size:I}},y=await n(m,t);return{...d,products:{...d.products,size:s,hits:[...((c=d.products)==null?void 0:c.hits)||[],...((a=y.products)==null?void 0:a.hits)||[]],total:((u=y.products)==null?void 0:u.total)||0}}}const Ve=3e4,B=new Map;function Ze(e,t){const n=B.get(e);if(!n)return;const r=Date.now()-n.created>Ve,o=$(t,n.query);if(r||!o){B.delete(e);return}return n.result}function Xe(e,t,n){B.set(e,{query:t,result:n,created:Date.now()})}async function Ye(e,t,n){if(!t.useMemoryCache)return n(e,t);const r=JSON.stringify(e),o=Ze(r,e);if(o)return o;const i=await n(e,t);return Xe(r,e,i),i}function et(e){return new Promise(t=>setTimeout(t,e))}async function tt(e,{maxRetries:t=0,retryInterval:n=0,...r},o){let i=0;for(;;)try{return await o(e,r)}catch(c){if(i>=t)throw c;if(!nt(c))throw C.info("Skipping retry logic for",c),c;i++,await et(n)}}function nt(e){return!e||typeof e!="object"?!1:!("status"in e)||rt(e.status)}function rt(e){return typeof e=="number"&&(e<400||e>=500)}async function ot(e,t={}){const n=await new Promise(H);return it(n.search,tt,Ye,We,_e)(e,t)}function it(e,...t){return t.reduce((n,r)=>(o,i)=>r(o,i,n),e)}const st=["productId","url","name","imageUrl","imageHash","thumbUrl","description","brand","variantId","availability","price","priceText","categoryIds","categories","customFields.key","customFields.value","priceCurrencyCode","datePublished","listPrice","unitPricingBaseMeasure","unitPricingUnit","unitPricingMeasure","googleCategory","gtin","ageGroup","gender","condition","alternateImageUrls","ratingValue","reviewCount","inventoryLevel","skus.id","skus.name","skus.price","skus.listPrice","skus.priceText","skus.url","skus.imageUrl","skus.inventoryLevel","skus.customFields.key","skus.customFields.value","skus.availability","pid","onDiscount","extra.key","extra.value","saleable","available","tags1","tags2","tags3"];async function W(e,t={}){const n=e.products?.fields??st,r=e.products?.facets??["*"],o=e.products?.size??20,i=e.products?.from??0,c=await ot({...e,products:{...e.products,fields:n,facets:r,size:o,from:i}},t);return{query:e,response:c}}const Q={serpPath:"/search",queryParamName:"query",enabled:!0};function le(){return{minQueryLength:2,historyEnabled:!0,historySize:5,hitDecorators:[],nostoAnalytics:!0,googleAnalytics:Q,routingHandler:e=>{location.href=e},nativeSubmit:!1,submit:(e,t,n)=>{e.length>=(t.minQueryLength??le().minQueryLength)&&W({query:e},{redirect:!0,track:t.nostoAnalytics?"serp":void 0,hitDecorators:t.hitDecorators,...n})}}}function at(e){e.setAttribute("autocomplete","off")}function ct(e,{onClick:t,onFocus:n,onInput:r,onKeyDown:o,onSubmit:i},{form:c=e.form??void 0,nativeSubmit:a}={}){const u=[];function l(s,d,h){s.addEventListener(d,h),u.push(()=>s.removeEventListener(d,h))}return(o||i)&&l(e,"keydown",s=>{o?.(e.value,s.key),o&&(s.key==="ArrowDown"||s.key==="ArrowUp")?s.preventDefault():i&&s.key==="Enter"&&(e.value!==""&&!s.repeat&&i(e.value),a||s.preventDefault())}),i&&c&&(l(c,"submit",s=>{a||s.preventDefault(),i(e.value)}),c.querySelectorAll("[type=submit]").forEach(s=>{l(s,"click",d=>{a||d.preventDefault(),i(e.value)})})),t&&l(e,"click",()=>t(e.value)),n&&l(e,"focus",()=>n(e.value)),r&&l(e,"input",()=>r(e.value)),{destroy(){u.forEach(s=>s())}}}function ut(e,t,n,r,o,i,c){let a=[],u=[],l=!0,s=-1;function d(f){const k=f?.dataset?.nsHit;if(k){const w=V(k);if(g(),w?.item){r(w.item);return}if(w?.keyword){r(w.keyword,{redirect:!!w?._redirect,isKeyword:!0}),w?._redirect&&i(w._redirect);return}w?.url&&i(w.url)}}function h(){l=!e.innerHTML.trim(),l||(a=Array.from(e.querySelectorAll("[data-ns-hit]")).map(f=>(I(f),f)))}function A(){Object.entries(c??{}).map(([f,k])=>{const w=`[data-ns-${f.replace(/([A-Z])/g,"-$1").toLowerCase()}]`;Array.from(e.querySelectorAll(w)).map(P=>{const be=P?.dataset?.[`ns${f.charAt(0).toUpperCase()+f.slice(1)}`],Y=()=>{k({data:be,el:P,update:y})};P.addEventListener("click",Y),u.push(()=>{P.removeEventListener("click",Y)})})})}function I(f){const k=()=>{d(f)};f.addEventListener("click",k),u.push(()=>{f.removeEventListener("click",k)})}function p(f,k){if(typeof k=="number"&&a[k]&&a[k].classList.remove("selected"),typeof f=="number"&&a[f]){a[f]?.classList.add("selected");const w=a[f]?.dataset?.nsHit;if(w){const P=V(w);if(P.item){o(P.item);return}if(P.keyword){o(P.keyword);return}}}}function m(){F(),a=[],u.forEach(f=>f()),u=[]}async function y(f){m(),await n(e,f),setTimeout(()=>{h(),A(),T()},0)}function g(){F(),e.style.display="none"}function T(){l?g():e.style.display=""}function U(){m(),l=!0,g()}function E(){return e.style.display!=="none"}function O(){let f=s;s===a.length-1?s=0:f=s++,p(s,f)}function J(){if(j()){let f=s;s===0?s=a.length-1:f=s--,p(s,f)}else s=a.length-1,p(s)}function S(){E()&&j()&&a[s]&&d(a[s])}function j(){return s>-1}function ve(){return a[s]}function F(){j()&&(a[s]?.classList.remove("selected"),s=-1)}function me(){m(),l=!0,e.innerHTML=""}async function we(){const f=await Promise.resolve(t);await Promise.resolve(n(e,f)),setTimeout(()=>{h(),A(),g()},0)}return we(),{update:y,clear:U,isOpen:E,goDown:O,goUp:J,handleSubmit:S,destroy:me,show:T,hide:g,resetHighlight:F,hasHighlight:j,getHighlight:ve,container:e}}function V(e){try{return JSON.parse(e)??{}}catch(t){return C.warn("Could not parse hit",t),{}}}class de extends Error{}function lt(e){let t=!1;return{promise:new Promise((n,r)=>e.then(o=>t?r(new de("cancelled promise")):n(o),o=>r(t?new de("cancelled promise"):o))),cancel(){t=!0}}}function dt({config:e,history:t,input:n}){let r;const o=(s,d,h)=>typeof d.fetch=="function"?d.fetch(s):W({query:s,...d.fetch},{track:d.nostoAnalytics?"autocomplete":void 0,redirect:!1,hitDecorators:d.hitDecorators,...h});function i(s){return Promise.resolve({query:{query:s},history:t?.getItems()})}function c(s,d){return r?.cancel(),s&&s.length>=e.minQueryLength?(r=lt(o(s,e,d)),r.promise):t?i(s??""):r?.promise??Promise.resolve({})}function a(s){return t&&t.add(s),i(n.value)}function u(s){return t&&t.remove(s),i(n.value)}function l(){return t&&t.clear(),i(n.value)}return{updateState:c,addHistoryItem:a,removeHistoryItem:u,clearHistory:l}}function _(e,t){return(typeof e=="string"?Array.from(document.querySelectorAll(e)):[e]).filter(n=>t?n instanceof t:!0)}function fe(e,t){let n=[];return _(e).forEach(r=>{const o=r.parentNode;o!==document&&o instanceof Element&&(n.push(o),n=n.concat(fe(o)))}),n.filter(r=>t===void 0)}function ft([e,t],n){const r=o=>{const i=o.target;i instanceof HTMLElement&&e&&i!==e&&i!==t&&!fe(i).includes(e)&&n()};return document.addEventListener("click",r),{destroy:()=>{document.removeEventListener("click",r)}}}const Z="nosto:autocomplete:gaEvent";function M(e){const{delay:t=!1,title:n=document.title,location:r=window.location.href}=e||{};if(t)pt(n,r);else{if("gtag"in window&&typeof window.gtag=="function"){const o="google_tag_manager"in window&&typeof window.google_tag_manager=="object"?Object.keys(window.google_tag_manager||[]).filter(i=>i.substring(0,2)=="G-"):[];if(o.length>1)for(let i=0;i<o.length;i++)window.gtag("event","page_view",{page_title:n,page_location:r,send_to:o[i]});else window.gtag("event","page_view",{page_title:n,page_location:r})}if("ga"in window&&typeof window.ga=="function"&&"getAll"in window.ga&&typeof window.ga.getAll=="function")try{const o=new URL(r),i=window.ga.getAll();i?.length>0&&i[0]?.send("pageview",o.pathname+o.search)}catch(o){C.warn("Could not send pageview to GA",o)}}}const x=e=>typeof e.googleAnalytics=="boolean"?e.googleAnalytics:typeof e.googleAnalytics=="object"&&e.googleAnalytics.enabled,X=(e,t)=>{const n=x(t)?typeof t.googleAnalytics=="boolean"?Q:{...Q,...t.googleAnalytics}:void 0;if(e&&n)try{return new URL(`${n?.serpPath||location.pathname}?${`${encodeURIComponent(n.queryParamName)}=${encodeURIComponent(e).replace(/%20/g,"+")}`}`,window.location.origin).toString()}catch(r){C.warn("Could not create track url",r);return}};function pt(e,t){localStorage.setItem(Z,JSON.stringify({title:e,location:t}))}function ht(){const e=localStorage.getItem(Z);if(typeof e=="string"){localStorage.removeItem(Z);try{const t=JSON.parse(e);M(t)}catch(t){C.warn("Could not consume pageView",t)}}}function yt(e){let t,n=!1;return r=>{n?(t&&clearTimeout(t),t=setTimeout(async()=>{await r(),n=!1},e)):(r(),n=!0)}}function gt(e){const t="nosto:autocomplete:history";let n=r();function r(){try{return JSON.parse(localStorage.getItem(t)??"[]")??[]}catch(l){return C.error("Could not get history items.",l),[]}}function o(l){try{localStorage.setItem(t,JSON.stringify(l))}catch(s){C.error("Could not set history items.",s)}}function i(l){o(n=[{item:l},...n?.filter(s=>s.item!==l)||[]].slice(0,e))}function c(){o(n=[])}function a(l){o(n=n.filter(s=>s.item!==l))}function u(){return n}return{add:i,clear:c,remove:a,getItems:u}}function pe(e){const t={...le(),...e},n=t.historyEnabled?gt(t.historySize):void 0,r=yt(300);x(e)&&setTimeout(ht,1e3);const o=_(e.inputSelector,HTMLInputElement).map(i=>{const c=dt({config:t,history:n,input:i}),a=vt({input:i,config:t,actions:c});if(!a)return;at(i);const u=ct(i,{onInput:async s=>{r(async()=>{const d=await c.updateState(s);a.update(d)})},onClick(){a.resetHighlight()},onFocus(){a.show()},onSubmit(){if(a.isOpen()&&a.hasHighlight()){const s=a.getHighlight()?.dataset?.nsHit;s&&he({config:t,data:s,query:i.value}),a.handleSubmit()}else ye({actions:c,config:t})(i.value)},onKeyDown(s,d){d==="Escape"?a.hide():d==="ArrowDown"?a.isOpen()?a.goDown():a.show():d==="ArrowUp"&&a.isOpen()&&a.goUp()}},{nativeSubmit:t.nativeSubmit}),l=ft([a.container,i],()=>{a.hide()});return{open(){a.show()},close(){a.hide()},destroy(){u.destroy(),l.destroy(),a.destroy()}}});return{destroy(){o.forEach(i=>i?.destroy())},open(){o.forEach(i=>i?.open())},close(){o.forEach(i=>i?.close())}}}function vt({input:e,config:t,actions:n}){const r=typeof t.dropdownSelector=="function"?_(t.dropdownSelector(e),HTMLElement):_(t.dropdownSelector,HTMLElement);if(r.length===0){C.error(`No dropdown element found for input ${e}`);return}else r.length>1&&C.error(`Multiple dropdown elements found for input ${e}, using the first element`);const o=r[0];return ut(o,n.updateState(e.value),t.render,ye({actions:n,config:t}),i=>e.value=i,t.routingHandler,{removeHistory:async function({data:i,update:c}){if(i==="all"){const a=await n.clearHistory();return c(a)}else if(i){const a=await n.removeHistoryItem(i);return c(a)}},hit:function({data:i}){i&&he({config:t,data:i,query:e.value})}})}async function he({config:e,data:t,query:n}){if(!e.googleAnalytics&&!e.nostoAnalytics)return;const r=V(t);e.nostoAnalytics&&r&&$e(r),x(e)&&(r._redirect&&M({delay:!0,location:X(r.keyword,e)}),r.url&&M({delay:!0,location:X(n,e)}))}function ye(e){return async(t,n)=>{const{config:r,actions:o}=e,{redirect:i=!1}=n??{};t.length>0&&(r.historyEnabled&&o.addHistoryItem(t),r.nostoAnalytics&&Re(t),x(r)&&M({delay:!0,location:X(t,r)}),!i&&typeof r?.submit=="function"&&r.submit(t,r,n))}}const mt={defaultCurrency:"EUR",defaultLocale:"en-US",currencySettings:{}},wt={EUR:"de-DE",GBP:"en-GB",USD:"en-US",AUD:"en-AU",CAD:"en-CA",INR:"en-IN",AFN:"en-IN",BDT:"en-IN",BTN:"en-IN",MMK:"en-IN",NPR:"en-IN",PKR:"en-IN"};function bt(e={}){const t={...mt,...e};e.currencySettings||H(r=>{t.currencySettings=r.internal.getSettings().currencySettings??{}});function n(r,o){const{defaultCurrency:i,currencySettings:c,defaultLocale:a}=t,u=o??i,l=wt[u]??a;if(u in c){const s=c[u],d=new Intl.NumberFormat(l,{useGrouping:!!s.groupingSeparator,minimumFractionDigits:s.decimalPlaces,maximumFractionDigits:s.decimalPlaces}).formatToParts(r).map(h=>h.type==="group"?s.groupingSeparator:h.type==="decimal"?s.decimalCharacter:h.value).join("");return s!=null&&s.currencyBeforeAmount?`${s.currencyToken}${d}`:`${d}${s?.currencyToken}`}return new Intl.NumberFormat(l,{style:"currency",currency:u}).format(r)}return{formatCurrency:n}}function St(e){const{formatCurrency:t}=bt(e);function n(o,i){const c={};return o.price!==void 0&&(c.priceText=t(o.price,i)),o.listPrice!==void 0&&(c.listPriceText=t(o.listPrice,i)),Object.assign({},o,c)}function r(o){return o.price!==void 0||o.listPrice!==void 0}return function(o){if(!r(o))return o;const i=n(o,o.priceCurrencyCode);return i.skus&&i.skus.some(r)&&(i.skus=i.skus.map(c=>r(c)?n(c,o.priceCurrencyCode):c)),i}}async function kt(e,{handler:t,defaultTemplate:n}){const r=e.querySelector("script[autocomplete-template]")?.textContent,o=Ct(e);if(!Object.keys(o).length)throw new Error("NostoAutocomplete: Missing required config.");return pe({...o,nativeSubmit:!0,render:t(r??n),submit(i){e.querySelector(o.inputSelector).value=i,e.querySelector("form")?.submit()}})}function Ct(e){const t=e.querySelector("script[autocomplete-config]");return t?JSON.parse(t.textContent):{}}class ge extends HTMLElement{async connectedCallback(){return kt(this,{handler:re,defaultTemplate:ne})}}customElements.define("nosto-autocomplete",ge);export{ge as NostoAutocomplete,pe as autocomplete,ne as defaultMustacheTemplate,re as fromMustacheTemplate,St as priceDecorator,W as search}; //# sourceMappingURL=autocomplete.bundle.mjs.map