workbox-window.dev.es5.mjs 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125
  1. try {
  2. self['workbox:window:5.1.4'] && _();
  3. } catch (e) {}
  4. /*
  5. Copyright 2019 Google LLC
  6. Use of this source code is governed by an MIT-style
  7. license that can be found in the LICENSE file or at
  8. https://opensource.org/licenses/MIT.
  9. */
  10. /**
  11. * Sends a data object to a service worker via `postMessage` and resolves with
  12. * a response (if any).
  13. *
  14. * A response can be set in a message handler in the service worker by
  15. * calling `event.ports[0].postMessage(...)`, which will resolve the promise
  16. * returned by `messageSW()`. If no response is set, the promise will not
  17. * resolve.
  18. *
  19. * @param {ServiceWorker} sw The service worker to send the message to.
  20. * @param {Object} data An object to send to the service worker.
  21. * @return {Promise<Object|undefined>}
  22. * @memberof module:workbox-window
  23. */
  24. function messageSW(sw, data) {
  25. return new Promise(function (resolve) {
  26. var messageChannel = new MessageChannel();
  27. messageChannel.port1.onmessage = function (event) {
  28. resolve(event.data);
  29. };
  30. sw.postMessage(data, [messageChannel.port2]);
  31. });
  32. }
  33. function _defineProperties(target, props) {
  34. for (var i = 0; i < props.length; i++) {
  35. var descriptor = props[i];
  36. descriptor.enumerable = descriptor.enumerable || false;
  37. descriptor.configurable = true;
  38. if ("value" in descriptor) descriptor.writable = true;
  39. Object.defineProperty(target, descriptor.key, descriptor);
  40. }
  41. }
  42. function _createClass(Constructor, protoProps, staticProps) {
  43. if (protoProps) _defineProperties(Constructor.prototype, protoProps);
  44. if (staticProps) _defineProperties(Constructor, staticProps);
  45. return Constructor;
  46. }
  47. function _inheritsLoose(subClass, superClass) {
  48. subClass.prototype = Object.create(superClass.prototype);
  49. subClass.prototype.constructor = subClass;
  50. subClass.__proto__ = superClass;
  51. }
  52. function _unsupportedIterableToArray(o, minLen) {
  53. if (!o) return;
  54. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  55. var n = Object.prototype.toString.call(o).slice(8, -1);
  56. if (n === "Object" && o.constructor) n = o.constructor.name;
  57. if (n === "Map" || n === "Set") return Array.from(o);
  58. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  59. }
  60. function _arrayLikeToArray(arr, len) {
  61. if (len == null || len > arr.length) len = arr.length;
  62. for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  63. return arr2;
  64. }
  65. function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  66. var it;
  67. if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) {
  68. if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
  69. if (it) o = it;
  70. var i = 0;
  71. return function () {
  72. if (i >= o.length) return {
  73. done: true
  74. };
  75. return {
  76. done: false,
  77. value: o[i++]
  78. };
  79. };
  80. }
  81. throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  82. }
  83. it = o[Symbol.iterator]();
  84. return it.next.bind(it);
  85. }
  86. try {
  87. self['workbox:core:5.1.4'] && _();
  88. } catch (e) {}
  89. /*
  90. Copyright 2018 Google LLC
  91. Use of this source code is governed by an MIT-style
  92. license that can be found in the LICENSE file or at
  93. https://opensource.org/licenses/MIT.
  94. */
  95. /**
  96. * The Deferred class composes Promises in a way that allows for them to be
  97. * resolved or rejected from outside the constructor. In most cases promises
  98. * should be used directly, but Deferreds can be necessary when the logic to
  99. * resolve a promise must be separate.
  100. *
  101. * @private
  102. */
  103. var Deferred =
  104. /**
  105. * Creates a promise and exposes its resolve and reject functions as methods.
  106. */
  107. function Deferred() {
  108. var _this = this;
  109. this.promise = new Promise(function (resolve, reject) {
  110. _this.resolve = resolve;
  111. _this.reject = reject;
  112. });
  113. };
  114. /*
  115. Copyright 2019 Google LLC
  116. Use of this source code is governed by an MIT-style
  117. license that can be found in the LICENSE file or at
  118. https://opensource.org/licenses/MIT.
  119. */
  120. /**
  121. * A helper function that prevents a promise from being flagged as unused.
  122. *
  123. * @private
  124. **/
  125. function dontWaitFor(promise) {
  126. // Effective no-op.
  127. promise.then(function () {});
  128. }
  129. /*
  130. Copyright 2019 Google LLC
  131. Use of this source code is governed by an MIT-style
  132. license that can be found in the LICENSE file or at
  133. https://opensource.org/licenses/MIT.
  134. */
  135. var logger = function () {
  136. // Don't overwrite this value if it's already set.
  137. // See https://github.com/GoogleChrome/workbox/pull/2284#issuecomment-560470923
  138. if (!('__WB_DISABLE_DEV_LOGS' in self)) {
  139. self.__WB_DISABLE_DEV_LOGS = false;
  140. }
  141. var inGroup = false;
  142. var methodToColorMap = {
  143. debug: "#7f8c8d",
  144. log: "#2ecc71",
  145. warn: "#f39c12",
  146. error: "#c0392b",
  147. groupCollapsed: "#3498db",
  148. groupEnd: null
  149. };
  150. var print = function print(method, args) {
  151. var _console2;
  152. if (self.__WB_DISABLE_DEV_LOGS) {
  153. return;
  154. }
  155. if (method === 'groupCollapsed') {
  156. // Safari doesn't print all console.groupCollapsed() arguments:
  157. // https://bugs.webkit.org/show_bug.cgi?id=182754
  158. if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {
  159. var _console;
  160. (_console = console)[method].apply(_console, args);
  161. return;
  162. }
  163. }
  164. var styles = ["background: " + methodToColorMap[method], "border-radius: 0.5em", "color: white", "font-weight: bold", "padding: 2px 0.5em"]; // When in a group, the workbox prefix is not displayed.
  165. var logPrefix = inGroup ? [] : ['%cworkbox', styles.join(';')];
  166. (_console2 = console)[method].apply(_console2, logPrefix.concat(args));
  167. if (method === 'groupCollapsed') {
  168. inGroup = true;
  169. }
  170. if (method === 'groupEnd') {
  171. inGroup = false;
  172. }
  173. };
  174. var api = {};
  175. var loggerMethods = Object.keys(methodToColorMap);
  176. var _loop = function _loop() {
  177. var key = _loggerMethods[_i];
  178. var method = key;
  179. api[method] = function () {
  180. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  181. args[_key] = arguments[_key];
  182. }
  183. print(method, args);
  184. };
  185. };
  186. for (var _i = 0, _loggerMethods = loggerMethods; _i < _loggerMethods.length; _i++) {
  187. _loop();
  188. }
  189. return api;
  190. }();
  191. /*
  192. Copyright 2019 Google LLC
  193. Use of this source code is governed by an MIT-style
  194. license that can be found in the LICENSE file or at
  195. https://opensource.org/licenses/MIT.
  196. */
  197. /**
  198. * A minimal `EventTarget` shim.
  199. * This is necessary because not all browsers support constructable
  200. * `EventTarget`, so using a real `EventTarget` will error.
  201. * @private
  202. */
  203. var WorkboxEventTarget = /*#__PURE__*/function () {
  204. function WorkboxEventTarget() {
  205. this._eventListenerRegistry = new Map();
  206. }
  207. /**
  208. * @param {string} type
  209. * @param {Function} listener
  210. * @private
  211. */
  212. var _proto = WorkboxEventTarget.prototype;
  213. _proto.addEventListener = function addEventListener(type, listener) {
  214. var foo = this._getEventListenersByType(type);
  215. foo.add(listener);
  216. }
  217. /**
  218. * @param {string} type
  219. * @param {Function} listener
  220. * @private
  221. */
  222. ;
  223. _proto.removeEventListener = function removeEventListener(type, listener) {
  224. this._getEventListenersByType(type).delete(listener);
  225. }
  226. /**
  227. * @param {Object} event
  228. * @private
  229. */
  230. ;
  231. _proto.dispatchEvent = function dispatchEvent(event) {
  232. event.target = this;
  233. var listeners = this._getEventListenersByType(event.type);
  234. for (var _iterator = _createForOfIteratorHelperLoose(listeners), _step; !(_step = _iterator()).done;) {
  235. var listener = _step.value;
  236. listener(event);
  237. }
  238. }
  239. /**
  240. * Returns a Set of listeners associated with the passed event type.
  241. * If no handlers have been registered, an empty Set is returned.
  242. *
  243. * @param {string} type The event type.
  244. * @return {Set<ListenerCallback>} An array of handler functions.
  245. * @private
  246. */
  247. ;
  248. _proto._getEventListenersByType = function _getEventListenersByType(type) {
  249. if (!this._eventListenerRegistry.has(type)) {
  250. this._eventListenerRegistry.set(type, new Set());
  251. }
  252. return this._eventListenerRegistry.get(type);
  253. };
  254. return WorkboxEventTarget;
  255. }();
  256. /*
  257. Copyright 2019 Google LLC
  258. Use of this source code is governed by an MIT-style
  259. license that can be found in the LICENSE file or at
  260. https://opensource.org/licenses/MIT.
  261. */
  262. /**
  263. * Returns true if two URLs have the same `.href` property. The URLS can be
  264. * relative, and if they are the current location href is used to resolve URLs.
  265. *
  266. * @private
  267. * @param {string} url1
  268. * @param {string} url2
  269. * @return {boolean}
  270. */
  271. function urlsMatch(url1, url2) {
  272. var _location = location,
  273. href = _location.href;
  274. return new URL(url1, href).href === new URL(url2, href).href;
  275. }
  276. /*
  277. Copyright 2019 Google LLC
  278. Use of this source code is governed by an MIT-style
  279. license that can be found in the LICENSE file or at
  280. https://opensource.org/licenses/MIT.
  281. */
  282. /**
  283. * A minimal `Event` subclass shim.
  284. * This doesn't *actually* subclass `Event` because not all browsers support
  285. * constructable `EventTarget`, and using a real `Event` will error.
  286. * @private
  287. */
  288. var WorkboxEvent = function WorkboxEvent(type, props) {
  289. this.type = type;
  290. Object.assign(this, props);
  291. };
  292. // `skipWaiting()` wasn't called. This 200 amount wasn't scientifically
  293. // chosen, but it seems to avoid false positives in my testing.
  294. function _await(value, then, direct) {
  295. if (direct) {
  296. return then ? then(value) : value;
  297. }
  298. if (!value || !value.then) {
  299. value = Promise.resolve(value);
  300. }
  301. return then ? value.then(then) : value;
  302. }
  303. var WAITING_TIMEOUT_DURATION = 200; // The amount of time after a registration that we can reasonably conclude
  304. // that the registration didn't trigger an update.
  305. function _async(f) {
  306. return function () {
  307. for (var args = [], i = 0; i < arguments.length; i++) {
  308. args[i] = arguments[i];
  309. }
  310. try {
  311. return Promise.resolve(f.apply(this, args));
  312. } catch (e) {
  313. return Promise.reject(e);
  314. }
  315. };
  316. }
  317. var REGISTRATION_TIMEOUT_DURATION = 60000;
  318. /**
  319. * A class to aid in handling service worker registration, updates, and
  320. * reacting to service worker lifecycle events.
  321. *
  322. * @fires [message]{@link module:workbox-window.Workbox#message}
  323. * @fires [installed]{@link module:workbox-window.Workbox#installed}
  324. * @fires [waiting]{@link module:workbox-window.Workbox#waiting}
  325. * @fires [controlling]{@link module:workbox-window.Workbox#controlling}
  326. * @fires [activated]{@link module:workbox-window.Workbox#activated}
  327. * @fires [redundant]{@link module:workbox-window.Workbox#redundant}
  328. * @fires [externalinstalled]{@link module:workbox-window.Workbox#externalinstalled}
  329. * @fires [externalwaiting]{@link module:workbox-window.Workbox#externalwaiting}
  330. * @fires [externalactivated]{@link module:workbox-window.Workbox#externalactivated}
  331. * @memberof module:workbox-window
  332. */
  333. function _empty() {}
  334. var Workbox = /*#__PURE__*/function (_WorkboxEventTarget) {
  335. _inheritsLoose(Workbox, _WorkboxEventTarget);
  336. /**
  337. * Creates a new Workbox instance with a script URL and service worker
  338. * options. The script URL and options are the same as those used when
  339. * calling `navigator.serviceWorker.register(scriptURL, options)`. See:
  340. * https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/register
  341. *
  342. * @param {string} scriptURL The service worker script associated with this
  343. * instance.
  344. * @param {Object} [registerOptions] The service worker options associated
  345. * with this instance.
  346. */
  347. function Workbox(scriptURL, registerOptions) {
  348. var _this;
  349. if (registerOptions === void 0) {
  350. registerOptions = {};
  351. }
  352. _this = _WorkboxEventTarget.call(this) || this;
  353. _this._registerOptions = {};
  354. _this._updateFoundCount = 0; // Deferreds we can resolve later.
  355. _this._swDeferred = new Deferred();
  356. _this._activeDeferred = new Deferred();
  357. _this._controllingDeferred = new Deferred();
  358. _this._registrationTime = 0;
  359. _this._ownSWs = new Set();
  360. /**
  361. * @private
  362. */
  363. _this._onUpdateFound = function () {
  364. // `this._registration` will never be `undefined` after an update is found.
  365. var registration = _this._registration;
  366. var installingSW = registration.installing; // If the script URL passed to `navigator.serviceWorker.register()` is
  367. // different from the current controlling SW's script URL, we know any
  368. // successful registration calls will trigger an `updatefound` event.
  369. // But if the registered script URL is the same as the current controlling
  370. // SW's script URL, we'll only get an `updatefound` event if the file
  371. // changed since it was last registered. This can be a problem if the user
  372. // opens up the same page in a different tab, and that page registers
  373. // a SW that triggers an update. It's a problem because this page has no
  374. // good way of knowing whether the `updatefound` event came from the SW
  375. // script it registered or from a registration attempt made by a newer
  376. // version of the page running in another tab.
  377. // To minimize the possibility of a false positive, we use the logic here:
  378. var updateLikelyTriggeredExternally = // Since we enforce only calling `register()` once, and since we don't
  379. // add the `updatefound` event listener until the `register()` call, if
  380. // `_updateFoundCount` is > 0 then it means this method has already
  381. // been called, thus this SW must be external
  382. _this._updateFoundCount > 0 || // If the script URL of the installing SW is different from this
  383. // instance's script URL, we know it's definitely not from our
  384. // registration.
  385. !urlsMatch(installingSW.scriptURL, _this._scriptURL) || // If all of the above are false, then we use a time-based heuristic:
  386. // Any `updatefound` event that occurs long after our registration is
  387. // assumed to be external.
  388. performance.now() > _this._registrationTime + REGISTRATION_TIMEOUT_DURATION ? // If any of the above are not true, we assume the update was
  389. // triggered by this instance.
  390. true : false;
  391. if (updateLikelyTriggeredExternally) {
  392. _this._externalSW = installingSW;
  393. registration.removeEventListener('updatefound', _this._onUpdateFound);
  394. } else {
  395. // If the update was not triggered externally we know the installing
  396. // SW is the one we registered, so we set it.
  397. _this._sw = installingSW;
  398. _this._ownSWs.add(installingSW);
  399. _this._swDeferred.resolve(installingSW); // The `installing` state isn't something we have a dedicated
  400. // callback for, but we do log messages for it in development.
  401. {
  402. if (navigator.serviceWorker.controller) {
  403. logger.log('Updated service worker found. Installing now...');
  404. } else {
  405. logger.log('Service worker is installing...');
  406. }
  407. }
  408. } // Increment the `updatefound` count, so future invocations of this
  409. // method can be sure they were triggered externally.
  410. ++_this._updateFoundCount; // Add a `statechange` listener regardless of whether this update was
  411. // triggered externally, since we have callbacks for both.
  412. installingSW.addEventListener('statechange', _this._onStateChange);
  413. };
  414. /**
  415. * @private
  416. * @param {Event} originalEvent
  417. */
  418. _this._onStateChange = function (originalEvent) {
  419. // `this._registration` will never be `undefined` after an update is found.
  420. var registration = _this._registration;
  421. var sw = originalEvent.target;
  422. var state = sw.state;
  423. var isExternal = sw === _this._externalSW;
  424. var eventPrefix = isExternal ? 'external' : '';
  425. var eventProps = {
  426. sw: sw,
  427. originalEvent: originalEvent
  428. };
  429. if (!isExternal && _this._isUpdate) {
  430. eventProps.isUpdate = true;
  431. }
  432. _this.dispatchEvent(new WorkboxEvent(eventPrefix + state, eventProps));
  433. if (state === 'installed') {
  434. // This timeout is used to ignore cases where the service worker calls
  435. // `skipWaiting()` in the install event, thus moving it directly in the
  436. // activating state. (Since all service workers *must* go through the
  437. // waiting phase, the only way to detect `skipWaiting()` called in the
  438. // install event is to observe that the time spent in the waiting phase
  439. // is very short.)
  440. // NOTE: we don't need separate timeouts for the own and external SWs
  441. // since they can't go through these phases at the same time.
  442. _this._waitingTimeout = self.setTimeout(function () {
  443. // Ensure the SW is still waiting (it may now be redundant).
  444. if (state === 'installed' && registration.waiting === sw) {
  445. _this.dispatchEvent(new WorkboxEvent(eventPrefix + 'waiting', eventProps));
  446. {
  447. if (isExternal) {
  448. logger.warn('An external service worker has installed but is ' + 'waiting for this client to close before activating...');
  449. } else {
  450. logger.warn('The service worker has installed but is waiting ' + 'for existing clients to close before activating...');
  451. }
  452. }
  453. }
  454. }, WAITING_TIMEOUT_DURATION);
  455. } else if (state === 'activating') {
  456. clearTimeout(_this._waitingTimeout);
  457. if (!isExternal) {
  458. _this._activeDeferred.resolve(sw);
  459. }
  460. }
  461. {
  462. switch (state) {
  463. case 'installed':
  464. if (isExternal) {
  465. logger.warn('An external service worker has installed. ' + 'You may want to suggest users reload this page.');
  466. } else {
  467. logger.log('Registered service worker installed.');
  468. }
  469. break;
  470. case 'activated':
  471. if (isExternal) {
  472. logger.warn('An external service worker has activated.');
  473. } else {
  474. logger.log('Registered service worker activated.');
  475. if (sw !== navigator.serviceWorker.controller) {
  476. logger.warn('The registered service worker is active but ' + 'not yet controlling the page. Reload or run ' + '`clients.claim()` in the service worker.');
  477. }
  478. }
  479. break;
  480. case 'redundant':
  481. if (sw === _this._compatibleControllingSW) {
  482. logger.log('Previously controlling service worker now redundant!');
  483. } else if (!isExternal) {
  484. logger.log('Registered service worker now redundant!');
  485. }
  486. break;
  487. }
  488. }
  489. };
  490. /**
  491. * @private
  492. * @param {Event} originalEvent
  493. */
  494. _this._onControllerChange = function (originalEvent) {
  495. var sw = _this._sw;
  496. if (sw === navigator.serviceWorker.controller) {
  497. _this.dispatchEvent(new WorkboxEvent('controlling', {
  498. sw: sw,
  499. originalEvent: originalEvent,
  500. isUpdate: _this._isUpdate
  501. }));
  502. {
  503. logger.log('Registered service worker now controlling this page.');
  504. }
  505. _this._controllingDeferred.resolve(sw);
  506. }
  507. };
  508. /**
  509. * @private
  510. * @param {Event} originalEvent
  511. */
  512. _this._onMessage = _async(function (originalEvent) {
  513. var data = originalEvent.data,
  514. source = originalEvent.source; // Wait until there's an "own" service worker. This is used to buffer
  515. // `message` events that may be received prior to calling `register()`.
  516. return _await(_this.getSW(), function () {
  517. if (_this._ownSWs.has(source)) {
  518. _this.dispatchEvent(new WorkboxEvent('message', {
  519. data: data,
  520. sw: source,
  521. originalEvent: originalEvent
  522. }));
  523. }
  524. }); // If the service worker that sent the message is in the list of own
  525. // service workers for this instance, dispatch a `message` event.
  526. // NOTE: we check for all previously owned service workers rather than
  527. // just the current one because some messages (e.g. cache updates) use
  528. // a timeout when sent and may be delayed long enough for a service worker
  529. // update to be found.
  530. });
  531. _this._scriptURL = scriptURL;
  532. _this._registerOptions = registerOptions; // Add a message listener immediately since messages received during
  533. // page load are buffered only until the DOMContentLoaded event:
  534. // https://github.com/GoogleChrome/workbox/issues/2202
  535. navigator.serviceWorker.addEventListener('message', _this._onMessage);
  536. return _this;
  537. }
  538. /**
  539. * Registers a service worker for this instances script URL and service
  540. * worker options. By default this method delays registration until after
  541. * the window has loaded.
  542. *
  543. * @param {Object} [options]
  544. * @param {Function} [options.immediate=false] Setting this to true will
  545. * register the service worker immediately, even if the window has
  546. * not loaded (not recommended).
  547. */
  548. var _proto = Workbox.prototype;
  549. _proto.register = function register(_temp) {
  550. var _ref = _temp === void 0 ? {} : _temp,
  551. _ref$immediate = _ref.immediate,
  552. immediate = _ref$immediate === void 0 ? false : _ref$immediate;
  553. try {
  554. var _this3 = this;
  555. if ("dev" !== 'production') {
  556. if (_this3._registrationTime) {
  557. logger.error('Cannot re-register a Workbox instance after it has ' + 'been registered. Create a new instance instead.');
  558. return;
  559. }
  560. }
  561. return _invoke(function () {
  562. if (!immediate && document.readyState !== 'complete') {
  563. return _awaitIgnored(new Promise(function (res) {
  564. return window.addEventListener('load', res);
  565. }));
  566. }
  567. }, function () {
  568. // Set this flag to true if any service worker was controlling the page
  569. // at registration time.
  570. _this3._isUpdate = Boolean(navigator.serviceWorker.controller); // Before registering, attempt to determine if a SW is already controlling
  571. // the page, and if that SW script (and version, if specified) matches this
  572. // instance's script.
  573. _this3._compatibleControllingSW = _this3._getControllingSWIfCompatible();
  574. return _await(_this3._registerScript(), function (_this2$_registerScrip) {
  575. _this3._registration = _this2$_registerScrip;
  576. // If we have a compatible controller, store the controller as the "own"
  577. // SW, resolve active/controlling deferreds and add necessary listeners.
  578. if (_this3._compatibleControllingSW) {
  579. _this3._sw = _this3._compatibleControllingSW;
  580. _this3._activeDeferred.resolve(_this3._compatibleControllingSW);
  581. _this3._controllingDeferred.resolve(_this3._compatibleControllingSW);
  582. _this3._compatibleControllingSW.addEventListener('statechange', _this3._onStateChange, {
  583. once: true
  584. });
  585. } // If there's a waiting service worker with a matching URL before the
  586. // `updatefound` event fires, it likely means that this site is open
  587. // in another tab, or the user refreshed the page (and thus the previous
  588. // page wasn't fully unloaded before this page started loading).
  589. // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#waiting
  590. var waitingSW = _this3._registration.waiting;
  591. if (waitingSW && urlsMatch(waitingSW.scriptURL, _this3._scriptURL)) {
  592. // Store the waiting SW as the "own" Sw, even if it means overwriting
  593. // a compatible controller.
  594. _this3._sw = waitingSW; // Run this in the next microtask, so any code that adds an event
  595. // listener after awaiting `register()` will get this event.
  596. dontWaitFor(Promise.resolve().then(function () {
  597. _this3.dispatchEvent(new WorkboxEvent('waiting', {
  598. sw: waitingSW,
  599. wasWaitingBeforeRegister: true
  600. }));
  601. if ("dev" !== 'production') {
  602. logger.warn('A service worker was already waiting to activate ' + 'before this script was registered...');
  603. }
  604. }));
  605. } // If an "own" SW is already set, resolve the deferred.
  606. if (_this3._sw) {
  607. _this3._swDeferred.resolve(_this3._sw);
  608. _this3._ownSWs.add(_this3._sw);
  609. }
  610. if ("dev" !== 'production') {
  611. logger.log('Successfully registered service worker.', _this3._scriptURL);
  612. if (navigator.serviceWorker.controller) {
  613. if (_this3._compatibleControllingSW) {
  614. logger.debug('A service worker with the same script URL ' + 'is already controlling this page.');
  615. } else {
  616. logger.debug('A service worker with a different script URL is ' + 'currently controlling the page. The browser is now fetching ' + 'the new script now...');
  617. }
  618. }
  619. var currentPageIsOutOfScope = function currentPageIsOutOfScope() {
  620. var scopeURL = new URL(_this3._registerOptions.scope || _this3._scriptURL, document.baseURI);
  621. var scopeURLBasePath = new URL('./', scopeURL.href).pathname;
  622. return !location.pathname.startsWith(scopeURLBasePath);
  623. };
  624. if (currentPageIsOutOfScope()) {
  625. logger.warn('The current page is not in scope for the registered ' + 'service worker. Was this a mistake?');
  626. }
  627. }
  628. _this3._registration.addEventListener('updatefound', _this3._onUpdateFound);
  629. navigator.serviceWorker.addEventListener('controllerchange', _this3._onControllerChange, {
  630. once: true
  631. });
  632. return _this3._registration;
  633. });
  634. });
  635. } catch (e) {
  636. return Promise.reject(e);
  637. }
  638. }
  639. /**
  640. * Checks for updates of the registered service worker.
  641. */
  642. ;
  643. _proto.update = function update() {
  644. try {
  645. var _this5 = this;
  646. if (!_this5._registration) {
  647. if ("dev" !== 'production') {
  648. logger.error('Cannot update a Workbox instance without ' + 'being registered. Register the Workbox instance first.');
  649. }
  650. return;
  651. } // Try to update registration
  652. return _awaitIgnored(_this5._registration.update());
  653. } catch (e) {
  654. return Promise.reject(e);
  655. }
  656. }
  657. /**
  658. * Resolves to the service worker registered by this instance as soon as it
  659. * is active. If a service worker was already controlling at registration
  660. * time then it will resolve to that if the script URLs (and optionally
  661. * script versions) match, otherwise it will wait until an update is found
  662. * and activates.
  663. *
  664. * @return {Promise<ServiceWorker>}
  665. */
  666. ;
  667. /**
  668. * Resolves with a reference to a service worker that matches the script URL
  669. * of this instance, as soon as it's available.
  670. *
  671. * If, at registration time, there's already an active or waiting service
  672. * worker with a matching script URL, it will be used (with the waiting
  673. * service worker taking precedence over the active service worker if both
  674. * match, since the waiting service worker would have been registered more
  675. * recently).
  676. * If there's no matching active or waiting service worker at registration
  677. * time then the promise will not resolve until an update is found and starts
  678. * installing, at which point the installing service worker is used.
  679. *
  680. * @return {Promise<ServiceWorker>}
  681. */
  682. _proto.getSW = function getSW() {
  683. try {
  684. var _this7 = this;
  685. // If `this._sw` is set, resolve with that as we want `getSW()` to
  686. // return the correct (new) service worker if an update is found.
  687. return _this7._sw !== undefined ? _this7._sw : _this7._swDeferred.promise;
  688. } catch (e) {
  689. return Promise.reject(e);
  690. }
  691. }
  692. /**
  693. * Sends the passed data object to the service worker registered by this
  694. * instance (via [`getSW()`]{@link module:workbox-window.Workbox#getSW}) and resolves
  695. * with a response (if any).
  696. *
  697. * A response can be set in a message handler in the service worker by
  698. * calling `event.ports[0].postMessage(...)`, which will resolve the promise
  699. * returned by `messageSW()`. If no response is set, the promise will never
  700. * resolve.
  701. *
  702. * @param {Object} data An object to send to the service worker
  703. * @return {Promise<Object>}
  704. */
  705. ;
  706. _proto.messageSW = function messageSW$1(data) {
  707. try {
  708. var _this9 = this;
  709. return _await(_this9.getSW(), function (sw) {
  710. return messageSW(sw, data);
  711. });
  712. } catch (e) {
  713. return Promise.reject(e);
  714. }
  715. }
  716. /**
  717. * Checks for a service worker already controlling the page and returns
  718. * it if its script URL matches.
  719. *
  720. * @private
  721. * @return {ServiceWorker|undefined}
  722. */
  723. ;
  724. _proto._getControllingSWIfCompatible = function _getControllingSWIfCompatible() {
  725. var controller = navigator.serviceWorker.controller;
  726. if (controller && urlsMatch(controller.scriptURL, this._scriptURL)) {
  727. return controller;
  728. } else {
  729. return undefined;
  730. }
  731. }
  732. /**
  733. * Registers a service worker for this instances script URL and register
  734. * options and tracks the time registration was complete.
  735. *
  736. * @private
  737. */
  738. ;
  739. _proto._registerScript = function _registerScript() {
  740. try {
  741. var _this11 = this;
  742. return _catch(function () {
  743. return _await(navigator.serviceWorker.register(_this11._scriptURL, _this11._registerOptions), function (reg) {
  744. // Keep track of when registration happened, so it can be used in the
  745. // `this._onUpdateFound` heuristic. Also use the presence of this
  746. // property as a way to see if `.register()` has been called.
  747. _this11._registrationTime = performance.now();
  748. return reg;
  749. });
  750. }, function (error) {
  751. if ("dev" !== 'production') {
  752. logger.error(error);
  753. } // Re-throw the error.
  754. throw error;
  755. });
  756. } catch (e) {
  757. return Promise.reject(e);
  758. }
  759. };
  760. _createClass(Workbox, [{
  761. key: "active",
  762. get: function get() {
  763. return this._activeDeferred.promise;
  764. }
  765. /**
  766. * Resolves to the service worker registered by this instance as soon as it
  767. * is controlling the page. If a service worker was already controlling at
  768. * registration time then it will resolve to that if the script URLs (and
  769. * optionally script versions) match, otherwise it will wait until an update
  770. * is found and starts controlling the page.
  771. * Note: the first time a service worker is installed it will active but
  772. * not start controlling the page unless `clients.claim()` is called in the
  773. * service worker.
  774. *
  775. * @return {Promise<ServiceWorker>}
  776. */
  777. }, {
  778. key: "controlling",
  779. get: function get() {
  780. return this._controllingDeferred.promise;
  781. }
  782. }]);
  783. return Workbox;
  784. }(WorkboxEventTarget);
  785. function _awaitIgnored(value, direct) {
  786. if (!direct) {
  787. return value && value.then ? value.then(_empty) : Promise.resolve();
  788. }
  789. } // The jsdoc comments below outline the events this instance may dispatch:
  790. // -----------------------------------------------------------------------
  791. /**
  792. * The `message` event is dispatched any time a `postMessage` is received.
  793. *
  794. * @event module:workbox-window.Workbox#message
  795. * @type {WorkboxEvent}
  796. * @property {*} data The `data` property from the original `message` event.
  797. * @property {Event} originalEvent The original [`message`]{@link https://developer.mozilla.org/en-US/docs/Web/API/MessageEvent}
  798. * event.
  799. * @property {string} type `message`.
  800. * @property {Workbox} target The `Workbox` instance.
  801. */
  802. /**
  803. * The `installed` event is dispatched if the state of a
  804. * [`Workbox`]{@link module:workbox-window.Workbox} instance's
  805. * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
  806. * changes to `installed`.
  807. *
  808. * Then can happen either the very first time a service worker is installed,
  809. * or after an update to the current service worker is found. In the case
  810. * of an update being found, the event's `isUpdate` property will be `true`.
  811. *
  812. * @event module:workbox-window.Workbox#installed
  813. * @type {WorkboxEvent}
  814. * @property {ServiceWorker} sw The service worker instance.
  815. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  816. * event.
  817. * @property {boolean|undefined} isUpdate True if a service worker was already
  818. * controlling when this `Workbox` instance called `register()`.
  819. * @property {string} type `installed`.
  820. * @property {Workbox} target The `Workbox` instance.
  821. */
  822. /**
  823. * The `waiting` event is dispatched if the state of a
  824. * [`Workbox`]{@link module:workbox-window.Workbox} instance's
  825. * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
  826. * changes to `installed` and then doesn't immediately change to `activating`.
  827. * It may also be dispatched if a service worker with the same
  828. * [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
  829. * was already waiting when the [`register()`]{@link module:workbox-window.Workbox#register}
  830. * method was called.
  831. *
  832. * @event module:workbox-window.Workbox#waiting
  833. * @type {WorkboxEvent}
  834. * @property {ServiceWorker} sw The service worker instance.
  835. * @property {Event|undefined} originalEvent The original
  836. * [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  837. * event, or `undefined` in the case where the service worker was waiting
  838. * to before `.register()` was called.
  839. * @property {boolean|undefined} isUpdate True if a service worker was already
  840. * controlling when this `Workbox` instance called `register()`.
  841. * @property {boolean|undefined} wasWaitingBeforeRegister True if a service worker with
  842. * a matching `scriptURL` was already waiting when this `Workbox`
  843. * instance called `register()`.
  844. * @property {string} type `waiting`.
  845. * @property {Workbox} target The `Workbox` instance.
  846. */
  847. /**
  848. * The `controlling` event is dispatched if a
  849. * [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
  850. * fires on the service worker [container]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer}
  851. * and the [`scriptURL`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/scriptURL}
  852. * of the new [controller]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/controller}
  853. * matches the `scriptURL` of the `Workbox` instance's
  854. * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}.
  855. *
  856. * @event module:workbox-window.Workbox#controlling
  857. * @type {WorkboxEvent}
  858. * @property {ServiceWorker} sw The service worker instance.
  859. * @property {Event} originalEvent The original [`controllerchange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/oncontrollerchange}
  860. * event.
  861. * @property {boolean|undefined} isUpdate True if a service worker was already
  862. * controlling when this service worker was registered.
  863. * @property {string} type `controlling`.
  864. * @property {Workbox} target The `Workbox` instance.
  865. */
  866. /**
  867. * The `activated` event is dispatched if the state of a
  868. * [`Workbox`]{@link module:workbox-window.Workbox} instance's
  869. * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
  870. * changes to `activated`.
  871. *
  872. * @event module:workbox-window.Workbox#activated
  873. * @type {WorkboxEvent}
  874. * @property {ServiceWorker} sw The service worker instance.
  875. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  876. * event.
  877. * @property {boolean|undefined} isUpdate True if a service worker was already
  878. * controlling when this `Workbox` instance called `register()`.
  879. * @property {string} type `activated`.
  880. * @property {Workbox} target The `Workbox` instance.
  881. */
  882. /**
  883. * The `redundant` event is dispatched if the state of a
  884. * [`Workbox`]{@link module:workbox-window.Workbox} instance's
  885. * [registered service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-precaching#def-registered-sw}
  886. * changes to `redundant`.
  887. *
  888. * @event module:workbox-window.Workbox#redundant
  889. * @type {WorkboxEvent}
  890. * @property {ServiceWorker} sw The service worker instance.
  891. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  892. * event.
  893. * @property {boolean|undefined} isUpdate True if a service worker was already
  894. * controlling when this `Workbox` instance called `register()`.
  895. * @property {string} type `redundant`.
  896. * @property {Workbox} target The `Workbox` instance.
  897. */
  898. /**
  899. * The `externalinstalled` event is dispatched if the state of an
  900. * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
  901. * changes to `installed`.
  902. *
  903. * @event module:workbox-window.Workbox#externalinstalled
  904. * @type {WorkboxEvent}
  905. * @property {ServiceWorker} sw The service worker instance.
  906. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  907. * event.
  908. * @property {string} type `externalinstalled`.
  909. * @property {Workbox} target The `Workbox` instance.
  910. */
  911. /**
  912. * The `externalwaiting` event is dispatched if the state of an
  913. * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
  914. * changes to `waiting`.
  915. *
  916. * @event module:workbox-window.Workbox#externalwaiting
  917. * @type {WorkboxEvent}
  918. * @property {ServiceWorker} sw The service worker instance.
  919. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  920. * event.
  921. * @property {string} type `externalwaiting`.
  922. * @property {Workbox} target The `Workbox` instance.
  923. */
  924. /**
  925. * The `externalactivated` event is dispatched if the state of an
  926. * [external service worker]{@link https://developers.google.com/web/tools/workbox/modules/workbox-window#when_an_unexpected_version_of_the_service_worker_is_found}
  927. * changes to `activated`.
  928. *
  929. * @event module:workbox-window.Workbox#externalactivated
  930. * @type {WorkboxEvent}
  931. * @property {ServiceWorker} sw The service worker instance.
  932. * @property {Event} originalEvent The original [`statechange`]{@link https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorker/onstatechange}
  933. * event.
  934. * @property {string} type `externalactivated`.
  935. * @property {Workbox} target The `Workbox` instance.
  936. */
  937. function _invoke(body, then) {
  938. var result = body();
  939. if (result && result.then) {
  940. return result.then(then);
  941. }
  942. return then(result);
  943. }
  944. function _catch(body, recover) {
  945. try {
  946. var result = body();
  947. } catch (e) {
  948. return recover(e);
  949. }
  950. if (result && result.then) {
  951. return result.then(void 0, recover);
  952. }
  953. return result;
  954. }
  955. export { Workbox, messageSW };
  956. //# sourceMappingURL=workbox-window.dev.es5.mjs.map