97 Zeilen
3.4 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
// Partially based on https://searchfox.org/mozilla-central/source/browser/extensions/webcompat/shims/google-analytics-and-tag-manager.js
(() => {
'use strict';
const noop = () => {};
const noopHandler = {
get: function (target, prop) {
return noop;
}
};
const gaPointer = window.GoogleAnalyticsObject = (window.GoogleAnalyticsObject === undefined) ? 'ga' : window.GoogleAnalyticsObject;
const datalayer = window.dataLayer;
const Tracker = new Proxy({}, {
get (target, prop) {
if (prop === 'get') {
return (fieldName) => {
if (fieldName === 'linkerParam') {
// This fixed string is an example value of this API.
// As the extension exposes itself with many featues we shouldn't be concerned by exposing ourselves here also.
// If we randomised this to some other fake value there wouldn't be much benefit and could risk being a tracking vector.
// https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#linkerParam
return '_ga=1.231587807.1974034684.1435105198';
}
return 'something';
};
}
return noop;
}
});
let callQueue = null;
if (window[gaPointer] && Array.isArray(window[gaPointer].q)) {
callQueue = window[gaPointer].q;
}
// Execute callback if exists.
// Note: There are other ways of using the API that aren't handled here yet.
const ga = function () {
const params = Array.from(arguments);
if (params.length === 1 && typeof params[0] === 'function') {
try {
params[0](Tracker);
} catch (error) {}
return undefined;
}
// See https://developers.google.com/analytics/devguides/collection/analyticsjs/field-reference#hitCallback
params.forEach((param) => {
if (param instanceof Object && typeof param.hitCallback === 'function') {
try {
param.hitCallback();
} catch (error) {}
}
});
};
ga.answer = 42;
ga.loaded = true;
ga.create = function () { return new Proxy({}, noopHandler); };
ga.getByName = function () { return new Proxy({}, noopHandler); };
ga.getAll = function () { return [Tracker]; };
ga.remove = noop;
window[gaPointer] = ga;
// prevent page delay, see https://developers.google.com/optimize
if (datalayer && datalayer.hide && typeof datalayer.hide.end === 'function') {
try {
datalayer.hide.end();
} catch (error) {}
}
if (!(window.gaplugins && window.gaplugins.Linker)) {
window.gaplugins = window.gaplugins || {};
window.gaplugins.Linker = class {
autoLink () {}
decorate (url) {
return url;
}
passthrough () {}
};
}
if (callQueue) {
for (const args of callQueue) {
try {
ga(...args);
} catch (e) { }
}
}
})();