Compare commits

...

7 Commits

Author SHA1 Message Date
Denys Konovalov
e58035d03a
Merge 97727a5e889109378fb7e7c86140a5216ef85e21 into dd1fd89185103958cb504e362df91fd2f7856939 2025-07-02 09:48:16 +08:00
Giteabot
97727a5e88
Merge branch 'main' into feat/flexbox-commit-list 2025-06-30 09:52:46 +08:00
Denys Konovalov
074f22c254 Merge branch 'feat/flexbox-commit-list' of ssh://github.com/denyskon/gitea into feat/flexbox-commit-list 2025-06-29 21:30:21 +02:00
Denys Konovalov
b12b135296 Fix tests 2025-06-29 21:29:18 +02:00
Denys Konovalov
8415d77327
Merge branch 'main' into feat/flexbox-commit-list 2025-06-29 20:54:05 +02:00
Denys Konovalov
6183ed41fd Fix expand commit message 2025-06-29 20:52:51 +02:00
Denys Konovalov
3807b2f629 Refactor commit list to flex-item 2025-06-29 20:32:53 +02:00
8 changed files with 87 additions and 154 deletions

View File

@ -1,89 +1,79 @@
<div class="ui attached table segment commit-table"> <div class="ui attached table segment commit-table">
<table class="ui very basic striped table unstackable" id="commits-table"> <div class="flex-list">
<thead> {{$commitRepoLink := $.RepoLink}}{{if $.CommitRepoLink}}{{$commitRepoLink = $.CommitRepoLink}}{{end}}
<tr> {{range .Commits}}
<th class="three wide">{{ctx.Locale.Tr "repo.commits.author"}}</th> <div class="flex-item tw-p-2 tw-items-center">
<th class="two wide sha">{{StringUtils.ToUpper $.Repository.ObjectFormatName}}</th> <div class="flex-item-main">
<th class="eight wide message">{{ctx.Locale.Tr "repo.commits.message"}}</th> <div class="flex-item-title">
<th class="two wide tw-text-right">{{ctx.Locale.Tr "repo.commits.date"}}</th>
<th class="one wide"></th>
</tr>
</thead>
<tbody class="commit-list">
{{$commitRepoLink := $.RepoLink}}{{if $.CommitRepoLink}}{{$commitRepoLink = $.CommitRepoLink}}{{end}}
{{range .Commits}}
<tr>
<td class="author">
<div class="tw-flex">
{{$userName := .Author.Name}}
{{if .User}}
{{if and .User.FullName DefaultShowFullName}}
{{$userName = .User.FullName}}
{{end}}
{{ctx.AvatarUtils.Avatar .User 28 "tw-mr-2"}}<a class="muted author-wrapper" href="{{.User.HomeLink}}">{{$userName}}</a>
{{else}}
{{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}}
<span class="author-wrapper">{{$userName}}</span>
{{end}}
</div>
</td>
<td class="sha">
{{$commitBaseLink := ""}}
{{if $.PageIsWiki}}
{{$commitBaseLink = printf "%s/wiki/commit" $commitRepoLink}}
{{else if $.PageIsPullCommits}}
{{$commitBaseLink = printf "%s/pulls/%d/commits" $commitRepoLink $.Issue.Index}}
{{else if $.Reponame}}
{{$commitBaseLink = printf "%s/commit" $commitRepoLink}}
{{end}}
{{template "repo/commit_sign_badge" dict "Commit" . "CommitBaseLink" $commitBaseLink "CommitSignVerification" .Verification}}
</td>
<td class="message">
<span class="message-wrapper"> <span class="message-wrapper">
{{if $.PageIsWiki}} {{if $.PageIsWiki}}
<span class="commit-summary {{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{.Summary | ctx.RenderUtils.RenderEmoji}}</span> <span class="commit-summary {{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{.Summary | ctx.RenderUtils.RenderEmoji}}</span>
{{else}} {{else}}
{{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}} {{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}}
<span class="commit-summary {{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink $.Repository}}</span> <span class="commit-summary {{if gt .ParentCount 1}} grey text{{end}}" title="{{.Summary}}">{{ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink $.Repository}}</span>
{{end}} {{end}}
</span> </span>
{{if IsMultilineCommitMessage .Message}} {{if IsMultilineCommitMessage .Message}}
<button class="ui button ellipsis-button" aria-expanded="false" data-global-click="onRepoEllipsisButtonClick">...</button> <button class="ui button ellipsis-button" aria-expanded="false" data-global-click="onRepoEllipsisButtonClick">...</button>
{{end}} {{end}}
<div class="sha">
{{$commitBaseLink := ""}}
{{if $.PageIsWiki}}
{{$commitBaseLink = printf "%s/wiki/commit" $commitRepoLink}}
{{else if $.PageIsPullCommits}}
{{$commitBaseLink = printf "%s/pulls/%d/commits" $commitRepoLink $.Issue.Index}}
{{else if $.Reponame}}
{{$commitBaseLink = printf "%s/commit" $commitRepoLink}}
{{end}}
{{template "repo/commit_sign_badge" dict "Commit" . "CommitBaseLink" $commitBaseLink "CommitSignVerification" .Verification}}
</div>
{{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}}
{{if IsMultilineCommitMessage .Message}}
<pre class="commit-body tw-hidden">{{ctx.RenderUtils.RenderCommitBody .Message $.Repository}}</pre>
{{end}}
{{if $.CommitsTagsMap}} {{if $.CommitsTagsMap}}
{{range (index $.CommitsTagsMap .ID.String)}} {{range (index $.CommitsTagsMap .ID.String)}}
{{- template "repo/tag/name" dict "RepoLink" $.Repository.Link "TagName" .TagName "IsRelease" (not .IsTag) -}} {{- template "repo/tag/name" dict "RepoLink" $.Repository.Link "TagName" .TagName "IsRelease" (not .IsTag) -}}
{{end}} {{end}}
{{end}} {{end}}
</td> </div>
{{if .Committer}} {{if IsMultilineCommitMessage .Message}}
<td class="tw-text-right">{{DateUtils.TimeSince .Committer.When}}</td> <pre class="commit-body tw-hidden">{{ctx.RenderUtils.RenderCommitBody .Message $.Repository}}</pre>
{{else}}
<td class="tw-text-right">{{DateUtils.TimeSince .Author.When}}</td>
{{end}} {{end}}
<td class="tw-text-right tw-py-0"> <div class="flex-item-body">
<button class="btn interact-bg tw-p-2 copy-commit-id" data-tooltip-content="{{ctx.Locale.Tr "copy_hash"}}" data-clipboard-text="{{.ID}}">{{svg "octicon-copy"}}</button> {{$userName := .Author.Name}}
{{/* at the moment, wiki doesn't support these "view" links like "view at history point" */}} {{if .User}}
{{if not $.PageIsWiki}} {{if and .User.FullName DefaultShowFullName}}
{{/* view single file diff */}} {{$userName = .User.FullName}}
{{if $.FileTreePath}}
<a class="btn interact-bg tw-p-2 view-single-diff" data-tooltip-content="{{ctx.Locale.Tr "repo.commits.view_file_diff"}}"
href="{{$commitRepoLink}}/commit/{{.ID.String}}?files={{$.FileTreePath}}"
>{{svg "octicon-file-diff"}}</a>
{{end}} {{end}}
{{ctx.AvatarUtils.Avatar .User 20}}
{{/* view at history point */}} <a class="muted author-wrapper" href="{{.User.HomeLink}}">{{$userName}}</a>
{{$viewCommitLink := printf "%s/src/commit/%s" $commitRepoLink (PathEscape .ID.String)}} {{else}}
{{if $.FileTreePath}}{{$viewCommitLink = printf "%s/%s" $viewCommitLink (PathEscapeSegments $.FileTreePath)}}{{end}} {{ctx.AvatarUtils.AvatarByEmail .Author.Email .Author.Name 28 "tw-mr-2"}}
<a class="btn interact-bg tw-p-2 view-commit-path" data-tooltip-content="{{ctx.Locale.Tr "repo.commits.view_path"}}" href="{{$viewCommitLink}}">{{svg "octicon-file-code"}}</a> <span class="author-wrapper">{{$userName}}</span>
{{end}} {{end}}
</td> {{if .Committer}}
</tr> {{DateUtils.TimeSince .Committer.When}}
{{end}} {{else}}
</tbody> {{DateUtils.TimeSince .Author.When}}
</table> {{end}}
</div>
</div>
<div class="flex-item-trailing">
<button class="btn interact-bg tw-p-2 copy-commit-id" data-tooltip-content="{{ctx.Locale.Tr "copy_hash"}}" data-clipboard-text="{{.ID}}">{{svg "octicon-copy"}}</button>
{{/* at the moment, wiki doesn't support these "view" links like "view at history point" */}}
{{if not $.PageIsWiki}}
{{/* view single file diff */}}
{{if $.FileTreePath}}
<a class="btn interact-bg tw-p-2 view-single-diff" data-tooltip-content="{{ctx.Locale.Tr "repo.commits.view_file_diff"}}"
href="{{$commitRepoLink}}/commit/{{.ID.String}}?files={{$.FileTreePath}}"
>{{svg "octicon-file-diff"}}</a>
{{end}}
{{/* view at history point */}}
{{$viewCommitLink := printf "%s/src/commit/%s" $commitRepoLink (PathEscape .ID.String)}}
{{if $.FileTreePath}}{{$viewCommitLink = printf "%s/%s" $viewCommitLink (PathEscapeSegments $.FileTreePath)}}{{end}}
<a class="btn interact-bg tw-p-2 view-commit-path" data-tooltip-content="{{ctx.Locale.Tr "repo.commits.view_path"}}" href="{{$viewCommitLink}}">{{svg "octicon-file-code"}}</a>
{{end}}
</div>
</div>
{{end}}
</div>
</div> </div>

View File

@ -708,7 +708,7 @@ func doAutoPRMerge(baseCtx *APITestContext, dstPath string) func(t *testing.T) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
// Get first commit URL // Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") commitURL, exists := doc.doc.Find(".commit-table .flex-list .flex-item .sha a").Last().Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)

View File

@ -50,7 +50,7 @@ func TestPullCreate_CommitStatus(t *testing.T) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
// Get first commit URL // Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") commitURL, exists := doc.doc.Find(".commit-table .flex-list .flex-item .sha a").Last().Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
@ -88,12 +88,12 @@ func TestPullCreate_CommitStatus(t *testing.T) {
resp = session.MakeRequest(t, req, http.StatusOK) resp = session.MakeRequest(t, req, http.StatusOK)
doc = NewHTMLParser(t, resp.Body) doc = NewHTMLParser(t, resp.Body)
commitURL, exists = doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") commitURL, exists = doc.doc.Find(".commit-table .flex-list .flex-item .sha a").Last().Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
assert.Equal(t, commitID, path.Base(commitURL)) assert.Equal(t, commitID, path.Base(commitURL))
cls, ok := doc.doc.Find("#commits-table tbody tr td.message .commit-status").Last().Attr("class") cls, ok := doc.doc.Find(".commit-table .flex-list .flex-item .flex-item-title .commit-status").Last().Attr("class")
assert.True(t, ok) assert.True(t, ok)
assert.Contains(t, cls, statesIcons[status]) assert.Contains(t, cls, statesIcons[status])
} }

