diff --git a/dist/latest/auto-events.js b/dist/latest/auto-events.js index 2e99bd7..cd391b6 100644 --- a/dist/latest/auto-events.js +++ b/dist/latest/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 54ac; v12) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 99ad; v12) */ -function t(){try{for(var e=document.getElementsByTagName("a"),t=0;t -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n \"phones\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (!useTitle || type === \"phone\") {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n if (useTitle) event = theTitle;\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/latest/custom/auto-events.js b/dist/latest/custom/auto-events.js index 2e99bd7..cd391b6 100644 --- a/dist/latest/custom/auto-events.js +++ b/dist/latest/custom/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 54ac; v12) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 99ad; v12) */ -function t(){try{for(var e=document.getElementsByTagName("a"),t=0;t -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n \"phones\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (!useTitle || type === \"phone\") {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n if (useTitle) event = theTitle;\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/auto-events.js b/dist/v12/auto-events.js index fe2cde2..b6b0f60 100644 --- a/dist/v12/auto-events.js +++ b/dist/v12/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 3352; SRI-version; v12) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 99ad; SRI-version; v12) */ -function r(t,e){var n,o;t.hasAttribute("data-simple-event")||(n=!1,b.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(b.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?n="download":b.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==h.location.hostname?n="outbound":b.emails&&/^mailto:/i.test(t.href)?n="email":b.phones&&/^tel:/i.test(t.href)&&(n="phone"),n&&(e?(o="saAutomatedLink(this, '"+n+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(o+=" return false;"),t.setAttribute("onclick",o)):t.addEventListener("click",function(){g(this,n)})))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (\n type !== \"phone\" &&\n !sent &&\n (!element.hasAttribute(\"target\") ||\n element.getAttribute(\"target\") === \"_self\")\n )\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\" || type === \"phone\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (\n !link.getAttribute(\"onclick\") &&\n !/^mailto:/.test(href) &&\n !/^tel:/.test(href)\n ) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","getAttribute","setAttribute","addEventListener","saAutomatedLink","this","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n \"phones\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (!useTitle || type === \"phone\") {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n if (useTitle) event = theTitle;\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/dist/v12/custom/auto-events.js b/dist/v12/custom/auto-events.js index fe2cde2..b6b0f60 100644 --- a/dist/v12/custom/auto-events.js +++ b/dist/v12/custom/auto-events.js @@ -1,4 +1,4 @@ -/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 3352; SRI-version; v12) */ +/* Simple Analytics - Privacy-first analytics (docs.simpleanalytics.com/script; 2026-10-15; 99ad; SRI-version; v12) */ -function r(t,e){var n,o;t.hasAttribute("data-simple-event")||(n=!1,b.downloads&&/^https?:\/\//i.test(t.href)&&new RegExp("\\.("+(b.downloadsExtensions||[]).join("|")+")$","i").test(t.pathname)?n="download":b.outbound&&/^https?:\/\//i.test(t.href)&&t.hostname!==h.location.hostname?n="outbound":b.emails&&/^mailto:/i.test(t.href)?n="email":b.phones&&/^tel:/i.test(t.href)&&(n="phone"),n&&(e?(o="saAutomatedLink(this, '"+n+"');",t.hasAttribute("target")&&"_self"!==t.getAttribute("target")||(o+=" return false;"),t.setAttribute("onclick",o)):t.addEventListener("click",function(){g(this,n)})))}function e(){try{for(var t=document.getElementsByTagName("a"),e=0;e -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n var sent = false;\n\n var callback = function () {\n if (\n type !== \"phone\" &&\n !sent &&\n (!element.hasAttribute(\"target\") ||\n element.getAttribute(\"target\") === \"_self\")\n )\n document.location = element.getAttribute(\"href\");\n sent = true;\n };\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (useTitle) {\n event = theTitle;\n } else {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, callback);\n\n log(\"collected \" + clean);\n\n return type === \"email\" || type === \"phone\"\n ? callback()\n : window.setTimeout(callback, 5000);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n return callback();\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link, onclick) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n if (onclick) {\n var onClickAttribute = \"saAutomatedLink(this, '\" + collect + \"');\";\n\n if (\n !link.hasAttribute(\"target\") ||\n link.getAttribute(\"target\") === \"_self\"\n )\n onClickAttribute += \" return false;\";\n\n link.setAttribute(\"onclick\", onClickAttribute);\n } else {\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n // We don't want to overwrite website behaviour so we check for the onclick attribute\n if (\n !link.getAttribute(\"onclick\") &&\n !/^mailto:/.test(href) &&\n !/^tel:/.test(href)\n ) {\n collectLink(link, true);\n } else {\n collectLink(link, false);\n }\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["collectLink","link","onclick","collect","onClickAttribute","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","getAttribute","setAttribute","addEventListener","saAutomatedLink","this","onDOMContentLoaded","a","document","getElementsByTagName","i","length","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","sent","callback","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","setTimeout","readyState","target"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"auto-events.source.js","sources":["auto-events.source.js"],"sourcesContent":["(function saAutomatedEvents(window) {\n // Skip server side rendered pages\n if (typeof window === \"undefined\") return;\n\n var log = function (message, type) {\n var logger = type === \"warn\" ? console.warn : console.info;\n return logger && logger(\"Simple Analytics auto events:\", message);\n };\n\n var doc = window.document;\n\n var scriptElement =\n doc.currentScript || doc.querySelector('script[src*=\"auto-events.js\"]');\n\n var setting = function (attribute, type, defaultValue) {\n var value = scriptElement && scriptElement.dataset[attribute];\n\n // Booleans\n if (type === \"bool\" && (value === \"true\" || value === \"false\"))\n return value === \"true\";\n else if (type === \"bool\") return defaultValue;\n\n // Arrays\n if (type === \"array\" && value)\n return value\n .split(\",\")\n .map(function (item) {\n return item.trim();\n })\n .filter(Boolean);\n else if (type === \"array\") return defaultValue;\n\n return value || defaultValue;\n };\n\n var collectTypes = setting(\"collect\", \"array\", [\n \"outbound\",\n \"emails\",\n \"downloads\",\n \"phones\",\n ]);\n var fullUrls = setting(\"fullUrls\", \"bool\", false);\n\n var options = {\n // What to collect\n outbound: collectTypes.indexOf(\"outbound\") > -1,\n emails: collectTypes.indexOf(\"emails\") > -1,\n downloads: collectTypes.indexOf(\"downloads\") > -1,\n phones: collectTypes.indexOf(\"phones\") > -1,\n // Downloads: enter file extensions you want to collect\n downloadsExtensions: setting(\"extensions\", \"array\", [\n \"pdf\",\n \"csv\",\n \"docx\",\n \"xlsx\",\n \"zip\",\n \"doc\",\n \"xls\",\n ]),\n\n // All: use title attribute if set for event name (for all events)\n // THIS TAKES PRECEDENCE OVER OTHER SETTINGS BELOW\n title: setting(\"useTitle\", \"bool\", true),\n // Outbound: use full URL of the links? false for just the hostname\n outboundFullUrl: fullUrls,\n // Downloads: if taking event name from URL, use full URL or just filename (default)\n downloadsFullUrl: fullUrls,\n };\n\n var saGlobal = setting(\"saGlobal\", \"string\", \"sa_event\");\n\n // For compiling the script\n var optionsLink = options;\n\n if (typeof optionsLink === \"undefined\")\n log(\"options object not found, please specify\", \"warn\");\n\n var saAutomatedLink = function saAutomatedLink(element, type) {\n try {\n if (!element) return log(\"no element found\");\n\n if (window[saGlobal] && window[saGlobal + \"_loaded\"]) {\n var hostname = element.hostname;\n var pathname = element.pathname;\n\n var event;\n var metadata = {\n title: element.getAttribute(\"title\") || undefined,\n };\n var url = element.href || undefined;\n\n var useTitle = false;\n if (optionsLink.title && element.hasAttribute(\"title\")) {\n var theTitle = element.getAttribute(\"title\").trim();\n if (theTitle != \"\") useTitle = true;\n }\n\n if (!useTitle || type === \"phone\") {\n switch (type) {\n case \"outbound\": {\n event = hostname + (optionsLink.outboundFullUrl ? pathname : \"\");\n metadata.url = url;\n break;\n }\n case \"download\": {\n event = optionsLink.downloadsFullUrl\n ? hostname + pathname\n : pathname.split(\"/\").pop();\n metadata.url = url;\n break;\n }\n case \"email\": {\n var href = element.getAttribute(\"href\");\n event = (href.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.email = event;\n break;\n }\n case \"phone\": {\n var hrefPhone = element.getAttribute(\"href\");\n event = (hrefPhone.split(\":\")[1] || \"\").split(\"?\")[0];\n metadata.phone = event;\n break;\n }\n }\n }\n if (useTitle) event = theTitle;\n\n var clean =\n type +\n \"_\" +\n event.replace(/[^a-z0-9]+/gi, \"_\").replace(/(^_+|_+$)/g, \"\");\n\n window[saGlobal](clean, metadata, function () {}, true);\n\n log(\"collected \" + clean);\n } else {\n log(saGlobal + \" is not defined\", \"warn\");\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n };\n\n window.saAutomatedLink = saAutomatedLink;\n\n function collectLink(link) {\n if (link.hasAttribute(\"data-simple-event\")) return;\n var collect = false;\n\n // Collect download clicks\n if (\n optionsLink.downloads &&\n /^https?:\\/\\//i.test(link.href) &&\n new RegExp(\n \"\\\\.(\" + (optionsLink.downloadsExtensions || []).join(\"|\") + \")$\",\n \"i\"\n ).test(link.pathname)\n ) {\n collect = \"download\";\n\n // Collect outbound links clicks\n } else if (\n optionsLink.outbound &&\n /^https?:\\/\\//i.test(link.href) &&\n link.hostname !== window.location.hostname\n ) {\n collect = \"outbound\";\n\n // Collect email clicks\n } else if (optionsLink.emails && /^mailto:/i.test(link.href)) {\n collect = \"email\";\n\n // Collect telephone clicks\n } else if (optionsLink.phones && /^tel:/i.test(link.href)) {\n collect = \"phone\";\n }\n\n if (!collect) return;\n\n link.addEventListener(\"click\", function () {\n saAutomatedLink(this, collect);\n });\n }\n\n function onDOMContentLoaded() {\n try {\n var a = document.getElementsByTagName(\"a\");\n\n // Loop over all links on the page\n for (var i = 0; i < a.length; i++) {\n var link = a[i];\n var href = link.getAttribute(\"href\");\n\n // Skip links that don't have an href\n if (!href) continue;\n\n collectLink(link);\n }\n } catch (error) {\n log(error.message, \"warn\");\n }\n }\n\n if (doc.readyState === \"ready\" || doc.readyState === \"complete\") {\n onDOMContentLoaded();\n } else {\n document.addEventListener(\"readystatechange\", function (event) {\n if (event.target.readyState === \"complete\") onDOMContentLoaded();\n });\n }\n})(window);\n"],"names":["onDOMContentLoaded","a","document","getElementsByTagName","i","length","link","getAttribute","collect","hasAttribute","optionsLink","downloads","test","href","RegExp","downloadsExtensions","join","pathname","outbound","hostname","window","location","emails","phones","addEventListener","saAutomatedLink","this","collectLink","error","log","message","doc","scriptElement","setting","collectTypes","fullUrls","options","saGlobal","type","logger","console","warn","info","currentScript","querySelector","attribute","defaultValue","value","dataset","split","map","item","trim","filter","Boolean","indexOf","title","outboundFullUrl","downloadsFullUrl","element","theTitle","metadata","undefined","url","useTitle","event","pop","email","phone","clean","replace","readyState","target"],"mappings":"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"} \ No newline at end of file diff --git a/src/auto-events.js b/src/auto-events.js index 5095d86..56a8874 100644 --- a/src/auto-events.js +++ b/src/auto-events.js @@ -95,9 +95,7 @@ if (theTitle != "") useTitle = true; } - if (useTitle) { - event = theTitle; - } else { + if (!useTitle || type === "phone") { switch (type) { case "outbound": { event = hostname + (optionsLink.outboundFullUrl ? pathname : ""); @@ -125,6 +123,7 @@ } } } + if (useTitle) event = theTitle; var clean = type + diff --git a/test/unit/auto-events.test.js b/test/unit/auto-events.test.js index 8193ded..0a3492e 100644 --- a/test/unit/auto-events.test.js +++ b/test/unit/auto-events.test.js @@ -19,6 +19,23 @@ function setupDOM() { } describe("auto-events", function () { + it("keeps phone metadata when the title names the event", function () { + const dom = setupDOM(); + const link = dom.window.document.createElement("a"); + link.href = "tel:+31201234567?extension=42"; + link.title = "Call sales"; + + dom.window.saAutomatedLink(link, "phone"); + + expect(dom.events).to.deep.equal([ + { + name: "phone_Call_sales", + metadata: { title: "Call sales", phone: "+31201234567" }, + }, + ]); + dom.window.close(); + }); + it("collects phone clicks by default without overriding cancelled navigation", function () { const events = []; const navigations = [];