{"version":3,"file":"analytics-38706d50.js","sources":["../../../app/webpacker/javascript/cookies.js","../../../app/webpacker/javascript/library.js","../../../app/webpacker/javascript/analytics.js"],"sourcesContent":["export function setCookie(name, value, expire = 60 * 60 * 24 * 365) {\n var expireDate = new Date()\n expireDate.setSeconds(expireDate.getSeconds() + expire)\n document.cookie =\n name +\n \"=\" +\n escape(value) +\n \"; expires=\" +\n expireDate.toGMTString() +\n \"; path=/\"\n}\n\nexport function readCookie(name) {\n var nameEQ = name + \"=\"\n var ca = document.cookie.split(\";\")\n for (var i = 0; i < ca.length; i++) {\n var c = ca[i]\n while (c.charAt(0) == \" \") c = c.substring(1, c.length)\n if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length)\n }\n return null\n}\n\nexport function deleteCookie(name) {\n setCookie(name, \"\", -1)\n}\n","import { readCookie } from \"./cookies\"\n\nexport function isStaff() {\n return configFor(\"userSession.isStaff\")\n}\n\nexport function configFor(keyString) {\n if (!window.oxnotes) {\n return null\n }\n return accessNestedKeyByString(window.oxnotes, keyString)\n}\n\nexport function railsEnv() {\n return configFor(\"settings.railsEnv\")\n}\n\nfunction accessNestedKeyByString(object, string) {\n string = string.replace(/\\[(\\w+)\\]/g, \".$1\") // convert indexes to properties\n string = string.replace(/^\\./, \"\") // strip a leading dot\n var a = string.split(\".\")\n for (var i = 0, n = a.length; i < n; ++i) {\n var key = a[i]\n if (key in object) {\n object = object[key]\n } else {\n return null\n }\n }\n // Often this is a string, but it could be any object\n return object\n}\n\n// Useful for debugging\nexport function logProps(obj, objName) {\n var result = \"\"\n for (var i in obj) {\n result += objName + \".\" + i + \" = \" + obj[i] + \"\\n\"\n }\n console.log(result)\n}\n\nexport function getDataFromDOM(dataAttr, namespaceID = null) {\n const el = getDataElementWithinNamespace(dataAttr, namespaceID)\n if (el) {\n const data = el.dataset[camelize(dataAttr)]\n if (!data) {\n throw `Unexpected null for value of ${dataAttr}`\n }\n return data\n } else {\n return null\n }\n}\n\nexport function isLoggedIn() {\n return readCookie(\"user_id\")\n}\n\nexport function getDataElementWithinNamespace(dataAttr, namespaceID = null) {\n const dataComponent = `[data-${dataAttr}]`\n const selector = namespaceID\n ? `#${namespaceID} ${dataComponent}`\n : dataComponent\n\n return document.querySelector(selector)\n}\n\n// Some browsers or browsing modes (e.g. Incognito) do not\n// support this storage system.\nexport function isSessionStorageNameSupported() {\n const testKey = \"test\"\n try {\n const storage = window.sessionStorage\n storage.setItem(testKey, \"1\")\n storage.removeItem(testKey)\n return true\n } catch (error) {\n return false\n }\n}\n\nexport function callOnDataAttribute(dataAttr, func) {\n const matchingEls = document.querySelectorAll(`[data-${dataAttr}]`)\n ;[].forEach.call(matchingEls, func)\n}\n\nexport function attachScript(src) {\n const script = document.createElement(\"script\")\n // script.async = true\n script.defer = true\n script.src = src\n document.body.appendChild(script)\n}\n\nexport function get(url, callback = () => {}) {\n if (!url) {\n throw TypeError(\"Must provide a URL\")\n }\n\n const xhr = new XMLHttpRequest()\n const async = true\n xhr.onreadystatechange = function () {\n if (this.readyState == 4 && this.status == 200) {\n callback(xhr)\n }\n }\n xhr.open(\"GET\", url, async)\n xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\")\n return xhr.send()\n}\n\nexport function getJSON(url, callback) {\n return get(url, (xhr) => {\n callback(JSON.parse(xhr.responseText))\n })\n}\n\nfunction camelize(string) {\n return string.replace(/-([a-z])/g, function (g) {\n return g[1].toUpperCase()\n })\n}\n","import { readCookie } from \"./cookies\";\nimport { isStaff, configFor } from \"./library\";\n\nfunction gtag() {\n if (window.dataLayer) {\n window.dataLayer.push(arguments);\n }\n}\n\n// optionalEventData is an object {}.\nexport function trackEvent(name, optionalEventData = {}) {\n gtag(\"event\", name, optionalEventData);\n}\n\nconst initTrackingsMadeTable = () => {\n return {\n googleAnalytics: false,\n\n // remarketing\n googleRemarketing: false,\n\n // conversion tracking\n googleConversion: false,\n facebookConversion: false,\n virtualPageViews: []\n };\n};\n\nexport const trackVirtualPageView = (pagePath) => {\n const id = configFor(\"credentials.googleAnalyticsId\");\n gtag(\"config\", id, { page_path: pagePath });\n\n if (window.trackingsMade && window.trackingsMade.virtualPageViews) {\n window.trackingsMade.virtualPageViews.push(pagePath);\n }\n};\n\nfunction Tracker() {\n // TODO These cookie names would be better off stored in a single file for\n // global reference.\n const trackingId = readCookie(\"trackingId\");\n const advancedTrackingEnabled =\n readCookie(\"advancedTrackingCookiesEnabled\") == \"true\";\n const shouldTrack = !isStaff();\n const conversion = document.querySelector(\"[data-conversion]\");\n\n const trackWithGoogleAnalytics = () => {\n initGoogleAnalytics();\n // Event for viewing a product OR sample in a certain category\n const defaultEventData = {\n product: configFor(\"userSession.currentProduct\"),\n taxon: configFor(\"userSession.currentTaxon\"),\n store: configFor(\"userSession.currentStore\")\n };\n\n // Sales related\n if (window.location.pathname.match(/t\\/.+/)) {\n trackEvent(\"view_item_list\", defaultEventData);\n }\n\n if (window.location.pathname.match(/notes\\/.+/)) {\n trackEvent(\"view_item\", defaultEventData);\n }\n\n const addToCartButtons = document.querySelectorAll(\n \"[data-add-to-cart-button]\"\n );\n addToCartButtons.forEach((el) => {\n el.addEventListener(\"click\", function () {\n trackEvent(\"add_to_cart\", defaultEventData);\n });\n });\n\n // Authors related\n if (window.location.pathname.match(/sell_notes/)) {\n trackEvent(\"browsed_become_author_page\");\n }\n\n // TODO: Use the URLs generated by Rails, if possible.\n if (window.location.pathname.match(/law_sellers/)) {\n trackEvent(\"browsed_uk_law_author_page\");\n }\n };\n\n const trackGoogleConversion = (data) => {\n // TODO: Track other types of conversion\n if (data.conversion == \"purchase\") {\n trackEvent(\"purchase\", {\n transaction_id: data.transactionId,\n value: data.value,\n currency: data.currency\n });\n\n window.trackingsMade.googleConversion = true;\n } else if (data.conversion == \"author_application\") {\n trackEvent(\"generate_lead\", {\n store: configFor(\"userSession.currentStore\")\n });\n\n window.trackingsMade.googleConversion = true;\n }\n };\n\n // Enables/disables add tracking as well as tracks pageview\n // with the config() call\n const initGoogleAnalytics = () => {\n const id = configFor(\"credentials.googleAnalyticsId\");\n\n window.dataLayer = window.dataLayer || [];\n gtag(\"js\", new Date());\n\n const config = {\n linker: {\n domains: [\"oxbridgenotes.co.uk\", \"oxbridgenotes.com\"]\n },\n page_location: location.href, // TurboLinks friendly\n allow_ad_personalization_signals: true,\n allow_google_signals: true,\n user_id: trackingId,\n anonymize_ip: true\n };\n\n if (advancedTrackingEnabled) {\n gtag(\"config\", id, config);\n window.trackingsMade.googleAnalytics = true;\n window.trackingsMade.googleRemarketing = true;\n } else {\n gtag(\"config\", id, {\n ...config,\n allow_ad_personalization_signals: false,\n allow_google_signals: false\n });\n window.trackingsMade.googleAnalytics = true;\n }\n };\n\n if (shouldTrack) {\n trackWithGoogleAnalytics();\n\n if (conversion) {\n const data = conversion.dataset;\n trackGoogleConversion(data);\n }\n }\n}\n\nexport default function track() {\n window.trackingsMade = initTrackingsMadeTable();\n Tracker();\n}\n"],"names":["readCookie","name","nameEQ","ca","i","c","isStaff","configFor","keyString","accessNestedKeyByString","object","string","a","n","key","isLoggedIn","callOnDataAttribute","dataAttr","func","matchingEls","get","url","callback","xhr","async","getJSON","gtag","trackEvent","optionalEventData","initTrackingsMadeTable","trackVirtualPageView","pagePath","id","Tracker","trackingId","advancedTrackingEnabled","shouldTrack","conversion","trackWithGoogleAnalytics","initGoogleAnalytics","defaultEventData","el","trackGoogleConversion","data","config","track"],"mappings":"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"}