var BigCommerceArtifi = BigCommerceArtifi || {}; BigCommerceArtifi.isEventIsAlreadyRegistered = false; /*Personalize Button Template use for personalizeButton*/ var personalizeButton = '
'; personalizeButton += ''; personalizeButton += '
'; var addtoCartButton = '
'; addtoCartButton += ''; addtoCartButton += '
'; var cartPreviewAndEditButton = '
'; cartPreviewAndEditButton += 'Edit'; cartPreviewAndEditButton += '|'; cartPreviewAndEditButton += 'Preview'; cartPreviewAndEditButton += '
'; /* This target is use for adding above HTML */ var cartButtonContainerRef = "" /*Change Option Container */ var changeButtonContainer = ""; /*Cart content Container */ var cartTableContainer = '.cart'; /*Artifi Design ID Regex*/ var regexArtifiDesignId = /Artifi\sDesign\sId/g; var regexArtifiPDF = /Artifi\sPDF/g; var regexArtifiXML = /Artifi\sXML/g; var regexDesignIdPdfXml = /(Artifi\sDesign\sId|Artifi\sPDF|Artifi\sXML|Artifi\sPersonalized\sData|Artifi\sText\sPersonalization\sOption|Artifi\sImage\sPersonalization\sOption)/g; /* Personalize Button Wrapper Container use for changing the wrapper container of personalize button*/ /* var personalizeButtonContainer = "#id" */ var personalizeButtonContainer = "#artifi-personalize-button-container"; /* Artifi Iframe Wrapper Id mentioned Here for avoide hardcoded on code. Right now we are refring the classing themae. If anyone have there id he can use add there Id in this parameter and mention in product view page.*/ /* var personalizeIframeContainer = "#id/.class" */ var personalizeIframeContainer = ""; /*Add to Cart selector BigC */ var addToCartSelector = "input#form-action-addToCart[type=submit]"; var editModeHTML = ''; var isArtifiInitialize = false; var checkoutPageName = ""; BigCommerceArtifi.Constants = { cartItemsCookieName: 'bigcommerce.artifi.connector.cartItems', customerCookieName: 'bigcommerce.artifi.connector.customer' }; BigCommerceArtifi.Application = (function ($) { 'use strict'; var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", merchantId, websiteId, webApiClientKey, applicationHost, integrationUrl, frontUrl, integrationType, artifiBaseUrl; function init(config) { merchantId = config.merchantId; websiteId = decode(config.websiteId); webApiClientKey = decode(config.webApiClientKey); applicationHost = config.applicationHost; integrationUrl = config.integrationUrl; frontUrl = config.frontUrl; integrationType = config.integrationType; artifiBaseUrl = config.artifiBaseUrl; $(window) .ready(loadArtifiLibrary()) .ready(loadCookieLibrary()) .ready(initRequestsObserver()); } function initRequestsObserver() { addMiniCartPopupHandler(); var pattern = /\/cart.php?/g; function addXMLRequestCallback(callback) { var oldSend, i; if (XMLHttpRequest.callbacks) { // we've already overridden send() so just add the callback XMLHttpRequest.callbacks.push(callback); } else { // create a callback queue XMLHttpRequest.callbacks = [callback]; // store the native send() oldSend = XMLHttpRequest.prototype.send; // override the native send() XMLHttpRequest.prototype.send = function () { // process the callback queue // the xhr instance is passed into each callback but seems pretty useless // you can't tell what its destination is or call abort() without an error // so only really good for logging that a request has happened // I could be wrong, I hope so... // EDIT: I suppose you could override the onreadystatechange handler though if (XMLHttpRequest.callbacks != undefined) { for (i = 0; i < XMLHttpRequest.callbacks.length; i++) { XMLHttpRequest.callbacks[i](this); } } // call the native send() oldSend.apply(this, arguments); } } } addXMLRequestCallback(function (xhr) { xhr.addEventListener('load', function () { var result = pattern.exec(xhr.responseURL); if (result !== null) { cartPageLoadEvents(); } }); }); } function loadArtifiLibrary() { var script_cycle = document.createElement('script'); script_cycle.setAttribute("type", "text/javascript"); script_cycle.setAttribute("src", integrationUrl); (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_cycle); } function loadCookieLibrary() { var script_cycle = document.createElement('script'); script_cycle.setAttribute("type", "text/javascript"); script_cycle.setAttribute("src", "https://cdnjs.cloudflare.com/ajax/libs/js-cookie/2.1.3/js.cookie.min.js"); (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(script_cycle); } function getWebsiteId() { return websiteId; } function getIntegrationUrl() { return integrationUrl; } function getFrontUrl() { return frontUrl; } function getWebApiClientKey() { return webApiClientKey; } function getIntegrationType() { return integrationType; } function getArtifiBaseUrl() { return artifiBaseUrl; } function sendRequest(endpoint, method, payload, callback, callbackData, errorCallback) { $.ajax({ type: method, url: applicationHost + endpoint, async: true, data: payload, contentType: "application/json; charset=utf-8", // ✅ Correct way to send JSON dataType: "json", beforeSend: function (xhr) { xhr.setRequestHeader('Authorization', merchantId); }, success: function (response) { callback(response, callbackData); }, error: function (response) { if (errorCallback) { errorCallback(response, callbackData); } } }); } function decode(input) { var output = ""; var chr1, chr2, chr3; var enc1, enc2, enc3, enc4; var i = 0; input = input.replace(/[^A-Za-z0-9\+\/\=]/g, ""); while (i < input.length) { enc1 = keyStr.indexOf(input.charAt(i++)); enc2 = keyStr.indexOf(input.charAt(i++)); enc3 = keyStr.indexOf(input.charAt(i++)); enc4 = keyStr.indexOf(input.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 != 64) { output = output + String.fromCharCode(chr2); } if (enc4 != 64) { output = output + String.fromCharCode(chr3); } } return _utf8_decode(output); } function _utf8_decode(utftext) { var string = ""; var i = 0; var c = 0, c2 = 0, c3 = 0; while (i < utftext.length) { c = utftext.charCodeAt(i); if (c < 128) { string += String.fromCharCode(c); i++; } else if ((c > 191) && (c < 224)) { c2 = utftext.charCodeAt(i + 1); string += String.fromCharCode(((c & 31) << 6) | (c2 & 63)); i += 2; } else { c2 = utftext.charCodeAt(i + 1); c3 = utftext.charCodeAt(i + 2); string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); i += 3; } } return string; } function getBaseIntergrationValues() { var integrationValues = {}; integrationValues.websiteId = getWebsiteId(); integrationValues.webApiClientKey = getWebApiClientKey(); integrationValues.divId = 'bigcommerce-artifi-iframe-container'; return integrationValues; } function getUrlParameter(searchedParameterName) { var pageUrl = decodeURIComponent(window.location.search.substring(1)), variables = pageUrl.split('&'), parameterName, i; for (i = 0; i < variables.length; i++) { parameterName = variables[i].split('='); if (parameterName[0] === searchedParameterName) { return parameterName[1] === undefined ? true : parameterName[1]; } } return false; } function generateUniqueIdentifier() { return guid4() + guid4() + '-' + guid4() + '-' + guid4() + '-' + guid4() + '-' + guid4() + guid4() + guid4(); } function guid4() { return Math.floor((1 + Math.random()) * 0x10000) .toString(16) .substring(1); } function cartPageLoadEvents() { if (BigCommerceArtifi.ProductPage.updatePreviewPopup) { BigCommerceArtifi.ProductPage.updatePreviewPopup(""); } if ($('#tempCartDiv').length) { $('#tempCartDiv').remove(); } var div = $('