diff options
author | Daniel Baumann <daniel@debian.org> | 2024-10-18 20:33:49 +0200 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-12-12 23:57:56 +0100 |
commit | e68b9d00a6e05b3a941f63ffb696f91e554ac5ec (patch) | |
tree | 97775d6c13b0f416af55314eb6a89ef792474615 /templates/base | |
parent | Initial commit. (diff) | |
download | forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.tar.xz forgejo-e68b9d00a6e05b3a941f63ffb696f91e554ac5ec.zip |
Adding upstream version 9.0.3.
Signed-off-by: Daniel Baumann <daniel@debian.org>
Diffstat (limited to '')
-rw-r--r-- | templates/base/alert.tmpl | 23 | ||||
-rw-r--r-- | templates/base/alert_details.tmpl | 7 | ||||
-rw-r--r-- | templates/base/disable_form_autofill.tmpl | 31 | ||||
-rw-r--r-- | templates/base/footer.tmpl | 20 | ||||
-rw-r--r-- | templates/base/footer_content.tmpl | 32 | ||||
-rw-r--r-- | templates/base/head.tmpl | 50 | ||||
-rw-r--r-- | templates/base/head_navbar.tmpl | 205 | ||||
-rw-r--r-- | templates/base/head_opengraph.tmpl | 53 | ||||
-rw-r--r-- | templates/base/head_script.tmpl | 50 | ||||
-rw-r--r-- | templates/base/head_style.tmpl | 2 | ||||
-rw-r--r-- | templates/base/modal_actions_confirm.tmpl | 35 | ||||
-rw-r--r-- | templates/base/paginate.tmpl | 34 |
12 files changed, 542 insertions, 0 deletions
diff --git a/templates/base/alert.tmpl b/templates/base/alert.tmpl new file mode 100644 index 0000000..e2853d3 --- /dev/null +++ b/templates/base/alert.tmpl @@ -0,0 +1,23 @@ +{{if .Flash.ErrorMsg}} + <div id="flash-message" class="ui negative message flash-message flash-error" hx-swap-oob="true"> + <p>{{.Flash.ErrorMsg | SanitizeHTML}}</p> + </div> +{{end}} +{{if .Flash.SuccessMsg}} + <div id="flash-message" class="ui positive message flash-message flash-success" hx-swap-oob="true"> + <p>{{.Flash.SuccessMsg | SanitizeHTML}}</p> + </div> +{{end}} +{{if .Flash.InfoMsg}} + <div id="flash-message" class="ui info message flash-message flash-info" hx-swap-oob="true"> + <p>{{.Flash.InfoMsg | SanitizeHTML}}</p> + </div> +{{end}} +{{if .Flash.WarningMsg}} + <div id="flash-message" class="ui warning message flash-message flash-warning" hx-swap-oob="true"> + <p>{{.Flash.WarningMsg | SanitizeHTML}}</p> + </div> +{{end}} +{{if and (not .Flash.ErrorMsg) (not .Flash.SuccessMsg) (not .Flash.InfoMsg) (not .Flash.WarningMsg) (not .IsHTMX)}} + <div id="flash-message" hx-swap-oob="true"></div> +{{end}} diff --git a/templates/base/alert_details.tmpl b/templates/base/alert_details.tmpl new file mode 100644 index 0000000..6801c82 --- /dev/null +++ b/templates/base/alert_details.tmpl @@ -0,0 +1,7 @@ +{{.Message}} +<details> + <summary>{{.Summary}}</summary> + <code> + {{.Details | SanitizeHTML}} + </code> +</details> diff --git a/templates/base/disable_form_autofill.tmpl b/templates/base/disable_form_autofill.tmpl new file mode 100644 index 0000000..6f06395 --- /dev/null +++ b/templates/base/disable_form_autofill.tmpl @@ -0,0 +1,31 @@ +{{/* +Why we need to disable form autofill: +1. Many pages contain different password inputs for different usages, eg: repo setting, autofill will make a mess. +2. We have `areYouSure` confirm dialog if a user leaves a pages without submit. +Autofill will make the form changed even if the user didn't input anything. Then the user keeps seeing annoying confirm dialog. + +In history, Gitea put `<input class="fake" type="password">` in forms to bypass the autofill, +but there were still many forms suffered the autofill problem. + +Now we improve it. + +Solutions which do NOT work: +1. Adding `autocomplete=off` doesn't help. New Chrome completely ignores it. +2. Use a JavaScript to run in a few seconds later after the page is loaded to process the autofilled inputs, it doesn't work. +Because for security reason, the inputs won't be filled before the user makes an interaction in the page. +So we can not predict the correct time to run the JavaScript code. + +Solutions which work: +1. Some hacky methods like: https://github.com/matteobad/detect-autofill +2. This solution: use invisible inputs. Be aware of: +(a) The inputs must be at the beginning of the form, and can not be hidden. +(b) The input for username must have a valid name. +(c) There should be no negative word (eg: fake) in the `name` attribute. +(d) Chrome seems to use a weighted algorithm to choose an input to fill text, so the using "username" as input name is better than using "user". +We make the names of these dummy inputs begin with an underline to indicate it is for special usage, +and these dummy form values won't be used by backend code. +*/}} +<div class="autofill-dummy" aria-hidden="true"> + <input type="text" name="_autofill_dummy_username" class="ays-ignore" tabindex="-1"> + <input type="password" name="_autofill_dummy_password" class="ays-ignore" tabindex="-1"> +</div> diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl new file mode 100644 index 0000000..fed426a --- /dev/null +++ b/templates/base/footer.tmpl @@ -0,0 +1,20 @@ +{{if false}} + {{/* to make html structure "likely" complete to prevent IDE warnings */}} +<html> +<body> + <div> +{{end}} + + {{template "custom/body_inner_post" .}} + + </div> + + {{template "custom/body_outer_post" .}} + + {{template "base/footer_content" .}} + + <script src="{{AssetUrlPrefix}}/js/index.js?v={{AssetVersion}}" onerror="alert('Failed to load asset files from ' + this.src + '. Please make sure the asset files can be accessed.')"></script> + + {{template "custom/footer" .}} +</body> +</html> diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl new file mode 100644 index 0000000..5db7464 --- /dev/null +++ b/templates/base/footer_content.tmpl @@ -0,0 +1,32 @@ +<footer class="page-footer" role="group" aria-label="{{ctx.Locale.Tr "aria.footer"}}"> + <div class="left-links" role="contentinfo" aria-label="{{ctx.Locale.Tr "aria.footer.software"}}"> + {{if ShowFooterPoweredBy}} + <a target="_blank" rel="noopener noreferrer" href="https://forgejo.org">{{ctx.Locale.Tr "powered_by" "Forgejo"}}</a> + {{end}} + {{if (or .ShowFooterVersion .PageIsAdmin)}} + {{ctx.Locale.Tr "version"}}: + {{if .IsAdmin}} + <a href="{{AppSubUrl}}/admin/config">{{AppVer}}</a> + {{else}} + {{AppVer}} + {{end}} + {{end}} + {{if and .TemplateLoadTimes ShowFooterTemplateLoadTime}} + {{ctx.Locale.Tr "page"}}: <strong>{{LoadTimes .PageStartTime}}</strong> + {{ctx.Locale.Tr "template"}}{{if .TemplateName}} {{.TemplateName}}{{end}}: <strong>{{call .TemplateLoadTimes}}</strong> + {{end}} + </div> + <div class="right-links" role="group" aria-label="{{ctx.Locale.Tr "aria.footer.links"}}"> + <div class="ui dropdown upward language"> + <span class="flex-text-inline">{{svg "octicon-globe" 14}} {{ctx.Locale.LangName}}</span> + <div class="menu language-menu"> + {{range .AllLangs}} + <a lang="{{.Lang}}" data-url="{{AppSubUrl}}/?lang={{.Lang}}" class="item {{if eq ctx.Locale.Lang .Lang}}active selected{{end}}">{{.Name}}</a> + {{end}} + </div> + </div> + <a href="{{AssetUrlPrefix}}/licenses.txt">{{ctx.Locale.Tr "licenses"}}</a> + {{if .EnableSwagger}}<a href="{{AppSubUrl}}/api/swagger">API</a>{{end}} + {{template "custom/extra_links_footer" .}} + </div> +</footer> diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl new file mode 100644 index 0000000..7753f49 --- /dev/null +++ b/templates/base/head.tmpl @@ -0,0 +1,50 @@ +<!DOCTYPE html> +<html lang="{{ctx.Locale.Lang}}" data-theme="{{ThemeName .SignedUser}}"> +<head> + <meta name="viewport" content="width=device-width, initial-scale=1"> + {{/* Display `- .Repository.FullName` only if `.Title` does not already start with that. */}} + <title>{{if .Title}}{{.Title}} - {{end}}{{if and (.Repository.Name) (not (StringUtils.HasPrefix .Title .Repository.FullName))}}{{.Repository.FullName}} - {{end}}{{AppDisplayName}}</title> + {{if .ManifestData}}<link rel="manifest" href="data:{{.ManifestData}}">{{end}} + <meta name="author" content="{{if .Repository}}{{.Owner.Name}}{{else}}{{MetaAuthor}}{{end}}"> + <meta name="description" content="{{if .Repository}}{{.Repository.Name}}{{if .Repository.Description}} - {{.Repository.Description}}{{end}}{{else}}{{MetaDescription}}{{end}}"> + <meta name="keywords" content="{{MetaKeywords}}"> + <meta name="referrer" content="no-referrer"> +{{if .GoGetImport}} + <meta name="go-import" content="{{.GoGetImport}} git {{.RepoCloneLink.HTTPS}}"> + <meta name="go-source" content="{{.GoGetImport}} _ {{.GoDocDirectory}} {{.GoDocFile}}"> +{{end}} +{{if and .EnableFeed .FeedURL}} + <link rel="alternate" type="application/atom+xml" title="" href="{{.FeedURL}}.atom"> + <link rel="alternate" type="application/rss+xml" title="" href="{{.FeedURL}}.rss"> +{{end}} + <link rel="icon" href="{{AssetUrlPrefix}}/img/favicon.svg" type="image/svg+xml"> + <link rel="alternate icon" href="{{AssetUrlPrefix}}/img/favicon.png" type="image/png"> + {{template "base/head_script" .}} + <noscript> + <style> + .dropdown:hover > .menu { display: block; } + .ui.secondary.menu .dropdown.item > .menu { margin-top: 0; } + </style> + </noscript> + {{template "base/head_opengraph" .}} + {{template "base/head_style" .}} + {{template "custom/header" .}} +</head> +<body hx-headers='{"x-csrf-token": "{{.CsrfToken}}"}' hx-swap="outerHTML" hx-ext="morph" hx-push-url="false"> + {{template "custom/body_outer_pre" .}} + + <div class="full height"> + <noscript>{{ctx.Locale.Tr "enable_javascript"}}</noscript> + + {{template "custom/body_inner_pre" .}} + + {{if not .PageIsInstall}} + {{template "base/head_navbar" .}} + {{end}} + +{{if false}} + {{/* to make html structure "likely" complete to prevent IDE warnings */}} + </div> +</body> +</html> +{{end}} diff --git a/templates/base/head_navbar.tmpl b/templates/base/head_navbar.tmpl new file mode 100644 index 0000000..ba17222 --- /dev/null +++ b/templates/base/head_navbar.tmpl @@ -0,0 +1,205 @@ +{{$notificationUnreadCount := 0}} +{{if and .IsSigned .NotificationUnreadCount}} + {{$notificationUnreadCount = call .NotificationUnreadCount}} +{{end}} + +<nav id="navbar" aria-label="{{ctx.Locale.Tr "aria.navbar"}}"> + <div class="navbar-left ui secondary menu"> + <!-- the logo --> + <a class="item" id="navbar-logo" href="{{AppSubUrl}}/" aria-label="{{if .IsSigned}}{{ctx.Locale.Tr "dashboard"}}{{else}}{{ctx.Locale.Tr "home"}}{{end}}"> + <img width="30" height="30" src="{{AssetUrlPrefix}}/img/logo.svg" alt="{{ctx.Locale.Tr "logo"}}" aria-hidden="true"> + </a> + + <!-- mobile right menu, it must be here because in mobile view, each item is a flex column, the first item is a full row column --> + <div class="ui secondary menu item navbar-mobile-right only-mobile"> + {{if .IsSigned}} + <a id="mobile-notifications-icon" class="item tw-w-auto tw-p-2" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{ctx.Locale.Tr "notifications"}}" aria-label="{{ctx.Locale.Tr "notifications"}}"> + <div class="tw-relative"> + {{svg "octicon-bell"}} + <span class="notification_count{{if not $notificationUnreadCount}} tw-hidden{{end}}">{{$notificationUnreadCount}}</span> + </div> + </a> + {{end}} + <button class="item tw-w-auto ui icon mini button tw-p-2 tw-m-0" id="navbar-expand-toggle" aria-label="{{ctx.Locale.Tr "toggle_menu"}}">{{svg "octicon-three-bars"}}</button> + </div> + + <!-- navbar links non-mobile --> + {{if and .IsSigned .MustChangePassword}} + {{/* No links */}} + {{else if .IsSigned}} + {{if not .UnitIssuesGlobalDisabled}} + <a class="item{{if .PageIsIssues}} active{{end}}" href="{{AppSubUrl}}/issues">{{ctx.Locale.Tr "issues"}}</a> + {{end}} + {{if not .UnitPullsGlobalDisabled}} + <a class="item{{if .PageIsPulls}} active{{end}}" href="{{AppSubUrl}}/pulls">{{ctx.Locale.Tr "pull_requests"}}</a> + {{end}} + {{if not (and .UnitIssuesGlobalDisabled .UnitPullsGlobalDisabled)}} + {{if .ShowMilestonesDashboardPage}} + <a class="item{{if .PageIsMilestonesDashboard}} active{{end}}" href="{{AppSubUrl}}/milestones">{{ctx.Locale.Tr "milestones"}}</a> + {{end}} + {{end}} + <a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/repos">{{ctx.Locale.Tr "explore"}}</a> + {{else if .IsLandingPageOrganizations}} + <a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/organizations">{{ctx.Locale.Tr "explore"}}</a> + {{else}} + <a class="item{{if .PageIsExplore}} active{{end}}" href="{{AppSubUrl}}/explore/repos">{{ctx.Locale.Tr "explore"}}</a> + {{end}} + + {{template "custom/extra_links" .}} + + {{if not .IsSigned}} + <a class="item" target="_blank" rel="noopener noreferrer" href="https://forgejo.org/docs/latest/">{{ctx.Locale.Tr "help"}}</a> + {{end}} + </div> + + <!-- the full dropdown menus --> + <div class="navbar-right ui secondary menu"> + {{if and .IsSigned .MustChangePassword}} + <div class="ui dropdown jump item" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}"> + <span class="text tw-flex tw-items-center"> + {{ctx.AvatarUtils.Avatar .SignedUser 24 "tw-mr-1"}} + <span class="only-mobile tw-ml-2">{{.SignedUser.Name}}</span> + <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> + </span> + <div class="menu user-menu"> + <div class="ui header"> + {{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong> + </div> + + <div class="divider"></div> + <a class="item link-action" href data-url="{{AppSubUrl}}/user/logout"> + {{svg "octicon-sign-out"}} + {{ctx.Locale.Tr "sign_out"}} + </a> + </div><!-- end content avatar menu --> + </div><!-- end dropdown avatar menu --> + {{else if .IsSigned}} + {{if EnableTimetracking}} + <a class="active-stopwatch-trigger item tw-mx-0{{if not .ActiveStopwatch}} tw-hidden{{end}}" href="{{.ActiveStopwatch.IssueLink}}" title="{{ctx.Locale.Tr "active_stopwatch"}}"> + <div class="tw-relative"> + {{svg "octicon-stopwatch"}} + <span class="header-stopwatch-dot"></span> + </div> + <span class="only-mobile tw-ml-2">{{ctx.Locale.Tr "active_stopwatch"}}</span> + </a> + <div class="active-stopwatch-popup item tippy-target tw-p-2"> + <div class="tw-flex tw-items-center"> + <a class="stopwatch-link tw-flex tw-items-center" href="{{.ActiveStopwatch.IssueLink}}"> + {{svg "octicon-issue-opened" 16 "tw-mr-2"}} + <span class="stopwatch-issue">{{.ActiveStopwatch.RepoSlug}}#{{.ActiveStopwatch.IssueIndex}}</span> + <span class="ui primary label stopwatch-time tw-my-0 tw-mx-4" data-seconds="{{.ActiveStopwatch.Seconds}}"> + {{if .ActiveStopwatch}}{{Sec2Time .ActiveStopwatch.Seconds}}{{end}} + </span> + </a> + <form class="stopwatch-commit" method="post" action="{{.ActiveStopwatch.IssueLink}}/times/stopwatch/toggle"> + {{.CsrfTokenHtml}} + <button + type="submit" + class="ui button mini compact basic icon" + data-tooltip-content="{{ctx.Locale.Tr "repo.issues.stop_tracking"}}" + >{{svg "octicon-square-fill"}}</button> + </form> + <form class="stopwatch-cancel" method="post" action="{{.ActiveStopwatch.IssueLink}}/times/stopwatch/cancel"> + {{.CsrfTokenHtml}} + <button + type="submit" + class="ui button mini compact basic icon" + data-tooltip-content="{{ctx.Locale.Tr "repo.issues.cancel_tracking"}}" + >{{svg "octicon-trash"}}</button> + </form> + </div> + </div> + {{end}} + + <a class="item not-mobile tw-mx-0" href="{{AppSubUrl}}/notifications" data-tooltip-content="{{ctx.Locale.Tr "notifications"}}" aria-label="{{ctx.Locale.Tr "notifications"}}"> + <div class="tw-relative"> + {{svg "octicon-bell"}} + <span class="notification_count{{if not $notificationUnreadCount}} tw-hidden{{end}}">{{$notificationUnreadCount}}</span> + </div> + </a> + + <div class="ui dropdown jump item tw-mx-0 tw-pr-2" data-tooltip-content="{{ctx.Locale.Tr "create_new"}}"> + <span class="text"> + {{svg "octicon-plus"}} + <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> + <span class="only-mobile">{{ctx.Locale.Tr "create_new"}}</span> + </span> + <div class="menu"> + <a class="item" href="{{AppSubUrl}}/repo/create"> + {{svg "octicon-plus"}} {{ctx.Locale.Tr "new_repo.link"}} + </a> + {{if not .DisableMigrations}} + <a class="item" href="{{AppSubUrl}}/repo/migrate"> + {{svg "octicon-repo-push"}} {{ctx.Locale.Tr "new_migrate.link"}} + </a> + {{end}} + {{if .SignedUser.CanCreateOrganization}} + <a class="item" href="{{AppSubUrl}}/org/create"> + {{svg "octicon-organization"}} {{ctx.Locale.Tr "new_org.link"}} + </a> + {{end}} + </div><!-- end content create new menu --> + </div><!-- end dropdown menu create new --> + + <div class="ui dropdown jump item tw-mx-0 tw-pr-2" data-tooltip-content="{{ctx.Locale.Tr "user_profile_and_more"}}"> + <span class="text tw-flex tw-items-center"> + {{ctx.AvatarUtils.Avatar .SignedUser 24 "tw-mr-1"}} + <span class="only-mobile tw-ml-2">{{.SignedUser.Name}}</span> + <span class="not-mobile">{{svg "octicon-triangle-down"}}</span> + </span> + <div class="menu user-menu"> + <div class="ui header"> + {{ctx.Locale.Tr "signed_in_as"}} <strong>{{.SignedUser.Name}}</strong> + </div> + + <div class="divider"></div> + <a class="item" href="{{.SignedUser.HomeLink}}"> + {{svg "octicon-person"}} + {{ctx.Locale.Tr "your_profile"}} + </a> + {{if not .DisableStars}} + <a class="item" href="{{.SignedUser.HomeLink}}?tab=stars"> + {{svg "octicon-star"}} + {{ctx.Locale.Tr "your_starred"}} + </a> + {{end}} + <a class="item" href="{{AppSubUrl}}/notifications/subscriptions"> + {{svg "octicon-bell"}} + {{ctx.Locale.Tr "notification.subscriptions"}} + </a> + <a class="{{if .PageIsUserSettings}}active {{end}}item" href="{{AppSubUrl}}/user/settings"> + {{svg "octicon-tools"}} + {{ctx.Locale.Tr "your_settings"}} + </a> + <a class="item" target="_blank" rel="noopener noreferrer" href="https://forgejo.org/docs/latest/"> + {{svg "octicon-question"}} + {{ctx.Locale.Tr "help"}} + </a> + {{if .IsAdmin}} + <div class="divider"></div> + + <a class="{{if .PageIsAdmin}}active {{end}}item" href="{{AppSubUrl}}/admin"> + {{svg "octicon-server"}} + {{ctx.Locale.Tr "admin_panel"}} + </a> + {{end}} + + <div class="divider"></div> + <a class="item link-action" href data-url="{{AppSubUrl}}/user/logout"> + {{svg "octicon-sign-out"}} + {{ctx.Locale.Tr "sign_out"}} + </a> + </div><!-- end content avatar menu --> + </div><!-- end dropdown avatar menu --> + {{else}} + {{if .ShowRegistrationButton}} + <a class="item{{if .PageIsSignUp}} active{{end}}" href="{{AppSubUrl}}/user/sign_up"> + {{svg "octicon-person"}} {{ctx.Locale.Tr "register"}} + </a> + {{end}} + <a class="item{{if .PageIsSignIn}} active{{end}}" rel="nofollow" href="{{AppSubUrl}}/user/login{{if not .PageIsSignIn}}?redirect_to={{.CurrentURL}}{{end}}"> + {{svg "octicon-sign-in"}} {{ctx.Locale.Tr "sign_in"}} + </a> + {{end}} + </div><!-- end full right menu --> +</nav> diff --git a/templates/base/head_opengraph.tmpl b/templates/base/head_opengraph.tmpl new file mode 100644 index 0000000..292c3bd --- /dev/null +++ b/templates/base/head_opengraph.tmpl @@ -0,0 +1,53 @@ +{{- /* og:description - a one to two sentence description of your object, maybe it only needs at most 300 bytes */ -}} +{{if .PageIsUserProfile}} + <meta property="og:title" content="{{.ContextUser.DisplayName}}"> + <meta property="og:type" content="profile"> + <meta property="og:image" content="{{.ContextUser.AvatarLink ctx}}"> + <meta property="og:url" content="{{.ContextUser.HTMLURL}}"> + {{if .ContextUser.Description}} + <meta property="og:description" content="{{StringUtils.EllipsisString .ContextUser.Description 300}}"> + {{end}} +{{else if .Repository}} + {{if .Issue}} + <meta property="og:title" content="{{.Issue.Title}}"> + <meta property="og:url" content="{{.Issue.HTMLURL}}"> + {{if .Issue.Content}} + <meta property="og:description" content="{{StringUtils.EllipsisString .Issue.Content 300}}"> + {{end}} + {{else if or .PageIsDiff .IsViewFile}} + <meta property="og:title" content="{{.Title}}"> + <meta property="og:url" content="{{AppUrl}}{{.Link}}"> + {{if and .PageIsDiff .Commit}} + {{- $commitMessageParts := StringUtils.Cut .Commit.Message "\n" -}} + {{- $commitMessageBody := index $commitMessageParts 1 -}} + {{- if $commitMessageBody -}} + <meta property="og:description" content="{{StringUtils.EllipsisString $commitMessageBody 300}}"> + {{- end -}} + {{end}} + {{else if .Pages}} + <meta property="og:title" content="{{.Title}}"> + <meta property="og:url" content="{{AppUrl}}{{.Link}}"> + {{if .Repository.Description}} + <meta property="og:description" content="{{StringUtils.EllipsisString .Repository.Description 300}}"> + {{end}} + {{else}} + <meta property="og:title" content="{{.Repository.Name}}"> + <meta property="og:url" content="{{.Repository.HTMLURL}}"> + {{if .Repository.Description}} + <meta property="og:description" content="{{StringUtils.EllipsisString .Repository.Description 300}}"> + {{end}} + {{end}} + <meta property="og:type" content="object"> + {{if (.Repository.AvatarLink ctx)}} + <meta property="og:image" content="{{.Repository.AvatarLink ctx}}"> + {{else}} + <meta property="og:image" content="{{.Repository.Owner.AvatarLink ctx}}"> + {{end}} +{{else}} + <meta property="og:title" content="{{AppDisplayName}}"> + <meta property="og:type" content="website"> + <meta property="og:image" content="{{AssetUrlPrefix}}/img/logo.png"> + <meta property="og:url" content="{{AppUrl}}"> + <meta property="og:description" content="{{MetaDescription}}"> +{{end}} +<meta property="og:site_name" content="{{AppDisplayName}}"> diff --git a/templates/base/head_script.tmpl b/templates/base/head_script.tmpl new file mode 100644 index 0000000..22e08e9 --- /dev/null +++ b/templates/base/head_script.tmpl @@ -0,0 +1,50 @@ +{{/* +==== 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> + {{/* before our JS code gets loaded, use arrays to store errors, then the arrays will be switched to our error handler later */}} + window.addEventListener('error', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);}); + window.addEventListener('unhandledrejection', function(e) {window._globalHandlerErrors=window._globalHandlerErrors||[]; window._globalHandlerErrors.push(e);}); + window.config = { + appUrl: '{{AppUrl}}', + appSubUrl: '{{AppSubUrl}}', + assetVersionEncoded: encodeURIComponent('{{AssetVersion}}'), // will be used in URL construction directly + assetUrlPrefix: '{{AssetUrlPrefix}}', + runModeIsProd: {{.RunModeIsProd}}, + customEmojis: {{CustomEmojis}}, + csrfToken: '{{.CsrfToken}}', + pageData: {{.PageData}}, + notificationSettings: {{NotificationSettings}}, {{/*a map provided by NewFuncMap in helper.go*/}} + enableTimeTracking: {{EnableTimetracking}}, + {{if or .Participants .Assignees .MentionableTeams}} + mentionValues: Array.from(new Map([ + {{- range .Participants -}} + ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], + {{- end -}} + {{- range .Assignees -}} + ['{{.Name}}', {key: '{{.Name}} {{.FullName}}', value: '{{.Name}}', name: '{{.Name}}', fullname: '{{.FullName}}', avatar: '{{.AvatarLink $.Context}}'}], + {{- 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: {{ctx.Locale.Tr "copy_success"}}, + copy_error: {{ctx.Locale.Tr "copy_error"}}, + error_occurred: {{ctx.Locale.Tr "error.occurred"}}, + network_error: {{ctx.Locale.Tr "error.network_error"}}, + remove_label_str: {{ctx.Locale.Tr "remove_label_str"}}, + modal_confirm: {{ctx.Locale.Tr "modal.confirm"}}, + modal_cancel: {{ctx.Locale.Tr "modal.cancel"}}, + more_items: {{ctx.Locale.Tr "more_items"}}, + }, + }; + {{/* 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> +<script src="{{AssetUrlPrefix}}/js/webcomponents.js?v={{AssetVersion}}"></script> diff --git a/templates/base/head_style.tmpl b/templates/base/head_style.tmpl new file mode 100644 index 0000000..0793eac --- /dev/null +++ b/templates/base/head_style.tmpl @@ -0,0 +1,2 @@ +<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/index.css?v={{AssetVersion}}"> +<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/theme-{{ThemeName .SignedUser | PathEscape}}.css?v={{AssetVersion}}"> diff --git a/templates/base/modal_actions_confirm.tmpl b/templates/base/modal_actions_confirm.tmpl new file mode 100644 index 0000000..c44320d --- /dev/null +++ b/templates/base/modal_actions_confirm.tmpl @@ -0,0 +1,35 @@ +{{/* +Two buttons (negative, positive): +* ModalButtonTypes: "yes" (default) or "confirm" +* ModalButtonColors: "primary" (default) / "blue" / "yellow" +* ModalButtonCancelText +* ModalButtonOkText + +Single danger button (GitHub-like): +* ModalButtonDangerText "This action will destroy your data" + +The ".ok.button" and ".cancel.button" selectors are also used by Fomantic Modal internally +*/}} +<div class="actions"> + {{if .ModalButtonDangerText}} + <button class="ui danger red ok button">{{.ModalButtonDangerText}}</button> + {{else}} + {{$textNegitive := ctx.Locale.Tr "modal.no"}} + {{$textPositive := ctx.Locale.Tr "modal.yes"}} + {{if eq .ModalButtonTypes "confirm"}} + {{$textNegitive = ctx.Locale.Tr "modal.cancel"}} + {{$textPositive = ctx.Locale.Tr "modal.confirm"}} + {{end}} + {{if .ModalButtonCancelText}}{{$textNegitive = .ModalButtonCancelText}}{{end}} + {{if .ModalButtonOkText}}{{$textPositive = .ModalButtonOkText}}{{end}} + + {{$stylePositive := "primary"}} + {{if eq .ModalButtonColors "blue"}} + {{$stylePositive = "blue"}} + {{else if eq .ModalButtonColors "yellow"}} + {{$stylePositive = "yellow"}} + {{end}} + <button class="ui cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button> + <button class="ui {{$stylePositive}} ok button">{{svg "octicon-check"}} {{$textPositive}}</button> + {{end}} +</div> diff --git a/templates/base/paginate.tmpl b/templates/base/paginate.tmpl new file mode 100644 index 0000000..2ca72f6 --- /dev/null +++ b/templates/base/paginate.tmpl @@ -0,0 +1,34 @@ +{{$paginationParams := .Page.GetParams}} +{{$paginationLink := $.Link}} +{{if eq $paginationLink AppSubUrl}}{{$paginationLink = print $paginationLink "/"}}{{end}} +{{with .Page.Paginater}} + {{if gt .TotalPages 1}} + <div class="center page buttons"> + <div class="ui borderless pagination menu"> + <a class="{{if .IsFirst}}disabled{{end}} item navigation" {{if not .IsFirst}}href="{{$paginationLink}}{{if $paginationParams}}?{{$paginationParams}}{{end}}"{{end}}> + {{svg "gitea-double-chevron-left" 16 "tw-mr-1"}} + <span class="navigation_label">{{ctx.Locale.Tr "admin.first_page"}}</span> + </a> + <a class="{{if not .HasPrevious}}disabled{{end}} item navigation" {{if .HasPrevious}}href="{{$paginationLink}}?page={{.Previous}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> + {{svg "octicon-chevron-left" 16 "tw-mr-1"}} + <span class="navigation_label">{{ctx.Locale.Tr "repo.issues.previous"}}</span> + </a> + {{range .Pages}} + {{if eq .Num -1}} + <a class="disabled item">...</a> + {{else}} + <a class="{{if .IsCurrent}}active {{end}}item tw-items-center" {{if not .IsCurrent}}href="{{$paginationLink}}?page={{.Num}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}>{{.Num}}</a> + {{end}} + {{end}} + <a class="{{if not .HasNext}}disabled{{end}} item navigation" {{if .HasNext}}href="{{$paginationLink}}?page={{.Next}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> + <span class="navigation_label">{{ctx.Locale.Tr "repo.issues.next"}}</span> + {{svg "octicon-chevron-right" 16 "tw-ml-1"}} + </a> + <a class="{{if .IsLast}}disabled{{end}} item navigation" {{if not .IsLast}}href="{{$paginationLink}}?page={{.TotalPages}}{{if $paginationParams}}&{{$paginationParams}}{{end}}"{{end}}> + <span class="navigation_label">{{ctx.Locale.Tr "admin.last_page"}}</span> + {{svg "gitea-double-chevron-right" 16 "tw-ml-1"}} + </a> + </div> + </div> + {{end}} +{{end}} |