UNPKG

31 kBJavaScriptView Raw
1this.workbox = this.workbox || {};
2this.workbox.routing = (function (assert_mjs,logger_mjs,WorkboxError_mjs,getFriendlyURL_mjs,cacheNames_mjs) {
3 'use strict';
4
5 try {
6 self.workbox.v['workbox:routing:3.5.0'] = 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 /**
25 * The default HTTP method, 'GET', used when there's no specific method
26 * configured for a route.
27 *
28 * @type {string}
29 *
30 * @private
31 */
32 const defaultMethod = 'GET';
33
34 /**
35 * The list of valid HTTP methods associated with requests that could be routed.
36 *
37 * @type {Array<string>}
38 *
39 * @private
40 */
41 const validMethods = ['DELETE', 'GET', 'HEAD', 'PATCH', 'POST', 'PUT'];
42
43 /*
44 Copyright 2017 Google Inc. All Rights Reserved.
45 Licensed under the Apache License, Version 2.0 (the "License");
46 you may not use this file except in compliance with the License.
47 You may obtain a copy of the License at
48
49 http://www.apache.org/licenses/LICENSE-2.0
50
51 Unless required by applicable law or agreed to in writing, software
52 distributed under the License is distributed on an "AS IS" BASIS,
53 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
54 See the License for the specific language governing permissions and
55 limitations under the License.
56 */
57
58 /**
59 * @param {function()|Object} handler Either a function, or an object with a
60 * 'handle' method.
61 * @return {Object} An object with a handle method.
62 *
63 * @private
64 */
65 var normalizeHandler = (handler => {
66 if (handler && typeof handler === 'object') {
67 {
68 assert_mjs.assert.hasMethod(handler, 'handle', {
69 moduleName: 'workbox-routing',
70 className: 'Route',
71 funcName: 'constructor',
72 paramName: 'handler'
73 });
74 }
75 return handler;
76 } else {
77 {
78 assert_mjs.assert.isType(handler, 'function', {
79 moduleName: 'workbox-routing',
80 className: 'Route',
81 funcName: 'constructor',
82 paramName: 'handler'
83 });
84 }
85 return { handle: handler };
86 }
87 });
88
89 /*
90 Copyright 2017 Google Inc. All Rights Reserved.
91 Licensed under the Apache License, Version 2.0 (the "License");
92 you may not use this file except in compliance with the License.
93 You may obtain a copy of the License at
94
95 http://www.apache.org/licenses/LICENSE-2.0
96
97 Unless required by applicable law or agreed to in writing, software
98 distributed under the License is distributed on an "AS IS" BASIS,
99 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
100 See the License for the specific language governing permissions and
101 limitations under the License.
102 */
103
104 /**
105 * A `Route` consists of a pair of callback functions, "match" and "handler".
106 * The "match" callback determine if a route should be used to "handle" a
107 * request by returning a non-falsy value if it can. The "handler" callback
108 * is called when there is a match and should return a Promise that resolves
109 * to a `Response`.
110 *
111 * @memberof workbox.routing
112 */
113 class Route {
114 /**
115 * Constructor for Route class.
116 *
117 * @param {workbox.routing.Route~matchCallback} match
118 * A callback function that determines whether the route matches a given
119 * `fetch` event by returning a non-falsy value.
120 * @param {workbox.routing.Route~handlerCallback} handler A callback
121 * function that returns a Promise resolving to a Response.
122 * @param {string} [method='GET'] The HTTP method to match the Route
123 * against.
124 */
125 constructor(match, handler, method) {
126 {
127 assert_mjs.assert.isType(match, 'function', {
128 moduleName: 'workbox-routing',
129 className: 'Route',
130 funcName: 'constructor',
131 paramName: 'match'
132 });
133
134 if (method) {
135 assert_mjs.assert.isOneOf(method, validMethods, { paramName: 'method' });
136 }
137 }
138
139 // These values are referenced directly by Router so cannot be
140 // altered by minifification.
141 this.handler = normalizeHandler(handler);
142 this.match = match;
143 this.method = method || defaultMethod;
144 }
145 }
146
147 /*
148 Copyright 2017 Google Inc. All Rights Reserved.
149 Licensed under the Apache License, Version 2.0 (the "License");
150 you may not use this file except in compliance with the License.
151 You may obtain a copy of the License at
152
153 http://www.apache.org/licenses/LICENSE-2.0
154
155 Unless required by applicable law or agreed to in writing, software
156 distributed under the License is distributed on an "AS IS" BASIS,
157 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
158 See the License for the specific language governing permissions and
159 limitations under the License.
160 */
161
162 /**
163 * RegExpRoute makes it easy to create a regular expression based
164 * [Route]{@link workbox.routing.Route}.
165 *
166 * For same-origin requests the RegExp only needs to match part of the URL. For
167 * requests against third-party servers, you must define a RegExp that matches
168 * the start of the URL.
169 *
170 * [See the module docs for info.]{@link https://developers.google.com/web/tools/workbox/modules/workbox-routing}
171 *
172 * @memberof workbox.routing
173 * @extends workbox.routing.Route
174 */
175 class RegExpRoute extends Route {
176 /**
177 * If the regulard expression contains
178 * [capture groups]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references},
179 * th ecaptured values will be passed to the
180 * [handler's]{@link workbox.routing.Route~handlerCallback} `params`
181 * argument.
182 *
183 * @param {RegExp} regExp The regular expression to match against URLs.
184 * @param {workbox.routing.Route~handlerCallback} handler A callback
185 * function that returns a Promise resulting in a Response.
186 * @param {string} [method='GET'] The HTTP method to match the Route
187 * against.
188 */
189 constructor(regExp, handler, method) {
190 {
191 assert_mjs.assert.isInstance(regExp, RegExp, {
192 moduleName: 'workbox-routing',
193 className: 'RegExpRoute',
194 funcName: 'constructor',
195 paramName: 'pattern'
196 });
197 }
198
199 const match = ({ url }) => {
200 const result = regExp.exec(url.href);
201
202 // Return null immediately if there's no match.
203 if (!result) {
204 return null;
205 }
206
207 // Require that the match start at the first character in the URL string
208 // if it's a cross-origin request.
209 // See https://github.com/GoogleChrome/workbox/issues/281 for the context
210 // behind this behavior.
211 if (url.origin !== location.origin && result.index !== 0) {
212 {
213 logger_mjs.logger.debug(`The regular expression '${regExp}' only partially matched ` + `against the cross-origin URL '${url}'. RegExpRoute's will only ` + `handle cross-origin requests if they match the entire URL.`);
214 }
215
216 return null;
217 }
218
219 // If the route matches, but there aren't any capture groups defined, then
220 // this will return [], which is truthy and therefore sufficient to
221 // indicate a match.
222 // If there are capture groups, then it will return their values.
223 return result.slice(1);
224 };
225
226 super(match, handler, method);
227 }
228 }
229
230 /*
231 Copyright 2017 Google Inc. All Rights Reserved.
232 Licensed under the Apache License, Version 2.0 (the "License");
233 you may not use this file except in compliance with the License.
234 You may obtain a copy of the License at
235
236 http://www.apache.org/licenses/LICENSE-2.0
237
238 Unless required by applicable law or agreed to in writing, software
239 distributed under the License is distributed on an "AS IS" BASIS,
240 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
241 See the License for the specific language governing permissions and
242 limitations under the License.
243 */
244
245 /**
246 * The Router can be used to process a FetchEvent through one or more
247 * [Routes]{@link workbox.routing.Route} responding with a Request if
248 * a matching route exists.
249 *
250 * If no route matches a given a request, the Router will use a "default"
251 * handler if one is defined.
252 *
253 * Should the matching Route throw an error, the Router will use a "catch"
254 * handler if one is defined to gracefully deal with issues and respond with a
255 * Request.
256 *
257 * If a request matches multiple routes, the **earliest** registered route will
258 * be used to respond to the request.
259 *
260 * @memberof workbox.routing
261 */
262 class Router {
263 /**
264 * Initializes a new Router.
265 */
266 constructor() {
267 // _routes will contain a mapping of HTTP method name ('GET', etc.) to an
268 // array of all the corresponding Route instances that are registered.
269 this._routes = new Map();
270 }
271
272 /**
273 * Apply the routing rules to a FetchEvent object to get a Response from an
274 * appropriate Route's handler.
275 *
276 * @param {FetchEvent} event The event from a service worker's 'fetch' event
277 * listener.
278 * @return {Promise<Response>|undefined} A promise is returned if a
279 * registered route can handle the FetchEvent's request. If there is no
280 * matching route and there's no `defaultHandler`, `undefined` is returned.
281 */
282 handleRequest(event) {
283 {
284 assert_mjs.assert.isInstance(event, FetchEvent, {
285 moduleName: 'workbox-routing',
286 className: 'Router',
287 funcName: 'handleRequest',
288 paramName: 'event'
289 });
290 }
291
292 const url = new URL(event.request.url);
293 if (!url.protocol.startsWith('http')) {
294 {
295 logger_mjs.logger.debug(`Workbox Router only supports URLs that start with 'http'.`);
296 }
297 return;
298 }
299
300 let route = null;
301 let handler = null;
302 let params = null;
303 let debugMessages = [];
304
305 const result = this._findHandlerAndParams(event, url);
306 handler = result.handler;
307 params = result.params;
308 route = result.route;
309 {
310 if (handler) {
311 debugMessages.push([`Found a route to handle this request:`, route]);
312
313 if (params) {
314 debugMessages.push([`Passing the following params to the route's handler:`, params]);
315 }
316 }
317 }
318
319 // If we don't have a handler because there was no matching route, then
320 // fall back to defaultHandler if that's defined.
321 if (!handler && this._defaultHandler) {
322 {
323 debugMessages.push(`Failed to find a matching route. Falling ` + `back to the default handler.`);
324
325 // This is used for debugging in logs in the case of an error.
326 route = '[Default Handler]';
327 }
328 handler = this._defaultHandler;
329 }
330
331 if (!handler) {
332 {
333 // No handler so Workbox will do nothing. If logs is set of debug
334 // i.e. verbose, we should print out this information.
335 logger_mjs.logger.debug(`No route found for: ${getFriendlyURL_mjs.getFriendlyURL(url)}`);
336 }
337 return;
338 }
339
340 {
341 // We have a handler, meaning Workbox is going to handle the route.
342 // print the routing details to the console.
343 logger_mjs.logger.groupCollapsed(`Router is responding to: ${getFriendlyURL_mjs.getFriendlyURL(url)}`);
344 debugMessages.forEach(msg => {
345 if (Array.isArray(msg)) {
346 logger_mjs.logger.log(...msg);
347 } else {
348 logger_mjs.logger.log(msg);
349 }
350 });
351
352 // The Request and Response objects contains a great deal of information,
353 // hide it under a group in case developers want to see it.
354 logger_mjs.logger.groupCollapsed(`View request details here.`);
355 logger_mjs.logger.unprefixed.log(event.request);
356 logger_mjs.logger.groupEnd();
357
358 logger_mjs.logger.groupEnd();
359 }
360
361 // Wrap in try and catch in case the handle method throws a synchronous
362 // error. It should still callback to the catch handler.
363 let responsePromise;
364 try {
365 responsePromise = handler.handle({ url, event, params });
366 } catch (err) {
367 responsePromise = Promise.reject(err);
368 }
369
370 if (responsePromise && this._catchHandler) {
371 responsePromise = responsePromise.catch(err => {
372 {
373 // Still include URL here as it will be async from the console group
374 // and may not make sense without the URL
375 logger_mjs.logger.groupCollapsed(`Error thrown when responding to: ` + ` ${getFriendlyURL_mjs.getFriendlyURL(url)}. Falling back to Catch Handler.`);
376 logger_mjs.logger.unprefixed.error(`Error thrown by:`, route);
377 logger_mjs.logger.unprefixed.error(err);
378 logger_mjs.logger.groupEnd();
379 }
380 return this._catchHandler.handle({ url, event, err });
381 });
382 }
383
384 return responsePromise;
385 }
386
387 /**
388 * Checks the incoming `event.request` against the registered routes, and if
389 * there's a match, returns the corresponding handler along with any params
390 * generated by the match.
391 *
392 * @param {FetchEvent} event
393 * @param {URL} url
394 * @return {Object} Returns an object with `handler` and `params` properties.
395 * They are populated if a matching route was found or `undefined` otherwise.
396 *
397 * @private
398 */
399 _findHandlerAndParams(event, url) {
400 const routes = this._routes.get(event.request.method) || [];
401 for (const route of routes) {
402 let matchResult = route.match({ url, event });
403 if (matchResult) {
404 if (Array.isArray(matchResult) && matchResult.length === 0) {
405 // Instead of passing an empty array in as params, use undefined.
406 matchResult = undefined;
407 } else if (matchResult.constructor === Object && Object.keys(matchResult).length === 0 || matchResult === true) {
408 // Instead of passing an empty object in as params, use undefined.
409 matchResult = undefined;
410 }
411
412 // Break out of the loop and return the appropriate values as soon as
413 // we have a match.
414 return {
415 route,
416 params: matchResult,
417 handler: route.handler
418 };
419 }
420 }
421
422 // If we didn't have a match, then return undefined values.
423 return { handler: undefined, params: undefined };
424 }
425
426 /**
427 * Define a default `handler` that's called when no routes explicitly
428 * match the incoming request.
429 *
430 * Without a default handler, unmatched requests will go against the
431 * network as if there were no service worker present.
432 *
433 * @param {workbox.routing.Route~handlerCallback} handler A callback
434 * function that returns a Promise resulting in a Response.
435 */
436 setDefaultHandler(handler) {
437 this._defaultHandler = normalizeHandler(handler);
438 }
439
440 /**
441 * If a Route throws an error while handling a request, this `handler`
442 * will be called and given a chance to provide a response.
443 *
444 * @param {workbox.routing.Route~handlerCallback} handler A callback
445 * function that returns a Promise resulting in a Response.
446 */
447 setCatchHandler(handler) {
448 this._catchHandler = normalizeHandler(handler);
449 }
450
451 /**
452 * Registers a route with the router.
453 *
454 * @param {workbox.routing.Route} route The route to register.
455 */
456 registerRoute(route) {
457 {
458 assert_mjs.assert.isType(route, 'object', {
459 moduleName: 'workbox-routing',
460 className: 'Router',
461 funcName: 'registerRoute',
462 paramName: 'route'
463 });
464
465 assert_mjs.assert.hasMethod(route, 'match', {
466 moduleName: 'workbox-routing',
467 className: 'Router',
468 funcName: 'registerRoute',
469 paramName: 'route'
470 });
471
472 assert_mjs.assert.isType(route.handler, 'object', {
473 moduleName: 'workbox-routing',
474 className: 'Router',
475 funcName: 'registerRoute',
476 paramName: 'route'
477 });
478
479 assert_mjs.assert.hasMethod(route.handler, 'handle', {
480 moduleName: 'workbox-routing',
481 className: 'Router',
482 funcName: 'registerRoute',
483 paramName: 'route.handler'
484 });
485
486 assert_mjs.assert.isType(route.method, 'string', {
487 moduleName: 'workbox-routing',
488 className: 'Router',
489 funcName: 'registerRoute',
490 paramName: 'route.method'
491 });
492 }
493
494 if (!this._routes.has(route.method)) {
495 this._routes.set(route.method, []);
496 }
497
498 // Give precedence to all of the earlier routes by adding this additional
499 // route to the end of the array.
500 this._routes.get(route.method).push(route);
501 }
502
503 /**
504 * Unregisters a route with the router.
505 *
506 * @param {workbox.routing.Route} route The route to unregister.
507 */
508 unregisterRoute(route) {
509 if (!this._routes.has(route.method)) {
510 throw new WorkboxError_mjs.WorkboxError('unregister-route-but-not-found-with-method', {
511 method: route.method
512 });
513 }
514
515 const routeIndex = this._routes.get(route.method).indexOf(route);
516 if (routeIndex > -1) {
517 this._routes.get(route.method).splice(routeIndex, 1);
518 } else {
519 throw new WorkboxError_mjs.WorkboxError('unregister-route-route-not-registered');
520 }
521 }
522 }
523
524 /*
525 Copyright 2016 Google Inc. All Rights Reserved.
526 Licensed under the Apache License, Version 2.0 (the "License");
527 you may not use this file except in compliance with the License.
528 You may obtain a copy of the License at
529
530 http://www.apache.org/licenses/LICENSE-2.0
531
532 Unless required by applicable law or agreed to in writing, software
533 distributed under the License is distributed on an "AS IS" BASIS,
534 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
535 See the License for the specific language governing permissions and
536 limitations under the License.
537 */
538
539 /**
540 * NavigationRoute makes it easy to create a [Route]{@link
541 * workbox.routing.Route} that matches for browser
542 * [navigation requests]{@link https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests}.
543 *
544 * It will only match incoming Requests whose
545 * [`mode`]{@link https://fetch.spec.whatwg.org/#concept-request-mode}
546 * is set to `navigate`.
547 *
548 * You can optionally only apply this route to a subset of navigation requests
549 * by using one or both of the `blacklist` and `whitelist` parameters.
550 *
551 * @memberof workbox.routing
552 * @extends workbox.routing.Route
553 */
554 class NavigationRoute extends Route {
555 /**
556 * If both `blacklist` and `whiltelist` are provided, the `blacklist` will
557 * take precedence and the request will not match this route.
558 *
559 * The regular expressions in `whitelist` and `blacklist`
560 * are matched against the concatenated
561 * [`pathname`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname}
562 * and [`search`]{@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search}
563 * portions of the requested URL.
564 *
565 * @param {workbox.routing.Route~handlerCallback} handler A callback
566 * function that returns a Promise resulting in a Response.
567 * @param {Object} options
568 * @param {Array<RegExp>} [options.blacklist] If any of these patterns match,
569 * the route will not handle the request (even if a whitelist RegExp matches).
570 * @param {Array<RegExp>} [options.whitelist=[/./]] If any of these patterns
571 * match the URL's pathname and search parameter, the route will handle the
572 * request (assuming the blacklist doesn't match).
573 */
574 constructor(handler, { whitelist = [/./], blacklist = [] } = {}) {
575 {
576 assert_mjs.assert.isArrayOfClass(whitelist, RegExp, {
577 moduleName: 'workbox-routing',
578 className: 'NavigationRoute',
579 funcName: 'constructor',
580 paramName: 'options.whitelist'
581 });
582 assert_mjs.assert.isArrayOfClass(blacklist, RegExp, {
583 moduleName: 'workbox-routing',
584 className: 'NavigationRoute',
585 funcName: 'constructor',
586 paramName: 'options.blacklist'
587 });
588 }
589
590 super((...args) => this._match(...args), handler);
591
592 this._whitelist = whitelist;
593 this._blacklist = blacklist;
594 }
595
596 /**
597 * Routes match handler.
598 *
599 * @param {Object} input
600 * @param {FetchEvent} input.event
601 * @param {URL} input.url
602 * @return {boolean}
603 *
604 * @private
605 */
606 _match({ event, url }) {
607 if (event.request.mode !== 'navigate') {
608 return false;
609 }
610
611 const pathnameAndSearch = url.pathname + url.search;
612
613 if (this._blacklist.some(regExp => regExp.test(pathnameAndSearch))) {
614 {
615 logger_mjs.logger.debug(`The navigation route is not being used, since the ` + `request URL matches both the whitelist and blacklist.`);
616 }
617 return false;
618 }
619
620 if (this._whitelist.some(regExp => regExp.test(pathnameAndSearch))) {
621 {
622 logger_mjs.logger.debug(`The navigation route is being used.`);
623 }
624 return true;
625 } else {
626 {
627 logger_mjs.logger.debug(`The navigation route is not being used, since the ` + `URL being navigated to doesn't match the whitelist.`);
628 }
629 }
630
631 return false;
632 }
633 }
634
635 /*
636 Copyright 2017 Google Inc.
637
638 Licensed under the Apache License, Version 2.0 (the "License");
639 you may not use this file except in compliance with the License.
640 You may obtain a copy of the License at
641
642 https://www.apache.org/licenses/LICENSE-2.0
643
644 Unless required by applicable law or agreed to in writing, software
645 distributed under the License is distributed on an "AS IS" BASIS,
646 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
647 See the License for the specific language governing permissions and
648 limitations under the License.
649 */
650
651 var publicAPI = /*#__PURE__*/Object.freeze({
652 RegExpRoute: RegExpRoute,
653 Route: Route,
654 Router: Router,
655 NavigationRoute: NavigationRoute
656 });
657
658 /*
659 Copyright 2017 Google Inc.
660
661 Licensed under the Apache License, Version 2.0 (the "License");
662 you may not use this file except in compliance with the License.
663 You may obtain a copy of the License at
664
665 https://www.apache.org/licenses/LICENSE-2.0
666
667 Unless required by applicable law or agreed to in writing, software
668 distributed under the License is distributed on an "AS IS" BASIS,
669 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
670 See the License for the specific language governing permissions and
671 limitations under the License.
672 */
673
674 {
675 assert_mjs.assert.isSwEnv('workbox-routing');
676 }
677
678 /**
679 * @private
680 */
681 class DefaultRouter extends Router {
682 /**
683 * Easily register a RegExp, string, or function with a caching
684 * strategy to the Router.
685 *
686 * This method will generate a Route for you if needed and
687 * call [Router.registerRoute()]{@link
688 * workbox.routing.Router#registerRoute}.
689 *
690 * @param {
691 * RegExp|
692 * string|
693 * workbox.routing.Route~matchCallback|
694 * workbox.routing.Route
695 * } capture
696 * If the capture param is a `Route`, all other arguments will be ignored.
697 * @param {workbox.routing.Route~handlerCallback} handler A callback
698 * function that returns a Promise resulting in a Response.
699 * @param {string} [method='GET'] The HTTP method to match the Route
700 * against.
701 * @return {workbox.routing.Route} The generated `Route`(Useful for
702 * unregistering).
703 *
704 * @alias workbox.routing.registerRoute
705 */
706 registerRoute(capture, handler, method = 'GET') {
707 let route;
708
709 if (typeof capture === 'string') {
710 const captureUrl = new URL(capture, location);
711
712 {
713 if (!(capture.startsWith('/') || capture.startsWith('http'))) {
714 throw new WorkboxError_mjs.WorkboxError('invalid-string', {
715 moduleName: 'workbox-routing',
716 className: 'DefaultRouter',
717 funcName: 'registerRoute',
718 paramName: 'capture'
719 });
720 }
721
722 // We want to check if Express-style wildcards are in the pathname only.
723 // TODO: Remove this log message in v4.
724 const valueToCheck = capture.startsWith('http') ? captureUrl.pathname : capture;
725 // See https://github.com/pillarjs/path-to-regexp#parameters
726 const wildcards = '[*:?+]';
727 if (valueToCheck.match(new RegExp(`${wildcards}`))) {
728 logger_mjs.logger.debug(`The '$capture' parameter contains an Express-style wildcard ` + `character (${wildcards}). Strings are now always interpreted as ` + `exact matches; use a RegExp for partial or wildcard matches.`);
729 }
730 }
731
732 const matchCallback = ({ url }) => {
733 {
734 if (url.pathname === captureUrl.pathname && url.origin !== captureUrl.origin) {
735 logger_mjs.logger.debug(`${capture} only partially matches the cross-origin URL ` + `${url}. This route will only handle cross-origin requests ` + `if they match the entire URL.`);
736 }
737 }
738
739 return url.href === captureUrl.href;
740 };
741
742 route = new Route(matchCallback, handler, method);
743 } else if (capture instanceof RegExp) {
744 route = new RegExpRoute(capture, handler, method);
745 } else if (typeof capture === 'function') {
746 route = new Route(capture, handler, method);
747 } else if (capture instanceof Route) {
748 route = capture;
749 } else {
750 throw new WorkboxError_mjs.WorkboxError('unsupported-route-type', {
751 moduleName: 'workbox-routing',
752 className: 'DefaultRouter',
753 funcName: 'registerRoute',
754 paramName: 'capture'
755 });
756 }
757
758 super.registerRoute(route);
759 return route;
760 }
761
762 /**
763 * Register a route that will return a precached file for a navigation
764 * request. This is useful for the
765 * [application shell pattern]{@link https://developers.google.com/web/fundamentals/architecture/app-shell}.
766 *
767 * This method will generate a
768 * [NavigationRoute]{@link workbox.routing.NavigationRoute}
769 * and call
770 * [Router.registerRoute()]{@link workbox.routing.Router#registerRoute}
771 * .
772 *
773 * @param {string} cachedAssetUrl
774 * @param {Object} [options]
775 * @param {string} [options.cacheName] Cache name to store and retrieve
776 * requests. Defaults to precache cache name provided by
777 * [workbox-core.cacheNames]{@link workbox.core.cacheNames}.
778 * @param {Array<RegExp>} [options.blacklist=[]] If any of these patterns
779 * match, the route will not handle the request (even if a whitelist entry
780 * matches).
781 * @param {Array<RegExp>} [options.whitelist=[/./]] If any of these patterns
782 * match the URL's pathname and search parameter, the route will handle the
783 * request (assuming the blacklist doesn't match).
784 * @return {workbox.routing.NavigationRoute} Returns the generated
785 * Route.
786 *
787 * @alias workbox.routing.registerNavigationRoute
788 */
789 registerNavigationRoute(cachedAssetUrl, options = {}) {
790 {
791 assert_mjs.assert.isType(cachedAssetUrl, 'string', {
792 moduleName: 'workbox-routing',
793 className: '[default export]',
794 funcName: 'registerNavigationRoute',
795 paramName: 'cachedAssetUrl'
796 });
797 }
798
799 const cacheName = cacheNames_mjs.cacheNames.getPrecacheName(options.cacheName);
800 const handler = () => caches.match(cachedAssetUrl, { cacheName }).then(response => {
801 if (response) {
802 return response;
803 }
804 // This shouldn't normally happen, but there are edge cases:
805 // https://github.com/GoogleChrome/workbox/issues/1441
806 throw new Error(`The cache ${cacheName} did not have an entry for ` + `${cachedAssetUrl}.`);
807 }).catch(error => {
808 // If there's either a cache miss, or the caches.match() call threw
809 // an exception, then attempt to fulfill the navigation request with
810 // a response from the network rather than leaving the user with a
811 // failed navigation.
812 {
813 logger_mjs.logger.debug(`Unable to respond to navigation request with cached ` + `response: ${error.message}. Falling back to network.`);
814 }
815
816 // This might still fail if the browser is offline...
817 return fetch(cachedAssetUrl);
818 });
819
820 const route = new NavigationRoute(handler, {
821 whitelist: options.whitelist,
822 blacklist: options.blacklist
823 });
824 super.registerRoute(route);
825
826 return route;
827 }
828 }
829
830 const router = new DefaultRouter();
831
832 // By default, register a fetch event listener that will respond to a request
833 // only if there's a matching route.
834 self.addEventListener('fetch', event => {
835 const responsePromise = router.handleRequest(event);
836 if (responsePromise) {
837 event.respondWith(responsePromise);
838 }
839 });
840
841 /*
842 Copyright 2017 Google Inc.
843
844 Licensed under the Apache License, Version 2.0 (the "License");
845 you may not use this file except in compliance with the License.
846 You may obtain a copy of the License at
847
848 https://www.apache.org/licenses/LICENSE-2.0
849
850 Unless required by applicable law or agreed to in writing, software
851 distributed under the License is distributed on an "AS IS" BASIS,
852 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
853 See the License for the specific language governing permissions and
854 limitations under the License.
855 */
856
857 const finalExport = Object.assign(router, publicAPI);
858
859 return finalExport;
860
861}(workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private));
862
863//# sourceMappingURL=workbox-routing.dev.js.map