-
Notifications
You must be signed in to change notification settings - Fork 30
/
google-analytics.js
158 lines (141 loc) · 4.56 KB
/
google-analytics.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
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
import {
hit,
noopFunc,
noopNull,
noopArray,
} from '../helpers';
/**
* @redirect google-analytics
*
* @description
* Mocks Google's Analytics and Tag Manager APIs.
* Covers functionality of
* the [obsolete googletagmanager-gtm redirect](https://github.com/AdguardTeam/Scriptlets/issues/127).
*
* Related UBO redirect resource:
* https://github.com/gorhill/uBlock/blob/master/src/web_accessible_resources/google-analytics_analytics.js
*
* ### Examples
*
* ```adblock
* ||google-analytics.com/analytics.js$script,redirect=google-analytics
* ||googletagmanager.com/gtm.js$script,redirect=google-analytics
* ```
*
* @added v1.0.10.
*/
export function GoogleAnalytics(source) {
// eslint-disable-next-line func-names
const Tracker = function () { }; // constructor
const proto = Tracker.prototype;
proto.get = noopFunc;
proto.set = noopFunc;
proto.send = noopFunc;
const googleAnalyticsName = window.GoogleAnalyticsObject || 'ga';
const queue = window[googleAnalyticsName]?.q;
// a -- fake arg for 'ga.length < 1' antiadblock checking
// eslint-disable-next-line no-unused-vars
function ga(a) {
const len = arguments.length;
if (len === 0) {
return;
}
// eslint-disable-next-line prefer-rest-params
const lastArg = arguments[len - 1];
let replacer;
if (lastArg instanceof Object
&& lastArg !== null
&& typeof lastArg.hitCallback === 'function') {
replacer = lastArg.hitCallback;
} else if (typeof lastArg === 'function') {
// https://github.com/AdguardTeam/Scriptlets/issues/98
replacer = () => {
lastArg(ga.create());
};
}
try {
setTimeout(replacer, 1);
// eslint-disable-next-line no-empty
} catch (ex) { }
}
ga.create = () => new Tracker();
// https://github.com/AdguardTeam/Scriptlets/issues/134
ga.getByName = () => new Tracker();
ga.getAll = () => [new Tracker()];
ga.remove = noopFunc;
ga.loaded = true;
window[googleAnalyticsName] = ga;
if (Array.isArray(queue)) {
const push = (arg) => {
ga(...arg);
};
queue.push = push;
queue.forEach(push);
}
const { dataLayer, google_optimize } = window; // eslint-disable-line camelcase
if (dataLayer instanceof Object === false) {
return;
}
if (dataLayer.hide instanceof Object
&& typeof dataLayer.hide.end === 'function') {
dataLayer.hide.end();
}
/**
* checks data object and delays callback
*
* @param {object|Array} dataObj gtag payload
* @param {string} funcName callback prop name
*/
const handleCallback = (dataObj, funcName) => {
if (dataObj && typeof dataObj[funcName] === 'function') {
setTimeout(dataObj[funcName]);
}
};
if (typeof dataLayer.push === 'function') {
dataLayer.push = (data) => {
if (data instanceof Object) {
handleCallback(data, 'eventCallback');
// eslint-disable-next-line no-restricted-syntax, guard-for-in
for (const key in data) {
handleCallback(data[key], 'event_callback');
}
// eslint-disable-next-line no-prototype-builtins
if (!data.hasOwnProperty('eventCallback') && !data.hasOwnProperty('eventCallback')) {
[].push.call(window.dataLayer, data);
}
}
if (Array.isArray(data)) {
data.forEach((arg) => {
handleCallback(arg, 'callback');
});
}
return noopFunc;
};
}
// https://github.com/AdguardTeam/Scriptlets/issues/81
// eslint-disable-next-line camelcase
if (google_optimize instanceof Object && typeof google_optimize.get === 'function') {
const googleOptimizeWrapper = {
get: noopFunc,
};
window.google_optimize = googleOptimizeWrapper;
}
hit(source);
}
export const GoogleAnalyticsNames = [
'google-analytics',
'ubo-google-analytics_analytics.js',
'google-analytics_analytics.js',
// https://github.com/AdguardTeam/Scriptlets/issues/127
'googletagmanager-gtm',
'ubo-googletagmanager_gtm.js',
'googletagmanager_gtm.js',
];
// eslint-disable-next-line prefer-destructuring
GoogleAnalytics.primaryName = GoogleAnalyticsNames[0];
GoogleAnalytics.injections = [
hit,
noopFunc,
noopNull,
noopArray,
];