Skip to content

Commit

Permalink
Adding the route logic (#893)
Browse files Browse the repository at this point in the history
* Adding the route logic

* Adding some todo's and fixing tests

* Always returning fresh cached urls
  • Loading branch information
Matt Gaunt authored and addyosmani committed Oct 14, 2017
1 parent 5ddd9ce commit 28f9a2c
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 13 deletions.
10 changes: 10 additions & 0 deletions packages/workbox-precaching/controllers/PrecacheController.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,16 @@ class PrecacheController {
};
});
}

/**
* Returns an array of fully qualified URL's that will be precached.
*
* @return {Array<string>} An array of URLs.
*/
async getCachedUrls() {
return Array.from(this._entriesToCacheMap.keys())
.map((url) => new URL(url, location).href);
}
}

export default PrecacheController;
126 changes: 114 additions & 12 deletions packages/workbox-precaching/default-precaching-export.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,32 @@
limitations under the License.
*/

import {_private} from 'workbox-core';
import PrecacheController from './controllers/PrecacheController.mjs';
import './_version.mjs';

const precacheController = new PrecacheController();
let listenersAdded = false;
let installActivateListenersAdded = false;
let fetchListenersAdded = false;

const addListeners = () => {
listenersAdded = true;
const cacheName = _private.cacheNames.getPrecacheName();
const precacheController = new PrecacheController(cacheName);

/**
* This method will add items to the precache list, removing duplicates
* and ensuring the information is valid.
*
* @param {Array<Object|string>} entries Array of entries to precache.
*
* @alias module:workbox-precaching.precache
*/
const precache = (entries) => {
precacheController.addToCacheList(entries);

if (installActivateListenersAdded || entries.length <= 0) {
return;
}

installActivateListenersAdded = true;
self.addEventListener('install', (event) => {
event.waitUntil(precacheController.install());
});
Expand All @@ -30,22 +48,106 @@ const addListeners = () => {
});
};

const removeIgnoreUrlParams = (url, ignoreUrlParametersMatching) => {

};

/**
* This method will add items to the precache list, removing duplicates
* and ensuring the information is valid.
* This function will take the request URL and manipulate it based on the
* configuration options.
*
* @param {Array<Object|string>} entries Array of entries to precache.
* @param {string} url
* @param {Object} options
* @return {string|null} Returns the URL in the cache that matches the request
* if available, other null.
*
* @alias module:workbox-precaching.precache
* @private
*/
const precache = (entries) => {
precacheController.addToCacheList(entries);
const _getPrecachedUrl = (url, options) => {
// If we precache '/some-url' but the URL referenced from the browser
// is '/some-url#1234', the comparison won't work unless we normalise
// the URLS.
// See https://github.com/GoogleChrome/workbox/issues/488.
url.hash = '';

if (entries.length > 0 && !listenersAdded) {
addListeners();
const cachedUrls = precacheController.getCachedUrls();
if (cachedUrls.indexOf(url.href) !== -1) {
// It's a perfect match
return url.href;
}

let strippedUrl = removeIgnoreUrlParams(
url.href, options.ignoreUrlParametersMatching
);
if (cachedUrls.indexOf(strippedUrl.href) !== -1) {
return strippedUrl.href;
}

if (options.directoryIndex && strippedUrl.pathname.endsWith('/')) {
strippedUrl.pathname += options.directoryIndex;
if (cachedUrls.indexOf(strippedUrl.href) !== -1) {
return strippedUrl.href;
}
}

return null;
};

/**
* This method will add a fetch listener to the service worker that will
* respond to `FetchEvents` if they are known to be precached.
*
* If they aren't precached, the event will not be responded to, allowing
* other `fetch` event listeners to respond to the `FetchEvent`.
*
* @param {Object} options
* @param {string} options.directoryIndex The `directoryIndex` will check
* cache entries for a URLs ending with '/' to see if there is a hit when
* appending the `directoryIndex` value.
* @param {Array<RegExp>} options.ignoreUrlParametersMatching An array of
* regex's to remove search params when looking for a cache match.
*
* @alias module:workbox-precaching.addRoute
*/
const addRoute = (options) => {
if (fetchListenersAdded) {
// TODO Throw error here.
return;
}

fetchListenersAdded = true;
self.addEventListener('fetch', (event) => {
const precachedUrl = _getPrecachedUrl(event.request.url, options);
if (!precachedUrl) {
return;
}

const responsePromise = caches.open(cacheName)
.then((cache) => {
return cache.match(precachedUrl);
});
event.respondWith(responsePromise);
});
};

/**
* This method will add entries for precaching and then add a route. This is
* a convenience method that will call precache() and addRoute() in a single
* call.
*
* @param {Array<Object|string>} entries Array of entries to precache.
* @param {Object} options See
* [addRoute() options]{@link module:workbox-precaching.addRoute}.
*
* @alias module:workbox-precaching.precacheAndRoute
*/
const precacheAndRoute = (entries, options) => {
precache(entries);
addRoute(options);
};

export default {
precache,
addRoute,
precacheAndRoute,
};
14 changes: 13 additions & 1 deletion test/workbox-precaching/node/test-precaching-module.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,11 @@ describe(`[workbox-precaching] Module`, function() {
describe('default export', function() {
it(`should expose known methods`, function() {
const defaultExport = precachingModule.default;
expect(Object.keys(defaultExport)).to.deep.equal(['precache']);
expect(Object.keys(defaultExport)).to.deep.equal([
'precache',
'addRoute',
'precacheAndRoute',
]);
});

describe(`precache()`, function() {
Expand All @@ -47,5 +51,13 @@ describe(`[workbox-precaching] Module`, function() {
]);
});
});

describe(`addRoute()`, function() {
// TODO @gauntface write tests for this
});

describe(`precacheAndRoute()`, function() {
// TODO @gauntface write tests for this
});
});
});

0 comments on commit 28f9a2c

Please sign in to comment.