From 32b47253ca0add536aa93667eea303ed359baf14 Mon Sep 17 00:00:00 2001 From: kerwin612 Date: Mon, 4 Aug 2025 19:57:05 +0800 Subject: [PATCH 1/4] feat: support multi-line selection with URL parameters --- templates/repo/view_file.tmpl | 2 +- web_src/js/features/repo-code.ts | 41 ++++++++++++++++++++++---------- 2 files changed, 29 insertions(+), 14 deletions(-) diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 1486d7181df8e..06aab23f90e75 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -108,7 +108,7 @@ {{range $idx, $code := .FileContent}} {{$line := Eval $idx "+" 1}} - + {{if $.EscapeStatus.Escaped}} {{if (index $.LineEscapeStatus $idx).Escaped}}{{end}} {{end}} diff --git a/web_src/js/features/repo-code.ts b/web_src/js/features/repo-code.ts index bf7fd762b0b34..d5d71ed0df8ed 100644 --- a/web_src/js/features/repo-code.ts +++ b/web_src/js/features/repo-code.ts @@ -14,7 +14,7 @@ function changeHash(hash: string) { // it selects the code lines defined by range: `L1-L3` (3 lines) or `L2` (singe line) function selectRange(range: string): Element { for (const el of document.querySelectorAll('.code-view tr.active')) el.classList.remove('active'); - const elLineNums = document.querySelectorAll(`.code-view td.lines-num span[data-line-number]`); + const elLineNums = document.querySelectorAll(`.code-view td.lines-num[id^="L"]`); const refInNewIssue = document.querySelector('a.ref-in-new-issue'); const copyPermalink = document.querySelector('a.copy-line-permalink'); @@ -81,11 +81,12 @@ function showLineButton() { el.remove(); } - // find active row and add button - const tr = document.querySelector('.code-view tr.active'); - if (!tr) return; + // Find first active row and add button + const activeRows = document.querySelectorAll('.code-view tr.active'); + if (activeRows.length === 0) return; - const td = tr.querySelector('td.lines-num'); + const firstActiveRow = activeRows[0]; + const td = firstActiveRow.querySelector('td.lines-num'); const btn = document.createElement('button'); btn.classList.add('code-line-button', 'ui', 'basic', 'button'); btn.innerHTML = svg('octicon-kebab-horizontal'); @@ -96,16 +97,30 @@ function showLineButton() { createTippy(btn, { theme: 'menu', - trigger: 'click', - hideOnClick: true, + trigger: 'manual', // Use manual trigger content: menu, placement: 'right-start', interactive: true, - onShow: (tippy) => { - tippy.popper.addEventListener('click', () => { - tippy.hide(); - }, {once: true}); - }, + appendTo: () => document.body, + }); + + // Handle menu button click manually + btn.addEventListener('click', (e) => { + e.stopPropagation(); + const tippyInstance = btn._tippy; + if (tippyInstance && tippyInstance.state.isVisible) { + tippyInstance.hide(); + } else if (tippyInstance) { + tippyInstance.show(); + } + }); + + // Hide menu when clicking menu items + menu.addEventListener('click', () => { + const tippyInstance = btn._tippy; + if (tippyInstance) { + tippyInstance.hide(); + } }); } @@ -118,7 +133,7 @@ export function initRepoCodeView() { // "file code view" and "blame" pages need this "line number button" feature let selRangeStart: string; - addDelegatedEventListener(document, 'click', '.code-view .lines-num span', (el: HTMLElement, e: KeyboardEvent) => { + addDelegatedEventListener(document, 'click', '.code-view .lines-num', (el: HTMLElement, e: KeyboardEvent) => { if (!selRangeStart || !e.shiftKey) { selRangeStart = el.getAttribute('id'); selectRange(selRangeStart); From d7ccf38396ea31b2111c5434f08f0bd4eecdeb98 Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Mon, 4 Aug 2025 21:22:39 +0800 Subject: [PATCH 2/4] Update web_src/js/features/repo-code.ts Co-authored-by: silverwind Signed-off-by: Kerwin Bryant --- web_src/js/features/repo-code.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_src/js/features/repo-code.ts b/web_src/js/features/repo-code.ts index d5d71ed0df8ed..fd0192ddf6d56 100644 --- a/web_src/js/features/repo-code.ts +++ b/web_src/js/features/repo-code.ts @@ -108,7 +108,7 @@ function showLineButton() { btn.addEventListener('click', (e) => { e.stopPropagation(); const tippyInstance = btn._tippy; - if (tippyInstance && tippyInstance.state.isVisible) { + if (tippyInstance?.state.isVisible) { tippyInstance.hide(); } else if (tippyInstance) { tippyInstance.show(); From c63f1d280e0cf1973b35f1e5cce46b85c29053fb Mon Sep 17 00:00:00 2001 From: Kerwin Bryant Date: Mon, 4 Aug 2025 21:22:50 +0800 Subject: [PATCH 3/4] Update web_src/js/features/repo-code.ts Co-authored-by: silverwind Signed-off-by: Kerwin Bryant --- web_src/js/features/repo-code.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/web_src/js/features/repo-code.ts b/web_src/js/features/repo-code.ts index fd0192ddf6d56..5262085939fb5 100644 --- a/web_src/js/features/repo-code.ts +++ b/web_src/js/features/repo-code.ts @@ -117,10 +117,7 @@ function showLineButton() { // Hide menu when clicking menu items menu.addEventListener('click', () => { - const tippyInstance = btn._tippy; - if (tippyInstance) { - tippyInstance.hide(); - } + btn._tippy?.hide(); }); } From 886f5465d2bd9ac53ad8524f4f82c71808ea0f7e Mon Sep 17 00:00:00 2001 From: kerwin612 Date: Sat, 9 Aug 2025 17:26:29 +0800 Subject: [PATCH 4/4] clean code --- web_src/js/features/repo-code.ts | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/web_src/js/features/repo-code.ts b/web_src/js/features/repo-code.ts index 5262085939fb5..a8bc4e6f5213b 100644 --- a/web_src/js/features/repo-code.ts +++ b/web_src/js/features/repo-code.ts @@ -81,12 +81,11 @@ function showLineButton() { el.remove(); } - // Find first active row and add button - const activeRows = document.querySelectorAll('.code-view tr.active'); - if (activeRows.length === 0) return; + // find active row and add button + const tr = document.querySelector('.code-view tr.active'); + if (!tr) return; - const firstActiveRow = activeRows[0]; - const td = firstActiveRow.querySelector('td.lines-num'); + const td = tr.querySelector('td.lines-num'); const btn = document.createElement('button'); btn.classList.add('code-line-button', 'ui', 'basic', 'button'); btn.innerHTML = svg('octicon-kebab-horizontal'); @@ -97,28 +96,28 @@ function showLineButton() { createTippy(btn, { theme: 'menu', - trigger: 'manual', // Use manual trigger + trigger: 'click', + hideOnClick: true, content: menu, placement: 'right-start', interactive: true, - appendTo: () => document.body, + onShow: (tippy) => { + tippy.popper.addEventListener('click', () => { + tippy.hide(); + }, {once: true}); + }, }); // Handle menu button click manually btn.addEventListener('click', (e) => { e.stopPropagation(); const tippyInstance = btn._tippy; - if (tippyInstance?.state.isVisible) { + if (tippyInstance?.state.isShown) { tippyInstance.hide(); } else if (tippyInstance) { tippyInstance.show(); } }); - - // Hide menu when clicking menu items - menu.addEventListener('click', () => { - btn._tippy?.hide(); - }); } export function initRepoCodeView() {