From 459878ed040140870088b51b0e2e38fd4f02e47d Mon Sep 17 00:00:00 2001 From: Grigory Entin Date: Sat, 12 Sep 2026 04:06:02 +0200 Subject: [PATCH] Added support for file:/// urls. --- src/CsvEditorProvider.ts | 6 +++--- src/test/provider-utils.test.ts | 10 +++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/CsvEditorProvider.ts b/src/CsvEditorProvider.ts index 9135ca8..0fb74ce 100644 --- a/src/CsvEditorProvider.ts +++ b/src/CsvEditorProvider.ts @@ -1999,7 +1999,7 @@ class CsvEditorController { private isAllowedExternalScheme(scheme: string): boolean { const normalized = scheme.toLowerCase(); - return normalized === 'http' || normalized === 'https' || normalized === 'ftp' || normalized === 'mailto'; + return normalized === 'http' || normalized === 'https' || normalized === 'ftp' || normalized === 'mailto' || normalized === 'file'; } private isAllowedExternalUrl(rawUrl: unknown): rawUrl is string { @@ -2029,8 +2029,8 @@ class CsvEditorController { private linkifyUrls(escapedText: string): string { // Match URLs in already-escaped text (handles & in query strings). - // Supports http, https, ftp, mailto, and www.*.* (Google Sheets-like behavior). - const urlPattern = /\b(?:(?:https?:\/\/|ftp:\/\/|mailto:)[^\s<>&"']+(?:&[^\s<>&"']+)*|www\.[^\s<>&"']+\.[^\s<>&"']+)/gi; + // Supports http, https, ftp, file, mailto, and www.*.* (Google Sheets-like behavior). + const urlPattern = /\b(?:(?:https?:\/\/|ftp:\/\/|file:\/\/|mailto:)[^\s<>&"']+(?:&[^\s<>&"']+)*|www\.[^\s<>&"']+\.[^\s<>&"']+)/gi; return escapedText.replace(urlPattern, (rawMatch) => { let matched = rawMatch; let trailing = ''; diff --git a/src/test/provider-utils.test.ts b/src/test/provider-utils.test.ts index d968cc1..8976249 100644 --- a/src/test/provider-utils.test.ts +++ b/src/test/provider-utils.test.ts @@ -46,6 +46,14 @@ describe('CsvEditorProvider utility methods', () => { assert.ok(html.includes('>www.google.com,')); }); + it('formatCellContent linkifies file:/// URLs when enabled', () => { + const format = CsvEditorProvider.__test.formatCellContent; + const html = format('Open file:///tmp/example.csv and continue.', true); + assert.ok(html.includes('class="csv-link"')); + assert.ok(html.includes('data-href="file:///tmp/example.csv"')); + assert.ok(html.includes('>file:///tmp/example.csv')); + }); + it('formatCellContent leaves URLs as plain text when linkify is disabled', () => { const format = CsvEditorProvider.__test.formatCellContent; const html = format('https://example.com?a=1&b=2', false); @@ -66,9 +74,9 @@ describe('CsvEditorProvider utility methods', () => { assert.strictEqual(allowed('http://example.com'), true); assert.strictEqual(allowed('ftp://example.com/file.txt'), true); assert.strictEqual(allowed('mailto:user@example.com'), true); + assert.strictEqual(allowed('file:///tmp/x.csv'), true); assert.strictEqual(allowed('javascript:alert(1)'), false); assert.strictEqual(allowed('data:text/plain,hello'), false); - assert.strictEqual(allowed('file:///tmp/x.csv'), false); assert.strictEqual(allowed(''), false); });