View File

@ -22,7 +22,7 @@ func testRepoCommitsSearch(t *testing.T, query, commit string) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
sel := doc.doc.Find("#commits-table tbody tr td.sha a") sel := doc.doc.Find(".commit-table .flex-list .flex-item .sha a")
assert.Equal(t, commit, strings.TrimSpace(sel.Text())) assert.Equal(t, commit, strings.TrimSpace(sel.Text()))
} }

View File

@ -32,7 +32,7 @@ func TestRepoCommits(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
commitURL, exists := doc.doc.Find("#commits-table .commit-id-short").Attr("href") commitURL, exists := doc.doc.Find(".commit-table .commit-id-short").Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
} }
@ -45,14 +45,14 @@ func Test_ReposGitCommitListNotMaster(t *testing.T) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
var commits []string var commits []string
doc.doc.Find("#commits-table .commit-id-short").Each(func(i int, s *goquery.Selection) { doc.doc.Find(".commit-table .commit-id-short").Each(func(i int, s *goquery.Selection) {
commitURL, _ := s.Attr("href") commitURL, _ := s.Attr("href")
commits = append(commits, path.Base(commitURL)) commits = append(commits, path.Base(commitURL))
}) })
assert.Equal(t, []string{"69554a64c1e6030f051e5c3f94bfbd773cd6a324", "27566bd5738fc8b4e3fef3c5e72cce608537bd95", "5099b81332712fe655e34e8dd63574f503f61811"}, commits) assert.Equal(t, []string{"69554a64c1e6030f051e5c3f94bfbd773cd6a324", "27566bd5738fc8b4e3fef3c5e72cce608537bd95", "5099b81332712fe655e34e8dd63574f503f61811"}, commits)
var userHrefs []string var userHrefs []string
doc.doc.Find("#commits-table .author-wrapper").Each(func(i int, s *goquery.Selection) { doc.doc.Find(".commit-table .author-wrapper").Each(func(i int, s *goquery.Selection) {
userHref, _ := s.Attr("href") userHref, _ := s.Attr("href")
userHrefs = append(userHrefs, userHref) userHrefs = append(userHrefs, userHref)
}) })
@ -70,7 +70,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
// Get first commit URL // Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table .commit-id-short").Attr("href") commitURL, exists := doc.doc.Find(".commit-table .commit-id-short").Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
@ -88,7 +88,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
doc = NewHTMLParser(t, resp.Body) doc = NewHTMLParser(t, resp.Body)
// Check if commit status is displayed in message column (.tippy-target to ignore the tippy trigger) // Check if commit status is displayed in message column (.tippy-target to ignore the tippy trigger)
sel := doc.doc.Find("#commits-table .message .tippy-target .commit-status") sel := doc.doc.Find(".commit-table .flex-item-title .tippy-target .commit-status")
assert.Equal(t, 1, sel.Length()) assert.Equal(t, 1, sel.Length())
for _, class := range classes { for _, class := range classes {
assert.True(t, sel.HasClass(class)) assert.True(t, sel.HasClass(class))
@ -164,7 +164,7 @@ func TestRepoCommitsStatusParallel(t *testing.T) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
// Get first commit URL // Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table .commit-id-short").Attr("href") commitURL, exists := doc.doc.Find(".commit-table .commit-id-short").Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
@ -199,7 +199,7 @@ func TestRepoCommitsStatusMultiple(t *testing.T) {
doc := NewHTMLParser(t, resp.Body) doc := NewHTMLParser(t, resp.Body)
// Get first commit URL // Get first commit URL
commitURL, exists := doc.doc.Find("#commits-table .commit-id-short").Attr("href") commitURL, exists := doc.doc.Find(".commit-table .commit-id-short").Attr("href")
assert.True(t, exists) assert.True(t, exists)
assert.NotEmpty(t, commitURL) assert.NotEmpty(t, commitURL)
@ -224,6 +224,6 @@ func TestRepoCommitsStatusMultiple(t *testing.T) {
doc = NewHTMLParser(t, resp.Body) doc = NewHTMLParser(t, resp.Body)
// Check that the data-global-init="initCommitStatuses" (for trigger) and commit-status (svg) are present // Check that the data-global-init="initCommitStatuses" (for trigger) and commit-status (svg) are present
sel := doc.doc.Find(`#commits-table .message [data-global-init="initCommitStatuses"] .commit-status`) sel := doc.doc.Find(`.commit-table .flex-list .flex-item .flex-item-title [data-global-init="initCommitStatuses"] .commit-status`)
assert.Equal(t, 1, sel.Length()) assert.Equal(t, 1, sel.Length())
} }

View File

@ -36,9 +36,9 @@ func TestCommitListActions(t *testing.T) {
req := NewRequest(t, "GET", "/user2/repo1/wiki/Home?action=_revision") req := NewRequest(t, "GET", "/user2/repo1/wiki/Home?action=_revision")
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
AssertHTMLElement(t, htmlDoc, ".commit-list .copy-commit-id", true) AssertHTMLElement(t, htmlDoc, ".commit-table .copy-commit-id", true)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, false) AssertHTMLElement(t, htmlDoc, `.commit-table .view-single-diff`, false)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, false) AssertHTMLElement(t, htmlDoc, `.commit-table .view-commit-path`, false)
}) })
t.Run("RepoCommitList", func(t *testing.T) { t.Run("RepoCommitList", func(t *testing.T) {
@ -48,9 +48,9 @@ func TestCommitListActions(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
AssertHTMLElement(t, htmlDoc, `.commit-list .copy-commit-id`, true) AssertHTMLElement(t, htmlDoc, `.commit-table .copy-commit-id`, true)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, false) AssertHTMLElement(t, htmlDoc, `.commit-table .view-single-diff`, false)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, true) AssertHTMLElement(t, htmlDoc, `.commit-table .view-commit-path`, true)
}) })
t.Run("RepoFileHistory", func(t *testing.T) { t.Run("RepoFileHistory", func(t *testing.T) {
@ -60,8 +60,8 @@ func TestCommitListActions(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK) resp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, resp.Body) htmlDoc := NewHTMLParser(t, resp.Body)
AssertHTMLElement(t, htmlDoc, `.commit-list .copy-commit-id`, true) AssertHTMLElement(t, htmlDoc, `.commit-table .copy-commit-id`, true)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-single-diff`, true) AssertHTMLElement(t, htmlDoc, `.commit-table .view-single-diff`, true)
AssertHTMLElement(t, htmlDoc, `.commit-list .view-commit-path`, true) AssertHTMLElement(t, htmlDoc, `.commit-table .view-commit-path`, true)
}) })
} }

View File

@ -572,12 +572,6 @@ td .commit-summary {
padding-top: 0; padding-top: 0;
} }
.repository.view.issue .comment-list .timeline-item.event > .commit-status-link {
float: right;
margin-right: 8px;
margin-top: 4px;
}
.repository.view.issue .comment-list .timeline-item .comparebox { .repository.view.issue .comment-list .timeline-item .comparebox {
line-height: 32px; line-height: 32px;
vertical-align: middle; vertical-align: middle;
@ -878,17 +872,6 @@ td .commit-summary {
padding: 5px 10px; padding: 5px 10px;
} }
.repository #commits-table td:not(.message) {
white-space: nowrap;
}
.repository #commits-table thead .sha {
width: 200px;
}
.repository #commits-table.ui.basic.striped.table tbody tr:nth-child(2n) {
background-color: var(--color-light) !important;
}
.repository .data-table { .repository .data-table {
width: 100%; width: 100%;
} }
@ -1541,10 +1524,6 @@ td .commit-summary {
min-height: 30px; min-height: 30px;
} }
tbody.commit-list {
vertical-align: baseline;
}
.message-wrapper, .message-wrapper,
.author-wrapper { .author-wrapper {
overflow: hidden; overflow: hidden;
@ -1564,44 +1543,12 @@ tbody.commit-list {
max-width: calc(100% - 2.5rem); max-width: calc(100% - 2.5rem);
} }
/* in the commit list, messages can wrap so we can use inline */
.commit-list .message-wrapper {
display: inline;
overflow-wrap: anywhere;
}
@media (max-width: 767.98px) { @media (max-width: 767.98px) {
tr.commit-list {
width: 100%;
}
.author-wrapper { .author-wrapper {
max-width: 80px; max-width: 80px;
} }
} }
@media (min-width: 768px) and (max-width: 991.98px) {
tr.commit-list {
width: 723px;
}
}
@media (min-width: 992px) and (max-width: 1200px) {
tr.commit-list {
width: 933px;
}
}
@media (min-width: 1201px) {
tr.commit-list {
width: 1127px;
}
}
.commit-list .commit-status-link {
display: inline-block;
vertical-align: middle;
}
.commit-body { .commit-body {
margin: 0.25em 0; margin: 0.25em 0;
white-space: pre-wrap; white-space: pre-wrap;
@ -2010,10 +1957,6 @@ tbody.commit-list {
.commit-table { .commit-table {
overflow-x: auto; overflow-x: auto;
} }
.commit-table td.sha,
.commit-table th.sha {
display: none !important;
}
.comment-header { .comment-header {
flex-wrap: wrap; flex-wrap: wrap;
} }

View File

@ -6,7 +6,7 @@ export function initRepoEllipsisButton() {
registerGlobalEventFunc('click', 'onRepoEllipsisButtonClick', async (el: HTMLInputElement, e: Event) => { registerGlobalEventFunc('click', 'onRepoEllipsisButtonClick', async (el: HTMLInputElement, e: Event) => {
e.preventDefault(); e.preventDefault();
const expanded = el.getAttribute('aria-expanded') === 'true'; const expanded = el.getAttribute('aria-expanded') === 'true';
toggleElem(el.parentElement.querySelector('.commit-body')); toggleElem(el.parentElement.parentElement.querySelector('.commit-body'));
el.setAttribute('aria-expanded', String(!expanded)); el.setAttribute('aria-expanded', String(!expanded));
}); });
} }