vinoShipperInjector = (function (window) {
var cartInitialized = false;
var cartIdInitialized = false;
var module = {};
var googleAttempts = 0;
var config = {
sidePanelId: 'vs-cart',
iframeId: 'vs-iframe',
disableResize: window.vsDisableResize ? window.vsDisableResize : false,
server: detectServer(),
clientCss: detectClientCSSOverride(),
injectorCss: detectServer() + '/static/css/iframe/v2/injector.css',
defaultIFramePadding: 100,
defaultClubSignUpCallback: function () {
vsLog('Club Sign Up Complete');
}
};
var SIDE_PANEL = '
';
var CART_BUTTON = '';
// Utility Functions
var vsLog = window.vsLog = function () { vsLog.history = vsLog.history || []; vsLog.history.push(arguments); if (this.console) { console.log(Array.prototype.slice.call(arguments)) } };
var onDocumentReady = (function () { var f, b, c = {}; c["[object Boolean]"] = "boolean"; c["[object Number]"] = "number"; c["[object String]"] = "string"; c["[object Function]"] = "function"; c["[object Array]"] = "array"; c["[object Date]"] = "date"; c["[object RegExp]"] = "regexp"; c["[object Object]"] = "object"; var d = { isReady: false, readyWait: 1, holdReady: function (g) { if (g) { d.readyWait++ } else { d.ready(true) } }, ready: function (g) { if ((g === true && !--d.readyWait) || (g !== true && !d.isReady)) { if (!document.body) { return setTimeout(d.ready, 1) } d.isReady = true; if (g !== true && --d.readyWait > 0) { return } f.resolveWith(document, [d]) } }, bindReady: function () { if (f) { return } f = d._Deferred(); if (document.readyState === "complete") { return setTimeout(d.ready, 1) } if (document.addEventListener) { document.addEventListener("DOMContentLoaded", b, false); window.addEventListener("load", d.ready, false) } else { if (document.attachEvent) { document.attachEvent("onreadystatechange", b); window.attachEvent("onload", d.ready); var g = false; try { g = window.frameElement == null } catch (h) { } if (document.documentElement.doScroll && g) { a() } } } }, _Deferred: function () { var j = [], k, h, i, g = { done: function () { if (!i) { var m = arguments, n, q, p, o, l; if (k) { l = k; k = 0 } for (n = 0, q = m.length; n < q; n++) { p = m[n]; o = d.type(p); if (o === "array") { g.done.apply(g, p) } else { if (o === "function") { j.push(p) } } } if (l) { g.resolveWith(l[0], l[1]) } } return this }, resolveWith: function (m, l) { if (!i && !k && !h) { l = l || []; h = 1; try { while (j[0]) { j.shift().apply(m, l) } } catch (n) { } finally { k = [m, l]; h = 0 } } return this }, resolve: function () { g.resolveWith(this, arguments); return this }, isResolved: function () { return !!(h || k) }, cancel: function () { i = 1; j = []; return this } }; return g }, type: function (g) { return g == null ? String(g) : c[Object.prototype.toString.call(g)] || "object" } }; function a() { if (d.isReady) { return } try { document.documentElement.doScroll("left") } catch (g) { setTimeout(a, 1); return } d.ready() } if (document.addEventListener) { b = function () { document.removeEventListener("DOMContentLoaded", b, false); d.ready() } } else { if (document.attachEvent) { b = function () { if (document.readyState === "complete") { document.detachEvent("onreadystatechange", b); d.ready() } } } } function e(h) { d.bindReady(); var g = d.type(h); f.done(h) } return e })();
var whichAnimationEvent = function () { var t, el = document.createElement("fakeelement"); var animations = { "animation": "animationend", "OAnimation": "oAnimationEnd", "MozAnimation": "animationend", "WebkitAnimation": "webkitAnimationEnd" }; for (t in animations) { if (el.style[t] !== undefined) { return animations[t]; } } };
var detectAnimationSupport = function (id) { var animation = false, animationstring = 'animation', keyframeprefix = '', domPrefixes = 'Webkit Moz O ms Khtml'.split(' '), pfx = '', elm = document.getElementById(id); if (elm.style.animationName !== undefined) { animation = true; } if (animation === false) { for (var i = 0; i < domPrefixes.length; i++) { if (elm.style[domPrefixes[i] + 'AnimationName'] !== undefined) { pfx = domPrefixes[i]; animationstring = pfx + 'Animation'; keyframeprefix = '-' + pfx.toLowerCase() + '-'; animation = true; break; } } } return animation; };
var supplant = function (input, model) { vsLog(input); vsLog(model); if (!input || !model) { return input; } return input.replace(/{([^{}]*)}/g, function (a, b) { var r = model[b]; return typeof r === 'string' || typeof r === 'number' ? r : a; }); };
var qsParam = function (name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); };
var isBlocker = function (callback) {
var msie = window.navigator.userAgent.indexOf("MSIE ");
if (msie > -1 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) return;
var testURL = 'https://www.google-analytics.com/analytics.js'
var myInit = {
method: 'HEAD',
mode: 'no-cors'
};
var myRequest = new Request(testURL, myInit);
fetch(myRequest).then(function (response) {
return response;
}).then(function (response) {
callback && callback(false)
}).catch(function (e) {
callback && callback(true)
});
}
// Detect Configuration, for CI builds we want to use the same hostname as the parent frame,
// everywhere else we want to use the specific url for our environment. IE: vinoshipper.com or staging.aws.zlminc.com
function detectServer() {
var server = 'https://vinoshipper.com';
if (window.location.hostname && window.location.hostname.indexOf('aws.zlminc.com') > 0 && window.location.hostname.indexOf('catalog.aws.zlminc.com') < 0) {
server = '//' + window.location.hostname;
}
return server;
}
function detectClientCSSOverride() {
return window.vsCssUrl || window.vinoshipperCss || "";
}
//Page Manipulation Functions
function injectCss(href) {
// bail out if already injected
var styles = document.styleSheets;
for (var i = 0, max = styles.length; i < max; i++) {
if (styles[i].href === href) return;
}
var head = document.getElementsByTagName('head')[0];
var style = document.createElement('link');
style.type = 'text/css';
style.rel = 'stylesheet';
style.href = href;
head.insertBefore(style, head.firstChild);
}
function injectHtml(html, containerId) {
var container = containerId ? document.getElementById(containerId) : document.getElementsByTagName('body')[0];
container.insertAdjacentHTML('beforeend', html);
var x = document.getElementsByClassName("vs-loading-msg");
for (var i = 0; i < x.length; i++) {
x[i].style.display = "none";
}
}
function appendHtmlInto(target, content, data) {
clearHtml(target);
var interpolated = supplant(content, data);
var receiverDiv = document.getElementById(target);
receiverDiv.insertAdjacentHTML('beforeend', interpolated);
}
function clearHtml() {
var div = document.getElementById('vs-injected-div');
if (div) {
div.parentNode.removeChild(div);
}
}
function injectFragmentFromServer(path, container) {
var xhr = new XMLHttpRequest();
xhr.timeout = 2000;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
container.innerHTML = xhr.responseText;
} else if (xhr.status == 404) {
container.appendChild(document.createComment("Winery ID / Product ID combination not found"));
} else {
console.log('Not ready');
}
}
}
xhr.ontimeout = function () {
console.log('Timeout');
}
xhr.open("GET", config.server + path);
xhr.send();
}
function resizeContentIframe(height) {
var body = document.body,
html = document.documentElement;
//hack: need fixed height to deal with mobile safari iframe in a fixed div issues
var width = Math.max(body.scrollWidth, body.offsetWidth, html.clientWidth, html.scrollWidth, html.offsetWidth);
if (width > 480) return;
if (!height) {
height = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
}
document.getElementById('vs-iframe-wrapper').style.height = height + 'px';
}
//HTML Generation Functions
function contentIframeHTML(title, page, cssFile, angularPath, params) {
module.onClubSignupComplete = params.callback || config.defaultClubSignUpCallback;
module.padding = isNaN(params.padding) ? config.defaultIFramePadding : params.padding;
var scrolling = config.disableResize ? '' : 'scrolling="no"';
var angular = angularPath ? '#' + angularPath + '?' : '&';
var tkit = window.tkit ? 'tkit=' + window.tkit + "&" : '';
var galinker = module.gaLinker ? module.gaLinker + '&' : '';
var gacid = module.gaClientId ? 'gacid='+module.gaClientId + '&' : '';
var preorder = params.preorder ? 'preorder=true' + '&' : '';
var clubIdLock = window.vsClubIdLock ? 'clubidlock=true' + '&' : '';
var clubAllowList = window.vsClubAllowList ? 'cluballowlist=' + window.vsClubAllowList.join(',') + '&' : '';
var cart = module.sessionid ? 'cartId=' + module.sessionid + '&' : '';
return '
';
}
function cartIFrameHTML() {
var cartId = "";
if (module.sessionid) {
cartId = "cartId=" + module.sessionid + "&";
}
var wineryId = '';
if(window.vsWineryId) {
wineryId = "wineryId=" + window.vsWineryId + "&";
}
var returnUrl = window.vsReturnUrl || window.location.href;
var galinker = module.gaLinker ? module.gaLinker + '&' : '';
var gacid = module.gaClientId ? 'gacid='+module.gaClientId + '&' : '';
return '';
}
//Interact with the cart
function initCart() {
if ((typeof window.vsShowCart !== undefined) && window.vsShowCart === false)
return;
injectHtml(SIDE_PANEL);
destroyCart();
cartInitialized = true;
}
//Initialize cart sessionid
function initCartId() {
var cartId = "";
if (module.sessionid) {
cartId = "cartId=" + module.sessionid + "&";
}
var wineryId = '';
if(window.vsWineryId) {
wineryId = "wineryId=" + window.vsWineryId + "&";
}
cartSessionIframe = '';
injectHtml(cartSessionIframe);
cartIdInitialized = true;
}
function cartContents(cartId, cb) {
var contents = { items: 0 };
if (!cartId) {
cartQty = contents;
return;
}
var xhr = new XMLHttpRequest();
xhr.timeout = 2000;
xhr.onreadystatechange = function() {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
var cart = JSON.parse(xhr.responseText);
var totalQty = 0;
cart.contents.forEach(function(lineItem) {
totalQty += lineItem.qty;
})
cb({ items: totalQty });
} else {
console.log('Not ready');
}
}
}
xhr.ontimeout = function () {
console.log('Timeout');
}
xhr.open("GET", config.server + '/json-api/v2/cart/' + cartId);
xhr.send();
}
function addItemToCart(productId, quantity, landingPage) {
var xhr = new XMLHttpRequest();
xhr.open("POST", config.server + '/iframe/v2/cart/add?cartId=' + module.sessionid);
xhr.onload = showCart;
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("id=" + productId + "&quantity=" + quantity + "&landingPage=" + landingPage);
}
function destroyCart() {
cartQty = { items: '' };
appendHtmlInto(config.sidePanelId, CART_BUTTON, cartQty);
cartContents(module.sessionid, function(qty){
appendHtmlInto(config.sidePanelId, CART_BUTTON, qty);
document.getElementsByTagName("body")[0].style.overflow = 'visible';
document.getElementById('vs-injected-div').onclick = showCart;
});
}
function hideCart() {
if (detectAnimationSupport(config.sidePanelId)) {
var elm = document.getElementById('vs-injected-div');
var transitionEvent = whichAnimationEvent();
var onAnimationEnd = function (event) {
elm.removeEventListener(transitionEvent, onAnimationEnd);
destroyCart();
};
elm.addEventListener(transitionEvent, onAnimationEnd);
elm.className = 'vs-cart-open vs-closing';
} else {
destroyCart();
}
}
function showCart() {
appendHtmlInto(config.sidePanelId, cartIFrameHTML());
document.getElementsByTagName("body")[0].style.overflow = 'hidden';
document.getElementById('vs-injected-div').onclick = hideCart;
document.getElementById('vs-iframe-stage').focus();
}
//Communicate with the IFrame
function onMessage(message) {
vsLog(message);
if (typeof message.data !== "string") return;
if (message.data === 'canHazPostMessage') {
document.getElementById(config.iframeId).contentWindow.postMessage('canHazPostMessage ack', "*");
} else if (message.data.indexOf('canHazPostMessage:') >= 0) {
module.sessionid = message.data.split(':')[1];
window.parent.document.dispatchEvent(new CustomEvent('vsCartIdEvent', { detail: module.sessionid }));
if (document.getElementById('vs-cart-count')) {
cartContents(module.sessionid, function(qty) {
document.getElementById('vs-cart-count').innerText = qty.items;
});
}
if (document.getElementById('vs-iframe')) {
document.getElementById(config.iframeId).contentWindow.postMessage('canHazPostMessage ack', "*");
}
} else if (message.data.indexOf('displayCart:') >= 0) {
module.sessionid = message.data.split(':')[1];
showCart();
} else if (message.data === 'hideCart') {
hideCart();
} else if (message.data.indexOf('iframe-height:') >= 0) {
var height = message.data.split(':')[1];
if (!config.disableResize) {
height = parseInt(height) + module.padding;
if (document.getElementById('vs-iframe')) {
document.getElementById('vs-iframe').parentNode.style.height = height + 'px';
}
}
} else if (message.data.indexOf('height:') >= 0) {
resizeContentIframe(message.data.split(':')[1]);
} else if (message.data.indexOf('clubSignUpComplete') >= 0) {
var payload = message.data.split(':')[1];
module.onClubSignupComplete(payload);
}
}
function initGoogle(callback) {
attempts = googleAttempts || 0;
if (!isBlocker() && window.ga && ga.create && !window.vsSkipAnalytics) {
ga(function () {
if (ga.getAll && ga.getAll().length > 0) {
var tracker = ga.getAll()[0];
module.gaClientId = tracker.get('clientId');
module.gaLinker = tracker.get('linkerParam');
}
googleAttempts = attempts + 1;
callback();
});
} else {
if (attempts <= 3) {
//retry in case GA is just slow
setTimeout(function () {
vsLog("attempt to load google: " + attempts + " skip:" + window.vsSkipAnalytics);
googleAttempts = attempts + 1;
initGoogle(callback);
}, 100);
} else {
vsLog('Google Analytics is blocked');
googleAttempts = attempts + 1;
callback();
}
}
googleAttempts = attempts + 1;
}
// add parameters you need here
var onReady = function (callback) {
callback = callback || function () { };
// wait until DOM is ready to append stuff
onDocumentReady(function () {
(function (callback) {
injectCss(config.injectorCss);
initGoogle(callback);
})(callback);
});
};
(window.addEventListener) ?
window.addEventListener('message', onMessage) :
window.attachEvent('onmessage', onMessage);
//Public functions
module.sessionid = window.vsCartId || '';
module.onReady = onReady;
module.isBlocker = isBlocker;
module.initCart = initCart;
module.initCartId = initCartId;
module.cartContents = cartContents;
module.showCart = showCart;
module.hideCart = hideCart;
module.addToCart = addItemToCart;
module.injectHtml = injectHtml;
module.outerIFrame = contentIframeHTML;
module.qsParam = qsParam;
module.injectFragmentFromServer = injectFragmentFromServer;
module.cartInitialized = cartInitialized;
return module;
})(window);
vsWineList = (function (window) {
var initialized = false;
function initInjector(container, force) {
if (!initialized || force) {
vinoShipperInjector.onReady(function () {
var wineryId = window.vsWineryId;
var cssFile = window.vsCssUrl || '';
var listId = window.vsWineListId || '';
var bustCache = window.vsBustCache || false;
var padding = window.vsIFramePadding || '';
if (document.getElementById(container)) {
var iframe = vinoShipperInjector.outerIFrame('Product List', '/iframe/v2/wine-list', cssFile, null, {
wineryId: wineryId,
listId: listId,
bustCache: bustCache,
padding: padding
});
vinoShipperInjector.injectHtml(iframe, container);
if (!document.getElementById('vs-cart'))
vinoShipperInjector.initCart();
initialized = true;
}
}, true);
}
}
return {
init: initInjector,
initialized: function () {
return initialized;
}
};
})(window);
vsWineClub = (function (window) {
var initialized = false;
function initInjector(container, force) {
if (!initialized || force) {
vinoShipperInjector.onReady(function () {
var wineryId = window.vsWineryId;
var cssFile = window.vsCssUrl || '';
var clubId = window.vsClubId || window.clubId || vinoShipperInjector.qsParam('clubId') || '';
var padding = window.vsIFramePadding;
var preorder = window.vsPreorder;
var clubIdLock = window.vsClubIdLock;
var clubAllowList = window.vsClubAllowList;
var iFrameTitle = 'Club Sign Up';
if (preorder) {
iFrameTitle = 'Pre-Order Sign Up';
}
if (document.getElementById(container)) {
var iframe = vinoShipperInjector.outerIFrame(iFrameTitle, '/apps/registration/club/CLUB', cssFile, null, {
wineryId: wineryId,
clubId: clubId,
preorder: preorder,
clubIdLock: clubIdLock,
clubAllowList: clubAllowList,
padding: padding,
callback: window.vsOnClubSignUpComplete
});
vinoShipperInjector.injectHtml(iframe, container);
initialized = true;
}
}, true);
}
}
return {
init: initInjector,
initialized: function () {
return initialized;
}
};
})(window);
vsAddToCartButton = (function (window) {
var module = {};
var addToCartButtonInitialized = false;
function renderWidget(target) {
var productId = target.getAttribute('data-product-id');
var wineryId = target.getAttribute('data-account-id') || target.getAttribute('data-winery-id');
var program = target.getAttribute('data-affinity-program');
var isMember = target.getAttribute('data-is-member');
var units = target.getAttribute('data-product-units') || '';
vinoShipperInjector.injectFragmentFromServer("/iframe/v3/add-to-cart-button?wineryId=" + wineryId + "&productId=" + productId + "&program=" + program + "&member=" + isMember + "&units=" + units, target);
}
function handleSubmit(event, form) {
event.preventDefault();
var productId = form.productId ? form.productId.value : form.id.value;
var quantity = 0;
var minimumOrder = form.minimumOrder ? form.minimumOrder.value || 1 : 1;
var landingPage = form.landingPage && form.landingPage.value ? form.landingPage.value : '';
for (var i = 0; i < form.elements.length; i++) {
var el = form.elements[i];
if (el.name === 'quantity') {
quantity += parseInt(el.value);
}
}
quantity = quantity > 0 ? quantity : minimumOrder;
vinoShipperInjector.addToCart(productId, quantity, landingPage);
return false;
}
function initInjector(selector, force) {
if (!addToCartButtonInitialized || force) {
vinoShipperInjector.onReady(function () {
var buttons = document.querySelectorAll(selector);
for (var i = 0; i < buttons.length; i++) {
renderWidget(buttons[i]);
}
if (!document.getElementById('vs-cart'))
vinoShipperInjector.initCart();
addToCartButtonInitialized = true;
});
}
}
//Communicate with the IFrame
function onMessage(message) {
vsLog(message);
if (typeof message.data !== "string") return;
if (message.data === 'canHazPostMessage') {
document.getElementById(config.iframeId).contentWindow.postMessage('canHazPostMessage ack', "*");
} else if (message.data.indexOf('canHazPostMessage:') >= 0) {
module.sessionid = message.data.split(':')[1];
vsLog('session id: ' + module.sessionid);
window.parent.document.dispatchEvent(new CustomEvent('vsCartIdEvent', { detail: module.sessionid }));
var itemCount = 0;
vinoShipperInjector.cartContents(module.sessionid, function(qty){
itemCount = qty;
});
// var itemCount = vinoShipperInjector.cartQty;
var vsCartCountElement = window.document.getElementById('vs-cart-count');
if (vsCartCountElement && itemCount) {
vsCartCountElement.innerText = itemCount.items;
}
}
}
(window.addEventListener) ?
window.addEventListener('message', onMessage) :
window.attachEvent('onmessage', onMessage);
return {
submit: handleSubmit,
init: initInjector,
sessionid: window.vsCartId || ''
};
})(window);
////////////////////////////
function init() {
vinoShipperInjector.isBlocker(function (blocked) {
if (blocked) {
console.info('init', 'ads are blocked');
} else {
console.info('init', 'ads are not blocked');
}
})
}
document.addEventListener('DOMContentLoaded', init, false);
////////////////////////
vsSquarespace = (function (window) {
var targetId = window.vsWineryId;
var type = window.type;
var module = {};
function isSquarespace() {
if ((document.getElementsByTagName('head')[0].innerHTML.search("")) > -1) {
console.log('Squarespace found');
return true;
}
return false;
}
function vsPageWatch() {
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
var a = new MutationObserver(function (a) {
for (var b = 0; b < a.length; b++) {
var c = a[b];
if ("attributes" === c.type) {
var d = new Event("pageChange");
document.dispatchEvent(d);
}
}
});
a.observe(document.body, { attributes: !0, attributeFilter: ["id"] });
}
module.isSquarespace = isSquarespace;
module.vsPageWatch = vsPageWatch;
return module;
})(window);
vsIframeInit = (function () {
if (vsSquarespace.isSquarespace()) {
vsSquarespace.vsPageWatch();
document.addEventListener("pageChange", function () {
if (document.getElementById("vs-winelist")) {
vsWineList.init("vs-winelist", 1);
}
if (document.getElementById("vs-wineclub-signup")) {
vsWineClub.init("vs-wineclub-signup", 1);
}
if (document.getElementsByClassName(".vs-add-to-cart")) {
vsAddToCartButton.init(".vs-add-to-cart", 1);
}
});
}
if (!vsWineList.initialized() && document.getElementById("vs-winelist"))
vsWineList.init('vs-winelist');
if (!vsWineClub.initialized() && document.getElementById("vs-wineclub-signup"))
vsWineClub.init('vs-wineclub-signup');
if (document.getElementsByClassName("vs-add-to-cart"))
vsAddToCartButton.init('.vs-add-to-cart');
if (!vinoShipperInjector.cartInitialized && !vsWineClub.initialized()) {
vinoShipperInjector.initCart();
}
if (!vinoShipperInjector.cartIdInitialized) {
vinoShipperInjector.initCartId();
}
});
window.addEventListener ? window.addEventListener("load", vsIframeInit, false) : window.attachEvent && window.attachEvent("onload", vsIframeInit);