enhance: move window.config to JSON, improve CSP format (#39236)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
silverwind
2026-09-05 08:50:43 +00:00
committed by GitHub
co-authored by wxiaoguang
parent efa69e7230
commit eb501f6b19
8 changed files with 72 additions and 50 deletions
+9 -6
View File
@@ -1,15 +1,18 @@
// DO NOT IMPORT window.config HERE!
// to make sure the error handler always works, we should never import `window.config`, because
// some user's custom template breaks it.
import {showGlobalErrorMessage, processWindowErrorEvent} from './modules/errors.ts';
// window.config is initialized here
try {
window.config = JSON.parse(document.querySelector('#global-window-config')!.textContent);
// in case some pages don't render the pageData, we make sure it is an object to prevent null access
window.config.pageData ??= {};
} catch {
showGlobalErrorMessage(`Gitea JavaScript code couldn't run correctly, please check your custom templates`);
}
// A module should not be imported twice, otherwise there will be bugs when a module has its internal states.
// A real example is "generateElemId" in "utils/dom.ts", if it is imported twice in different module scopes,
// It will generate duplicate IDs (ps: don't try to use "random" to fix, it is just a real example to show the importance of "do not import a module twice")
if (!window._globalHandlerErrors?._inited) {
if (!window.config) {
showGlobalErrorMessage(`Gitea JavaScript code couldn't run correctly, please check your custom templates`);
}
// we added an event handler for window error at the very beginning of <script> of page head the
// handler calls `_globalHandlerErrors.push` (array method) to record all errors occur before
// this init then in this init, we can collect all error events and show them.
+1 -1
View File
@@ -1,6 +1,6 @@
// This file is the entry point for the code which should block the page rendering, it is compiled by our "iife" vite plugin
// bootstrap module must be the first one to be imported, it handles global errors
// bootstrap module must be the first one to be imported, it handles global config and errors
import './bootstrap.ts';
// many users expect to use jQuery in their custom scripts (https://docs.gitea.com/administration/customizing-gitea#example-plantuml)
+8 -2
View File
@@ -3,6 +3,12 @@ import {html} from '../utils/html.ts';
import isNetworkError from 'is-network-error';
import type {Intent} from '../types.ts';
// The code in this module might be executed before window.config is initialized,
// Don't access window.config directly.
function windowConfig(): typeof window.config | undefined {
return window.config;
}
/** Extract a message string from an unknown caught value. */
export function errorMessage(err: unknown): string {
return (err as Error)?.message || String(err);
@@ -50,7 +56,7 @@ export function showGlobalErrorMessage(msg: string, msgType: Intent = 'error', d
const extensionRe = /(chrome|moz|safari(-web)?)-extension:\/\//;
export function isGiteaError(filename: string, stack: string): boolean {
if (extensionRe.test(filename) || extensionRe.test(stack)) return false;
const assetBaseUrl = new URL(`${window.config.assetUrlPrefix}/`, window.location.origin).href;
const assetBaseUrl = new URL(`${windowConfig()?.assetUrlPrefix}/`, window.location.origin).href;
if (filename && !filename.startsWith(assetBaseUrl) && !filename.startsWith(window.location.origin)) return false;
return !stack || stack.includes(assetBaseUrl);
}
@@ -64,7 +70,7 @@ export function processWindowErrorEvent({error, reason, message, type, filename,
// - https://github.com/go-gitea/gitea/issues/20240
if (!err) {
if (message) console.error(new Error(message));
if (window.config.runModeIsProd) return;
if (windowConfig()?.runModeIsProd) return;
}
// Don't show network errors, happens on ref-issue when clicking on the