diff --git a/.eslintrc b/.eslintrc
index 3a731cbf6b..3156f88375 100644
--- a/.eslintrc
+++ b/.eslintrc
@@ -25,7 +25,7 @@ globals:
Tribute: false
overrides:
- - files: ["web_src/**/*.worker.js"]
+ - files: ["web_src/**/*.worker.js", "web_src/js/serviceworker.js"]
env:
worker: true
rules:
@@ -58,6 +58,7 @@ rules:
no-restricted-syntax: [0]
no-return-await: [0]
no-shadow: [0]
+ no-underscore-dangle: [0]
no-unused-vars: [2, {args: all, argsIgnorePattern: ^_, varsIgnorePattern: ^_, ignoreRestSiblings: true}]
no-use-before-define: [0]
no-var: [2]
diff --git a/Makefile b/Makefile
index 37c9a46d81..1afdcf7d3f 100644
--- a/Makefile
+++ b/Makefile
@@ -88,7 +88,7 @@ GO_PACKAGES ?= $(filter-out code.gitea.io/gitea/integrations/migration-test,$(fi
WEBPACK_SOURCES := $(shell find web_src/js web_src/less -type f)
WEBPACK_CONFIGS := webpack.config.js
WEBPACK_DEST := public/js/index.js public/css/index.css
-WEBPACK_DEST_DIRS := public/js public/css public/fonts
+WEBPACK_DEST_ENTRIES := public/js public/css public/fonts public/serviceworker.js
BINDATA_DEST := modules/public/bindata.go modules/options/bindata.go modules/templates/bindata.go
BINDATA_HASH := $(addsuffix .hash,$(BINDATA_DEST))
@@ -194,7 +194,7 @@ node-check:
.PHONY: clean-all
clean-all: clean
- rm -rf $(WEBPACK_DEST_DIRS) $(FOMANTIC_DEST_DIR)
+ rm -rf $(WEBPACK_DEST_ENTRIES) $(FOMANTIC_DEST_DIR)
.PHONY: clean
clean:
@@ -295,6 +295,7 @@ lint-frontend: node_modules
.PHONY: watch-frontend
watch-frontend: node_modules
+ rm -rf $(WEBPACK_DEST_ENTRIES)
NODE_ENV=development npx webpack --hide-modules --display-entrypoints=false --watch --progress
.PHONY: test
@@ -598,7 +599,7 @@ $(FOMANTIC_DEST): $(FOMANTIC_CONFIGS) package-lock.json | node_modules
webpack: $(WEBPACK_DEST)
$(WEBPACK_DEST): $(WEBPACK_SOURCES) $(WEBPACK_CONFIGS) package-lock.json | node_modules
- rm -rf $(WEBPACK_DEST_DIRS)
+ rm -rf $(WEBPACK_DEST_ENTRIES)
npx webpack --hide-modules --display-entrypoints=false
@touch $(WEBPACK_DEST)
diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl
index a6a715531d..9ad7f8496c 100644
--- a/templates/base/head.tmpl
+++ b/templates/base/head.tmpl
@@ -92,8 +92,6 @@
-
-
{{if .RequireSimpleMDE}}
{{end}}
diff --git a/web_src/js/features/serviceworker.js b/web_src/js/features/serviceworker.js
index a8fd2d41df..fa415866cd 100644
--- a/web_src/js/features/serviceworker.js
+++ b/web_src/js/features/serviceworker.js
@@ -1,16 +1,18 @@
const {UseServiceWorker, AppSubUrl, AppVer} = window.config;
-const cacheName = 'static-cache-v2';
+const cachePrefix = 'static-cache-v'; // actual version is set in the service worker script
async function unregister() {
- for (const registration of await navigator.serviceWorker.getRegistrations()) {
- const serviceWorker = registration.active;
- if (!serviceWorker) continue;
- registration.unregister();
- }
+ const registrations = await navigator.serviceWorker.getRegistrations();
+ await Promise.all(registrations.map((registration) => {
+ return registration.active && registration.unregister();
+ }));
}
async function invalidateCache() {
- await caches.delete(cacheName);
+ const cacheKeys = await caches.keys();
+ await Promise.all(cacheKeys.map((key) => {
+ return key.startsWith(cachePrefix) && caches.delete(key);
+ }));
}
async function checkCacheValidity() {
@@ -19,7 +21,7 @@ async function checkCacheValidity() {
// invalidate cache if it belongs to a different gitea version
if (cacheKey && storedCacheKey !== cacheKey) {
- invalidateCache();
+ await invalidateCache();
localStorage.setItem('staticCacheKey', cacheKey);
}
}
@@ -28,16 +30,24 @@ export default async function initServiceWorker() {
if (!('serviceWorker' in navigator)) return;
if (UseServiceWorker) {
- await checkCacheValidity();
try {
- await navigator.serviceWorker.register(`${AppSubUrl}/serviceworker.js`);
+ // normally we'd serve the service worker as a static asset from StaticUrlPrefix but
+ // the spec strictly requires it to be same-origin so it has to be AppSubUrl to work
+ await Promise.all([
+ checkCacheValidity(),
+ navigator.serviceWorker.register(`${AppSubUrl}/serviceworker.js`),
+ ]);
} catch (err) {
console.error(err);
- await invalidateCache();
- await unregister();
+ await Promise.all([
+ invalidateCache(),
+ unregister(),
+ ]);
}
} else {
- await invalidateCache();
- await unregister();
+ await Promise.all([
+ invalidateCache(),
+ unregister(),
+ ]);
}
}
diff --git a/web_src/js/index.js b/web_src/js/index.js
index 58cbd42933..5c749ce4ca 100644
--- a/web_src/js/index.js
+++ b/web_src/js/index.js
@@ -2469,7 +2469,7 @@ $(document).ready(async () => {
}
});
- // parallel init of lazy-loaded features
+ // parallel init of async loaded features
await Promise.all([
highlight(document.querySelectorAll('pre code')),
attachTribute(document.querySelectorAll('#content, .emoji-input')),
diff --git a/web_src/js/serviceworker.js b/web_src/js/serviceworker.js
index e9dfde22f9..c96ef8bd97 100644
--- a/web_src/js/serviceworker.js
+++ b/web_src/js/serviceworker.js
@@ -3,9 +3,16 @@ import {StaleWhileRevalidate} from 'workbox-strategies';
const cacheName = 'static-cache-v2';
+// disable workbox debug logging in development, remove when debugging the service worker
+self.__WB_DISABLE_DEV_LOGS = true;
+
+// see https://developer.mozilla.org/en-US/docs/Web/API/RequestDestination for possible values
const cachedDestinations = new Set([
+ 'font',
'manifest',
+ 'paintworklet',
'script',
+ 'sharedworker',
'style',
'worker',
]);