UNPKG

@nosto/autocomplete

Version:

Library designed to simplify the implementation of search autocomplete functionality

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