2018-04-02 16:31:57 +00:00
|
|
|
var __wpo = {"assets":{"main":["/packs/base_polyfills.js","/packs/extra_polyfills.js","/packs/features/compose.js","/packs/modals/onboarding_modal.js","/packs/emoji_picker.js","/packs/features/notifications.js","/packs/features/account_timeline.js","/packs/features/home_timeline.js","/packs/features/public_timeline.js","/packs/features/community_timeline.js","/packs/features/favourited_statuses.js","/packs/features/list_timeline.js","/packs/features/following.js","/packs/features/followers.js","/packs/features/hashtag_timeline.js","/packs/features/status.js","/packs/features/account_gallery.js","/packs/features/blocks.js","/packs/features/follow_requests.js","/packs/features/reblogs.js","/packs/features/favourites.js","/packs/features/getting_started.js","/packs/features/keyboard_shortcuts.js","/packs/features/generic_not_found.js","/packs/features/list_editor.js","/packs/status/media_gallery.js","/packs/share.js","/packs/application.js","/packs/about.js","/packs/public.js","/packs/mailer.js","/packs/default.js","/packs/admin.js","/packs/common.js","/packs/common.css","/packs/mailer.css","/packs/default.css","/packs/manifest.json"],"additional":["/emoji/1f602.svg","/emoji/sheet.png"],"optional":["/packs/locale_zh-TW.js","/packs/locale_zh-HK.js","/packs/locale_zh-CN.js","/packs/locale_uk.js","/packs/locale_tr.js","/packs/locale_th.js","/packs/locale_sv.js","/packs/locale_sr.js","/packs/locale_sr-Latn.js","/packs/locale_sk.js","/packs/locale_ru.js","/packs/locale_pt.js","/packs/locale_pt-BR.js","/packs/locale_pl.js","/packs/locale_oc.js","/packs/locale_no.js","/packs/locale_nl.js","/packs/locale_ko.js","/packs/locale_ja.js","/packs/locale_it.js","/packs/locale_io.js","/packs/locale_id.js","/packs/locale_hy.js","/packs/locale_hu.js","/packs/locale_hr.js","/packs/locale_he.js","/packs/locale_gl.js","/packs/locale_fr.js","/packs/locale_fi.js","/packs/locale_fa.js","/packs/locale_es.js","/packs/locale_eo.js","/packs/locale_en.js","/packs/locale_de.js","/packs/locale_ca.js","/packs/locale_bg.js","/packs/locale_ar.js","/packs/roboto-italic-webfont-50efdad8c62f5f279e3f4f1f63a4f9bc.woff2","/packs/roboto-bold-webfont-f633cb5c651ba4d50791e1adf55d3c18.woff2","/packs/roboto-medium-webfont-69c55fc2fe77d38934ea98dc31642ce6.woff2","/packs/roboto-regular-webfont-3ec24f953ed5e859a6402cb3c030ea8b.woff2","/packs/fontawesome-webfont-af7ae505a9eed503f8b8e6982036873e.woff2","/packs/robotomono-regular-webfont-6c1ce30b90ee993b22618ec489585594.woff2","/packs/Montserrat-Regular-080422d4c1328f3407818d25c86cce51.woff2","/packs/void-65dfe5bd31335a5b308d36964d320574.png","/packs/reticle-7d7ce959271e5ff1193fb32cff90ea56.png","/packs/elephant-fren-d16fd77f9a9387e7d146b5f9d4dc1e7f.png","/packs/icon_cached-98a757f1d9e93652742be43c22f46287.png","/packs/icon_done-12b87c12f915597dccbd2ca4d7167ba4.png","/packs/icon_email-738c89662d6640f5e6539151023d049a.png","/packs/icon_file_download-e5c29678f3a639e1e62374911d85e1d0.png","/packs/icon_grade-3ec67253b37908d2ab783f7225f20682.png","/packs/icon_lock_open-0bfd71a52eb3f34934edd59088b559fb.png","/packs/icon_person_add-e2c6b660f6e1c95785d8d2bfa7a823af.png","/packs/icon_reply-4f6ada7a0b886b084706a484753a0ff0.png","/packs/logo_full-5c51cffe1fcb8225ae02400d6a7e7077.png","/packs/logo_transparent-6f79eeb2c38ec2d12ed4d978322457d6.png","/packs/preview-9a17d32fc48369e8ccd910a75260e67d.jpg","/packs/elephant_ui_plane-e3f2d57c12c376e189c274cbe81af8dd.svg","/packs/elephant_ui_disappointed-8864342480c3612e3061702851d3a798.svg","/packs/elephant_ui_greeting-475430963d0b00fe82b07b17857ebf6c.svg","/packs/elephant_ui_working-2e653cc278c2ac871c23aeb10de1c0e2.svg","/packs/icon_cached-108e30d96e1d5152be7fe2978bcdfe14.svg","/packs/icon_done-dba357bfbba455428787fefc655ce120.svg","/packs/icon_email-1346985c7aaceb601b0d4257133254f4.svg","/packs/icon_file_download-4b5c054e76b0df3cbbc851854cd10c3c.svg","/packs/icon_grade-8e81b8e88c2b5834347a2a226c65d440.svg","/packs/icon_lock_open-c9627928caaaa505ac7de2a64bd065ec.svg","/packs/icon_person_add-5c56ef10b9e99e77a44d89041f4b77b5.svg","/packs/icon_reply-b5e28e1fe6acd4ec003e643e947f1c4a.svg","/packs/
|
2017-11-12 13:23:05 +00:00
|
|
|
|
2018-03-31 16:15:28 +00:00
|
|
|
/******/ (function(modules) { // webpackBootstrap
|
|
|
|
/******/ // The module cache
|
|
|
|
/******/ var installedModules = {};
|
|
|
|
/******/
|
|
|
|
/******/ // The require function
|
|
|
|
/******/ function __webpack_require__(moduleId) {
|
|
|
|
/******/
|
|
|
|
/******/ // Check if module is in cache
|
|
|
|
/******/ if(installedModules[moduleId]) {
|
|
|
|
/******/ return installedModules[moduleId].exports;
|
|
|
|
/******/ }
|
|
|
|
/******/ // Create a new module (and put it into the cache)
|
|
|
|
/******/ var module = installedModules[moduleId] = {
|
|
|
|
/******/ i: moduleId,
|
|
|
|
/******/ l: false,
|
|
|
|
/******/ exports: {}
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // Execute the module function
|
|
|
|
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
|
|
|
/******/
|
|
|
|
/******/ // Flag the module as loaded
|
|
|
|
/******/ module.l = true;
|
|
|
|
/******/
|
|
|
|
/******/ // Return the exports of the module
|
|
|
|
/******/ return module.exports;
|
|
|
|
/******/ }
|
|
|
|
/******/
|
|
|
|
/******/
|
|
|
|
/******/ // expose the modules object (__webpack_modules__)
|
|
|
|
/******/ __webpack_require__.m = modules;
|
|
|
|
/******/
|
|
|
|
/******/ // expose the module cache
|
|
|
|
/******/ __webpack_require__.c = installedModules;
|
|
|
|
/******/
|
|
|
|
/******/ // define getter function for harmony exports
|
|
|
|
/******/ __webpack_require__.d = function(exports, name, getter) {
|
|
|
|
/******/ if(!__webpack_require__.o(exports, name)) {
|
|
|
|
/******/ Object.defineProperty(exports, name, {
|
|
|
|
/******/ configurable: false,
|
|
|
|
/******/ enumerable: true,
|
|
|
|
/******/ get: getter
|
|
|
|
/******/ });
|
|
|
|
/******/ }
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
|
|
|
/******/ __webpack_require__.n = function(module) {
|
|
|
|
/******/ var getter = module && module.__esModule ?
|
|
|
|
/******/ function getDefault() { return module['default']; } :
|
|
|
|
/******/ function getModuleExports() { return module; };
|
|
|
|
/******/ __webpack_require__.d(getter, 'a', getter);
|
|
|
|
/******/ return getter;
|
|
|
|
/******/ };
|
|
|
|
/******/
|
|
|
|
/******/ // Object.prototype.hasOwnProperty.call
|
|
|
|
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
|
|
|
/******/
|
|
|
|
/******/ // __webpack_public_path__
|
|
|
|
/******/ __webpack_require__.p = "/packs/";
|
|
|
|
/******/
|
|
|
|
/******/ // Load entry module and return exports
|
|
|
|
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
|
|
|
/******/ })
|
|
|
|
/************************************************************************/
|
|
|
|
/******/ ([
|
|
|
|
/* 0 */
|
|
|
|
/***/ (function(module, exports, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
|
|
(function () {
|
|
|
|
var waitUntil = ExtendableEvent.prototype.waitUntil;
|
|
|
|
var respondWith = FetchEvent.prototype.respondWith;
|
|
|
|
var promisesMap = new WeakMap();
|
|
|
|
|
|
|
|
ExtendableEvent.prototype.waitUntil = function (promise) {
|
|
|
|
var extendableEvent = this;
|
|
|
|
var promises = promisesMap.get(extendableEvent);
|
|
|
|
|
|
|
|
if (promises) {
|
|
|
|
promises.push(Promise.resolve(promise));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
promises = [Promise.resolve(promise)];
|
|
|
|
promisesMap.set(extendableEvent, promises);
|
|
|
|
|
|
|
|
// call original method
|
|
|
|
return waitUntil.call(extendableEvent, Promise.resolve().then(function processPromises() {
|
|
|
|
var len = promises.length;
|
|
|
|
|
|
|
|
// wait for all to settle
|
|
|
|
return Promise.all(promises.map(function (p) {
|
|
|
|
return p["catch"](function () {});
|
|
|
|
})).then(function () {
|
|
|
|
// have new items been added? If so, wait again
|
|
|
|
if (promises.length != len) return processPromises();
|
|
|
|
// we're done!
|
|
|
|
promisesMap["delete"](extendableEvent);
|
|
|
|
// reject if one of the promises rejected
|
|
|
|
return Promise.all(promises);
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
};
|
|
|
|
|
|
|
|
FetchEvent.prototype.respondWith = function (promise) {
|
|
|
|
this.waitUntil(promise);
|
|
|
|
return respondWith.call(this, promise);
|
|
|
|
};
|
|
|
|
})();;
|
|
|
|
'use strict';
|
|
|
|
|
|
|
|
if (typeof DEBUG === 'undefined') {
|
|
|
|
var DEBUG = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
function WebpackServiceWorker(params, helpers) {
|
|
|
|
var loaders = helpers.loaders;
|
|
|
|
var cacheMaps = helpers.cacheMaps;
|
|
|
|
|
|
|
|
var strategy = params.strategy;
|
|
|
|
var responseStrategy = params.responseStrategy;
|
|
|
|
|
|
|
|
var assets = params.assets;
|
|
|
|
var loadersMap = params.loaders || {};
|
|
|
|
|
|
|
|
var hashesMap = params.hashesMap;
|
|
|
|
var externals = params.externals;
|
|
|
|
|
|
|
|
// Not used yet
|
|
|
|
// const alwaysRevalidate = params.alwaysRevalidate;
|
|
|
|
// const ignoreSearch = params.ignoreSearch;
|
|
|
|
// const preferOnline = params.preferOnline;
|
|
|
|
|
|
|
|
var CACHE_PREFIX = params.name;
|
|
|
|
var CACHE_TAG = params.version;
|
|
|
|
var CACHE_NAME = CACHE_PREFIX + ':' + CACHE_TAG;
|
|
|
|
|
|
|
|
var STORED_DATA_KEY = '__offline_webpack__data';
|
|
|
|
|
|
|
|
mapAssets();
|
|
|
|
|
|
|
|
var allAssets = [].concat(assets.main, assets.additional, assets.optional);
|
|
|
|
var navigateFallbackURL = params.navigateFallbackURL;
|
|
|
|
var navigateFallbackForRedirects = params.navigateFallbackForRedirects;
|
|
|
|
|
|
|
|
self.addEventListener('install', function (event) {
|
|
|
|
console.log('[SW]:', 'Install event');
|
|
|
|
|
|
|
|
var installing = undefined;
|
|
|
|
|
|
|
|
if (strategy === 'changed') {
|
|
|
|
installing = cacheChanged('main');
|
|
|
|
} else {
|
|
|
|
installing = cacheAssets('main');
|
|
|
|
}
|
|
|
|
|
|
|
|
event.waitUntil(installing);
|
|
|
|
});
|
|
|
|
|
|
|
|
self.addEventListener('activate', function (event) {
|
|
|
|
console.log('[SW]:', 'Activate event');
|
|
|
|
|
|
|
|
var activation = cacheAdditional();
|
|
|
|
|
|
|
|
// Delete all assets which name starts with CACHE_PREFIX and
|
|
|
|
// is not current cache (CACHE_NAME)
|
|
|
|
activation = activation.then(storeCacheData);
|
|
|
|
activation = activation.then(deleteObsolete);
|
|
|
|
activation = activation.then(function () {
|
|
|
|
if (self.clients && self.clients.claim) {
|
|
|
|
return self.clients.claim();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
event.waitUntil(activation);
|
|
|
|
});
|
|
|
|
|
|
|
|
function cacheAdditional() {
|
|
|
|
if (!assets.additional.length) {
|
|
|
|
return Promise.resolve();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'Caching additional');
|
|
|
|
}
|
|
|
|
|
|
|
|
var operation = undefined;
|
|
|
|
|
|
|
|
if (strategy === 'changed') {
|
|
|
|
operation = cacheChanged('additional');
|
|
|
|
} else {
|
|
|
|
operation = cacheAssets('additional');
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ignore fail of `additional` cache section
|
|
|
|
return operation['catch'](function (e) {
|
|
|
|
console.error('[SW]:', 'Cache section `additional` failed to load');
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function cacheAssets(section) {
|
|
|
|
var batch = assets[section];
|
|
|
|
|
|
|
|
return caches.open(CACHE_NAME).then(function (cache) {
|
|
|
|
return addAllNormalized(cache, batch, {
|
|
|
|
bust: params.version,
|
|
|
|
request: params.prefetchRequest
|
|
|
|
});
|
|
|
|
}).then(function () {
|
|
|
|
logGroup('Cached assets: ' + section, batch);
|
|
|
|
})['catch'](function (e) {
|
|
|
|
console.error(e);
|
|
|
|
throw e;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function cacheChanged(section) {
|
|
|
|
return getLastCache().then(function (args) {
|
|
|
|
if (!args) {
|
|
|
|
return cacheAssets(section);
|
|
|
|
}
|
|
|
|
|
|
|
|
var lastCache = args[0];
|
|
|
|
var lastKeys = args[1];
|
|
|
|
var lastData = args[2];
|
|
|
|
|
|
|
|
var lastMap = lastData.hashmap;
|
|
|
|
var lastVersion = lastData.version;
|
|
|
|
|
|
|
|
if (!lastData.hashmap || lastVersion === params.version) {
|
|
|
|
return cacheAssets(section);
|
|
|
|
}
|
|
|
|
|
|
|
|
var lastHashedAssets = Object.keys(lastMap).map(function (hash) {
|
|
|
|
return lastMap[hash];
|
|
|
|
});
|
|
|
|
|
|
|
|
var lastUrls = lastKeys.map(function (req) {
|
|
|
|
var url = new URL(req.url);
|
|
|
|
url.search = '';
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
return url.toString();
|
|
|
|
});
|
|
|
|
|
|
|
|
var sectionAssets = assets[section];
|
|
|
|
var moved = [];
|
|
|
|
var changed = sectionAssets.filter(function (url) {
|
|
|
|
if (lastUrls.indexOf(url) === -1 || lastHashedAssets.indexOf(url) === -1) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(hashesMap).forEach(function (hash) {
|
|
|
|
var asset = hashesMap[hash];
|
|
|
|
|
|
|
|
// Return if not in sectionAssets or in changed or moved array
|
|
|
|
if (sectionAssets.indexOf(asset) === -1 || changed.indexOf(asset) !== -1 || moved.indexOf(asset) !== -1) return;
|
|
|
|
|
|
|
|
var lastAsset = lastMap[hash];
|
|
|
|
|
|
|
|
if (lastAsset && lastUrls.indexOf(lastAsset) !== -1) {
|
|
|
|
moved.push([lastAsset, asset]);
|
|
|
|
} else {
|
|
|
|
changed.push(asset);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
logGroup('Changed assets: ' + section, changed);
|
|
|
|
logGroup('Moved assets: ' + section, moved);
|
|
|
|
|
|
|
|
var movedResponses = Promise.all(moved.map(function (pair) {
|
|
|
|
return lastCache.match(pair[0]).then(function (response) {
|
|
|
|
return [pair[1], response];
|
|
|
|
});
|
|
|
|
}));
|
|
|
|
|
|
|
|
return caches.open(CACHE_NAME).then(function (cache) {
|
|
|
|
var move = movedResponses.then(function (responses) {
|
|
|
|
return Promise.all(responses.map(function (pair) {
|
|
|
|
return cache.put(pair[0], pair[1]);
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all([move, addAllNormalized(cache, changed, {
|
|
|
|
bust: params.version,
|
|
|
|
request: params.prefetchRequest
|
|
|
|
})]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function deleteObsolete() {
|
|
|
|
return caches.keys().then(function (keys) {
|
|
|
|
var all = keys.map(function (key) {
|
|
|
|
if (key.indexOf(CACHE_PREFIX) !== 0 || key.indexOf(CACHE_NAME) === 0) return;
|
|
|
|
|
|
|
|
console.log('[SW]:', 'Delete cache:', key);
|
|
|
|
return caches['delete'](key);
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all(all);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function getLastCache() {
|
|
|
|
return caches.keys().then(function (keys) {
|
|
|
|
var index = keys.length;
|
|
|
|
var key = undefined;
|
|
|
|
|
|
|
|
while (index--) {
|
|
|
|
key = keys[index];
|
|
|
|
|
|
|
|
if (key.indexOf(CACHE_PREFIX) === 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!key) return;
|
|
|
|
|
|
|
|
var cache = undefined;
|
|
|
|
|
|
|
|
return caches.open(key).then(function (_cache) {
|
|
|
|
cache = _cache;
|
|
|
|
return _cache.match(new URL(STORED_DATA_KEY, location).toString());
|
|
|
|
}).then(function (response) {
|
|
|
|
if (!response) return;
|
|
|
|
|
|
|
|
return Promise.all([cache, cache.keys(), response.json()]);
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function storeCacheData() {
|
|
|
|
return caches.open(CACHE_NAME).then(function (cache) {
|
|
|
|
var data = new Response(JSON.stringify({
|
|
|
|
version: params.version,
|
|
|
|
hashmap: hashesMap
|
|
|
|
}));
|
|
|
|
|
|
|
|
return cache.put(new URL(STORED_DATA_KEY, location).toString(), data);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
self.addEventListener('fetch', function (event) {
|
|
|
|
var url = new URL(event.request.url);
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
var urlString = url.toString();
|
|
|
|
|
|
|
|
// Not external, so search part of the URL should be stripped,
|
|
|
|
// if it's external URL, the search part should be kept
|
|
|
|
if (externals.indexOf(urlString) === -1) {
|
|
|
|
url.search = '';
|
|
|
|
urlString = url.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle only GET requests
|
|
|
|
var isGET = event.request.method === 'GET';
|
|
|
|
var assetMatches = allAssets.indexOf(urlString) !== -1;
|
|
|
|
var cacheUrl = urlString;
|
|
|
|
|
|
|
|
if (!assetMatches) {
|
|
|
|
var cacheRewrite = matchCacheMap(event.request);
|
|
|
|
|
|
|
|
if (cacheRewrite) {
|
|
|
|
cacheUrl = cacheRewrite;
|
|
|
|
assetMatches = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!assetMatches && isGET) {
|
|
|
|
// If isn't a cached asset and is a navigation request,
|
|
|
|
// fallback to navigateFallbackURL if available
|
|
|
|
if (navigateFallbackURL && isNavigateRequest(event.request)) {
|
|
|
|
event.respondWith(handleNavigateFallback(fetch(event.request)));
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!assetMatches || !isGET) {
|
|
|
|
// Fix for https://twitter.com/wanderview/status/696819243262873600
|
|
|
|
if (url.origin !== location.origin && navigator.userAgent.indexOf('Firefox/44.') !== -1) {
|
|
|
|
event.respondWith(fetch(event.request));
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Logic of caching / fetching is here
|
|
|
|
// * urlString -- url to match from the CACHE_NAME
|
|
|
|
// * event.request -- original Request to perform fetch() if necessary
|
|
|
|
var resource = undefined;
|
|
|
|
|
|
|
|
if (responseStrategy === 'network-first') {
|
|
|
|
resource = networkFirstResponse(event, urlString, cacheUrl);
|
|
|
|
}
|
|
|
|
// 'cache-first'
|
|
|
|
// (responseStrategy has been validated before)
|
|
|
|
else {
|
|
|
|
resource = cacheFirstResponse(event, urlString, cacheUrl);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (navigateFallbackURL && isNavigateRequest(event.request)) {
|
|
|
|
resource = handleNavigateFallback(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
event.respondWith(resource);
|
|
|
|
});
|
|
|
|
|
|
|
|
self.addEventListener('message', function (e) {
|
|
|
|
var data = e.data;
|
|
|
|
if (!data) return;
|
|
|
|
|
|
|
|
switch (data.action) {
|
|
|
|
case 'skipWaiting':
|
|
|
|
{
|
|
|
|
if (self.skipWaiting) self.skipWaiting();
|
|
|
|
}break;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
function cacheFirstResponse(event, urlString, cacheUrl) {
|
|
|
|
return cachesMatch(cacheUrl, CACHE_NAME).then(function (response) {
|
|
|
|
if (response) {
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'URL [' + cacheUrl + '](' + urlString + ') from cache');
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Load and cache known assets
|
|
|
|
var fetching = fetch(event.request).then(function (response) {
|
|
|
|
if (!response.ok) {
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'URL [' + urlString + '] wrong response: [' + response.status + '] ' + response.type);
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'URL [' + urlString + '] from network');
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cacheUrl === urlString) {
|
|
|
|
(function () {
|
|
|
|
var responseClone = response.clone();
|
|
|
|
var storing = caches.open(CACHE_NAME).then(function (cache) {
|
|
|
|
return cache.put(urlString, responseClone);
|
|
|
|
}).then(function () {
|
|
|
|
console.log('[SW]:', 'Cache asset: ' + urlString);
|
|
|
|
});
|
|
|
|
|
|
|
|
event.waitUntil(storing);
|
|
|
|
})();
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
});
|
|
|
|
|
|
|
|
return fetching;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function networkFirstResponse(event, urlString, cacheUrl) {
|
|
|
|
return fetch(event.request).then(function (response) {
|
|
|
|
if (response.ok) {
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'URL [' + urlString + '] from network');
|
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Throw to reach the code in the catch below
|
|
|
|
throw new Error('Response is not ok');
|
|
|
|
})
|
|
|
|
// This needs to be in a catch() and not just in the then() above
|
|
|
|
// cause if your network is down, the fetch() will throw
|
|
|
|
['catch'](function () {
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'URL [' + urlString + '] from cache if possible');
|
|
|
|
}
|
|
|
|
|
|
|
|
return cachesMatch(cacheUrl, CACHE_NAME);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function handleNavigateFallback(fetching) {
|
|
|
|
return fetching['catch'](function () {}).then(function (response) {
|
|
|
|
var isOk = response && response.ok;
|
|
|
|
var isRedirect = response && response.type === 'opaqueredirect';
|
|
|
|
|
|
|
|
if (isOk || isRedirect && !navigateFallbackForRedirects) {
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (DEBUG) {
|
|
|
|
console.log('[SW]:', 'Loading navigation fallback [' + navigateFallbackURL + '] from cache');
|
|
|
|
}
|
|
|
|
|
|
|
|
return cachesMatch(navigateFallbackURL, CACHE_NAME);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function mapAssets() {
|
|
|
|
Object.keys(assets).forEach(function (key) {
|
|
|
|
assets[key] = assets[key].map(function (path) {
|
|
|
|
var url = new URL(path, location);
|
|
|
|
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
if (externals.indexOf(path) === -1) {
|
|
|
|
url.search = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
return url.toString();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
Object.keys(loadersMap).forEach(function (key) {
|
|
|
|
loadersMap[key] = loadersMap[key].map(function (path) {
|
|
|
|
var url = new URL(path, location);
|
|
|
|
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
if (externals.indexOf(path) === -1) {
|
|
|
|
url.search = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
return url.toString();
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
hashesMap = Object.keys(hashesMap).reduce(function (result, hash) {
|
|
|
|
var url = new URL(hashesMap[hash], location);
|
|
|
|
url.search = '';
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
result[hash] = url.toString();
|
|
|
|
return result;
|
|
|
|
}, {});
|
|
|
|
|
|
|
|
externals = externals.map(function (path) {
|
|
|
|
var url = new URL(path, location);
|
|
|
|
url.hash = '';
|
|
|
|
|
|
|
|
return url.toString();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function addAllNormalized(cache, requests, options) {
|
|
|
|
var allowLoaders = options.allowLoaders !== false;
|
|
|
|
var bustValue = options && options.bust;
|
|
|
|
var requestInit = options.request || {
|
|
|
|
credentials: 'omit',
|
|
|
|
mode: 'cors'
|
|
|
|
};
|
|
|
|
|
|
|
|
return Promise.all(requests.map(function (request) {
|
|
|
|
if (bustValue) {
|
|
|
|
request = applyCacheBust(request, bustValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetch(request, requestInit).then(fixRedirectedResponse);
|
|
|
|
})).then(function (responses) {
|
|
|
|
if (responses.some(function (response) {
|
|
|
|
return !response.ok;
|
|
|
|
})) {
|
|
|
|
return Promise.reject(new Error('Wrong response status'));
|
|
|
|
}
|
|
|
|
|
|
|
|
var extracted = [];
|
|
|
|
var addAll = responses.map(function (response, i) {
|
|
|
|
if (allowLoaders) {
|
|
|
|
extracted.push(extractAssetsWithLoaders(requests[i], response));
|
|
|
|
}
|
|
|
|
|
|
|
|
return cache.put(requests[i], response);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (extracted.length) {
|
|
|
|
(function () {
|
|
|
|
var newOptions = copyObject(options);
|
|
|
|
newOptions.allowLoaders = false;
|
|
|
|
|
|
|
|
var waitAll = addAll;
|
|
|
|
|
|
|
|
addAll = Promise.all(extracted).then(function (all) {
|
|
|
|
var extractedRequests = [].concat.apply([], all);
|
|
|
|
|
|
|
|
if (requests.length) {
|
|
|
|
waitAll = waitAll.concat(addAllNormalized(cache, extractedRequests, newOptions));
|
|
|
|
}
|
|
|
|
|
|
|
|
return Promise.all(waitAll);
|
|
|
|
});
|
|
|
|
})();
|
|
|
|
} else {
|
|
|
|
addAll = Promise.all(addAll);
|
|
|
|
}
|
|
|
|
|
|
|
|
return addAll;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function extractAssetsWithLoaders(request, response) {
|
|
|
|
var all = Object.keys(loadersMap).map(function (key) {
|
|
|
|
var loader = loadersMap[key];
|
|
|
|
|
|
|
|
if (loader.indexOf(request) !== -1 && loaders[key]) {
|
|
|
|
return loaders[key](response.clone());
|
|
|
|
}
|
|
|
|
}).filter(function (a) {
|
|
|
|
return !!a;
|
|
|
|
});
|
|
|
|
|
|
|
|
return Promise.all(all).then(function (all) {
|
|
|
|
return [].concat.apply([], all);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function matchCacheMap(request) {
|
|
|
|
var urlString = request.url;
|
|
|
|
var url = new URL(urlString);
|
|
|
|
|
|
|
|
var requestType = undefined;
|
|
|
|
|
|
|
|
if (request.mode === 'navigate') {
|
|
|
|
requestType = 'navigate';
|
|
|
|
} else if (url.origin === location.origin) {
|
|
|
|
requestType = 'same-origin';
|
|
|
|
} else {
|
|
|
|
requestType = 'cross-origin';
|
|
|
|
}
|
|
|
|
|
|
|
|
for (var i = 0; i < cacheMaps.length; i++) {
|
|
|
|
var map = cacheMaps[i];
|
|
|
|
|
|
|
|
if (!map) continue;
|
|
|
|
if (map.requestTypes && map.requestTypes.indexOf(requestType) === -1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
var newString = undefined;
|
|
|
|
|
|
|
|
if (typeof map.match === 'function') {
|
|
|
|
newString = map.match(url, request);
|
|
|
|
} else {
|
|
|
|
newString = urlString.replace(map.match, map.to);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newString && newString !== urlString) {
|
|
|
|
return newString;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function cachesMatch(request, cacheName) {
|
|
|
|
return caches.match(request, {
|
|
|
|
cacheName: cacheName
|
|
|
|
}).then(function (response) {
|
|
|
|
if (isNotRedirectedResponse()) {
|
|
|
|
return response;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Fix already cached redirected responses
|
|
|
|
return fixRedirectedResponse(response).then(function (fixedResponse) {
|
|
|
|
return caches.open(cacheName).then(function (cache) {
|
|
|
|
return cache.put(request, fixedResponse);
|
|
|
|
}).then(function () {
|
|
|
|
return fixedResponse;
|
|
|
|
});
|
|
|
|
});
|
|
|
|
})
|
|
|
|
// Return void if error happened (cache not found)
|
|
|
|
['catch'](function () {});
|
|
|
|
}
|
|
|
|
|
|
|
|
function applyCacheBust(asset, key) {
|
|
|
|
var hasQuery = asset.indexOf('?') !== -1;
|
|
|
|
return asset + (hasQuery ? '&' : '?') + '__uncache=' + encodeURIComponent(key);
|
|
|
|
}
|
|
|
|
|
|
|
|
function getClientsURLs() {
|
|
|
|
if (!self.clients) {
|
|
|
|
return Promise.resolve([]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.clients.matchAll({
|
|
|
|
includeUncontrolled: true
|
|
|
|
}).then(function (clients) {
|
|
|
|
if (!clients.length) return [];
|
|
|
|
|
|
|
|
var result = [];
|
|
|
|
|
|
|
|
clients.forEach(function (client) {
|
|
|
|
var url = new URL(client.url);
|
|
|
|
url.search = '';
|
|
|
|
url.hash = '';
|
|
|
|
var urlString = url.toString();
|
|
|
|
|
|
|
|
if (!result.length || result.indexOf(urlString) === -1) {
|
|
|
|
result.push(urlString);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
return result;
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function isNavigateRequest(request) {
|
|
|
|
return request.mode === 'navigate' || request.headers.get('Upgrade-Insecure-Requests') || (request.headers.get('Accept') || '').indexOf('text/html') !== -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
function isNotRedirectedResponse(response) {
|
|
|
|
return !response || !response.redirected || !response.ok || response.type === 'opaqueredirect';
|
|
|
|
}
|
|
|
|
|
|
|
|
// Based on https://github.com/GoogleChrome/sw-precache/pull/241/files#diff-3ee9060dc7a312c6a822cac63a8c630bR85
|
|
|
|
function fixRedirectedResponse(response) {
|
|
|
|
if (isNotRedirectedResponse(response)) {
|
|
|
|
return Promise.resolve(response);
|
|
|
|
}
|
|
|
|
|
|
|
|
var body = 'body' in response ? Promise.resolve(response.body) : response.blob();
|
|
|
|
|
|
|
|
return body.then(function (data) {
|
|
|
|
return new Response(data, {
|
|
|
|
headers: response.headers,
|
|
|
|
status: response.status
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function copyObject(original) {
|
|
|
|
return Object.keys(original).reduce(function (result, key) {
|
|
|
|
result[key] = original[key];
|
|
|
|
return result;
|
|
|
|
}, {});
|
|
|
|
}
|
|
|
|
|
|
|
|
function logGroup(title, assets) {
|
|
|
|
console.groupCollapsed('[SW]:', title);
|
|
|
|
|
|
|
|
assets.forEach(function (asset) {
|
|
|
|
console.log('Asset:', asset);
|
|
|
|
});
|
|
|
|
|
|
|
|
console.groupEnd();
|
|
|
|
}
|
|
|
|
WebpackServiceWorker(__wpo, {
|
|
|
|
loaders: {},
|
|
|
|
cacheMaps: [],
|
|
|
|
});
|
|
|
|
module.exports = __webpack_require__(1)
|
|
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/* 1 */
|
|
|
|
/***/ (function(module, __webpack_exports__, __webpack_require__) {
|
|
|
|
|
|
|
|
"use strict";
|
|
|
|
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__web_push_notifications__ = __webpack_require__(2);
|
|
|
|
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__web_push_notifications___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0__web_push_notifications__);
|
|
|
|
/*** IMPORTS FROM imports-loader ***/
|
|
|
|
var process = (process || {});
|
2018-04-02 16:31:57 +00:00
|
|
|
process.env = {"GJS_DEBUG_TOPICS":"JS ERROR;JS LOG","npm_config_cache_lock_stale":"60000","npm_config_ham_it_up":"","npm_package_dependencies_mark_loader":"^0.1.6","npm_config_legacy_bundling":"","npm_config_sign_git_tag":"","USER":"howl","LANGUAGE":"en_GB:en","npm_package_dependencies_autoprefixer":"^7.1.6","npm_package_dependencies_mkdirp":"^0.5.1","npm_package_dependencies_node_sass":"^4.7.2","npm_package_devDependencies_jest":"^21.2.1","npm_config_user_agent":"npm/5.6.0 node/v9.10.1 linux x64","npm_config_always_auth":"","COMP_WORDBREAKS":" \t\n\"'><;|&(:","XDG_SEAT":"seat0","npm_package_dependencies_detect_passive_events":"^1.0.2","npm_package_dependencies_immutable":"^3.8.2","npm_package_bugs_url":"https://github.com/tootsuite/mastodon/issues","npm_config_bin_links":"true","npm_config_key":"","SSH_AGENT_PID":"1448","XDG_SESSION_TYPE":"x11","npm_package_dependencies_react_overlays":"^0.8.3","npm_config_allow_same_version":"","npm_config_description":"true","npm_config_fetch_retries":"2","npm_config_heading":"npm","npm_config_if_present":"","npm_config_init_version":"1.0.0","npm_config_user":"","npm_node_execpath":"/usr/bin/node","LD_LIBRARY_PATH":"/home/howl/torch-cl/install/lib:/home/howl/torch-cl/install/lib:","LUA_PATH":"/home/howl/.luarocks/share/lua/5.1/?.lua;/home/howl/.luarocks/share/lua/5.1/?/init.lua;/home/howl/torch-cl/install/share/lua/5.1/?.lua;/home/howl/torch-cl/install/share/lua/5.1/?/init.lua;./?.lua;/home/howl/torch-cl/install/share/luajit-2.1.0-beta1/?.lua;/usr/local/share/lua/5.1/?.lua;/usr/local/share/lua/5.1/?/init.lua","SHLVL":"2","npm_package_scripts_manage_translations":"node ./config/webpack/translationRunner.js","npm_package_dependencies_babel_plugin_transform_class_properties":"^6.24.1","npm_package_dependencies_babel_plugin_transform_es2015_modules_commonjs":"^6.24.1","npm_package_dependencies_escape_html":"^1.0.3","npm_package_dependencies_imports_loader":"^0.8.0","npm_package_optionalDependencies_node_zopfli":"^2.0.2","npm_config_prefer_online":"","OLDPWD":"/home/howl/oc/mastofe/public","HOME":"/home/howl","npm_package_dependencies_postcss_loader":"^2.0.9","npm_config_force":"","OSU_API_KEY":"e0146ddaf01d1e9d107afedcd340b42347186260","DESKTOP_SESSION":"cinnamon","npm_package_dependencies_react_redux_loading_bar":"^2.9.3","npm_package_dependencies_redis":"^2.7.1","npm_config_only":"","npm_config_read_only":"","GIO_LAUNCHED_DESKTOP_FILE":"/usr/share/applications/xfce4-terminal.desktop","npm_package_engines_node":">=6","npm_package_dependencies_babel_plugin_react_intl":"^2.3.1","npm_package_dependencies_npmlog":"^4.1.2","npm_package_devDependencies_enzyme_adapter_react_16":"^1.1.0","npm_config_cache_min":"10","npm_config_init_license":"ISC","GTK_MODULES":"gail:atk-bridge","XDG_SEAT_PATH":"/org/freedesktop/DisplayManager/Seat0","npm_package_scripts_build_production":"cross-env NODE_ENV=production webpack --config config/webpack/production.js","npm_package_dependencies_glob":"^7.1.1","npm_package_dependencies_webpack_merge":"^4.1.1","npm_config_editor":"vi","npm_config_rollback":"true","npm_config_tag_version_prefix":"v","OSU_PASSWORD":"il mio cane gioca meglio di me","npm_package_dependencies_redux_thunk":"^2.2.0","npm_package_dependencies_webpack":"^3.9.1","npm_config_cache_max":"Infinity","npm_config_timing":"","npm_config_userconfig":"/home/howl/.npmrc","DBUS_SESSION_BUS_ADDRESS":"unix:path=/run/user/1000/bus","CINNAMON_VERSION":"3.6.7","npm_package_dependencies_babel_plugin_lodash":"^3.3.2","npm_package_dependencies_dotenv":"^4.0.0","npm_package_dependencies_precss":"^2.0.0","npm_package_dependencies_react_hotkeys":"^0.10.0","npm_config_engine_strict":"","npm_config_init_author_name":"","npm_config_init_author_url":"","npm_config_tmp":"/tmp","COLORTERM":"truecolor","GIO_LAUNCHED_DESKTOP_FILE_PID":"4122","npm_package_description":"mastodon","npm_package_dependencies_react_router_dom":"^4.1.1","npm_config_depth":"Infinity","npm_config_package_lock_only":"","npm_config_save_dev":"","npm_config_usage":"","npm_package_scripts_test_jest":"cross-env NODE_ENV=test jest --coverage","npm_package
|
2018-03-31 16:15:28 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function openSystemCache() {
|
|
|
|
return caches.open('mastodon-system');
|
|
|
|
}
|
|
|
|
|
|
|
|
function openWebCache() {
|
|
|
|
return caches.open('mastodon-web');
|
|
|
|
}
|
|
|
|
|
|
|
|
function fetchRoot() {
|
2018-04-01 09:36:53 +00:00
|
|
|
return fetch('/web', { credentials: 'include' });
|
2018-03-31 16:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Cause a new version of a registered Service Worker to replace an existing one
|
|
|
|
// that is already installed, and replace the currently active worker on open pages.
|
|
|
|
self.addEventListener('install', function (event) {
|
|
|
|
event.waitUntil(Promise.all([openWebCache(), fetchRoot()]).then(function (_ref) {
|
|
|
|
var cache = _ref[0],
|
|
|
|
root = _ref[1];
|
2018-04-01 09:36:53 +00:00
|
|
|
return cache.put('/web', root);
|
2018-03-31 16:15:28 +00:00
|
|
|
}));
|
|
|
|
});
|
|
|
|
self.addEventListener('activate', function (event) {
|
|
|
|
event.waitUntil(self.clients.claim());
|
|
|
|
});
|
|
|
|
self.addEventListener('fetch', function (event) {
|
|
|
|
var url = new URL(event.request.url);
|
|
|
|
|
2018-04-01 09:36:53 +00:00
|
|
|
if (url.pathname.startsWith('/web')) {
|
2018-04-02 16:31:57 +00:00
|
|
|
// we always make /web/login go through
|
|
|
|
if (url.pathname.startsWith('/web/login')) {
|
|
|
|
return;
|
|
|
|
}
|
2018-03-31 16:15:28 +00:00
|
|
|
var asyncResponse = fetchRoot();
|
|
|
|
var asyncCache = openWebCache();
|
|
|
|
|
|
|
|
event.respondWith(asyncResponse.then(async function (response) {
|
2018-04-02 16:31:57 +00:00
|
|
|
// response was redirected - let's actually do the request from the event
|
|
|
|
// and return its response
|
|
|
|
if (response.redirected || response.type === 'opaqueredirect') {
|
|
|
|
return await fetch(event.request);
|
|
|
|
}
|
2018-03-31 16:15:28 +00:00
|
|
|
if (response.ok) {
|
|
|
|
var cache = await asyncCache;
|
2018-04-01 09:36:53 +00:00
|
|
|
await cache.put('/web', response);
|
2018-03-31 16:15:28 +00:00
|
|
|
return response.clone();
|
|
|
|
}
|
|
|
|
|
|
|
|
throw null;
|
|
|
|
}).catch(function () {
|
|
|
|
return asyncCache.then(function (cache) {
|
2018-04-01 09:36:53 +00:00
|
|
|
return cache.match('/web');
|
2018-03-31 16:15:28 +00:00
|
|
|
});
|
|
|
|
}));
|
|
|
|
} else if (url.pathname === '/auth/sign_out') {
|
|
|
|
var _asyncResponse = fetch(event.request);
|
|
|
|
var _asyncCache = openWebCache();
|
|
|
|
|
|
|
|
event.respondWith(_asyncResponse.then(async function (response) {
|
|
|
|
if (response.ok || response.type === 'opaqueredirect') {
|
|
|
|
var cache = await _asyncCache;
|
2018-04-01 09:36:53 +00:00
|
|
|
await cache.delete('/web');
|
2018-03-31 16:15:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return response;
|
|
|
|
}));
|
|
|
|
} else if (process.env.CDN_HOST ? url.host === process.env.CDN_HOST : url.pathname.startsWith('/system/')) {
|
|
|
|
event.respondWith(openSystemCache().then(async function (cache) {
|
|
|
|
var cached = await cache.match(event.request.url);
|
|
|
|
|
|
|
|
if (cached === undefined) {
|
|
|
|
var fetched = await fetch(event.request);
|
|
|
|
|
|
|
|
if (fetched.ok) {
|
|
|
|
await cache.put(event.request.url, fetched.clone());
|
|
|
|
}
|
|
|
|
|
|
|
|
return fetched;
|
|
|
|
}
|
|
|
|
|
|
|
|
return cached;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
/***/ }),
|
|
|
|
/* 2 */
|
|
|
|
/***/ (function(module, exports) {
|
|
|
|
|
|
|
|
var MAX_NOTIFICATIONS = 5;
|
|
|
|
var GROUP_TAG = 'tag';
|
|
|
|
|
|
|
|
// Avoid loading intl-messageformat and dealing with locales in the ServiceWorker
|
|
|
|
var formatGroupTitle = function formatGroupTitle(message, count) {
|
|
|
|
return message.replace('%{count}', count);
|
|
|
|
};
|
|
|
|
|
|
|
|
var notify = function notify(options) {
|
|
|
|
return self.registration.getNotifications().then(function (notifications) {
|
|
|
|
if (notifications.length === MAX_NOTIFICATIONS) {
|
|
|
|
// Reached the maximum number of notifications, proceed with grouping
|
|
|
|
var group = {
|
|
|
|
title: formatGroupTitle(options.data.message, notifications.length + 1),
|
|
|
|
body: notifications.sort(function (n1, n2) {
|
|
|
|
return n1.timestamp < n2.timestamp;
|
|
|
|
}).map(function (notification) {
|
|
|
|
return notification.title;
|
|
|
|
}).join('\n'),
|
|
|
|
badge: '/badge.png',
|
|
|
|
icon: '/android-chrome-192x192.png',
|
|
|
|
tag: GROUP_TAG,
|
|
|
|
data: {
|
|
|
|
url: new URL('/web/notifications', self.location).href,
|
|
|
|
count: notifications.length + 1,
|
|
|
|
message: options.data.message
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
notifications.forEach(function (notification) {
|
|
|
|
return notification.close();
|
|
|
|
});
|
|
|
|
|
|
|
|
return self.registration.showNotification(group.title, group);
|
|
|
|
} else if (notifications.length === 1 && notifications[0].tag === GROUP_TAG) {
|
|
|
|
// Already grouped, proceed with appending the notification to the group
|
|
|
|
var _group = cloneNotification(notifications[0]);
|
|
|
|
|
|
|
|
_group.title = formatGroupTitle(_group.data.message, _group.data.count + 1);
|
|
|
|
_group.body = options.title + '\n' + _group.body;
|
|
|
|
_group.data = Object.assign({}, _group.data, { count: _group.data.count + 1 });
|
|
|
|
|
|
|
|
return self.registration.showNotification(_group.title, _group);
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.registration.showNotification(options.title, options);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var handlePush = function handlePush(event) {
|
|
|
|
var options = event.data.json();
|
|
|
|
|
|
|
|
options.body = options.data.nsfw || options.data.content;
|
|
|
|
options.dir = options.data.dir;
|
|
|
|
options.image = options.image || undefined; // Null results in a network request (404)
|
|
|
|
options.timestamp = options.timestamp && new Date(options.timestamp);
|
|
|
|
|
|
|
|
var expandAction = options.data.actions.find(function (action) {
|
|
|
|
return action.todo === 'expand';
|
|
|
|
});
|
|
|
|
|
|
|
|
if (expandAction) {
|
|
|
|
options.actions = [expandAction];
|
|
|
|
options.hiddenActions = options.data.actions.filter(function (action) {
|
|
|
|
return action !== expandAction;
|
|
|
|
});
|
|
|
|
options.data.hiddenImage = options.image;
|
|
|
|
options.image = undefined;
|
|
|
|
} else {
|
|
|
|
options.actions = options.data.actions;
|
|
|
|
}
|
|
|
|
|
|
|
|
event.waitUntil(notify(options));
|
|
|
|
};
|
|
|
|
|
|
|
|
var cloneNotification = function cloneNotification(notification) {
|
|
|
|
var clone = {};
|
|
|
|
|
|
|
|
for (var k in notification) {
|
|
|
|
clone[k] = notification[k];
|
|
|
|
}
|
|
|
|
|
|
|
|
return clone;
|
|
|
|
};
|
|
|
|
|
|
|
|
var expandNotification = function expandNotification(notification) {
|
|
|
|
var nextNotification = cloneNotification(notification);
|
|
|
|
|
|
|
|
nextNotification.body = notification.data.content;
|
|
|
|
nextNotification.image = notification.data.hiddenImage;
|
|
|
|
nextNotification.actions = notification.data.actions.filter(function (action) {
|
|
|
|
return action.todo !== 'expand';
|
|
|
|
});
|
|
|
|
|
|
|
|
return self.registration.showNotification(nextNotification.title, nextNotification);
|
|
|
|
};
|
|
|
|
|
|
|
|
var makeRequest = function makeRequest(notification, action) {
|
|
|
|
return fetch(action.action, {
|
|
|
|
headers: {
|
|
|
|
'Authorization': 'Bearer ' + notification.data.access_token,
|
|
|
|
'Content-Type': 'application/json'
|
|
|
|
},
|
|
|
|
method: action.method,
|
|
|
|
credentials: 'include'
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var findBestClient = function findBestClient(clients) {
|
|
|
|
var focusedClient = clients.find(function (client) {
|
|
|
|
return client.focused;
|
|
|
|
});
|
|
|
|
var visibleClient = clients.find(function (client) {
|
|
|
|
return client.visibilityState === 'visible';
|
|
|
|
});
|
|
|
|
|
|
|
|
return focusedClient || visibleClient || clients[0];
|
|
|
|
};
|
|
|
|
|
|
|
|
var openUrl = function openUrl(url) {
|
|
|
|
return self.clients.matchAll({ type: 'window' }).then(function (clientList) {
|
|
|
|
if (clientList.length !== 0) {
|
|
|
|
var webClients = clientList.filter(function (client) {
|
|
|
|
return (/\/web\//.test(client.url)
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
|
|
|
if (webClients.length !== 0) {
|
|
|
|
var client = findBestClient(webClients);
|
|
|
|
|
|
|
|
var _ref = new URL(url),
|
|
|
|
pathname = _ref.pathname;
|
|
|
|
|
|
|
|
if (pathname.startsWith('/web/')) {
|
|
|
|
return client.focus().then(function (client) {
|
|
|
|
return client.postMessage({
|
|
|
|
type: 'navigate',
|
|
|
|
path: pathname.slice('/web/'.length - 1)
|
|
|
|
});
|
|
|
|
});
|
|
|
|
}
|
|
|
|
} else if ('navigate' in clientList[0]) {
|
|
|
|
// Chrome 42-48 does not support navigate
|
|
|
|
var _client = findBestClient(clientList);
|
|
|
|
|
|
|
|
return _client.navigate(url).then(function (client) {
|
|
|
|
return client.focus();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return self.clients.openWindow(url);
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
var removeActionFromNotification = function removeActionFromNotification(notification, action) {
|
|
|
|
var actions = notification.actions.filter(function (act) {
|
|
|
|
return act.action !== action.action;
|
|
|
|
});
|
|
|
|
var nextNotification = cloneNotification(notification);
|
|
|
|
|
|
|
|
nextNotification.actions = actions;
|
|
|
|
|
|
|
|
return self.registration.showNotification(nextNotification.title, nextNotification);
|
|
|
|
};
|
|
|
|
|
|
|
|
var handleNotificationClick = function handleNotificationClick(event) {
|
|
|
|
var reactToNotificationClick = new Promise(function (resolve, reject) {
|
|
|
|
if (event.action) {
|
|
|
|
var action = event.notification.data.actions.find(function (_ref2) {
|
|
|
|
var action = _ref2.action;
|
|
|
|
return action === event.action;
|
|
|
|
});
|
|
|
|
|
|
|
|
if (action.todo === 'expand') {
|
|
|
|
resolve(expandNotification(event.notification));
|
|
|
|
} else if (action.todo === 'request') {
|
|
|
|
resolve(makeRequest(event.notification, action).then(function () {
|
|
|
|
return removeActionFromNotification(event.notification, action);
|
|
|
|
}));
|
|
|
|
} else {
|
|
|
|
reject('Unknown action: ' + action.todo);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
event.notification.close();
|
|
|
|
resolve(openUrl(event.notification.data.url));
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
event.waitUntil(reactToNotificationClick);
|
|
|
|
};
|
|
|
|
|
|
|
|
self.addEventListener('push', handlePush);
|
|
|
|
self.addEventListener('notificationclick', handleNotificationClick);
|
|
|
|
|
|
|
|
/***/ })
|
|
|
|
/******/ ]);
|