1 | this.workbox = this.workbox || {};
|
2 | this.workbox.googleAnalytics = (function (exports,Plugin_mjs,cacheNames_mjs,Route_mjs,Router_mjs,NetworkFirst_mjs,NetworkOnly_mjs) {
|
3 | ;
|
4 |
|
5 | try {
|
6 | self.workbox.v['workbox:google-analytics:3.6.2'] = 1;
|
7 | } catch (e) {} // eslint-disable-line
|
8 |
|
9 | /*
|
10 | Copyright 2017 Google Inc. All Rights Reserved.
|
11 | Licensed under the Apache License, Version 2.0 (the "License");
|
12 | you may not use this file except in compliance with the License.
|
13 | You may obtain a copy of the License at
|
14 |
|
15 | http://www.apache.org/licenses/LICENSE-2.0
|
16 |
|
17 | Unless required by applicable law or agreed to in writing, software
|
18 | distributed under the License is distributed on an "AS IS" BASIS,
|
19 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
20 | See the License for the specific language governing permissions and
|
21 | limitations under the License.
|
22 | */
|
23 |
|
24 | const QUEUE_NAME = 'workbox-google-analytics';
|
25 | const MAX_RETENTION_TIME = 60 * 48; // Two days in minutes
|
26 | const GOOGLE_ANALYTICS_HOST = 'www.google-analytics.com';
|
27 | const GTM_HOST = 'www.googletagmanager.com';
|
28 | const ANALYTICS_JS_PATH = '/analytics.js';
|
29 | const GTAG_JS_PATH = '/gtag/js';
|
30 |
|
31 | // This RegExp matches all known Measurement Protocol single-hit collect
|
32 | // endpoints. Most of the time the default path (/collect) is used, but
|
33 | // occasionally an experimental endpoint is used when testing new features,
|
34 | // (e.g. /r/collect or /j/collect)
|
35 | const COLLECT_PATHS_REGEX = /^\/(\w+\/)?collect/;
|
36 |
|
37 | /*
|
38 | Copyright 2017 Google Inc. All Rights Reserved.
|
39 | Licensed under the Apache License, Version 2.0 (the "License");
|
40 | you may not use this file except in compliance with the License.
|
41 | You may obtain a copy of the License at
|
42 |
|
43 | http://www.apache.org/licenses/LICENSE-2.0
|
44 |
|
45 | Unless required by applicable law or agreed to in writing, software
|
46 | distributed under the License is distributed on an "AS IS" BASIS,
|
47 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
48 | See the License for the specific language governing permissions and
|
49 | limitations under the License.
|
50 | */
|
51 |
|
52 | /**
|
53 | * Promisifies the FileReader API to await a text response from a Blob.
|
54 | *
|
55 | * @param {Blob} blob
|
56 | * @return {Promise<string>}
|
57 | *
|
58 | * @private
|
59 | */
|
60 | const getTextFromBlob = (() => {
|
61 | var _ref = babelHelpers.asyncToGenerator(function* (blob) {
|
62 | // This usage of `return await new Promise...` is intentional to work around
|
63 | // a bug in the transpiled/minified output.
|
64 | // See https://github.com/GoogleChrome/workbox/issues/1186
|
65 | return yield new Promise(function (resolve, reject) {
|
66 | const reader = new FileReader();
|
67 | reader.onloadend = function () {
|
68 | return resolve(reader.result);
|
69 | };
|
70 | reader.onerror = function () {
|
71 | return reject(reader.error);
|
72 | };
|
73 | reader.readAsText(blob);
|
74 | });
|
75 | });
|
76 |
|
77 | return function getTextFromBlob(_x) {
|
78 | return _ref.apply(this, arguments);
|
79 | };
|
80 | })();
|
81 |
|
82 | /**
|
83 | * Creates the requestWillDequeue callback to be used with the background
|
84 | * sync queue plugin. The callback takes the failed request and adds the
|
85 | * `qt` param based on the current time, as well as applies any other
|
86 | * user-defined hit modifications.
|
87 | *
|
88 | * @param {Object} config See workbox.googleAnalytics.initialize.
|
89 | * @return {Function} The requestWillDequeu callback function.
|
90 | *
|
91 | * @private
|
92 | */
|
93 | const createRequestWillReplayCallback = config => {
|
94 | return (() => {
|
95 | var _ref2 = babelHelpers.asyncToGenerator(function* (storableRequest) {
|
96 | let { url, requestInit, timestamp } = storableRequest;
|
97 | url = new URL(url);
|
98 |
|
99 | // Measurement protocol requests can set their payload parameters in either
|
100 | // the URL query string (for GET requests) or the POST body.
|
101 | let params;
|
102 | if (requestInit.body) {
|
103 | const payload = requestInit.body instanceof Blob ? yield getTextFromBlob(requestInit.body) : requestInit.body;
|
104 |
|
105 | params = new URLSearchParams(payload);
|
106 | } else {
|
107 | params = url.searchParams;
|
108 | }
|
109 |
|
110 | // Calculate the qt param, accounting for the fact that an existing
|
111 | // qt param may be present and should be updated rather than replaced.
|
112 | const originalHitTime = timestamp - (Number(params.get('qt')) || 0);
|
113 | const queueTime = Date.now() - originalHitTime;
|
114 |
|
115 | // Set the qt param prior to applying the hitFilter or parameterOverrides.
|
116 | params.set('qt', queueTime);
|
117 |
|
118 | if (config.parameterOverrides) {
|
119 | for (const param of Object.keys(config.parameterOverrides)) {
|
120 | const value = config.parameterOverrides[param];
|
121 | params.set(param, value);
|
122 | }
|
123 | }
|
124 |
|
125 | if (typeof config.hitFilter === 'function') {
|
126 | config.hitFilter.call(null, params);
|
127 | }
|
128 |
|
129 | requestInit.body = params.toString();
|
130 | requestInit.method = 'POST';
|
131 | requestInit.mode = 'cors';
|
132 | requestInit.credentials = 'omit';
|
133 | requestInit.headers = { 'Content-Type': 'text/plain' };
|
134 |
|
135 | // Ignore URL search params as they're now in the post body.
|
136 | storableRequest.url = `${url.origin}${url.pathname}`;
|
137 | });
|
138 |
|
139 | return function (_x2) {
|
140 | return _ref2.apply(this, arguments);
|
141 | };
|
142 | })();
|
143 | };
|
144 |
|
145 | /**
|
146 | * Creates GET and POST routes to catch failed Measurement Protocol hits.
|
147 | *
|
148 | * @param {Plugin} queuePlugin
|
149 | * @return {Array<Route>} The created routes.
|
150 | *
|
151 | * @private
|
152 | */
|
153 | const createCollectRoutes = queuePlugin => {
|
154 | const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST && COLLECT_PATHS_REGEX.test(url.pathname);
|
155 |
|
156 | const handler = new NetworkOnly_mjs.NetworkOnly({
|
157 | plugins: [queuePlugin]
|
158 | });
|
159 |
|
160 | return [new Route_mjs.Route(match, handler, 'GET'), new Route_mjs.Route(match, handler, 'POST')];
|
161 | };
|
162 |
|
163 | /**
|
164 | * Creates a route with a network first strategy for the analytics.js script.
|
165 | *
|
166 | * @param {string} cacheName
|
167 | * @return {Route} The created route.
|
168 | *
|
169 | * @private
|
170 | */
|
171 | const createAnalyticsJsRoute = cacheName => {
|
172 | const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST && url.pathname === ANALYTICS_JS_PATH;
|
173 | const handler = new NetworkFirst_mjs.NetworkFirst({ cacheName });
|
174 |
|
175 | return new Route_mjs.Route(match, handler, 'GET');
|
176 | };
|
177 |
|
178 | /**
|
179 | * Creates a route with a network first strategy for the gtag.js script.
|
180 | *
|
181 | * @param {string} cacheName
|
182 | * @return {Route} The created route.
|
183 | *
|
184 | * @private
|
185 | */
|
186 | const createGtagJsRoute = cacheName => {
|
187 | const match = ({ url }) => url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH;
|
188 | const handler = new NetworkFirst_mjs.NetworkFirst({ cacheName });
|
189 |
|
190 | return new Route_mjs.Route(match, handler, 'GET');
|
191 | };
|
192 |
|
193 | /**
|
194 | * @param {Object=} [options]
|
195 | * @param {Object} [options.cacheName] The cache name to store and retrieve
|
196 | * analytics.js. Defaults to the cache names provided by `workbox-core`.
|
197 | * @param {Object} [options.parameterOverrides]
|
198 | * [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),
|
199 | * expressed as key/value pairs, to be added to replayed Google Analytics
|
200 | * requests. This can be used to, e.g., set a custom dimension indicating
|
201 | * that the request was replayed.
|
202 | * @param {Function} [options.hitFilter] A function that allows you to modify
|
203 | * the hit parameters prior to replaying
|
204 | * the hit. The function is invoked with the original hit's URLSearchParams
|
205 | * object as its only argument.
|
206 | *
|
207 | * @memberof workbox.googleAnalytics
|
208 | */
|
209 | const initialize = (options = {}) => {
|
210 | const cacheName = cacheNames_mjs.cacheNames.getGoogleAnalyticsName(options.cacheName);
|
211 |
|
212 | const queuePlugin = new Plugin_mjs.Plugin(QUEUE_NAME, {
|
213 | maxRetentionTime: MAX_RETENTION_TIME,
|
214 | callbacks: {
|
215 | requestWillReplay: createRequestWillReplayCallback(options)
|
216 | }
|
217 | });
|
218 |
|
219 | const routes = [createAnalyticsJsRoute(cacheName), createGtagJsRoute(cacheName), ...createCollectRoutes(queuePlugin)];
|
220 |
|
221 | const router = new Router_mjs.Router();
|
222 | for (const route of routes) {
|
223 | router.registerRoute(route);
|
224 | }
|
225 |
|
226 | self.addEventListener('fetch', evt => {
|
227 | const responsePromise = router.handleRequest(evt);
|
228 | if (responsePromise) {
|
229 | evt.respondWith(responsePromise);
|
230 | }
|
231 | });
|
232 | };
|
233 |
|
234 | /*
|
235 | Copyright 2017 Google Inc. All Rights Reserved.
|
236 | Licensed under the Apache License, Version 2.0 (the "License");
|
237 | you may not use this file except in compliance with the License.
|
238 | You may obtain a copy of the License at
|
239 |
|
240 | http://www.apache.org/licenses/LICENSE-2.0
|
241 |
|
242 | Unless required by applicable law or agreed to in writing, software
|
243 | distributed under the License is distributed on an "AS IS" BASIS,
|
244 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
245 | See the License for the specific language governing permissions and
|
246 | limitations under the License.
|
247 | */
|
248 |
|
249 | exports.initialize = initialize;
|
250 |
|
251 | return exports;
|
252 |
|
253 | }({},workbox.backgroundSync,workbox.core._private,workbox.routing,workbox.routing,workbox.strategies,workbox.strategies));
|
254 |
|
255 | //# sourceMappingURL=workbox-google-analytics.dev.js.map
|