diff --git a/extensions/html/server/src/service/htmlLanguageService.ts b/extensions/html/server/src/service/htmlLanguageService.ts
index b3ed7f3a60f..fb7efc32619 100644
--- a/extensions/html/server/src/service/htmlLanguageService.ts
+++ b/extensions/html/server/src/service/htmlLanguageService.ts
@@ -3,12 +3,13 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
-import { parse} from './parser/htmlParser';
-import { doComplete } from './services/htmlCompletion';
-import { format } from './services/htmlFormatter';
-import { TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, MarkedString } from 'vscode-languageserver-types';
+import {parse} from './parser/htmlParser';
+import {doComplete} from './services/htmlCompletion';
+import {format} from './services/htmlFormatter';
+import {findDocumentHighlights} from './services/htmlHighlighting';
+import {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString } from 'vscode-languageserver-types';
-export { TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, FormattingOptions, MarkedString };
+export {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString };
export interface HTMLFormatConfiguration {
@@ -35,10 +36,8 @@ export interface LanguageService {
configure(settings: LanguageSettings): void;
parseHTMLDocument(document: TextDocument): HTMLDocument;
doValidation(document: TextDocument, htmlDocument: HTMLDocument): Diagnostic[];
-
-// doResolve(item: CompletionItem): CompletionItem;
- doComplete(document: TextDocument, position: Position, doc: HTMLDocument): CompletionList;
-// findDocumentSymbols(document: TextDocument, doc: HTMLDocument): SymbolInformation[];
+ findDocumentHighlights(document: TextDocument, position: Position, htmlDocument: HTMLDocument): DocumentHighlight[];
+ doComplete(document: TextDocument, position: Position, htmlDocument: HTMLDocument): CompletionList;
// doHover(document: TextDocument, position: Position, doc: HTMLDocument): Hover;
format(document: TextDocument, range: Range, options: HTMLFormatConfiguration): TextEdit[];
}
@@ -46,10 +45,10 @@ export interface LanguageService {
export function getLanguageService() : LanguageService {
return {
doValidation: (document, htmlDocument) => { return []; },
-
configure: (settings) => {},
parseHTMLDocument: (document) => parse(document.getText()),
doComplete,
- format
+ format,
+ findDocumentHighlights
};
}
\ No newline at end of file
diff --git a/extensions/html/server/src/service/services/htmlHighlighting.ts b/extensions/html/server/src/service/services/htmlHighlighting.ts
new file mode 100644
index 00000000000..0bb0f148382
--- /dev/null
+++ b/extensions/html/server/src/service/services/htmlHighlighting.ts
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import {HTMLDocument} from '../parser/htmlParser';
+import {TokenType, createScanner} from '../parser/htmlScanner';
+import {TextDocument, Range, Position, DocumentHighlightKind, DocumentHighlight} from 'vscode-languageserver-types';
+
+export function findDocumentHighlights(document: TextDocument, position: Position, htmlDocument: HTMLDocument): DocumentHighlight[] {
+ let offset = document.offsetAt(position);
+ let node = htmlDocument.findNodeAt(offset);
+ if (!node.tag || typeof node.endTagStart !== 'number') {
+ return [];
+ }
+ let startTagRange = getTagNameRange(TokenType.StartTag, document, node.start);
+ let endTagRange = getTagNameRange(TokenType.EndTag, document, node.endTagStart);
+ if (startTagRange && endTagRange && (covers(startTagRange, position) || covers(endTagRange, position))) {
+ return [ { kind: DocumentHighlightKind.Read, range: startTagRange }, { kind: DocumentHighlightKind.Read, range: endTagRange }];
+ }
+ return [];
+}
+
+function isBeforeOrEqual(pos1: Position, pos2: Position) {
+ return pos1.line < pos2.line || (pos1.line === pos2.line && pos1.character <= pos2.character);
+}
+
+function covers(range: Range, position: Position) {
+ return isBeforeOrEqual(range.start, position) && isBeforeOrEqual(position, range.end);
+}
+
+function getTagNameRange(tokenType: TokenType, document: TextDocument, startOffset: number ) : Range {
+ let scanner = createScanner(document.getText(), startOffset);
+ let token = scanner.scan();
+ while (token !== TokenType.EOS && token !== TokenType.StartTag) {
+ token = scanner.scan();
+ }
+ if (token !== TokenType.EOS) {
+ return { start: document.positionAt(scanner.getTokenOffset()), end: document.positionAt(scanner.getTokenEnd()) };
+ }
+ return null;
+}
diff --git a/extensions/html/server/src/service/test/completion.test.ts b/extensions/html/server/src/service/test/completion.test.ts
index 06c85214d6e..04237fe03f3 100644
--- a/extensions/html/server/src/service/test/completion.test.ts
+++ b/extensions/html/server/src/service/test/completion.test.ts
@@ -60,8 +60,8 @@ let testCompletionFor = function (value: string, expected: { count?: number, ite
let document = TextDocument.create('test://test/test.html', 'html', 0, value);
let position = document.positionAt(offset);
- let jsonDoc = ls.parseHTMLDocument(document);
- return asPromise(ls.doComplete(document, position, jsonDoc)).then(list => {
+ let htmlDoc = ls.parseHTMLDocument(document);
+ return asPromise(ls.doComplete(document, position, htmlDoc)).then(list => {
try {
if (expected.count) {
assert.equal(list.items, expected.count);
diff --git a/extensions/html/server/src/service/test/highlighting.test.ts b/extensions/html/server/src/service/test/highlighting.test.ts
new file mode 100644
index 00000000000..959abd92685
--- /dev/null
+++ b/extensions/html/server/src/service/test/highlighting.test.ts
@@ -0,0 +1,43 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ * Licensed under the MIT License. See License.txt in the project root for license information.
+ *--------------------------------------------------------------------------------------------*/
+'use strict';
+
+import * as assert from 'assert';
+import * as htmlLanguageService from '../htmlLanguageService';
+import {CompletionList, TextDocument, TextEdit, Position, CompletionItemKind} from 'vscode-languageserver-types';
+
+export function assertHighlights(value: string, expectedMatches: number[], elementName: string): Thenable {
+ let offset = value.indexOf('|');
+ value = value.substr(0, offset) + value.substr(offset + 1);
+
+ let document = TextDocument.create('test://test/test.html', 'html', 0, value);
+ let htmlDocument = htmlLanguageService.getLanguageService().parseHTMLDocument(document);
+
+ let position = document.positionAt(offset);
+ let ls = htmlLanguageService.getLanguageService();
+ let htmlDoc = ls.parseHTMLDocument(document);
+
+ let highlights = ls.findDocumentHighlights(document, position, htmlDoc);
+ assert.equal(highlights.length, expectedMatches.length);
+ for (let i = 0; i < highlights.length; i++) {
+ let actualStartOffset = document.offsetAt(highlights[i].range.start);
+ assert.equal(actualStartOffset, expectedMatches[i]);
+ let actualEndOffset = document.offsetAt(highlights[i].range.end);
+ assert.equal(actualEndOffset, expectedMatches[i] + elementName.length);
+
+ assert.equal(document.getText().substring(actualStartOffset, actualEndOffset), elementName);
+ }
+}
+
+suite('HTML Highlighting', () => {
+
+
+
+ test('Highlighting', function (testDone): any {
+ testHighlighting
+
+
+
+}
\ No newline at end of file