forked from duckduckgo/duckduckgo-help-pages
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpixels.js
113 lines (98 loc) · 3.75 KB
/
pixels.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/*
Pixels
-------
Concerned about your privacy? We do not store IP addresses, and we do not create unique cookies.
See: https://duck.co/help/privacy/atb
Pixel format:
help.[kebab-pathname].load
help.[kebab-pathname].click?link-url=
Examples:
help.company-advertising-and-affiliates.load
help.company-advertising-and-affiliates.click?link-url=https-reddit-com-r-duckduckgo
*/
(function ready(fn) {
document.readyState !== "loading"
? fn()
: document.addEventListener("DOMContentLoaded", fn);
})(function () {
var externalLinkAllowList = {
"https://about.ads.microsoft.com/en-us/h/a/microsoft-advertising": true,
"https://about.ads.microsoft.com/en-us/h/a/microsoft-advertising?ref=duckduckgo-help-pages-advertise-on-search-toplink": true,
"https://about.ads.microsoft.com/en-us/h/a/microsoft-advertising?ref=duckduckgo-help-pages-advertise-on-search-bottomlink": true,
};
var hasFired = {}; // Fire pixels only once
var pathname = location.pathname
.replace(/^\/duckduckgo-help-pages/, "")
.replace(/\/(.+)\//, "$1");
var basePixelUrl =
"https://improving.duckduckgo.com/t/help_" +
sanitize(pathname === "/" ? "home" : pathname);
/**
* Fires the pixel
* @param {event, extraData} ops
*/
function firePixel(event, extraData) {
extraData = extraData || {};
var pixelUrl = basePixelUrl + "_" + event;
var extraDataString = "";
Object.keys(extraData).forEach(function (extraDataKey) {
extraDataString =
extraDataString +
(extraDataString === "" ? "?" : "&") +
encodeURIComponent(sanitize(extraDataKey)) +
"=" +
encodeURIComponent(sanitize(extraData[extraDataKey]));
});
pixelUrl = pixelUrl + extraDataString;
if (hasFired[pixelUrl]) {
return;
}
hasFired[pixelUrl] = true;
if ("sendBeacon" in navigator) {
// https://developer.mozilla.org/en-US/docs/Web/API/Beacon_API
navigator.sendBeacon(pixelUrl);
} else {
// sendBeacon fallback: img tag
var pixel = document.createElement("img");
pixel.setAttribute("src", pixelUrl);
}
}
function sanitize(str) {
return (
str
// strip leading/trailing slash
.replace(/^\/|\/$/, "")
// strip unsafe chars for grafana
.replace(/[^a-z0-9_-]+/gi, "-")
// strip 'duckduckgo-help-pages-'
.replace(/^duckduckgo-help-pages-/, "")
// strip underscores as well
.replace(/_/g, "-")
);
}
// --------------------
// Event Listeners
// --------------------
// Page loads: Fire here as we're already in an onload event
firePixel("load");
// Link clicks: Fire when links within the article are clicked
Array.prototype.slice
.call(document.querySelectorAll("article a"), 0)
.forEach(function (link) {
link.addEventListener("click", function () {
var href = link.href;
var hostname = link.hostname;
if (
hostname === location.hostname ||
hostname === "help.duckduckgo.com" ||
externalLinkAllowList[href]
) {
// internal link clicks and allow-listed external links can send the href
firePixel("click", { "link-url": href });
} else {
// otherwise we don't send the href but fire a click pixel for measuring engagement
firePixel("click");
}
});
});
});