Skip to content
Draft
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -574,8 +574,6 @@ export default defineConfig([
'no-restricted-properties': [2, ...restrictedProperties],
'no-restricted-imports': [2, {paths: [
{name: 'jquery', message: 'Use the global $ instead', allowTypeImports: true},
{name: 'htmx.org', message: 'Use the global htmx instead', allowTypeImports: true},
{name: 'idiomorph/htmx', message: 'Loaded in globals.ts', allowTypeImports: true},
]}],
'no-restricted-syntax': [2, 'WithStatement', 'ForInStatement', 'LabeledStatement', 'SequenceExpression'],
'no-return-assign': [0],
Expand Down Expand Up @@ -1022,6 +1020,6 @@ export default defineConfig([
},
{
files: ['web_src/**/*'],
languageOptions: {globals: {...globals.browser, ...globals.jquery, htmx: false}},
languageOptions: {globals: {...globals.browser, ...globals.jquery}},
},
]);
2 changes: 0 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
"dropzone": "6.0.0-beta.2",
"easymde": "2.20.0",
"esbuild": "0.27.4",
"htmx.org": "2.0.8",
"idiomorph": "0.7.4",
"jquery": "4.0.0",
"js-yaml": "4.1.1",
"katex": "0.16.44",
Expand Down
16 changes: 0 additions & 16 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion routers/web/repo/star.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ func ActionStar(ctx *context.Context) {
ctx.ServerError("GetRepositoryByName", err)
return
}
ctx.RespHeader().Add("hx-trigger", "refreshUserCards") // see the `hx-trigger="refreshUserCards ..."` comments in tmpl
ctx.RespHeader().Add("X-Gitea-Dispatch-Event", "refreshUserCards")
ctx.HTML(http.StatusOK, tplStarUnstar)
}
2 changes: 1 addition & 1 deletion routers/web/repo/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ func ActionWatch(ctx *context.Context) {
ctx.ServerError("GetRepositoryByName", err)
return
}
ctx.RespHeader().Add("hx-trigger", "refreshUserCards") // see the `hx-trigger="refreshUserCards ..."` comments in tmpl
ctx.RespHeader().Add("X-Gitea-Dispatch-Event", "refreshUserCards")
ctx.HTML(http.StatusOK, tplWatchUnwatch)
}
10 changes: 5 additions & 5 deletions services/context/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,11 @@ func (b *Base) Redirect(location string, status ...int) {
// So in this case, we should remove the session cookie from the response header
removeSessionCookieHeader(b.Resp)
}
// in case the request is made by htmx, have it redirect the browser instead of trying to follow the redirect inside htmx
if b.Req.Header.Get("HX-Request") == "true" {
b.Resp.Header().Set("HX-Redirect", location)
// we have to return a non-redirect status code so XMLHTTPRequest will not immediately follow the redirect
// so as to give htmx redirect logic a chance to run
// for page-action requests (form-fetch-action with data-swap), return 204 with a redirect header
// instead of a 30x redirect, because fetch() auto-follows redirects and the JS handler needs
// to perform a full navigation instead
if b.Req.Header.Get("X-Gitea-Page-Action") == "true" {
b.Resp.Header().Set("X-Gitea-Redirect", location)
b.Status(http.StatusNoContent)
return
}
Expand Down
4 changes: 2 additions & 2 deletions services/context/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ func TestRedirect(t *testing.T) {

req, _ = http.NewRequest(http.MethodGet, "/", nil)
resp := httptest.NewRecorder()
req.Header.Add("HX-Request", "true")
req.Header.Add("X-Gitea-Page-Action", "true")
b := NewBaseContextForTest(resp, req)
b.Redirect("/other")
assert.Equal(t, "/other", resp.Header().Get("HX-Redirect"))
assert.Equal(t, "/other", resp.Header().Get("X-Gitea-Redirect"))
assert.Equal(t, http.StatusNoContent, resp.Code)
}
2 changes: 1 addition & 1 deletion services/gitdiff/gitdiff.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ func (d *DiffLine) RenderBlobExcerptButtons(fileNameHash string, data *DiffBlobE
link += fmt.Sprintf("&pull_issue_index=%d", data.PullIssueIndex)
}
return htmlutil.HTMLFormat(
`<button class="code-expander-button" hx-target="closest tr" hx-get="%s" data-hidden-comment-ids=",%s,">%s</button>`,
`<button class="code-expander-button" data-url="%s" data-hidden-comment-ids=",%s,">%s</button>`,
link, dataHiddenCommentIDs, svg.RenderHTML(svgName),
)
}
Expand Down
3 changes: 1 addition & 2 deletions templates/admin/dashboard.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,7 @@
</h4>
{{/* TODO: make these stats work in multi-server deployments, likely needs per-server stats in DB */}}
<div class="ui attached table segment">
<div class="no-loading-indicator tw-hidden"></div>
<div hx-get="{{$.Link}}/system_status" hx-swap="morph:innerHTML" hx-trigger="every 5s" hx-indicator=".no-loading-indicator">
<div data-global-init="initAdminSystemStatus" data-poll-url="{{$.Link}}/system_status">
{{template "admin/system_status" .}}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion templates/base/head.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
{{template "base/head_script" .}}
{{template "custom/header" .}}
</head>
<body hx-swap="outerHTML" hx-ext="morph" hx-push-url="false">
<body>
{{template "custom/body_outer_pre" .}}

