File size: 8,388 Bytes
4202035 | 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 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | // Strips off protocol and trailing path and URL params
function getDomain(url)
{
return url.replace(/^http[s]?:\/\//, '').replace(/\/.*/, '');
}
function addEventListener(element, eventType, eventHandler) {
if (element.addEventListener) {
element.addEventListener(eventType, eventHandler, false);
return true;
}
if (element.attachEvent) {
return element.attachEvent('on' + eventType, eventHandler);
}
element['on' + eventType] = eventHandler;
}
// Strips off protocol and trailing path and URL params
function getHostName(url)
{
// scheme : // [username [: password] @] hostame [: port] [/ [path] [? query] [# fragment]]
var e = new RegExp('^(?:(?:https?|ftp):)/*(?:[^@]+@)?([^:/#]+)'),
matches = e.exec(url);
return matches ? matches[1] : url;
}
function isOptIn() {
return document.getElementById('trackVisits').checked;
}
/**
* Check for common error conditions (cases where we know the optout will not work) and warning conditions (cases
* where the optout may not work on some browsers). Displays a message if warning/error conditions are encountered,
* and also hides the checkbox in the case of an error condition.
* @param obj message The message as received from the tracking JS
* @returns {boolean} Whether we should display the checkbox and the optin/optout text. Returns false if an error
* condition was encountered, otherwise true.
*/
function showWarningIfHttp()
{
var optOutUrl = window.location.href;
var isHttp = optOutUrl && optOutUrl.indexOf('http:') === 0;
if (isHttp) {
var errorPara = document.getElementById('textError_https');
if (errorPara) {
errorPara.style.display = 'block';
}
}
}
function getDataIfMessageIsForThisFrame(e){
if (!e || !e.data) {
return false;
}
try {
var data = JSON.parse(e.data);
} catch (e) {
return false;
}
if (!data || !data.maq_url) {
return false;
}
var originHost = getHostName(data.maq_url);
if (originHost !== getHostName(window.location.href)) {
// just to double check it really is for this optOut script...
return false;
}
return data;
}
function submitForm(e, form) {
// Find out whether checkbox is turned on
var optedIn = isOptIn();
var hasOptOutChangeWorkedThroughPostMessage = null;
// Send a message to the parent window so that it can set a first-party cookie (a fallback in case
// third-party cookies are not permitted by the browser).
if (typeof parent === 'object' && typeof parent.postMessage !== 'undefined') {
addEventListener(window, 'message', function(e) {
var data = getDataIfMessageIsForThisFrame(e);
if (!data || typeof data.maq_confirm_opted_in === 'undefined') {
return;
}
var optedIn = isOptIn(); // need to get value again as otherwise might be changed
hasOptOutChangeWorkedThroughPostMessage = optedIn == data.maq_confirm_opted_in;
if (!hasOptOutChangeWorkedThroughPostMessage) {
// looks like opt out or opt in did maybe not work...
// this might be IF eg the Matomo instance trackerUrl on the page does not match the Matomo instance optOut url...
showWarningIfHttp();
}
});
var optOutStatus = {maq_opted_in: optedIn};
parent.postMessage(JSON.stringify(optOutStatus), "*");
}
// Update the text on the form
updateText(optedIn);
// Fire off a request to Matomo in the background, which will try to set the third-party cookie.
// We have the first-party cookie but it's nice to set this too if we can, since it will respect the
// user's wishes across multiple sites.
var now = Date.now ? Date.now() : (+(new Date())); // Date.now does not exist in < IE8
var openedWindow = window.open(form.action + '&time=' + now);
if (openedWindow) {
var checkWindowClosedInterval;
checkWindowClosedInterval = setInterval(function() {
if (openedWindow.closed) {
clearInterval(checkWindowClosedInterval);
checkWindowClosedInterval = null;
if (!hasOptOutChangeWorkedThroughPostMessage) {
// this is not always 100% correct but better show a warning if post message hasn't completed by now.
// Technically, the postMessage should finish before the window.open but this might not always be the case
showWarningIfHttp();
}
}
}, 200);
} else {
var errorPara = document.getElementById('textError_popupBlocker');
if (errorPara) {
errorPara.style.display = 'block';
}
}
return false;
}
function updateText(optedIn) {
var optInPara = document.getElementById('textOptIn');
var optOutPara = document.getElementById('textOptOut');
var optInLabel = document.getElementById('labelOptIn');
var optOutLabel = document.getElementById('labelOptOut');
var checkbox = document.getElementById('trackVisits');
if (optedIn) {
optInPara.style.display = 'none';
optOutPara.style.display = 'block';
optInLabel.style.display = 'none';
optOutLabel.style.display = 'inline';
checkbox.checked = true;
} else {
optOutPara.style.display = 'none';
optInPara.style.display = 'block';
optOutLabel.style.display = 'none';
optInLabel.style.display = 'inline';
checkbox.checked = false;
}
}
function showWarningIfCookiesDisabled() {
if (navigator && !navigator.cookieEnabled) {
// Error condition: cookies disabled and Matomo not configured to opt the user out by default = they can't opt out
var errorPara = document.getElementById('textError_cookies');
if (errorPara) {
errorPara.style.display = 'block';
}
var checkbox = document.getElementById('trackVisits');
var optInPara = document.getElementById('textOptIn');
var optOutPara = document.getElementById('textOptOut');
var optInLabel = document.getElementById('labelOptIn');
var optOutLabel = document.getElementById('labelOptOut');
// Hide the checkbox
checkbox.style.display = 'none';
optInPara.style.display = 'none';
optOutPara.style.display = 'none';
optInLabel.style.display = 'none';
optOutLabel.style.display = 'none';
}
}
var initializationTimer = null;
addEventListener(document, 'DOMContentLoaded', function() {
showWarningIfCookiesDisabled();
var trackVisitsCheckbox = document.getElementById('trackVisits');
if (trackVisitsCheckbox && typeof parent === 'object') {
var initiallyChecked = trackVisitsCheckbox.checked;
// Ask the parent window to send us initial state of the optout cookie so that we can display the form correctly
var numAttempts = 0;
function checkParentTrackerLoaded() {
var message = {maq_initial_value: initiallyChecked};
parent.postMessage(JSON.stringify(message), '*');
numAttempts++;
// 0.15 times per second * 1200 = 3 minutes
// If the tracker JS hasn't finished loading by now, it ain't gonna, so let's stop trying
if (numAttempts > 1200) {
clearInterval(initializationTimer);
initializationTimer = null;
}
}
initializationTimer = setInterval(checkParentTrackerLoaded, 150);
}
});
// Listener for initialization message from parent window
// This will tell us the initial state the form should be in
// based on the first-party cookie value (which we can't access directly)
addEventListener(window, 'message', function(e) {
var data = getDataIfMessageIsForThisFrame(e);
if (!data) {
return;
}
if (typeof data.maq_opted_in !== 'undefined'
&& typeof data.maq_url !== 'undefined'
&& typeof data.maq_optout_by_default !== 'undefined'
) {
// Cancel the interval so that we don't keep sending requests to the parent
if (initializationTimer) {
clearInterval(initializationTimer);
}
updateText(data.maq_opted_in);
}
}); |