[Port] gitea#30014: Various code view improvements
1. Restore missing styles for message close icon 2. Move `code-line-button` so that it does not go off-screen on small viewports 3. Make `code-line-button` look and behave like other buttons 4. Make `code-line-button` work in blame 5. Make the active selection span the whole line, not just the code part 6. Tweak colors, make dark theme code bg darker, make line numbers same color in diff and file view. 7. Move code background to parent, fixing border radius and other problems 8. Enable code wrap in blame 9. Improve blame responsiveness 10. Remove `--color-code-sidebar-bg` in blame, now it uses same background as code 11. Rename `--color-active-line` to `--color-highlight-bg` 12. Add `--color-highlight-bg` 13. Fix button group borders on hover and border-right on last button. <img width="1343" alt="Screenshot 2024-03-23 at 22 34 13" src="https://github.com/go-gitea/gitea/assets/115237/fcbb919f-5dc3-43f0-97f6-870d6f412554"> <img width="1334" alt="Screenshot 2024-03-23 at 22 34 26" src="https://github.com/go-gitea/gitea/assets/115237/ca44c3b7-4328-4645-ba49-b0dc6a5ac06d"> <img width="1338" alt="Screenshot 2024-03-23 at 22 34 57" src="https://github.com/go-gitea/gitea/assets/115237/00eb0b5a-1ec7-4669-a94a-4602b9d1c1ac"> <img width="1337" alt="Screenshot 2024-03-23 at 22 34 42" src="https://github.com/go-gitea/gitea/assets/115237/752edc4a-064f-413c-9dff-c086187fcd85"> Fixes: https://github.com/go-gitea/gitea/issues/18074 --- Conflict resolution: Trivial. Ref: https://codeberg.org/forgejo/forgejo/issues/2776 (cherry picked from commit db01bf6cc88a8a7b5132b9306b3af1649566b10f)
This commit is contained in:
		
					parent
					
						
							
								1ee494a045
							
						
					
				
			
			
				commit
				
					
						a579a0f318
					
				
			
		
					 12 changed files with 145 additions and 103 deletions
				
			
		| 
						 | 
				
			
			@ -258,7 +258,7 @@ func renderBlame(ctx *context.Context, blameParts []*git.BlamePart, commitNames
 | 
			
		|||
 | 
			
		||||
				var avatar string
 | 
			
		||||
				if commit.User != nil {
 | 
			
		||||
					avatar = string(avatarUtils.Avatar(commit.User, 18, "gt-mr-3"))
 | 
			
		||||
					avatar = string(avatarUtils.Avatar(commit.User, 18))
 | 
			
		||||
				} else {
 | 
			
		||||
					avatar = string(avatarUtils.AvatarByEmail(commit.Author.Email, commit.Author.Name, 18, "gt-mr-3"))
 | 
			
		||||
				}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,13 @@
 | 
			
		|||
<link rel="stylesheet" href="{{AssetUrlPrefix}}/css/devtest.css?v={{AssetVersion}}">
 | 
			
		||||
<div class="page-content devtest ui container">
 | 
			
		||||
	<div>
 | 
			
		||||
		<h1>Link</h1>
 | 
			
		||||
		<div>
 | 
			
		||||
			<a href="#">normal</a>
 | 
			
		||||
			<a class="muted" href="#">muted</a>
 | 
			
		||||
			<a class="suppressed" href="#">suppressed</a>
 | 
			
		||||
			<a class="silenced" href="#">silenced</a>
 | 
			
		||||
		</div>
 | 
			
		||||
		<h1>Button</h1>
 | 
			
		||||
		<div>
 | 
			
		||||
			Style:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -50,11 +50,11 @@
 | 
			
		|||
											{{$row.Avatar}}
 | 
			
		||||
										</div>
 | 
			
		||||
										<div class="blame-message">
 | 
			
		||||
											<a href="{{$row.CommitURL}}" title="{{$row.CommitMessage}}">
 | 
			
		||||
											<a class="suppressed tw-text-text" href="{{$row.CommitURL}}" title="{{$row.CommitMessage}}">
 | 
			
		||||
												{{$row.CommitMessage}}
 | 
			
		||||
											</a>
 | 
			
		||||
										</div>
 | 
			
		||||
										<div class="blame-time">
 | 
			
		||||
										<div class="blame-time not-mobile">
 | 
			
		||||
											{{$row.CommitSince}}
 | 
			
		||||
										</div>
 | 
			
		||||
									</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -62,7 +62,7 @@
 | 
			
		|||
							</td>
 | 
			
		||||
							<td class="lines-blame-btn">
 | 
			
		||||
								{{if $row.PreviousSha}}
 | 
			
		||||
									<a href="{{$row.PreviousShaURL}}" data-tooltip-content='{{ctx.Locale.Tr "repo.blame_prior"}}'>
 | 
			
		||||
									<a role="button" class="muted" href="{{$row.PreviousShaURL}}" data-tooltip-content='{{ctx.Locale.Tr "repo.blame_prior"}}'>
 | 
			
		||||
										{{svg "octicon-versions"}}
 | 
			
		||||
									</a>
 | 
			
		||||
								{{end}}
 | 
			
		||||
| 
						 | 
				
			
			@ -84,6 +84,12 @@
 | 
			
		|||
					{{end}}
 | 
			
		||||
				</tbody>
 | 
			
		||||
			</table>
 | 
			
		||||
			<div class="code-line-menu tippy-target">
 | 
			
		||||
				{{if $.Permission.CanRead $.UnitTypeIssues}}
 | 
			
		||||
					<a class="item ref-in-new-issue" role="menuitem" data-url-issue-new="{{.RepoLink}}/issues/new" data-url-param-body-link="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}" rel="nofollow noindex">{{ctx.Locale.Tr "repo.issues.context.reference_issue"}}</a>
 | 
			
		||||
				{{end}}
 | 
			
		||||
				<a class="item copy-line-permalink" role="menuitem" data-url="{{.Repository.Link}}/src/commit/{{PathEscape .CommitID}}/{{PathEscapeSegments .TreePath}}{{if $.HasSourceRenderedToggle}}?display=source{{end}}">{{ctx.Locale.Tr "repo.file_copy_permalink"}}</a>
 | 
			
		||||
			</div>
 | 
			
		||||
			{{end}}
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -226,10 +226,14 @@ h1.error-code {
 | 
			
		|||
a {
 | 
			
		||||
  color: var(--color-primary);
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  text-decoration-line: none;
 | 
			
		||||
  text-decoration-skip-ink: all;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a:hover {
 | 
			
		||||
  text-decoration-line: underline;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* a = always colored, underlined on hover */
 | 
			
		||||
/* a.muted = colored on hover, underlined on hover */
 | 
			
		||||
/* a.suppressed = never colored, underlined on hover */
 | 
			
		||||
| 
						 | 
				
			
			@ -256,7 +260,7 @@ a.suppressed:hover {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
a.silenced:hover {
 | 
			
		||||
  text-decoration: none;
 | 
			
		||||
  text-decoration-line: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
a.label,
 | 
			
		||||
| 
						 | 
				
			
			@ -264,7 +268,7 @@ a.label,
 | 
			
		|||
.ui .menu a,
 | 
			
		||||
.ui.cards a.card,
 | 
			
		||||
.issue-keyword a {
 | 
			
		||||
  text-decoration: none !important;
 | 
			
		||||
  text-decoration-line: none !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.search > .results {
 | 
			
		||||
| 
						 | 
				
			
			@ -1433,18 +1437,15 @@ a.ui.active.label:hover {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.lines-blame-btn {
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  text-align: right !important;
 | 
			
		||||
  background-color: var(--color-code-sidebar-bg);
 | 
			
		||||
  width: 2%;
 | 
			
		||||
  padding: 0 0 0 5px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lines-num {
 | 
			
		||||
  padding-left: 10px;
 | 
			
		||||
  padding-right: 10px;
 | 
			
		||||
  padding: 0 8px;
 | 
			
		||||
  text-align: right !important;
 | 
			
		||||
  color: var(--color-text-light-1);
 | 
			
		||||
  color: var(--color-text-light-2);
 | 
			
		||||
  width: 1%;
 | 
			
		||||
  font-family: var(--fonts-monospace);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1498,22 +1499,34 @@ a.ui.active.label:hover {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.lines-code {
 | 
			
		||||
  background-color: var(--color-code-bg);
 | 
			
		||||
  padding-left: 5px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lines-code.active,
 | 
			
		||||
.lines-code .active {
 | 
			
		||||
  background: var(--color-active-line) !important;
 | 
			
		||||
.file-view tr.active {
 | 
			
		||||
  color: inherit !important;
 | 
			
		||||
  background: inherit !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.blame .lines-num {
 | 
			
		||||
  padding: 0 !important;
 | 
			
		||||
  background-color: var(--color-code-sidebar-bg);
 | 
			
		||||
.file-view tr.active .lines-num,
 | 
			
		||||
.file-view tr.active .lines-code {
 | 
			
		||||
  background: var(--color-highlight-bg) !important;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.blame .lines-code {
 | 
			
		||||
  padding: 0 !important;
 | 
			
		||||
.file-view tr.active:last-of-type .lines-code {
 | 
			
		||||
  border-bottom-right-radius: var(--border-radius);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.file-view tr.active .lines-num {
 | 
			
		||||
  position: relative;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.file-view tr.active .lines-num::before {
 | 
			
		||||
  content: "";
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  left: 0;
 | 
			
		||||
  width: 2px;
 | 
			
		||||
  height: 100%;
 | 
			
		||||
  background: var(--color-highlight-fg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code-inner {
 | 
			
		||||
| 
						 | 
				
			
			@ -1524,24 +1537,21 @@ a.ui.active.label:hover {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.blame .code-inner {
 | 
			
		||||
  white-space: pre;
 | 
			
		||||
  word-break: normal;
 | 
			
		||||
  word-wrap: normal; /* not using overflow-wrap because safari does not treat is an an alias */
 | 
			
		||||
  white-space: pre-wrap;
 | 
			
		||||
  overflow-wrap: anywhere;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lines-commit {
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
  color: var(--color-text-light-2);
 | 
			
		||||
  color: var(--color-text-light-1);
 | 
			
		||||
  padding: 0 !important;
 | 
			
		||||
  background: var(--color-code-sidebar-bg);
 | 
			
		||||
  width: 1%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lines-commit .blame-info {
 | 
			
		||||
  width: 350px;
 | 
			
		||||
  max-width: 350px;
 | 
			
		||||
  width: min(26vw, 300px);
 | 
			
		||||
  display: block;
 | 
			
		||||
  padding: 0 0 0 10px;
 | 
			
		||||
  padding: 0 0 0 6px;
 | 
			
		||||
  line-height: 20px;
 | 
			
		||||
  box-sizing: content-box;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1563,11 +1573,10 @@ a.ui.active.label:hover {
 | 
			
		|||
  flex-shrink: 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.lines-commit .ui.avatar {
 | 
			
		||||
  height: 18px;
 | 
			
		||||
  width: 18px;
 | 
			
		||||
  display: block;
 | 
			
		||||
  margin-top: 1px;
 | 
			
		||||
.blame-avatar {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  margin-right: 4px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.top-line-blame {
 | 
			
		||||
| 
						 | 
				
			
			@ -1583,6 +1592,11 @@ a.ui.active.label:hover {
 | 
			
		|||
  border-bottom: 1px solid var(--color-secondary);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code-view {
 | 
			
		||||
  background: var(--color-code-bg);
 | 
			
		||||
  border-radius: var(--border-radius);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code-view table {
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,3 @@
 | 
			
		|||
.chroma {
 | 
			
		||||
  background-color: var(--color-code-bg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* LineTableTD */
 | 
			
		||||
.chroma .lntd {
 | 
			
		||||
  vertical-align: top;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -11,6 +11,7 @@
 | 
			
		|||
.ui.button:focus {
 | 
			
		||||
  background: var(--color-hover);
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
  border-color: var(--color-secondary-dark-2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.page-content .ui.button {
 | 
			
		||||
| 
						 | 
				
			
			@ -63,11 +64,17 @@ It needs some tricks to tweak the left/right borders with active state */
 | 
			
		|||
  border-right: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.buttons .button:first-child {
 | 
			
		||||
.ui.buttons .button:hover + .button {
 | 
			
		||||
  border-left: 1px solid var(--color-secondary-dark-2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.buttons .button:first-child,
 | 
			
		||||
.ui.buttons .button.gt-hidden:first-child + .button {
 | 
			
		||||
  border-left: 1px solid var(--color-light-border);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.buttons .button:last-child {
 | 
			
		||||
.ui.buttons .button:last-child,
 | 
			
		||||
.ui.buttons .button:nth-last-child(2):has(+ .button.gt-hidden) {
 | 
			
		||||
  border-right: 1px solid var(--color-light-border);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,6 +114,7 @@ It needs some tricks to tweak the left/right borders with active state */
 | 
			
		|||
.ui.basic.button:focus {
 | 
			
		||||
  color: var(--color-text);
 | 
			
		||||
  background: var(--color-hover);
 | 
			
		||||
  border-color: var(--color-secondary-dark-2);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.basic.buttons .button:active,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -100,3 +100,15 @@
 | 
			
		|||
  color: var(--color-warning-text);
 | 
			
		||||
  border-color: var(--color-warning-border);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.message > .close.icon {
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  top: 9px;
 | 
			
		||||
  right: 9px;
 | 
			
		||||
  opacity: .7;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.ui.message > .close.icon:hover {
 | 
			
		||||
  opacity: 1;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1601,7 +1601,6 @@
 | 
			
		|||
 | 
			
		||||
.repository .diff-file-box .file-body.file-code .lines-num {
 | 
			
		||||
  text-align: right;
 | 
			
		||||
  color: var(--color-text-light);
 | 
			
		||||
  width: 1%;
 | 
			
		||||
  min-width: 50px;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,18 +3,16 @@
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
.code-line-button {
 | 
			
		||||
  background-color: var(--color-menu);
 | 
			
		||||
  color: var(--color-text-light);
 | 
			
		||||
  border: 1px solid var(--color-secondary);
 | 
			
		||||
  border-radius: var(--border-radius);
 | 
			
		||||
  padding: 1px 10px;
 | 
			
		||||
  padding: 1px 4px !important;
 | 
			
		||||
  position: absolute;
 | 
			
		||||
  font-family: var(--fonts-regular);
 | 
			
		||||
  left: 0;
 | 
			
		||||
  transform: translateX(-50%);
 | 
			
		||||
  transform: translateX(calc(-50% + 6px));
 | 
			
		||||
  cursor: pointer;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.code-line-button:hover {
 | 
			
		||||
  color: var(--color-primary);
 | 
			
		||||
  background: var(--color-secondary) !important;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,7 +183,7 @@
 | 
			
		|||
  --color-body: #1c1f25;
 | 
			
		||||
  --color-box-header: #1a1d1f;
 | 
			
		||||
  --color-box-body: #14171a;
 | 
			
		||||
  --color-box-body-highlight: #121517;
 | 
			
		||||
  --color-box-body-highlight: #1c2227;
 | 
			
		||||
  --color-text-dark: #f8f8f9;
 | 
			
		||||
  --color-text: #d1d5d8;
 | 
			
		||||
  --color-text-light: #bdc3c7;
 | 
			
		||||
| 
						 | 
				
			
			@ -207,11 +207,10 @@
 | 
			
		|||
  --color-markup-table-row: #e8e8ff06;
 | 
			
		||||
  --color-markup-code-block: #e8e8ff16;
 | 
			
		||||
  --color-button: #151a1e;
 | 
			
		||||
  --color-code-bg: #191d20;
 | 
			
		||||
  --color-code-sidebar-bg: #1b1f22;
 | 
			
		||||
  --color-code-bg: #14171a;
 | 
			
		||||
  --color-shadow: #00001758;
 | 
			
		||||
  --color-secondary-bg: #2f3135;
 | 
			
		||||
  --color-expand-button: #414348;
 | 
			
		||||
  --color-secondary-bg: #2f3138;
 | 
			
		||||
  --color-expand-button: #2b353e;
 | 
			
		||||
  --color-placeholder-text: var(--color-text-light-3);
 | 
			
		||||
  --color-editor-line-highlight: var(--color-primary-light-5);
 | 
			
		||||
  --color-project-board-bg: var(--color-secondary-light-2);
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +232,8 @@
 | 
			
		|||
  --color-label-active-bg: #73828eff;
 | 
			
		||||
  --color-accent: var(--color-primary-light-1);
 | 
			
		||||
  --color-small-accent: var(--color-primary-light-5);
 | 
			
		||||
  --color-active-line: #534d1b;
 | 
			
		||||
  --color-highlight-fg: #87651e;
 | 
			
		||||
  --color-highlight-bg: #352c1c;
 | 
			
		||||
  --color-overlay-backdrop: #080808c0;
 | 
			
		||||
  accent-color: var(--color-accent);
 | 
			
		||||
  color-scheme: dark;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -183,7 +183,7 @@
 | 
			
		|||
  --color-body: #ffffff;
 | 
			
		||||
  --color-box-header: #f1f3f5;
 | 
			
		||||
  --color-box-body: #ffffff;
 | 
			
		||||
  --color-box-body-highlight: #f4faff;
 | 
			
		||||
  --color-box-body-highlight: #ecf5fd;
 | 
			
		||||
  --color-text-dark: #01050a;
 | 
			
		||||
  --color-text: #181c21;
 | 
			
		||||
  --color-text-light: #30363b;
 | 
			
		||||
| 
						 | 
				
			
			@ -208,10 +208,9 @@
 | 
			
		|||
  --color-markup-code-block: #00001710;
 | 
			
		||||
  --color-button: #f8f9fb;
 | 
			
		||||
  --color-code-bg: #fafdff;
 | 
			
		||||
  --color-code-sidebar-bg: #f2f5f8;
 | 
			
		||||
  --color-shadow: #00001726;
 | 
			
		||||
  --color-secondary-bg: #f2f5f8;
 | 
			
		||||
  --color-expand-button: #d8efff;
 | 
			
		||||
  --color-expand-button: #cfe8fa;
 | 
			
		||||
  --color-placeholder-text: var(--color-text-light-3);
 | 
			
		||||
  --color-editor-line-highlight: var(--color-primary-light-6);
 | 
			
		||||
  --color-project-board-bg: var(--color-secondary-light-4);
 | 
			
		||||
| 
						 | 
				
			
			@ -233,7 +232,8 @@
 | 
			
		|||
  --color-label-active-bg: #949da6ff;
 | 
			
		||||
  --color-accent: var(--color-primary-light-1);
 | 
			
		||||
  --color-small-accent: var(--color-primary-light-6);
 | 
			
		||||
  --color-active-line: #fffbdd;
 | 
			
		||||
  --color-highlight-fg: #eed200;
 | 
			
		||||
  --color-highlight-bg: #fffbdd;
 | 
			
		||||
  --color-overlay-backdrop: #080808c0;
 | 
			
		||||
  accent-color: var(--color-accent);
 | 
			
		||||
  color-scheme: light;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,16 @@ function changeHash(hash) {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function selectRange($list, $select, $from) {
 | 
			
		||||
  $list.removeClass('active');
 | 
			
		||||
function isBlame() {
 | 
			
		||||
  return Boolean(document.querySelector('div.blame'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getLineEls() {
 | 
			
		||||
  return document.querySelectorAll(`.code-view td.lines-code${isBlame() ? '.blame-code' : ''}`);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function selectRange($linesEls, $selectionEndEl, $selectionStartEls) {
 | 
			
		||||
  $linesEls.closest('tr').removeClass('active');
 | 
			
		||||
 | 
			
		||||
  // add hashchange to permalink
 | 
			
		||||
  const $refInNewIssue = $('a.ref-in-new-issue');
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +33,7 @@ function selectRange($list, $select, $from) {
 | 
			
		|||
  const $viewGitBlame = $('a.view_git_blame');
 | 
			
		||||
 | 
			
		||||
  const updateIssueHref = function (anchor) {
 | 
			
		||||
    if ($refInNewIssue.length === 0) {
 | 
			
		||||
    if (!$refInNewIssue.length) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const urlIssueNew = $refInNewIssue.attr('data-url-issue-new');
 | 
			
		||||
| 
						 | 
				
			
			@ -35,9 +43,7 @@ function selectRange($list, $select, $from) {
 | 
			
		|||
  };
 | 
			
		||||
 | 
			
		||||
  const updateViewGitBlameFragment = function (anchor) {
 | 
			
		||||
    if ($viewGitBlame.length === 0) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!$viewGitBlame.length) return;
 | 
			
		||||
    let href = $viewGitBlame.attr('href');
 | 
			
		||||
    href = `${href.replace(/#L\d+$|#L\d+-L\d+$/, '')}`;
 | 
			
		||||
    if (anchor.length !== 0) {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,17 +53,15 @@ function selectRange($list, $select, $from) {
 | 
			
		|||
  };
 | 
			
		||||
 | 
			
		||||
  const updateCopyPermalinkUrl = function(anchor) {
 | 
			
		||||
    if ($copyPermalink.length === 0) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    if (!$copyPermalink.length) return;
 | 
			
		||||
    let link = $copyPermalink.attr('data-url');
 | 
			
		||||
    link = `${link.replace(/#L\d+$|#L\d+-L\d+$/, '')}#${anchor}`;
 | 
			
		||||
    $copyPermalink.attr('data-url', link);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  if ($from) {
 | 
			
		||||
    let a = parseInt($select.attr('rel').slice(1));
 | 
			
		||||
    let b = parseInt($from.attr('rel').slice(1));
 | 
			
		||||
  if ($selectionStartEls) {
 | 
			
		||||
    let a = parseInt($selectionEndEl.attr('rel').slice(1));
 | 
			
		||||
    let b = parseInt($selectionStartEls.attr('rel').slice(1));
 | 
			
		||||
    let c;
 | 
			
		||||
    if (a !== b) {
 | 
			
		||||
      if (a > b) {
 | 
			
		||||
| 
						 | 
				
			
			@ -69,7 +73,9 @@ function selectRange($list, $select, $from) {
 | 
			
		|||
      for (let i = a; i <= b; i++) {
 | 
			
		||||
        classes.push(`[rel=L${i}]`);
 | 
			
		||||
      }
 | 
			
		||||
      $list.filter(classes.join(',')).addClass('active');
 | 
			
		||||
      $linesEls.filter(classes.join(',')).each(function () {
 | 
			
		||||
        $(this).closest('tr').addClass('active');
 | 
			
		||||
      });
 | 
			
		||||
      changeHash(`#L${a}-L${b}`);
 | 
			
		||||
 | 
			
		||||
      updateIssueHref(`L${a}-L${b}`);
 | 
			
		||||
| 
						 | 
				
			
			@ -78,12 +84,12 @@ function selectRange($list, $select, $from) {
 | 
			
		|||
      return;
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  $select.addClass('active');
 | 
			
		||||
  changeHash(`#${$select.attr('rel')}`);
 | 
			
		||||
  $selectionEndEl.closest('tr').addClass('active');
 | 
			
		||||
  changeHash(`#${$selectionEndEl.attr('rel')}`);
 | 
			
		||||
 | 
			
		||||
  updateIssueHref($select.attr('rel'));
 | 
			
		||||
  updateViewGitBlameFragment($select.attr('rel'));
 | 
			
		||||
  updateCopyPermalinkUrl($select.attr('rel'));
 | 
			
		||||
  updateIssueHref($selectionEndEl.attr('rel'));
 | 
			
		||||
  updateViewGitBlameFragment($selectionEndEl.attr('rel'));
 | 
			
		||||
  updateCopyPermalinkUrl($selectionEndEl.attr('rel'));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function showLineButton() {
 | 
			
		||||
| 
						 | 
				
			
			@ -96,10 +102,10 @@ function showLineButton() {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  // find active row and add button
 | 
			
		||||
  const tr = document.querySelector('.code-view td.lines-code.active').closest('tr');
 | 
			
		||||
  const td = tr.querySelector('td');
 | 
			
		||||
  const tr = document.querySelector('.code-view tr.active');
 | 
			
		||||
  const td = tr.querySelector('td.lines-num');
 | 
			
		||||
  const btn = document.createElement('button');
 | 
			
		||||
  btn.classList.add('code-line-button');
 | 
			
		||||
  btn.classList.add('code-line-button', 'ui', 'basic', 'button');
 | 
			
		||||
  btn.innerHTML = svg('octicon-kebab-horizontal');
 | 
			
		||||
  td.prepend(btn);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,14 +129,18 @@ function showLineButton() {
 | 
			
		|||
export function initRepoCodeView() {
 | 
			
		||||
  if ($('.code-view .lines-num').length > 0) {
 | 
			
		||||
    $(document).on('click', '.lines-num span', function (e) {
 | 
			
		||||
      const $select = $(this);
 | 
			
		||||
      let $list;
 | 
			
		||||
      if ($('div.blame').length) {
 | 
			
		||||
        $list = $('.code-view td.lines-code.blame-code');
 | 
			
		||||
      } else {
 | 
			
		||||
        $list = $('.code-view td.lines-code');
 | 
			
		||||
      const linesEls = getLineEls();
 | 
			
		||||
      const selectedEls = Array.from(linesEls).filter((el) => {
 | 
			
		||||
        return el.matches(`[rel=${this.getAttribute('id')}]`);
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      let from;
 | 
			
		||||
      if (e.shiftKey) {
 | 
			
		||||
        from = Array.from(linesEls).filter((el) => {
 | 
			
		||||
          return el.closest('tr').classList.contains('active');
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
      selectRange($list, $list.filter(`[rel=${$select.attr('id')}]`), (e.shiftKey ? $list.filter('.active').eq(0) : null));
 | 
			
		||||
      selectRange($(linesEls), $(selectedEls), from ? $(from) : null);
 | 
			
		||||
 | 
			
		||||
      if (window.getSelection) {
 | 
			
		||||
        window.getSelection().removeAllRanges();
 | 
			
		||||
| 
						 | 
				
			
			@ -138,28 +148,20 @@ export function initRepoCodeView() {
 | 
			
		|||
        document.selection.empty();
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      // show code view menu marker (don't show in blame page)
 | 
			
		||||
      if ($('div.blame').length === 0) {
 | 
			
		||||
        showLineButton();
 | 
			
		||||
      }
 | 
			
		||||
      showLineButton();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $(window).on('hashchange', () => {
 | 
			
		||||
      let m = window.location.hash.match(rangeAnchorRegex);
 | 
			
		||||
      let $list;
 | 
			
		||||
      if ($('div.blame').length) {
 | 
			
		||||
        $list = $('.code-view td.lines-code.blame-code');
 | 
			
		||||
      } else {
 | 
			
		||||
        $list = $('.code-view td.lines-code');
 | 
			
		||||
      }
 | 
			
		||||
      const $linesEls = $(getLineEls());
 | 
			
		||||
      let $first;
 | 
			
		||||
      if (m) {
 | 
			
		||||
        $first = $list.filter(`[rel=${m[1]}]`);
 | 
			
		||||
        $first = $linesEls.filter(`[rel=${m[1]}]`);
 | 
			
		||||
        if ($first.length) {
 | 
			
		||||
          selectRange($list, $first, $list.filter(`[rel=${m[2]}]`));
 | 
			
		||||
          selectRange($linesEls, $first, $linesEls.filter(`[rel=${m[2]}]`));
 | 
			
		||||
 | 
			
		||||
          // show code view menu marker (don't show in blame page)
 | 
			
		||||
          if ($('div.blame').length === 0) {
 | 
			
		||||
          if (!isBlame()) {
 | 
			
		||||
            showLineButton();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -169,12 +171,12 @@ export function initRepoCodeView() {
 | 
			
		|||
      }
 | 
			
		||||
      m = window.location.hash.match(singleAnchorRegex);
 | 
			
		||||
      if (m) {
 | 
			
		||||
        $first = $list.filter(`[rel=L${m[2]}]`);
 | 
			
		||||
        $first = $linesEls.filter(`[rel=L${m[2]}]`);
 | 
			
		||||
        if ($first.length) {
 | 
			
		||||
          selectRange($list, $first);
 | 
			
		||||
          selectRange($linesEls, $first);
 | 
			
		||||
 | 
			
		||||
          // show code view menu marker (don't show in blame page)
 | 
			
		||||
          if ($('div.blame').length === 0) {
 | 
			
		||||
          if (!isBlame()) {
 | 
			
		||||
            showLineButton();
 | 
			
		||||
          }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue