diff --git a/tests/e2e/file-view-render.test.ts b/tests/e2e/file-view-render.test.ts index 89cca628010..70838a9d9fa 100644 --- a/tests/e2e/file-view-render.test.ts +++ b/tests/e2e/file-view-render.test.ts @@ -39,6 +39,18 @@ test('pdf file', async ({page, request}) => { await assertFlushWithParent(container, page.locator('.file-view')); }); +test('code line anchors', async ({page, request}) => { + const repoName = `e2e-line-anchor-${randomString(8)}`; + const owner = env.GITEA_TEST_E2E_USER; + await apiCreateRepo(request, {name: repoName}); + await apiCreateFiles(request, owner, repoName, [{path: 'test.txt', content: 'a\n'}]); + const url = `/${owner}/${repoName}/src/branch/main/test.txt`; + await page.goto(`${url}#L0`); + await page.goto(`${url}#L1`); + await expect(page.locator('.code-view tr.active')).toHaveCount(1); + await assertNoJsError(page); +}); + test('asciicast file', async ({page, request}) => { const repoName = `e2e-asciicast-render-${randomString(8)}`; const owner = env.GITEA_TEST_E2E_USER; diff --git a/web_src/js/features/repo-code.ts b/web_src/js/features/repo-code.ts index 679577da325..54a63caa511 100644 --- a/web_src/js/features/repo-code.ts +++ b/web_src/js/features/repo-code.ts @@ -58,6 +58,7 @@ function selectRange(range: string): Element | null { stopLineNum = tmp; range = `${stop}-${start}`; } + if (startLineNum < 1) return null; const first = elLineNums[startLineNum - 1] ?? null; for (let i = startLineNum - 1; i <= stopLineNum - 1 && i < elLineNums.length; i++) { diff --git a/web_src/js/modules/errors.test.ts b/web_src/js/modules/errors.test.ts index 53618b45695..a8db4680b2e 100644 --- a/web_src/js/modules/errors.test.ts +++ b/web_src/js/modules/errors.test.ts @@ -17,7 +17,11 @@ test('isGiteaError', () => { expect(isGiteaError('', `Error\n at chrome-extension://abc/content.js:1:1`)).toBe(false); expect(isGiteaError('', `Error\n at https://other-site.com/script.js:1:1`)).toBe(false); expect(isGiteaError('', `Error\n at ${origin}/assets/js/index.abc123.js:1:1`)).toBe(true); + expect(isGiteaError('', `Error\n at ${origin}/web_src/js/index.ts:1:1`)).toBe(false); expect(isGiteaError(`${origin}/assets/js/index.js`, `Error\n at chrome-extension://abc/content.js:1:1`)).toBe(false); + vi.spyOn(window.config, 'runModeIsProd', 'get').mockReturnValue(false); + expect(isGiteaError('', `Error\n at ${origin}/web_src/js/index.ts:1:1`)).toBe(true); + vi.restoreAllMocks(); }); test('showGlobalErrorMessage', () => { diff --git a/web_src/js/modules/errors.ts b/web_src/js/modules/errors.ts index 5c62b4c5d9a..22c0e693ff3 100644 --- a/web_src/js/modules/errors.ts +++ b/web_src/js/modules/errors.ts @@ -58,6 +58,7 @@ export function isGiteaError(filename: string, stack: string): boolean { if (extensionRe.test(filename) || extensionRe.test(stack)) return false; const assetBaseUrl = new URL(`${windowConfig()?.assetUrlPrefix}/`, window.location.origin).href; if (filename && !filename.startsWith(assetBaseUrl) && !filename.startsWith(window.location.origin)) return false; + if (!windowConfig()?.runModeIsProd && stack.includes(`${window.location.origin}/web_src/`)) return true; return !stack || stack.includes(assetBaseUrl); }