Skip to content

Commit 2fa4ede

Browse files
committed
[html] Follow Link in Multi Root Workspace. Fixes microsoft#38469
1 parent 099e284 commit 2fa4ede

5 files changed

Lines changed: 87 additions & 50 deletions

File tree

extensions/html/server/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
"node": "*"
99
},
1010
"dependencies": {
11-
"vscode-css-languageservice": "^3.0.2",
12-
"vscode-html-languageservice": "^2.0.13",
11+
"vscode-css-languageservice": "^3.0.3",
12+
"vscode-html-languageservice": "^2.0.14",
1313
"vscode-languageserver": "^3.5.0",
1414
"vscode-nls": "^2.0.2",
1515
"vscode-uri": "^1.0.1"

extensions/html/server/src/htmlServerMain.ts

Lines changed: 17 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
'use strict';
66

77
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities, Position } from 'vscode-languageserver';
8-
import { DocumentContext } from 'vscode-html-languageservice';
98
import { TextDocument, Diagnostic, DocumentLink, SymbolInformation } from 'vscode-languageserver-types';
109
import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes';
1110

@@ -15,13 +14,11 @@ import { DidChangeWorkspaceFoldersNotification, WorkspaceFolder } from 'vscode-l
1514

1615
import { format } from './modes/formatting';
1716
import { pushAll } from './utils/arrays';
18-
import { endsWith, startsWith } from './utils/strings';
19-
20-
import * as url from 'url';
21-
import * as path from 'path';
17+
import { getDocumentContext } from './utils/documentContext';
2218
import uri from 'vscode-uri';
2319

2420
import * as nls from 'vscode-nls';
21+
2522
nls.config(process.env['VSCODE_NLS_CONFIG']);
2623

2724
namespace TagCloseRequest {
@@ -41,7 +38,6 @@ let documents: TextDocuments = new TextDocuments();
4138
// for open, change and close text document events
4239
documents.listen(connection);
4340

44-
let workspacePath: string | undefined | null;
4541
let workspaceFolders: WorkspaceFolder[] | undefined;
4642

4743
var languageModes: LanguageModes;
@@ -77,8 +73,13 @@ function getDocumentSettings(textDocument: TextDocument, needsDocumentSettings:
7773
connection.onInitialize((params: InitializeParams): InitializeResult => {
7874
let initializationOptions = params.initializationOptions;
7975

80-
workspacePath = params.rootPath;
8176
workspaceFolders = (<any>params).workspaceFolders;
77+
if (!Array.isArray(workspaceFolders)) {
78+
workspaceFolders = [];
79+
if (params.rootPath) {
80+
workspaceFolders.push({ name: '', uri: uri.file(params.rootPath).toString() });
81+
}
82+
}
8283

8384
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true });
8485
documents.onDidClose(e => {
@@ -305,45 +306,19 @@ connection.onDocumentRangeFormatting(async formatParams => {
305306

306307
connection.onDocumentLinks(documentLinkParam => {
307308
let document = documents.get(documentLinkParam.textDocument.uri);
308-
let documentContext: DocumentContext = {
309-
resolveReference: (ref, base) => {
310-
if (base) {
311-
ref = url.resolve(base, ref);
312-
}
313-
if (ref[0] === '/') {
314-
let root = getRootFolder(document.uri);
315-
if (root) {
316-
return uri.file(path.join(root, ref)).toString();
317-
}
318-
}
319-
return url.resolve(document.uri, ref);
320-
},
321-
322-
};
323309
let links: DocumentLink[] = [];
324-
languageModes.getAllModesInDocument(document).forEach(m => {
325-
if (m.findDocumentLinks) {
326-
pushAll(links, m.findDocumentLinks(document, documentContext));
327-
}
328-
});
310+
if (document) {
311+
let documentContext = getDocumentContext(document.uri, workspaceFolders);
312+
languageModes.getAllModesInDocument(document).forEach(m => {
313+
if (m.findDocumentLinks) {
314+
pushAll(links, m.findDocumentLinks(document, documentContext));
315+
}
316+
});
317+
}
329318
return links;
330319
});
331320

332-
function getRootFolder(docUri: string): string | undefined {
333-
if (workspaceFolders) {
334-
for (let folder of workspaceFolders) {
335-
let folderURI = folder.uri;
336-
if (!endsWith(folderURI, '/')) {
337-
folderURI = folderURI + '/';
338-
}
339-
if (startsWith(docUri, folderURI)) {
340-
return uri.parse(folderURI).fsPath;
341-
}
342-
}
343-
return void 0;
344-
}
345-
return workspacePath;
346-
}
321+
347322

348323
connection.onDocumentSymbol(documentSymbolParms => {
349324
let document = documents.get(documentSymbolParms.textDocument.uri);
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import * as assert from 'assert';
8+
import { getDocumentContext } from '../utils/documentContext';
9+
10+
suite('Document Context', () => {
11+
12+
test('Context', function (): any {
13+
const docURI = 'file:///users/test/folder/test.html';
14+
const rootFolders = [{ name: '', uri: 'file:///users/test/' }];
15+
16+
let context = getDocumentContext(docURI, rootFolders);
17+
assert.equal(context.resolveReference('/', docURI), 'file:///users/test/');
18+
assert.equal(context.resolveReference('/message.html', docURI), 'file:///users/test/message.html');
19+
assert.equal(context.resolveReference('message.html', docURI), 'file:///users/test/folder/message.html');
20+
assert.equal(context.resolveReference('message.html', 'file:///users/test/'), 'file:///users/test/message.html');
21+
});
22+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
'use strict';
6+
7+
import { DocumentContext } from 'vscode-html-languageservice';
8+
import { endsWith, startsWith } from '../utils/strings';
9+
import * as url from 'url';
10+
import { WorkspaceFolder } from 'vscode-languageserver-protocol/lib/protocol.workspaceFolders.proposed';
11+
12+
export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext {
13+
function getRootFolder(): string | undefined {
14+
for (let folder of workspaceFolders) {
15+
let folderURI = folder.uri;
16+
if (!endsWith(folderURI, '/')) {
17+
folderURI = folderURI + '/';
18+
}
19+
if (startsWith(documentUri, folderURI)) {
20+
return folderURI;
21+
}
22+
}
23+
return void 0;
24+
}
25+
26+
return {
27+
resolveReference: (ref, base = documentUri) => {
28+
if (ref[0] === '/') { // resolve absolute path against the current workspace folder
29+
if (startsWith(base, 'file://')) {
30+
let folderUri = getRootFolder();
31+
if (folderUri) {
32+
return folderUri + ref.substr(1);
33+
}
34+
}
35+
}
36+
return url.resolve(base, ref);
37+
},
38+
};
39+
}
40+

extensions/html/server/yarn.lock

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@
1010
version "7.0.43"
1111
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
1212

13-
vscode-css-languageservice@^3.0.2:
14-
version "3.0.2"
15-
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.2.tgz#ae0c43836318455aa290c777556394d6127b8f6c"
13+
vscode-css-languageservice@^3.0.3:
14+
version "3.0.3"
15+
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.3.tgz#02cc4efa5335f5104e0a2f3b6920faaf59db4f7a"
1616
dependencies:
1717
vscode-languageserver-types "3.5.0"
1818
vscode-nls "^2.0.1"
1919

20-
vscode-html-languageservice@^2.0.13:
21-
version "2.0.13"
22-
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.0.13.tgz#09c4437cffb0800b865d71552f4dfd8240c796d8"
20+
vscode-html-languageservice@^2.0.14:
21+
version "2.0.14"
22+
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.0.14.tgz#15491c11bb7e196f6fd03b6c6c768901935862eb"
2323
dependencies:
2424
vscode-languageserver-types "3.5.0"
2525
vscode-nls "^2.0.2"

0 commit comments

Comments
 (0)