<div class="full height">
Expand Down
16 changes: 9 additions & 7 deletions templates/org/follow_unfollow.tmpl
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<button class="ui basic button tw-mr-0" hx-post="{{.Org.HomeLink}}?action={{if $.IsFollowing}}unfollow{{else}}follow{{end}}">
{{if $.IsFollowing}}
{{ctx.Locale.Tr "user.unfollow"}}
{{else}}
{{ctx.Locale.Tr "user.follow"}}
{{end}}
</button>
<form class="form-fetch-action" data-swap="this" method="post" action="{{.Org.HomeLink}}?action={{if $.IsFollowing}}unfollow{{else}}follow{{end}}">
<button type="submit" class="ui basic button tw-mr-0">
{{if $.IsFollowing}}
{{ctx.Locale.Tr "user.unfollow"}}
{{else}}
{{ctx.Locale.Tr "user.follow"}}
{{end}}
</button>
</form>
2 changes: 1 addition & 1 deletion templates/repo/actions/workflow_dispatch.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<label>{{ctx.Locale.Tr "actions.workflow.from_ref"}}:</label>
</span>
<div class="ui inline field dropdown button select-branch branch-selector-dropdown ellipsis-text-items">
<input type="hidden" name="ref" hx-sync="this:replace" hx-target="#runWorkflowDispatchModalInputs" hx-swap="innerHTML" hx-get="{{$.Link}}/workflow-dispatch-inputs?workflow={{$.CurWorkflow}}" hx-trigger="change" value="refs/heads/{{index .Branches 0}}">
<input type="hidden" name="ref" data-global-init="initWorkflowDispatchRef" data-dispatch-url="{{$.Link}}/workflow-dispatch-inputs?workflow={{$.CurWorkflow}}" data-target="#runWorkflowDispatchModalInputs" value="refs/heads/{{index .Branches 0}}">
{{svg "octicon-git-branch" 14}}
<div class="default text">{{index .Branches 0}}</div>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/actions/workflow_dispatch_inputs.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
<div class="ui field {{if .Required}}required{{end}}">
{{if eq .Type "choice"}}
<label>{{or .Description .Name}}:</label>
{{/* htmx won't initialize the fomantic dropdown, so it is a standard "select" input */}}
{{/* this content is dynamically loaded, so use a standard "select" instead of fomantic dropdown */}}
<select class="ui selection dropdown" name="{{.Name}}">
{{range .Options}}
<option value="{{.}}" {{if eq $item.Default .}}selected{{end}}>{{.}}</option>
{{end}}
</select>
{{else if eq .Type "boolean"}}
{{/* htmx doesn't trigger our JS code to attach fomantic label to checkbox, so here we use standard checkbox */}}
{{/* this content is dynamically loaded, so use a standard checkbox instead of fomantic */}}
<label class="tw-flex flex-text-inline">
<input type="checkbox" name="{{.Name}}" {{if eq .Default "true"}}checked{{end}}>
{{or .Description .Name}}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/editor/edit.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<a class="active item" data-tab="write">{{svg "octicon-code"}} {{if .IsNewFile}}{{ctx.Locale.Tr "repo.editor.new_file"}}{{else}}{{ctx.Locale.Tr "repo.editor.edit_file"}}{{end}}</a>
<a class="item{{if not .CodeEditorConfig.Previewable}} tw-hidden{{end}}" data-tab="preview" data-preview-url="{{.Repository.Link}}/markup" data-preview-context-ref="{{.RepoLink}}/src/{{.RefTypeNameSubURL}}">{{svg "octicon-eye"}} {{ctx.Locale.Tr "preview"}}</a>
{{if not .IsNewFile}}
<a class="item" data-tab="diff" hx-params="context,content" hx-vals='{"context":"{{.BranchLink}}"}' hx-include="#edit_area" hx-swap="innerHTML" hx-target=".tab[data-tab='diff']" hx-indicator=".tab[data-tab='diff']" hx-post="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
<a class="item" data-tab="diff" data-diff-url="{{.RepoLink}}/_preview/{{.BranchName | PathEscapeSegments}}/{{.TreePath | PathEscapeSegments}}" data-diff-context="{{.BranchLink}}">{{svg "octicon-diff"}} {{ctx.Locale.Tr "repo.editor.preview_changes"}}</a>
{{end}}
</div>
{{template "repo/editor/options" dict "CodeEditorConfig" $.CodeEditorConfig}}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/issue/view_content/watching.tmpl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<form hx-boost="true" hx-sync="this:replace" hx-target="this" method="post" action="{{.Issue.Link}}/watch">
<form class="form-fetch-action" data-swap="this" method="post" action="{{.Issue.Link}}/watch">
<input type="hidden" name="watch" value="{{if $.IssueWatch.IsWatching}}0{{else}}1{{end}}">
<button class="fluid ui button">
{{if $.IssueWatch.IsWatching}}
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/star_unstar.tmpl
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<form class="flex-text-inline" hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}unstar{{else}}star{{end}}">
<form class="flex-text-inline form-fetch-action" data-swap="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsStaringRepo}}unstar{{else}}star{{end}}">
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.star_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.star"}}
{{if $.IsStaringRepo}}{{$buttonText = ctx.Locale.Tr "repo.unstar"}}{{end}}
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg (Iif $.IsStaringRepo "octicon-star-fill" "octicon-star")}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{$.RepoLink}}/stars">
<a class="ui basic label" href="{{$.RepoLink}}/stars">
{{CountFmt .Repository.NumStars}}
</a>
</div>
Expand Down
12 changes: 1 addition & 11 deletions templates/repo/user_cards.tmpl
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
<!-- Refresh the content if a htmx response contains "HX-Trigger" header.
This usually happens when a user stays on the watchers/stargazers page
when they watched/unwatched/starred/unstarred and the list should be refreshed.
To test go to the watchers page and click the watch button. The user cards should reload.
At the moment, no JS initialization would re-trigger (fortunately there is no JS for this page).
-->
<div class="no-loading-indicator tw-hidden"></div>
<div class="user-cards"
hx-trigger="refreshUserCards from:body" hx-indicator=".no-loading-indicator"
hx-get="" hx-swap="outerHTML" hx-select=".user-cards"
>
<div class="user-cards">
{{if .CardsTitle}}
<h2 class="ui dividing header">
{{.CardsTitle}}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/view_list.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{/* use grid layout, still use the old ID because there are many other CSS styles depending on this ID */}}
<div id="repo-files-table" {{if .HasFilesWithoutLatestCommit}}hx-indicator="#repo-files-table .repo-file-cell.message" hx-trigger="load" hx-swap="morph" hx-post="{{.LastCommitLoaderURL}}"{{end}}>
<div id="repo-files-table" {{if .HasFilesWithoutLatestCommit}}data-global-init="initLastCommitLoader" data-loader-url="{{.LastCommitLoaderURL}}"{{end}}>
<div class="repo-file-line repo-file-last-commit">
{{template "repo/latest_commit" .}}
<div>{{if and .LatestCommit .LatestCommit.Committer}}{{DateUtils.TimeSince .LatestCommit.Committer.When}}{{end}}</div>
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/watch_unwatch.tmpl
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<form class="flex-text-inline" hx-boost="true" hx-target="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}unwatch{{else}}watch{{end}}">
<form class="flex-text-inline form-fetch-action" data-swap="this" method="post" action="{{$.RepoLink}}/action/{{if $.IsWatchingRepo}}unwatch{{else}}watch{{end}}">
<div class="ui labeled button" {{if not $.IsSigned}}data-tooltip-content="{{ctx.Locale.Tr "repo.watch_guest_user"}}"{{end}}>
{{$buttonText := ctx.Locale.Tr "repo.watch"}}
{{if $.IsWatchingRepo}}{{$buttonText = ctx.Locale.Tr "repo.unwatch"}}{{end}}
<button type="submit" class="ui compact small basic button"{{if not $.IsSigned}} disabled{{end}} aria-label="{{$buttonText}}">
{{svg "octicon-eye"}}
<span class="not-mobile" aria-hidden="true">{{$buttonText}}</span>
</button>
<a hx-boost="false" class="ui basic label" href="{{.RepoLink}}/watchers">
<a class="ui basic label" href="{{.RepoLink}}/watchers">
{{CountFmt .Repository.NumWatches}}
</a>
</div>
Expand Down
14 changes: 5 additions & 9 deletions templates/shared/user/profile_big_avatar.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -115,16 +115,12 @@
{{end}}
{{if and .IsSigned (ne .SignedUserID .ContextUser.ID)}}
{{if not .UserBlocking}}
<li class="follow" hx-target="#profile-avatar-card" hx-indicator="#profile-avatar-card">
{{if $.IsFollowing}}
<button hx-post="{{.ContextUser.HomeLink}}?action=unfollow" class="ui basic red button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.unfollow"}}
<li class="follow">
<form class="form-fetch-action" data-swap="#profile-avatar-card" method="post" action="{{.ContextUser.HomeLink}}?action={{if $.IsFollowing}}unfollow{{else}}follow{{end}}">
<button type="submit" class="ui basic {{if $.IsFollowing}}red{{else}}primary{{end}} button">
{{svg "octicon-person"}} {{ctx.Locale.Tr (Iif $.IsFollowing "user.unfollow" "user.follow")}}
</button>
{{else}}
<button hx-post="{{.ContextUser.HomeLink}}?action=follow" class="ui basic primary button">
{{svg "octicon-person"}} {{ctx.Locale.Tr "user.follow"}}
</button>
{{end}}
</form>
</li>
{{end}}
<li>
Expand Down
3 changes: 1 addition & 2 deletions templates/user/notification/notification_div.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,7 @@
{{DateUtils.TimeSince $one.UpdatedUnix}}
{{end}}
</div>
<form class="notifications-buttons" action="{{AppSubUrl}}/notifications/status?type={{$.PageType}}&page={{$.Page.Paginater.Current}}&perPage={{$.Page.Paginater.PagingNum}}" method="post"
hx-boost="true" hx-target="#notification_div" hx-swap="outerHTML"
<form class="notifications-buttons form-fetch-action" data-swap="#notification_div" action="{{AppSubUrl}}/notifications/status?type={{$.PageType}}&page={{$.Page.Paginater.Current}}&perPage={{$.Page.Paginater.PagingNum}}" method="post"
>
<input type="hidden" name="notification_id" value="{{$one.ID}}">
{{if ne $one.Status $statusPinned}}
Expand Down
Loading
Loading