forked from forgejo/forgejo
Show messages for users if the ROOT_URL is wrong, show JavaScript errors (#18971)
* ROOT_URL issues: some users did wrong to there app.ini config, then: * The assets can not be loaded (AppSubUrl != "" and users try to access http://host:3000/) *The ROOT_URL is wrong, then many URLs in Gitea are broken. Now Gitea show enough information to users. * JavaScript error issues, there are many users affected by JavaScript errors, some are caused by frontend bugs, some are caused by broken customized templates. If these JS errors can be found at first time, then maintainers do not need to ask about how bug occurs again and again. * Some people like to modify the `head.tmpl`, so we separate the script part to `head_script.tmpl`, then it's much safer. * use specialized CSS class "js-global-error", end users still have a chance to hide error messages by customized CSS styles.
This commit is contained in:
parent
ea8622d454
commit
2bce1ea986
7 changed files with 118 additions and 52 deletions
|
@ -22,7 +22,7 @@
|
|||
<script src='https://hcaptcha.com/1/api.js' async></script>
|
||||
{{end}}
|
||||
{{end}}
|
||||
<script src="{{AssetUrlPrefix}}/js/index.js?v={{MD5 AppVer}}"></script>
|
||||
<script src="{{AssetUrlPrefix}}/js/index.js?v={{MD5 AppVer}}" onerror="alert('Failed to load asset files from ' + this.src + ', please make sure the asset files can be accessed and the ROOT_URL setting in app.ini is correct.')"></script>
|
||||
{{template "custom/footer" .}}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -19,51 +19,12 @@
|
|||
<link rel="alternate" type="application/atom+xml" title="" href="{{.FeedURL}}.atom">
|
||||
<link rel="alternate" type="application/rss+xml" title="" href="{{.FeedURL}}.rss">
|
||||
{{end}}
|
||||
<script>
|
||||
<!-- /* eslint-disable */ -->
|
||||
window.config = {
|
||||
appVer: '{{AppVer}}',
|
||||
appSubUrl: '{{AppSubUrl}}',
|
||||
assetUrlPrefix: '{{AssetUrlPrefix}}',
|
||||
runModeIsProd: {{.RunModeIsProd}},
|
||||
customEmojis: {{CustomEmojis}},
|
||||
useServiceWorker: {{UseServiceWorker}},
|
||||
csrfToken: '{{.CsrfToken}}',
|
||||
pageData: {{.PageData}},
|
||||
requireTribute: {{.RequireTribute}},
|
||||
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
|
||||
enableTimeTracking: {{EnableTimetracking}},
|
||||
{{if .RequireTribute}}
|
||||
tributeValues: Array.from(new Map([
|
||||
{{ range .Participants }}
|
||||
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}',
|
||||
name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink}}'}],
|
||||
{{ end }}
|
||||
{{ range .Assignees }}
|
||||
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}',
|
||||
name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink}}'}],
|
||||
{{ end }}
|
||||
{{ range .MentionableTeams }}
|
||||
['{{$.MentionableTeamsOrg}}/{{.Name}}', {key: '{{$.MentionableTeamsOrg}}/{{.Name}}', value: '{{$.MentionableTeamsOrg}}/{{.Name}}',
|
||||
name: '{{$.MentionableTeamsOrg}}/{{.Name}}', avatar: '{{$.MentionableTeamsOrgAvatar}}'}],
|
||||
{{ end }}
|
||||
]).values()),
|
||||
{{end}}
|
||||
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
|
||||
{{/* this global i18n object should only contain general texts. for specialized texts, it should be provided inside the related modules by: (1) API response (2) HTML data-attribute (3) PageData */}}
|
||||
i18n: {
|
||||
copy_success: '{{.i18n.Tr "copy_success"}}',
|
||||
copy_error: '{{.i18n.Tr "copy_error"}}',
|
||||
error_occurred: '{{.i18n.Tr "error.occurred"}}',
|
||||
network_error: '{{.i18n.Tr "error.network_error"}}',
|
||||
},
|
||||
};
|
||||
{{/* in case some pages don't render the pageData, we make sure it is an object to prevent null access */}}
|
||||
window.config.pageData = window.config.pageData || {};
|
||||
</script>
|
||||
<link rel="icon" href="{{AssetUrlPrefix}}/img/logo.svg" type="image/svg+xml">
|
||||
<link rel="alternate icon" href="{{AssetUrlPrefix}}/img/favicon.png" type="image/png">
|
||||
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/index.css?v={{MD5 AppVer}}">
|
||||
|
||||
{{template "base/head_script" .}}
|
||||
|
||||
<noscript>
|
||||
<style>
|
||||
.dropdown:hover > .menu { display: block; }
|
||||
|
|
49
templates/base/head_script.tmpl
Normal file
49
templates/base/head_script.tmpl
Normal file
|
@ -0,0 +1,49 @@
|
|||
{{/*
|
||||
==== DO NOT EDIT ====
|
||||
If you are customizing Gitea, please do not change this file.
|
||||
If you introduce mistakes in it, Gitea JavaScript code wouldn't run correctly.
|
||||
*/}}
|
||||
<script>
|
||||
<!-- /* eslint-disable */ -->
|
||||
window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);});
|
||||
window.config = {
|
||||
appVer: '{{AppVer}}',
|
||||
appUrl: '{{AppUrl}}',
|
||||
appSubUrl: '{{AppSubUrl}}',
|
||||
assetUrlPrefix: '{{AssetUrlPrefix}}',
|
||||
runModeIsProd: {{.RunModeIsProd}},
|
||||
customEmojis: {{CustomEmojis}},
|
||||
useServiceWorker: {{UseServiceWorker}},
|
||||
csrfToken: '{{.CsrfToken}}',
|
||||
pageData: {{.PageData}},
|
||||
requireTribute: {{.RequireTribute}},
|
||||
notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}}
|
||||
enableTimeTracking: {{EnableTimetracking}},
|
||||
{{if .RequireTribute}}
|
||||
tributeValues: Array.from(new Map([
|
||||
{{ range .Participants }}
|
||||
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}',
|
||||
name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink}}'}],
|
||||
{{ end }}
|
||||
{{ range .Assignees }}
|
||||
['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}',
|
||||
name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink}}'}],
|
||||
{{ end }}
|
||||
{{ range .MentionableTeams }}
|
||||
['{{$.MentionableTeamsOrg}}/{{.Name}}', {key: '{{$.MentionableTeamsOrg}}/{{.Name}}', value: '{{$.MentionableTeamsOrg}}/{{.Name}}',
|
||||
name: '{{$.MentionableTeamsOrg}}/{{.Name}}', avatar: '{{$.MentionableTeamsOrgAvatar}}'}],
|
||||
{{ end }}
|
||||
]).values()),
|
||||
{{end}}
|
||||
mermaidMaxSourceCharacters: {{MermaidMaxSourceCharacters}},
|
||||
{{/* this global i18n object should only contain general texts. for specialized texts, it should be provided inside the related modules by: (1) API response (2) HTML data-attribute (3) PageData */}}
|
||||
i18n: {
|
||||
copy_success: '{{.i18n.Tr "copy_success"}}',
|
||||
copy_error: '{{.i18n.Tr "copy_error"}}',
|
||||
error_occurred: '{{.i18n.Tr "error.occurred"}}',
|
||||
network_error: '{{.i18n.Tr "error.network_error"}}',
|
||||
},
|
||||
};
|
||||
{{/* in case some pages don't render the pageData, we make sure it is an object to prevent null access */}}
|
||||
window.config.pageData = window.config.pageData || {};
|
||||
</script>
|
Loading…
Add table
Add a link
Reference in a new issue