refactor(telegram): use snapshot for orphaned TLD offset clarity

Use explicit snapshot variable when checking tag positions in orphaned
TLD pass. While JavaScript's replace() doesn't mutate during iteration,
this makes intent explicit and adds test coverage for multi-TLD HTML.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
divanoli
2026-02-05 12:41:08 +03:00
parent 352398b9a5
commit 90974e1030
2 changed files with 24 additions and 3 deletions

View File

@@ -222,14 +222,17 @@ export function wrapFileReferencesInHtml(html: string): string {
`([^a-zA-Z0-9]|^)([A-Za-z]\\.(?:${extensionsPattern}))(?=[^a-zA-Z0-9/]|$)`,
"g",
);
result = result.replace(orphanedTldPattern, (m, prefix, tld, offset) => {
// Snapshot for offset calculations (offset is relative to pre-replacement string)
// Note: replace() doesn't mutate, but snapshot makes intent explicit
const snapshot = result;
result = snapshot.replace(orphanedTldPattern, (m, prefix, tld, offset) => {
// Skip if prefix is > (right after a tag close)
if (prefix === ">") {
return m;
}
// Skip if we're inside an HTML tag (between < and >)
const lastOpen = result.lastIndexOf("<", offset);
const lastClose = result.lastIndexOf(">", offset);
const lastOpen = snapshot.lastIndexOf("<", offset);
const lastClose = snapshot.lastIndexOf(">", offset);
if (lastOpen > lastClose) {
return m; // Inside a tag
}

View File

@@ -341,4 +341,22 @@ describe("edge cases", () => {
const result = wrapFileReferencesInHtml(input);
expect(result).toBe(input);
});
it("handles multiple orphaned TLDs with HTML tags (offset stability)", () => {
// This tests the bug where offset is relative to pre-replacement string
// but we were checking against the mutating result string
const input = '<a href="http://A.md">link</a> B.md <span title="C.sh">text</span> D.py';
const result = wrapFileReferencesInHtml(input);
// A.md in href should NOT be wrapped (inside attribute)
// B.md outside tags SHOULD be wrapped
// C.sh in title attribute should NOT be wrapped
// D.py outside tags SHOULD be wrapped
expect(result).toContain("<code>B.md</code>");
expect(result).toContain("<code>D.py</code>");
expect(result).not.toContain("<code>A.md</code>");
expect(result).not.toContain("<code>C.sh</code>");
// Attributes should be unchanged
expect(result).toContain('href="http://A.md"');
expect(result).toContain('title="C.sh"');
});
});