/** * Hallmark Data Layer * Loosely base upon the W3C Spec for Customer Experience Digital Data Layer 1.0 * * Please be careful not to overwrite properties in the dataLayer with statements like: dataLayer.modal = {}; * Use dataLayer.reset() instead. (see below) **/ (function () { window.parseQueryString = function() { var str = window.location.search; var objURL = {}; str.replace( new RegExp( "([^?=&]+)(=([^&]*))?", "g" ), function( $0, $1, $2, $3 ){ objURL[ $1 ] = $3; } ); return objURL; }; var dataLayer = window.dataLayer = { siteType : "responsive", siteID : "hallmark.com", page : { pageInfo : { pageURL : window.location.href, referringURL : document.referrer, sysEnv : "Production", language : navigator.language, IP: "163.172.137.41", adminView : "No" }, attributes : [{includedComponents: []}] }, product : { productInfo : [], category : { }, }, cart : { price: { orderLevelDiscountCodes: [] }, item: [], allItemsInCart:[] }, lists:{ item: [] }, transaction : { profile: { address: {}, shippingAddress: [] }, total: { paymentMethods: [], orderLevelDiscountCodes: [], shippingInfo: {}, numberofStorePickups: 0, shipmentInfo: [], storePickupInfo: [] }, item: [] }, event : [ ], messages: { formFieldMessages: [], informationalMessages: [], promotionalMessages: [], serverSideMessages: [], statusMessages: [] }, modal: { event: [], product: { productInfo:{} }, cart: { price:{ orderLevelPromoCodes: [] }, item: [] }, messages: { formFieldMessages: [], informationalMessages: [], promotionalMessages: [], serverSideMessages: [], statusMessages: [] }, store: { locator: {}, storeInfo:{} }, itemAddToCart: [], attributes: [] }, store: { storeInfo: {} }, navigation:{}, version: "1.1" }; var resetByDefault = { _include: true, // everything is included by default cart : false, event : true, messages : true, modal : true, page : false, product : false, siteID : false, siteType : false, store: false, transaction : false, version: false, user: false }; dataLayer.reset = function reset(include) { include = include || {}; include = dataLayer.extend({}, resetByDefault, include); dataLayer.preserveObjectIncludes(include, resetByDefault); dataLayer.resetObject(dataLayer, include); }; dataLayer.resetObject = function resetObject(obj, include) { include = (typeof include === "object") ? include : {_include: include || true}; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { var resetProperty = include._include; if (include.hasOwnProperty(prop)) { if (typeof include[prop] === "object") { resetProperty = include[prop]._include; } else { resetProperty = include[prop]; } } else { include[prop] = include._include; } switch (typeof obj[prop]) { case "object": if (Array.isArray(obj[prop])) { if (resetProperty) { obj[prop].length = 0; } } else { if (include[prop] === false) { } else { dataLayer.resetObject(obj[prop], include[prop]); } } break; case "function": break; default: if (resetProperty) { delete obj[prop]; } } } } }; dataLayer.preserveObjectIncludes = function preserveObjectIncludes(include, defaultInclude) { include = include || {}; for (var prop in include) { if (include.hasOwnProperty(prop)) { if (typeof include[prop] === "object") { if (typeof include[prop]._include === "undefined") { if (typeof defaultInclude[prop] === "boolean") { include[prop]._include = defaultInclude[prop]; } else { include[prop]._include = include._include; } } dataLayer.preserveObjectIncludes(include[prop], defaultInclude[prop]); } } } }; /** * This is just a modified version of the extend() function from: * * jQuery JavaScript Library v2.1.4 * http://jquery.com/ ** * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors * Released under the MIT license * http://jquery.org/license * * Date: 2015-04-28T16:01Z * * We use it here because we do not want the dataLayer to depend on any external libraries. */ dataLayer.extend = function extend() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation if ( typeof target === "boolean" ) { deep = target; // Skip the boolean and the target target = arguments[ i ] || {}; i++; } // Handle case when target is a string or something (possible in deep copy) if ( typeof target !== "object" && typeof target !== "function" ) { target = {}; } // Extend jQuery itself if only one argument is passed if ( i === length ) { target = this; i--; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values if ( (options = arguments[ i ]) !== null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays if ( deep && copy && ( typeof copy === "object" || (copyIsArray = Array.isArray(copy)) ) ) { if ( copyIsArray ) { copyIsArray = false; clone = src && Array.isArray(src) ? src : []; } else { clone = src && typeof src === "object" ? src : {}; } // Never move original objects, clone them target[ name ] = extend( deep, clone, copy ); // Don't bring in undefined values } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object return target; }; dataLayer.clearModal = function(){ dataLayer.reset({ modal: true, event: false, messages: false }); }; dataLayer.clearLists = function(){ dataLayer.reset({ lists: { item: true }, event: true, modal: false, user: false }); }; dataLayer.replaceCharsToQuotes = function(string){ var newString = string.replace(new RegExp('”|"', 'g'), '"'); return newString.replace('”|"', '"'); }; dataLayer.replaceChars = function(string){ var newString = string.replace(new RegExp('ñ', 'g'), 'n'); newString = newString.replace(/^\s*(.*?)\s*$/, "$1"); return newString.replace(new RegExp(/&.[a-z,0-9]*\;/g), ''); }; if (/iPod|iPhone|BlackBerry|IEMobile/.test(navigator.userAgent)) { dataLayer.page.pageInfo.deviceType = "Phone"; } else if (/iPad/.test(navigator.userAgent)) { dataLayer.page.pageInfo.deviceType = "Tablet"; } else { dataLayer.page.pageInfo.deviceType = "Desktop"; } dataLayer.page.pageInfo.geoRegion = "null"; dataLayer.page.pageInfo.geoLat = "48.8582"; dataLayer.page.pageInfo.geoLong = "2.3387000000000002"; if ("") { var optInfo = "".split(":"); if(optInfo.length == 3){ dataLayer.page.attributes.push({ optimizationName: optInfo[0] + optInfo[1], optimizationRecipe: optInfo[2] }); }else{ dataLayer.page.attributes.push({ optimizationName: optInfo[0], optimizationRecipe: optInfo[1] }); } } var customerGroupIDs = []; customerGroupIDs.push({ custGroupID: "AgentUsers" }); customerGroupIDs.push({ custGroupID: "Device-Desktop" }); customerGroupIDs.push({ custGroupID: "Everyone" }); customerGroupIDs.push({ custGroupID: "NONADMINPB" }); customerGroupIDs.push({ custGroupID: "Unregistered" }); dataLayer.user = { profile: { rewardsID: "null", sessionID: "ud30M8NRpWZxD5fRhjhOyr5ynJOANRaTA98=", profileID: "", guestProfileID: "null", authStatus: "not logged in", memberType: "NON", CID: "", customerGroup: customerGroupIDs, rewardsMembershipLevel: "", rewardsPointsAvailable: "", rewardsPointsYearToDate: "", rewardsPointsToNextLevel: "" } }; dataLayer.cart.itemsInCart = 0; dataLayer.cart.qtyInCart = 0; dataLayer.cart.subTotalOfCart = 0; })();