1const POSTCARD_EMOJI_REGEX=/[\p{Extended_Pictographic}\u{FE0F}]/gu;function stripPostcardEmojis(text){return text.replace(POSTCARD_EMOJI_REGEX,"")}function getBundledSections(){const sections=[];return document.documentElement.dispatchEvent(new CustomEvent("cart:prepare-bundled-sections",{bubbles:!0,detail:{sections}})),sections}async function addToCartWithSections(variantId,message){const sectionsToBundle=getBundledSections(),formData=new FormData;formData.set("id",variantId),formData.set("quantity",1),formData.set("properties[Personlig Besked]",message),formData.set("properties[_postcard]","true"),formData.set("sections",sectionsToBundle.join(",")),formData.set("sections_url",window.location.pathname);const response=await fetch(`${Shopify.routes.root}cart/add.js`,{method:"POST",body:formData,headers:{"X-Requested-With":"XMLHttpRequest"}});if(!response.ok)throw new Error("Failed to add postcard to cart");const responseJson=await response.json(),cartContent=await(await fetch(`${Shopify.routes.root}cart.js`)).json();return cartContent.sections=responseJson.sections,cartContent}async function updateCartItemWithSections(lineKey,properties){const sectionsToBundle=getBundledSections(),response=await fetch(`${Shopify.routes.root}cart/change.js`,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest"},body:JSON.stringify({id:lineKey,properties,sections:sectionsToBundle.join(","),sections_url:window.location.pathname})});if(!response.ok)throw new Error("Failed to update cart item");return await response.json()}class PostcardWidget extends HTMLElement{constructor(){super(),this.boundOnProductAdded=this.onProductAdded.bind(this),this.messageSaved=!1}connectedCallback(){this.checkbox=this.querySelector('input[type="checkbox"]'),this.fields=this.querySelector(".postcard-widget__fields"),this.messageInput=this.querySelector("textarea"),this.saveButton=this.querySelector(".postcard-widget__save"),this.statusEl=this.querySelector(".postcard-widget__status"),this.previewMessageEl=this.querySelector("[data-postcard-preview-message]"),this.modalOpenButton=this.querySelector("[data-postcard-preview-open]"),this.modalEl=this.querySelector("postcard-preview-modal"),this.modalMessageEl=this.querySelector("[data-postcard-modal-message]"),this.previewPlaceholder=this.previewMessageEl?this.previewMessageEl.textContent.trim():"",this.checkbox&&this.checkbox.addEventListener("change",this.toggleFields.bind(this)),this.saveButton&&this.saveButton.addEventListener("click",this.saveMessage.bind(this)),this.messageInput&&this.messageInput.addEventListener("input",this.onInput.bind(this)),this.modalOpenButton&&this.modalOpenButton.addEventListener("click",this.openModal.bind(this)),document.addEventListener("variant:add",this.boundOnProductAdded)}onInput(){if(!this.messageInput)return;const original=this.messageInput.value,cleaned=stripPostcardEmojis(original);if(cleaned!==original){const caret=this.messageInput.selectionStart;this.messageInput.value=cleaned;const newPos=Math.max(0,caret-(original.length-cleaned.length));try{this.messageInput.setSelectionRange(newPos,newPos)}catch{}}this.updatePreview(cleaned),this.messageSaved&&(this.messageSaved=!1,this.hideStatus())}updatePreview(text){const value=(text||"").trim(),display=value.length>0?text:this.previewPlaceholder,isPlaceholder=value.length===0;this.previewMessageEl&&(this.previewMessageEl.textContent=display,this.previewMessageEl.classList.toggle("postcard-preview-card__message--placeholder",isPlaceholder)),this.modalMessageEl&&(this.modalMessageEl.textContent=display,this.modalMessageEl.classList.toggle("postcard-preview-card__message--placeholder",isPlaceholder))}openModal(){this.modalEl&&typeof this.modalEl.open=="function"&&this.modalEl.open(this.messageInput?this.messageInput.value:"")}disconnectedCallback(){document.removeEventListener("variant:add",this.boundOnProductAdded)}toggleFields(){this.fields&&(this.fields.hidden=!this.checkbox.checked,this.checkbox.checked&&this.messageInput&&this.messageInput.focus(),this.checkbox.checked||(this.messageSaved=!1,this.hideStatus(),this.updatePreview("")))}saveMessage(){this.messageInput&&(this.messageSaved=!0,this.showStatus(),this.saveButton&&(this.saveButton.setAttribute("aria-busy","true"),setTimeout(()=>{this.saveButton.removeAttribute("aria-busy")},300)))}
1showStatus(){this.statusEl&&this.statusEl.classList.add("is-visible")}hideStatus(){this.statusEl&&this.statusEl.classList.remove("is-visible")}async onProductAdded(event){if(!this.checkbox||!this.checkbox.checked)return;const message=this.messageInput?.value||"",variantId=this.dataset.postcardVariantId;if(variantId){try{const cartContent=await addToCartWithSections(variantId,message);document.documentElement.dispatchEvent(new CustomEvent("cart:change",{bubbles:!0,detail:{cart:cartContent,baseEvent:"variant:add"}}))}catch(error){console.error("Error adding postcard to cart:",error)}this.checkbox.checked=!1,this.messageInput&&(this.messageInput.value=""),this.fields&&(this.fields.hidden=!0),this.messageSaved=!1,this.hideStatus(),this.updatePreview("")}}}class PostcardMessageEditor extends HTMLElement{connectedCallback(){this.lineKey=this.dataset.lineKey,this.toggle=this.querySelector(".postcard-message-editor__toggle"),this.content=this.querySelector(".postcard-message-editor__content"),this.saveButton=this.querySelector("[data-save-message]"),this.textarea=this.querySelector("textarea"),this.statusEl=this.querySelector(".postcard-message-editor__status"),this.toggle&&this.toggle.addEventListener("click",this.toggleContent.bind(this)),this.saveButton&&this.saveButton.addEventListener("click",this.saveMessage.bind(this)),this.textarea&&(this.textarea.addEventListener("blur",()=>{this.hasChanges&&this.saveMessage()}),this.textarea.addEventListener("input",()=>{this.hasChanges=!0})),this.hasChanges=!1}toggleContent(){const expanded=this.toggle.getAttribute("aria-expanded")==="true";this.toggle.setAttribute("aria-expanded",!expanded),this.content&&(this.content.hidden=expanded,!expanded&&this.textarea&&setTimeout(()=>this.textarea.focus(),50))}async saveMessage(){if(!this.lineKey||!this.textarea)return;const message=this.textarea.value;this.saveButton&&(this.saveButton.setAttribute("aria-busy","true"),this.saveButton.disabled=!0);try{const cartContent=await updateCartItemWithSections(this.lineKey,{"Personlig Besked":message,_postcard:"true"});this.showStatus(),this.hasChanges=!1,document.documentElement.dispatchEvent(new CustomEvent("cart:change",{bubbles:!0,detail:{cart:cartContent,baseEvent:"postcard:update"}}))}catch(error){console.error("Error saving postcard message:",error)}finally{this.saveButton&&(this.saveButton.removeAttribute("aria-busy"),this.saveButton.disabled=!1)}}showStatus(){this.statusEl&&(this.statusEl.classList.add("is-visible"),setTimeout(()=>{this.statusEl.classList.remove("is-visible")},2e3))}}class PostcardCartWidget extends HTMLElement{connectedCallback(){this.addButton=this.querySelector(".postcard-cart-widget__add"),this.fields=this.querySelector(".postcard-cart-widget__fields"),this.textarea=this.querySelector("textarea"),this.expanded=!1,this.addButton&&this.addButton.addEventListener("click",this.handleClick.bind(this)),this.textarea&&this.textarea.addEventListener("input",this.onInput.bind(this))}onInput(){if(!this.textarea)return;const original=this.textarea.value,cleaned=stripPostcardEmojis(original);if(cleaned!==original){const caret=this.textarea.selectionStart;this.textarea.value=cleaned;const newPos=Math.max(0,caret-(original.length-cleaned.length));try{this.textarea.setSelectionRange(newPos,newPos)}catch{}}}handleClick(){if(this.expanded)this.addToCart();else if(this.fields){this.fields.hidden=!1,this.expanded=!0;const addToCartText=this.dataset.addToCartText||"Add to cart";this.addButton.textContent=addToCartText,this.textarea&&setTimeout(()=>this.textarea.focus(),50)}}async addToCart(){const variantId=this.dataset.postcardVariantId;if(!variantId)return;const message=this.textarea?.value||"";this.addButton&&(this.addButton.setAttribute("aria-busy","true"),this.addButton.disabled=!0);try{const cartContent=await addToCartWithSections(variantId,message);document.documentElement.dispatchEvent(new CustomEvent("cart:change",{bubbles:!0,detail:{cart:cartContent,baseEvent:"variant:add",onSuccessDo:"force_open_drawer"}}))}catch(error){console.error("Error adding postcard to cart:",error)}finally{this.addButton&&(this.addButton.removeAttribute("aria-busy"),this.addButton.disabled=!1)}}}class PostcardPreviewModal extends HTMLElement{constructor(){super(),this.boundOnKeyDown=this.onKeyDown.bind(this),this.boundOnFocusIn=this.onFocusIn.bind(this)}connectedCallback(){this.flipper=this.querySelector("[data-postcard-modal-flipper]"),this.flipButton=this.querySelector("[data-postcard-modal-flip]"),this.stage=this.querySelector("[data-postcard-modal-stage]"),this.messageEl=this.querySelector("[data-postcard-modal-message]"),this.dismissTargets=this.querySelectorAll("[data-postcard-modal-dismiss]"),this.returnFocusEl=null,this.isFlipped=!1,this.placeholderText=this.messageEl?this.messageEl.textContent.trim():"",this.flipButton&&(this.flipButton.addEventListener("click",this.flip.bind(this)),this.flipButton.setAttribute("aria-pressed","fal
1se")),this.stage&&this.stage.addEventListener("click",this.flip.bind(this)),this.dismissTargets.forEach(el=>{el.addEventListener("click",event=>{event.stopPropagation(),this.close()})})}open(message){this.returnFocusEl=document.activeElement;const text=(message||"").trim();this.messageEl&&(text.length>0?(this.messageEl.textContent=message,this.messageEl.classList.remove("postcard-preview-card__message--placeholder")):(this.messageEl.textContent=this.placeholderText,this.messageEl.classList.add("postcard-preview-card__message--placeholder"))),this.setFlipped(!1),this.setAttribute("open",""),this.setAttribute("aria-hidden","false"),document.body.style.overflow="hidden",document.addEventListener("keydown",this.boundOnKeyDown),document.addEventListener("focusin",this.boundOnFocusIn);const firstFocusable=this.querySelector(".postcard-preview-modal__close");firstFocusable&&firstFocusable.focus()}close(){this.removeAttribute("open"),this.setAttribute("aria-hidden","true"),document.body.style.overflow="",document.removeEventListener("keydown",this.boundOnKeyDown),document.removeEventListener("focusin",this.boundOnFocusIn),this.returnFocusEl&&typeof this.returnFocusEl.focus=="function"&&this.returnFocusEl.focus()}flip(event){event&&event.stopPropagation(),this.setFlipped(!this.isFlipped)}setFlipped(flipped){this.isFlipped=flipped,this.flipper&&this.flipper.classList.toggle("is-flipped",flipped),this.flipButton&&this.flipButton.setAttribute("aria-pressed",flipped?"true":"false")}onKeyDown(event){if(event.key==="Escape"){event.preventDefault(),this.close();return}if(event.key==="Tab"){const focusables=this.querySelectorAll('button, [href], input, textarea, [tabindex]:not([tabindex="-1"])');if(focusables.length===0)return;const first=focusables[0],last=focusables[focusables.length-1];event.shiftKey&&document.activeElement===first?(event.preventDefault(),last.focus()):!event.shiftKey&&document.activeElement===last&&(event.preventDefault(),first.focus())}}onFocusIn(event){if(this.hasAttribute("open")&&!this.contains(event.target)){const first=this.querySelector(".postcard-preview-modal__close");first&&first.focus()}}}customElements.get("postcard-widget")||customElements.define("postcard-widget",PostcardWidget),customElements.get("postcard-message-editor")||customElements.define("postcard-message-editor",PostcardMessageEditor),customElements.get("postcard-cart-widget")||customElements.define("postcard-cart-widget",PostcardCartWidget),customElements.get("postcard-preview-modal")||customElements.define("postcard-preview-modal",PostcardPreviewModal); 2//# sourceMappingURL=/cdn/shop/t/128/assets/postcard-widget.js.map?v=148635756941297316411787662953
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.