diff --git a/_config.amane.yml b/_config.amane.yml
index 546b6f0..b00f7ea 100644
--- a/_config.amane.yml
+++ b/_config.amane.yml
@@ -197,7 +197,7 @@ widgets:
# Author's current location
# location: CLOUDFLARE.COM
# URL or path to the avatar image
- avatar: https://cdn.nofated.win/avatar/256
+ avatar: https://xgjalbum.oss-cn-hangzhou.aliyuncs.com/623fec2f97df7d3eee768933/AC1BFF0F-E891-41D0-8BB7-08C4DDB70CA9.png?x-oss-process=image/resize,m_fill,h_256,w_256,limit_0/format,webp
# Whether show the rounded avatar image
avatar_rounded: true
# Email address for the Gravatar
diff --git a/scripts/service-worker-injector.js b/scripts/service-worker-injector.js
index ee22056..4b412be 100644
--- a/scripts/service-worker-injector.js
+++ b/scripts/service-worker-injector.js
@@ -1 +1,3 @@
-hexo.extend.injector.register('body_end', '', 'default');
+hexo.extend.injector.register('body_end', '', 'default');
+
+hexo.extend.injector.register('body_end', '', 'default');
diff --git a/source/js/quicklink.js b/source/js/quicklink.js
new file mode 100644
index 0000000..153efcf
--- /dev/null
+++ b/source/js/quicklink.js
@@ -0,0 +1 @@
+!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n(e.quicklink={})}(this,function(e){function n(e){return new Promise(function(n,r,t){(t=new XMLHttpRequest).open("GET",e,t.withCredentials=!0),t.onload=function(){200===t.status?n():r()},t.send()})}var r,t=(r=document.createElement("link")).relList&&r.relList.supports&&r.relList.supports("prefetch")?function(e){return new Promise(function(n,r,t){(t=document.createElement("link")).rel="prefetch",t.href=e,t.onload=n,t.onerror=r,document.head.appendChild(t)})}:n,o=window.requestIdleCallback||function(e){var n=Date.now();return setTimeout(function(){e({didTimeout:!1,timeRemaining:function(){return Math.max(0,50-(Date.now()-n))}})},1)},i=new Set,c=new Set,u=!1;function a(e){if(e){if(e.saveData)return new Error("Save-Data is enabled");if(/2g/.test(e.effectiveType))return new Error("network conditions are poor")}return!0}function s(e,r,o){var s=a(navigator.connection);return s instanceof Error?Promise.reject(new Error("Cannot prefetch, "+s.message)):(c.size>0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document"),Promise.all([].concat(e).map(function(e){if(!i.has(e))return i.add(e),(r?function(e){return window.fetch?fetch(e,{credentials:"include"}):n(e)}:t)(new URL(e,location.href).toString())})))}function f(e,n){var r=a(navigator.connection);if(r instanceof Error)return Promise.reject(new Error("Cannot prerender, "+r.message));if(!HTMLScriptElement.supports("speculationrules"))return s(e),Promise.reject(new Error("This browser does not support the speculation rules API. Falling back to prefetch."));if(document.querySelector('script[type="speculationrules"]'))return Promise.reject(new Error("Speculation Rules is already defined and cannot be altered."));for(var t=0,o=[].concat(e);t0&&!u&&console.warn("[Warning] You are using both prefetching and prerendering on the same document");var l=function(e){var n=document.createElement("script");n.type="speculationrules",n.text='{"prerender":[{"source": "list","urls": ["'+Array.from(e).join('","')+'"]}]}';try{document.head.appendChild(n)}catch(e){return e}return!0}(c);return!0===l?Promise.resolve():Promise.reject(l)}e.listen=function(e){if(e||(e={}),window.IntersectionObserver){var n=function(e){e=e||1;var n=[],r=0;function t(){r0&&(n.shift()(),r++)}return[function(e){n.push(e)>1||t()},function(){r--,t()}]}(e.throttle||1/0),r=n[0],t=n[1],a=e.limit||1/0,l=e.origins||[location.hostname],d=e.ignores||[],h=e.delay||0,p=[],m=e.timeoutFn||o,w="function"==typeof e.hrefFn&&e.hrefFn,g=e.prerender||!1;u=e.prerenderAndPrefetch||!1;var v=new IntersectionObserver(function(n){n.forEach(function(n){if(n.isIntersecting)p.push((n=n.target).href),function(e,n){n?setTimeout(e,n):e()}(function(){-1!==p.indexOf(n.href)&&(v.unobserve(n),(u||g)&&c.size<1?f(w?w(n):n.href).catch(function(n){if(!e.onError)throw n;e.onError(n)}):i.size-1&&p.splice(o)}})},{threshold:e.threshold||0});return m(function(){(e.el||document).querySelectorAll("a").forEach(function(e){l.length&&!l.includes(e.hostname)||function e(n,r){return Array.isArray(r)?r.some(function(r){return e(n,r)}):(r.test||r).call(r,n.href,n)}(e,d)||v.observe(e)})},{timeout:e.timeout||2e3}),function(){i.clear(),v.disconnect()}}},e.prefetch=s,e.prerender=f});
diff --git a/source/js/sw.js b/source/js/sw.js
index 8c9877e..f3e44fd 100644
--- a/source/js/sw.js
+++ b/source/js/sw.js
@@ -1,7 +1,7 @@
-importScripts('https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/workbox-sw.js');
+importScripts('/js/workbox/workbox-sw.js');
workbox.setConfig({
- modulePathPrefix: 'https://cdn.jsdelivr.net/npm/workbox-cdn@5.1.4/workbox/'
+ modulePathPrefix: '/js/workbox/'
});
const { core, precaching, routing, strategies, expiration, cacheableResponse, backgroundSync } = workbox;
@@ -9,7 +9,7 @@ const { CacheFirst, NetworkFirst, NetworkOnly, StaleWhileRevalidate } = strategi
const { ExpirationPlugin } = expiration;
const { CacheableResponsePlugin } = cacheableResponse;
-const cacheSuffixVersion = '-231126',
+const cacheSuffixVersion = '-231126a',
// precacheCacheName = core.cacheNames.precache,
// runtimeCacheName = core.cacheNames.runtime,
maxEntries = 100;
@@ -18,8 +18,8 @@ self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then((keys) => {
return Promise.all(keys.map((key) => {
- if (key.includes('disqus-cdn-cache')) return caches.delete(key);
- if (key.includes('disqus-img-cache')) return caches.delete(key);
+ if (key.includes('waline-cdn-cache')) return caches.delete(key);
+ if (key.includes('waline-img-cache')) return caches.delete(key);
if (!key.includes(cacheSuffixVersion)) return caches.delete(key);
}));
})
@@ -203,10 +203,10 @@ routing.registerRoute(
);
routing.registerRoute(
- new RegExp('disqus'),
+ new RegExp('waline'),
new NetworkFirst({
plugins: [
- new backgroundSync.BackgroundSyncPlugin('disqus', {
+ new backgroundSync.BackgroundSyncPlugin('waline', {
maxRetentionTime: 12 * 60
}),
]
@@ -276,4 +276,4 @@ routing.registerRoute(
*/
routing.setDefaultHandler(
new NetworkOnly()
-);
\ No newline at end of file
+);
diff --git a/source/js/workbox/workbox-background-sync.dev.js b/source/js/workbox/workbox-background-sync.dev.js
new file mode 100644
index 0000000..ee97c46
--- /dev/null
+++ b/source/js/workbox/workbox-background-sync.dev.js
@@ -0,0 +1,818 @@
+this.workbox = this.workbox || {};
+this.workbox.backgroundSync = (function (exports, WorkboxError_js, logger_js, assert_js, getFriendlyURL_js, DBWrapper_js) {
+ 'use strict';
+
+ try {
+ self['workbox:background-sync:5.1.4'] && _();
+ } catch (e) {}
+
+ /*
+ Copyright 2018 Google LLC
+
+ Use of this source code is governed by an MIT-style
+ license that can be found in the LICENSE file or at
+ https://opensource.org/licenses/MIT.
+ */
+ const DB_VERSION = 3;
+ const DB_NAME = 'workbox-background-sync';
+ const OBJECT_STORE_NAME = 'requests';
+ const INDEXED_PROP = 'queueName';
+ /**
+ * A class to manage storing requests from a Queue in IndexedDB,
+ * indexed by their queue name for easier access.
+ *
+ * @private
+ */
+
+ class QueueStore {
+ /**
+ * Associates this instance with a Queue instance, so entries added can be
+ * identified by their queue name.
+ *
+ * @param {string} queueName
+ * @private
+ */
+ constructor(queueName) {
+ this._queueName = queueName;
+ this._db = new DBWrapper_js.DBWrapper(DB_NAME, DB_VERSION, {
+ onupgradeneeded: this._upgradeDb
+ });
+ }
+ /**
+ * Append an entry last in the queue.
+ *
+ * @param {Object} entry
+ * @param {Object} entry.requestData
+ * @param {number} [entry.timestamp]
+ * @param {Object} [entry.metadata]
+ * @private
+ */
+
+
+ async pushEntry(entry) {
+ {
+ assert_js.assert.isType(entry, 'object', {
+ moduleName: 'workbox-background-sync',
+ className: 'QueueStore',
+ funcName: 'pushEntry',
+ paramName: 'entry'
+ });
+ assert_js.assert.isType(entry.requestData, 'object', {
+ moduleName: 'workbox-background-sync',
+ className: 'QueueStore',
+ funcName: 'pushEntry',
+ paramName: 'entry.requestData'
+ });
+ } // Don't specify an ID since one is automatically generated.
+
+
+ delete entry.id;
+ entry.queueName = this._queueName;
+ await this._db.add(OBJECT_STORE_NAME, entry);
+ }
+ /**
+ * Prepend an entry first in the queue.
+ *
+ * @param {Object} entry
+ * @param {Object} entry.requestData
+ * @param {number} [entry.timestamp]
+ * @param {Object} [entry.metadata]
+ * @private
+ */
+
+
+ async unshiftEntry(entry) {
+ {
+ assert_js.assert.isType(entry, 'object', {
+ moduleName: 'workbox-background-sync',
+ className: 'QueueStore',
+ funcName: 'unshiftEntry',
+ paramName: 'entry'
+ });
+ assert_js.assert.isType(entry.requestData, 'object', {
+ moduleName: 'workbox-background-sync',
+ className: 'QueueStore',
+ funcName: 'unshiftEntry',
+ paramName: 'entry.requestData'
+ });
+ }
+
+ const [firstEntry] = await this._db.getAllMatching(OBJECT_STORE_NAME, {
+ count: 1
+ });
+
+ if (firstEntry) {
+ // Pick an ID one less than the lowest ID in the object store.
+ entry.id = firstEntry.id - 1;
+ } else {
+ // Otherwise let the auto-incrementor assign the ID.
+ delete entry.id;
+ }
+
+ entry.queueName = this._queueName;
+ await this._db.add(OBJECT_STORE_NAME, entry);
+ }
+ /**
+ * Removes and returns the last entry in the queue matching the `queueName`.
+ *
+ * @return {Promise