Skip to content

Commit

Permalink
Links with fragment can't be Ctrl+clicked (#180)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeschli authored Feb 26, 2024
1 parent 6b384d3 commit 6760ddb
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 8 deletions.
19 changes: 13 additions & 6 deletions src/services/htmlLinks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,21 +71,26 @@ function createLink(document: TextDocument, documentContext: DocumentContext, at
if (!workspaceUrl) {
return undefined;
}
const target = validateAndCleanURI(workspaceUrl);


const target = validateAndCleanURI(workspaceUrl, document);

return {
range: Range.create(document.positionAt(startOffset), document.positionAt(endOffset)),
target
};
}

function validateAndCleanURI(uriStr: string) : string | undefined {
const _hash = '#'.charCodeAt(0);

function validateAndCleanURI(uriStr: string, document: TextDocument): string | undefined {
try {
const uri = Uri.parse(uriStr);
let uri = Uri.parse(uriStr);
if (uri.scheme === 'file' && uri.query) {
// see https://github.com/microsoft/vscode/issues/194577 & https://github.com/microsoft/vscode/issues/206238
return uri.with({ query: null }).toString(/* skipEncodig*/ true);
uri = uri.with({ query: null });
uriStr = uri.toString(/* skipEncodig*/ true);
}
if (uri.scheme === 'file' && uri.fragment && !(uriStr.startsWith(document.uri) && uriStr.charCodeAt(document.uri.length) === _hash)) {
return uri.with({ fragment: null }).toString(/* skipEncodig*/ true);
}
return uriStr;
} catch (e) {
Expand Down Expand Up @@ -154,6 +159,8 @@ export class HTMLDocumentLinks {
if (offset !== undefined) {
const pos = document.positionAt(offset);
link.target = `${localWithHash}${pos.line + 1},${pos.character + 1}`;
} else {
link.target = document.uri;
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/test/links.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ suite('HTML Link Detection', () => {
test('Link creation', () => {
testLinkCreation('http://model/1.html', 'javascript:void;', null);
testLinkCreation('http://model/1.html', ' \tjavascript:alert(7);', null);
testLinkCreation('http://model/1.html', ' #relative', 'http://model/1.html#relative');
testLinkCreation('http://model/1.html', ' #relative', 'http://model/1.html');
testLinkCreation('http://model/1.html', 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt');
testLinkCreation('http://model/1.html', 'http://www.microsoft.com/', 'http://www.microsoft.com/');
testLinkCreation('http://model/1.html', 'https://www.microsoft.com/', 'https://www.microsoft.com/');
Expand All @@ -46,7 +46,7 @@ suite('HTML Link Detection', () => {

testLinkCreation('file:///C:/Alex/src/path/to/file.html', 'javascript:void;', null);
testLinkCreation('file:///C:/Alex/src/path/to/file.html', ' \tjavascript:alert(7);', null);
testLinkCreation('file:///C:/Alex/src/path/to/file.html', ' #relative', 'file:///C:/Alex/src/path/to/file.html#relative');
testLinkCreation('file:///C:/Alex/src/path/to/file.html', ' #relative', 'file:///C:/Alex/src/path/to/file.html');
testLinkCreation('file:///C:/Alex/src/path/to/file.html', 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt');
testLinkCreation('file:///C:/Alex/src/path/to/file.html', 'http://www.microsoft.com/', 'http://www.microsoft.com/');
testLinkCreation('file:///C:/Alex/src/path/to/file.html', 'https://www.microsoft.com/', 'https://www.microsoft.com/');
Expand Down Expand Up @@ -89,11 +89,13 @@ suite('HTML Link Detection', () => {
testLinkDetection('<blockquote cite="foo.png">', [{ offset: 18, length: 7, target: 'file:///test/data/abc/foo.png' }]);
testLinkDetection('<style src="styles.css?t=345">', [{ offset: 12, length: 16, target: 'file:///test/data/abc/styles.css' }]);
testLinkDetection('<a href="https://werkenvoor.be/nl/jobs?f%5B0%5D=activitydomains%3A115&f%5B1%5D=lang%3Anl">link</a>', [{ offset: 9, length: 79, target: 'https://werkenvoor.be/nl/jobs?f%5B0%5D=activitydomains%3A115&f%5B1%5D=lang%3Anl' }]);
testLinkDetection('<a href="jobs.html?f=bar">link</a>', [{ offset: 9, length: 15, target: 'file:///test/data/abc/jobs.html' }]);
});

test('Local targets', () => {
testLinkDetection('<body><h1 id="title"></h1><a href="#title"</a></body>', [{ offset: 35, length: 6, target: 'file:///test/data/abc/test.html#1,14' }]);
testLinkDetection('<body><h1 id="title"></h1><a href="file:///test/data/abc/test.html#title"</a></body>', [{ offset: 35, length: 37, target: 'file:///test/data/abc/test.html#1,14' }]);
testLinkDetection('<body><h1 id="title"></h1><a href="#body"</a></body>', [{ offset: 35, length: 5, target: 'file:///test/data/abc/test.html' }]);
});

});

0 comments on commit 6760ddb

Please sign in to comment.