From 8d6a8863fdfac06ff92a84764e748ff29a8dc340 Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 14 Sep 2016 23:31:30 +0200 Subject: [PATCH] [html] use html language service --- extensions/html/OSSREADME.json | 5 + extensions/html/server/package.json | 6 +- extensions/html/server/src/htmlServerMain.ts | 2 +- .../server/src/service/htmlLanguageService.ts | 51 - .../server/src/service/lib/OSSREADME.json | 9 - .../server/src/service/lib/beautify-css.d.ts | 18 - .../server/src/service/lib/beautify-css.js | 493 -------- .../server/src/service/lib/beautify-html.d.ts | 85 -- .../server/src/service/lib/beautify-html.js | 1023 ----------------- .../src/service/lib/beautify-html.license.txt | 9 - .../html/server/src/service/lib/beautify.ts | 11 - .../server/src/service/parser/htmlParser.ts | 123 -- .../server/src/service/parser/htmlScanner.ts | 451 -------- .../server/src/service/parser/htmlTags.ts | 644 ----------- .../server/src/service/parser/razorTags.ts | 39 - .../src/service/services/htmlCompletion.ts | 211 ---- .../src/service/services/htmlFormatter.ts | 57 - .../src/service/services/htmlHighlighting.ts | 49 - .../server/src/service/services/htmlLinks.ts | 117 -- .../src/service/test/completion.test.ts | 397 ------- .../src/service/test/highlighting.test.ts | 69 -- .../server/src/service/test/links.test.ts | 85 -- .../server/src/service/test/parser.test.ts | 85 -- .../server/src/service/test/scanner.test.ts | 745 ------------ .../src/service/test/textEditSupport.ts | 23 - .../html/server/src/service/utils/arrays.ts | 44 - .../html/server/src/service/utils/paths.ts | 76 -- .../html/server/src/service/utils/strings.ts | 50 - 28 files changed, 10 insertions(+), 4967 deletions(-) delete mode 100644 extensions/html/server/src/service/htmlLanguageService.ts delete mode 100644 extensions/html/server/src/service/lib/OSSREADME.json delete mode 100644 extensions/html/server/src/service/lib/beautify-css.d.ts delete mode 100644 extensions/html/server/src/service/lib/beautify-css.js delete mode 100644 extensions/html/server/src/service/lib/beautify-html.d.ts delete mode 100644 extensions/html/server/src/service/lib/beautify-html.js delete mode 100644 extensions/html/server/src/service/lib/beautify-html.license.txt delete mode 100644 extensions/html/server/src/service/lib/beautify.ts delete mode 100644 extensions/html/server/src/service/parser/htmlParser.ts delete mode 100644 extensions/html/server/src/service/parser/htmlScanner.ts delete mode 100644 extensions/html/server/src/service/parser/htmlTags.ts delete mode 100644 extensions/html/server/src/service/parser/razorTags.ts delete mode 100644 extensions/html/server/src/service/services/htmlCompletion.ts delete mode 100644 extensions/html/server/src/service/services/htmlFormatter.ts delete mode 100644 extensions/html/server/src/service/services/htmlHighlighting.ts delete mode 100644 extensions/html/server/src/service/services/htmlLinks.ts delete mode 100644 extensions/html/server/src/service/test/completion.test.ts delete mode 100644 extensions/html/server/src/service/test/highlighting.test.ts delete mode 100644 extensions/html/server/src/service/test/links.test.ts delete mode 100644 extensions/html/server/src/service/test/parser.test.ts delete mode 100644 extensions/html/server/src/service/test/scanner.test.ts delete mode 100644 extensions/html/server/src/service/test/textEditSupport.ts delete mode 100644 extensions/html/server/src/service/utils/arrays.ts delete mode 100644 extensions/html/server/src/service/utils/paths.ts delete mode 100644 extensions/html/server/src/service/utils/strings.ts diff --git a/extensions/html/OSSREADME.json b/extensions/html/OSSREADME.json index dcf7bfe0138..c2825ad5e53 100644 --- a/extensions/html/OSSREADME.json +++ b/extensions/html/OSSREADME.json @@ -1,5 +1,10 @@ // ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS: [{ + "name": "js-beautify", + "version": "1.6.2", + "license": "MIT", + "repositoryURL": "https://github.com/beautify-web/js-beautify" +},{ "name": "textmate/html.tmbundle", "version": "0.0.0", "license": "TextMate Bundle License", diff --git a/extensions/html/server/package.json b/extensions/html/server/package.json index 755a6eaadd8..e2003041cb3 100644 --- a/extensions/html/server/package.json +++ b/extensions/html/server/package.json @@ -9,12 +9,14 @@ }, "dependencies": { "vscode-languageserver": "^2.6.0-next.3", - "vscode-nls": "^1.0.4", - "vscode-uri": "^0.0.7" + "vscode-html-languageservice": "1.0.0-next.1", + "vscode-nls": "^1.0.4" }, "scripts": { "compile": "gulp compile-extension:json-server", "watch": "gulp watch-extension:json-server", + "install-service-next": "npm install vscode-html-languageservice@next -f -S", + "install-service-local": "npm install ../../../../vscode-html-languageservice -f -S", "install-server-next": "npm install vscode-languageserver@next -f -S", "install-server-local": "npm install ../../../../vscode-languageserver-node/server -f -S" } diff --git a/extensions/html/server/src/htmlServerMain.ts b/extensions/html/server/src/htmlServerMain.ts index 0dfbdceae88..03bd7a83dd7 100644 --- a/extensions/html/server/src/htmlServerMain.ts +++ b/extensions/html/server/src/htmlServerMain.ts @@ -9,7 +9,7 @@ import { TextDocuments, TextDocument, InitializeParams, InitializeResult } from 'vscode-languageserver'; -import {HTMLDocument, getLanguageService, CompletionConfiguration, HTMLFormatConfiguration} from './service/htmlLanguageService'; +import {HTMLDocument, getLanguageService, CompletionConfiguration, HTMLFormatConfiguration} from 'vscode-html-languageservice'; import * as nls from 'vscode-nls'; nls.config(process.env['VSCODE_NLS_CONFIG']); diff --git a/extensions/html/server/src/service/htmlLanguageService.ts b/extensions/html/server/src/service/htmlLanguageService.ts deleted file mode 100644 index 5b43b82bbc6..00000000000 --- a/extensions/html/server/src/service/htmlLanguageService.ts +++ /dev/null @@ -1,51 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {parse} from './parser/htmlParser'; -import {doComplete} from './services/htmlCompletion'; -import {format} from './services/htmlFormatter'; -import {findDocumentLinks} from './services/htmlLinks'; -import {findDocumentHighlights} from './services/htmlHighlighting'; -import {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString, DocumentLink } from 'vscode-languageserver-types'; - -export {TextDocument, Position, CompletionItem, CompletionList, Hover, Range, SymbolInformation, Diagnostic, TextEdit, DocumentHighlight, FormattingOptions, MarkedString, DocumentLink }; - -export interface HTMLFormatConfiguration { - tabSize: number; - insertSpaces: boolean; - wrapLineLength: number; - unformatted: string; - indentInnerHtml: boolean; - preserveNewLines: boolean; - maxPreserveNewLines: number; - indentHandlebars: boolean; - endWithNewline: boolean; - extraLiners: string; -} - -export interface CompletionConfiguration { - [provider: string]: boolean; -} - -export declare type HTMLDocument = {}; - -export interface LanguageService { - parseHTMLDocument(document: TextDocument): HTMLDocument; - findDocumentHighlights(document: TextDocument, position: Position, htmlDocument: HTMLDocument): DocumentHighlight[]; - doComplete(document: TextDocument, position: Position, htmlDocument: HTMLDocument, options?: CompletionConfiguration): CompletionList; - format(document: TextDocument, range: Range, options: HTMLFormatConfiguration): TextEdit[]; - findDocumentLinks(document: TextDocument, workspacePath: string): DocumentLink[]; -} - -export function getLanguageService(): LanguageService { - return { - parseHTMLDocument: document => parse(document.getText()), - doComplete, - format, - findDocumentHighlights, - findDocumentLinks - }; -} \ No newline at end of file diff --git a/extensions/html/server/src/service/lib/OSSREADME.json b/extensions/html/server/src/service/lib/OSSREADME.json deleted file mode 100644 index 82be90adc9e..00000000000 --- a/extensions/html/server/src/service/lib/OSSREADME.json +++ /dev/null @@ -1,9 +0,0 @@ -// June 2012 -// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS: THEY ARE CLEARED ONLY FOR LIMITED USE BY MONACO FOR THE MONACO PRODUCT. DO NOT USE OR SHARE THIS CODE WITHOUT APPROVAL PURSUANT TO THE MICROSOFT OPEN SOURCE SOFTWARE APPROVAL POLICY.APPROVAL - -[{ - "name": "js-beautify", - "version": "1.6.2", - "license": "MIT", - "repositoryURL": "https://github.com/beautify-web/js-beautify" -}] \ No newline at end of file diff --git a/extensions/html/server/src/service/lib/beautify-css.d.ts b/extensions/html/server/src/service/lib/beautify-css.d.ts deleted file mode 100644 index da38f539b5e..00000000000 --- a/extensions/html/server/src/service/lib/beautify-css.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface IBeautifyCSSOptions { - indent_size?: number; // (4) — indentation size, - indent_char?: string; // (space) — character to indent with, - selector_separator_newline?: boolean; // (true) - separate selectors with newline or not (e.g. "a,\nbr" or "a, br") - end_with_newline?: boolean; // (false) - end with a newline - newline_between_rules?: boolean; // (true) - add a new line after every css rule -} - -export interface IBeautifyCSS { - (value:string, options:IBeautifyCSSOptions): string; -} - -export declare var css_beautify:IBeautifyCSS; \ No newline at end of file diff --git a/extensions/html/server/src/service/lib/beautify-css.js b/extensions/html/server/src/service/lib/beautify-css.js deleted file mode 100644 index 376288a5815..00000000000 --- a/extensions/html/server/src/service/lib/beautify-css.js +++ /dev/null @@ -1,493 +0,0 @@ -// copied https://raw.githubusercontent.com/beautify-web/js-beautify/master/js/lib/beautify-css.js - -/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */ -/* - - The MIT License (MIT) - - Copyright (c) 2007-2013 Einar Lielmanis and contributors. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - - CSS Beautifier ---------------- - - Written by Harutyun Amirjanyan, (amirjanyan@gmail.com) - - Based on code initially developed by: Einar Lielmanis, - http://jsbeautifier.org/ - - Usage: - css_beautify(source_text); - css_beautify(source_text, options); - - The options are (default in brackets): - indent_size (4) — indentation size, - indent_char (space) — character to indent with, - selector_separator_newline (true) - separate selectors with newline or - not (e.g. "a,\nbr" or "a, br") - end_with_newline (false) - end with a newline - newline_between_rules (true) - add a new line after every css rule - - e.g - - css_beautify(css_source_text, { - 'indent_size': 1, - 'indent_char': '\t', - 'selector_separator': ' ', - 'end_with_newline': false, - 'newline_between_rules': true - }); -*/ - -// http://www.w3.org/TR/CSS21/syndata.html#tokenization -// http://www.w3.org/TR/css3-syntax/ - -(function() { - function css_beautify(source_text, options) { - options = options || {}; - source_text = source_text || ''; - // HACK: newline parsing inconsistent. This brute force normalizes the input. - source_text = source_text.replace(/\r\n|[\r\u2028\u2029]/g, '\n') - - var indentSize = options.indent_size || 4; - var indentCharacter = options.indent_char || ' '; - var selectorSeparatorNewline = (options.selector_separator_newline === undefined) ? true : options.selector_separator_newline; - var end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline; - var newline_between_rules = (options.newline_between_rules === undefined) ? true : options.newline_between_rules; - var eol = options.eol ? options.eol : '\n'; - - // compatibility - if (typeof indentSize === "string") { - indentSize = parseInt(indentSize, 10); - } - - if(options.indent_with_tabs){ - indentCharacter = '\t'; - indentSize = 1; - } - - eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n') - - - // tokenizer - var whiteRe = /^\s+$/; - var wordRe = /[\w$\-_]/; - - var pos = -1, - ch; - var parenLevel = 0; - - function next() { - ch = source_text.charAt(++pos); - return ch || ''; - } - - function peek(skipWhitespace) { - var result = ''; - var prev_pos = pos; - if (skipWhitespace) { - eatWhitespace(); - } - result = source_text.charAt(pos + 1) || ''; - pos = prev_pos - 1; - next(); - return result; - } - - function eatString(endChars) { - var start = pos; - while (next()) { - if (ch === "\\") { - next(); - } else if (endChars.indexOf(ch) !== -1) { - break; - } else if (ch === "\n") { - break; - } - } - return source_text.substring(start, pos + 1); - } - - function peekString(endChar) { - var prev_pos = pos; - var str = eatString(endChar); - pos = prev_pos - 1; - next(); - return str; - } - - function eatWhitespace() { - var result = ''; - while (whiteRe.test(peek())) { - next(); - result += ch; - } - return result; - } - - function skipWhitespace() { - var result = ''; - if (ch && whiteRe.test(ch)) { - result = ch; - } - while (whiteRe.test(next())) { - result += ch; - } - return result; - } - - function eatComment(singleLine) { - var start = pos; - singleLine = peek() === "/"; - next(); - while (next()) { - if (!singleLine && ch === "*" && peek() === "/") { - next(); - break; - } else if (singleLine && ch === "\n") { - return source_text.substring(start, pos); - } - } - - return source_text.substring(start, pos) + ch; - } - - - function lookBack(str) { - return source_text.substring(pos - str.length, pos).toLowerCase() === - str; - } - - // Nested pseudo-class if we are insideRule - // and the next special character found opens - // a new block - function foundNestedPseudoClass() { - var openParen = 0; - for (var i = pos + 1; i < source_text.length; i++) { - var ch = source_text.charAt(i); - if (ch === "{") { - return true; - } else if (ch === '(') { - // pseudoclasses can contain () - openParen += 1; - } else if (ch === ')') { - if (openParen == 0) { - return false; - } - openParen -= 1; - } else if (ch === ";" || ch === "}") { - return false; - } - } - return false; - } - - // printer - var basebaseIndentString = source_text.match(/^[\t ]*/)[0]; - var singleIndent = new Array(indentSize + 1).join(indentCharacter); - var indentLevel = 0; - var nestedLevel = 0; - - function indent() { - indentLevel++; - basebaseIndentString += singleIndent; - } - - function outdent() { - indentLevel--; - basebaseIndentString = basebaseIndentString.slice(0, -indentSize); - } - - var print = {}; - print["{"] = function(ch) { - print.singleSpace(); - output.push(ch); - print.newLine(); - }; - print["}"] = function(ch) { - print.newLine(); - output.push(ch); - print.newLine(); - }; - - print._lastCharWhitespace = function() { - return whiteRe.test(output[output.length - 1]); - }; - - print.newLine = function(keepWhitespace) { - if (output.length) { - if (!keepWhitespace && output[output.length - 1] !== '\n') { - print.trim(); - } - - output.push('\n'); - - if (basebaseIndentString) { - output.push(basebaseIndentString); - } - } - }; - print.singleSpace = function() { - if (output.length && !print._lastCharWhitespace()) { - output.push(' '); - } - }; - - print.preserveSingleSpace = function() { - if (isAfterSpace) { - print.singleSpace(); - } - }; - - print.trim = function() { - while (print._lastCharWhitespace()) { - output.pop(); - } - }; - - - var output = []; - /*_____________________--------------------_____________________*/ - - var insideRule = false; - var insidePropertyValue = false; - var enteringConditionalGroup = false; - var top_ch = ''; - var last_top_ch = ''; - - while (true) { - var whitespace = skipWhitespace(); - var isAfterSpace = whitespace !== ''; - var isAfterNewline = whitespace.indexOf('\n') !== -1; - last_top_ch = top_ch; - top_ch = ch; - - if (!ch) { - break; - } else if (ch === '/' && peek() === '*') { /* css comment */ - var header = indentLevel === 0; - - if (isAfterNewline || header) { - print.newLine(); - } - - output.push(eatComment()); - print.newLine(); - if (header) { - print.newLine(true); - } - } else if (ch === '/' && peek() === '/') { // single line comment - if (!isAfterNewline && last_top_ch !== '{' ) { - print.trim(); - } - print.singleSpace(); - output.push(eatComment()); - print.newLine(); - } else if (ch === '@') { - print.preserveSingleSpace(); - output.push(ch); - - // strip trailing space, if present, for hash property checks - var variableOrRule = peekString(": ,;{}()[]/='\""); - - if (variableOrRule.match(/[ :]$/)) { - // we have a variable or pseudo-class, add it and insert one space before continuing - next(); - variableOrRule = eatString(": ").replace(/\s$/, ''); - output.push(variableOrRule); - print.singleSpace(); - } - - variableOrRule = variableOrRule.replace(/\s$/, '') - - // might be a nesting at-rule - if (variableOrRule in css_beautify.NESTED_AT_RULE) { - nestedLevel += 1; - if (variableOrRule in css_beautify.CONDITIONAL_GROUP_RULE) { - enteringConditionalGroup = true; - } - } - } else if (ch === '#' && peek() === '{') { - print.preserveSingleSpace(); - output.push(eatString('}')); - } else if (ch === '{') { - if (peek(true) === '}') { - eatWhitespace(); - next(); - print.singleSpace(); - output.push("{}"); - print.newLine(); - if (newline_between_rules && indentLevel === 0) { - print.newLine(true); - } - } else { - indent(); - print["{"](ch); - // when entering conditional groups, only rulesets are allowed - if (enteringConditionalGroup) { - enteringConditionalGroup = false; - insideRule = (indentLevel > nestedLevel); - } else { - // otherwise, declarations are also allowed - insideRule = (indentLevel >= nestedLevel); - } - } - } else if (ch === '}') { - outdent(); - print["}"](ch); - insideRule = false; - insidePropertyValue = false; - if (nestedLevel) { - nestedLevel--; - } - if (newline_between_rules && indentLevel === 0) { - print.newLine(true); - } - } else if (ch === ":") { - eatWhitespace(); - if ((insideRule || enteringConditionalGroup) && - !(lookBack("&") || foundNestedPseudoClass())) { - // 'property: value' delimiter - // which could be in a conditional group query - insidePropertyValue = true; - output.push(':'); - print.singleSpace(); - } else { - // sass/less parent reference don't use a space - // sass nested pseudo-class don't use a space - if (peek() === ":") { - // pseudo-element - next(); - output.push("::"); - } else { - // pseudo-class - output.push(':'); - } - } - } else if (ch === '"' || ch === '\'') { - print.preserveSingleSpace(); - output.push(eatString(ch)); - } else if (ch === ';') { - insidePropertyValue = false; - output.push(ch); - print.newLine(); - } else if (ch === '(') { // may be a url - if (lookBack("url")) { - output.push(ch); - eatWhitespace(); - if (next()) { - if (ch !== ')' && ch !== '"' && ch !== '\'') { - output.push(eatString(')')); - } else { - pos--; - } - } - } else { - parenLevel++; - print.preserveSingleSpace(); - output.push(ch); - eatWhitespace(); - } - } else if (ch === ')') { - output.push(ch); - parenLevel--; - } else if (ch === ',') { - output.push(ch); - eatWhitespace(); - if (selectorSeparatorNewline && !insidePropertyValue && parenLevel < 1) { - print.newLine(); - } else { - print.singleSpace(); - } - } else if (ch === ']') { - output.push(ch); - } else if (ch === '[') { - print.preserveSingleSpace(); - output.push(ch); - } else if (ch === '=') { // no whitespace before or after - eatWhitespace() - ch = '='; - output.push(ch); - } else { - print.preserveSingleSpace(); - output.push(ch); - } - } - - - var sweetCode = ''; - if (basebaseIndentString) { - sweetCode += basebaseIndentString; - } - - sweetCode += output.join('').replace(/[\r\n\t ]+$/, ''); - - // establish end_with_newline - if (end_with_newline) { - sweetCode += '\n'; - } - - if (eol != '\n') { - sweetCode = sweetCode.replace(/[\n]/g, eol); - } - - return sweetCode; - } - - // https://developer.mozilla.org/en-US/docs/Web/CSS/At-rule - css_beautify.NESTED_AT_RULE = { - "@page": true, - "@font-face": true, - "@keyframes": true, - // also in CONDITIONAL_GROUP_RULE below - "@media": true, - "@supports": true, - "@document": true - }; - css_beautify.CONDITIONAL_GROUP_RULE = { - "@media": true, - "@supports": true, - "@document": true - }; - - /*global define */ - if (typeof define === "function" && define.amd) { - // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- ) - define([], function() { - return { - css_beautify: css_beautify - }; - }); - } else if (typeof exports !== "undefined") { - // Add support for CommonJS. Just put this file somewhere on your require.paths - // and you will be able to `var html_beautify = require("beautify").html_beautify`. - exports.css_beautify = css_beautify; - } else if (typeof window !== "undefined") { - // If we're running a web page and don't have either of the above, add our one global - window.css_beautify = css_beautify; - } else if (typeof global !== "undefined") { - // If we don't even have window, try global. - global.css_beautify = css_beautify; - } - -}()); \ No newline at end of file diff --git a/extensions/html/server/src/service/lib/beautify-html.d.ts b/extensions/html/server/src/service/lib/beautify-html.d.ts deleted file mode 100644 index c1d73b09058..00000000000 --- a/extensions/html/server/src/service/lib/beautify-html.d.ts +++ /dev/null @@ -1,85 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ - -export interface IBeautifyHTMLOptions { - /** - * indent and sections - * default false - */ - indent_inner_html?: boolean; - - /** - * indentation size - * default 4 - */ - indent_size?: number; // indentation size, - - /** - * character to indent with - * default space - */ - indent_char?: string; // character to indent with, - - /** - * maximum amount of characters per line (0 = disable) - * default 250 - */ - wrap_line_length?: number; - - /** - * put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. - * "collapse" | "expand" | "end-expand" | "none" - * default "collapse" - */ - brace_style?: string; - - /** - * list of tags, that shouldn't be reformatted - * defaults to inline tags - */ - unformatted?: string[]; - - /** - * "keep"|"separate"|"normal" - * default normal - */ - indent_scripts?: string; - - /** - * whether existing line breaks before elements should be preserved. Only works before elements, not inside tags or for text. - * default true - */ - preserve_newlines?: boolean; - - /** - * maximum number of line breaks to be preserved in one chunk - * default unlimited - */ - max_preserve_newlines?: number; - - /** - * format and indent {{#foo}} and {{/foo}} - * default false - */ - indent_handlebars?: boolean; - - /** - * end with a newline - * default false - */ - end_with_newline?: boolean; - - /** - * List of tags that should have an extra newline before them. - * default [head,body,/html] - */ - extra_liners?: string[]; -} - -export interface IBeautifyHTML { - (value:string, options:IBeautifyHTMLOptions): string; -} - -export declare var html_beautify:IBeautifyHTML; \ No newline at end of file diff --git a/extensions/html/server/src/service/lib/beautify-html.js b/extensions/html/server/src/service/lib/beautify-html.js deleted file mode 100644 index f78652794c3..00000000000 --- a/extensions/html/server/src/service/lib/beautify-html.js +++ /dev/null @@ -1,1023 +0,0 @@ -// copied from https://raw.githubusercontent.com/beautify-web/js-beautify/master/js/lib/beautify-html.js -/*jshint curly:true, eqeqeq:true, laxbreak:true, noempty:false */ -/* - - The MIT License (MIT) - - Copyright (c) 2007-2013 Einar Lielmanis and contributors. - - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS - BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. - - - Style HTML ---------------- - - Written by Nochum Sossonko, (nsossonko@hotmail.com) - - Based on code initially developed by: Einar Lielmanis, - http://jsbeautifier.org/ - - Usage: - style_html(html_source); - - style_html(html_source, options); - - The options are: - indent_inner_html (default false) — indent and sections, - indent_size (default 4) — indentation size, - indent_char (default space) — character to indent with, - wrap_line_length (default 250) - maximum amount of characters per line (0 = disable) - brace_style (default "collapse") - "collapse" | "expand" | "end-expand" | "none" - put braces on the same line as control statements (default), or put braces on own line (Allman / ANSI style), or just put end braces on own line, or attempt to keep them where they are. - unformatted (defaults to inline tags) - list of tags, that shouldn't be reformatted - indent_scripts (default normal) - "keep"|"separate"|"normal" - preserve_newlines (default true) - whether existing line breaks before elements should be preserved - Only works before elements, not inside tags or for text. - max_preserve_newlines (default unlimited) - maximum number of line breaks to be preserved in one chunk - indent_handlebars (default false) - format and indent {{#foo}} and {{/foo}} - end_with_newline (false) - end with a newline - extra_liners (default [head,body,/html]) -List of tags that should have an extra newline before them. - - e.g. - - style_html(html_source, { - 'indent_inner_html': false, - 'indent_size': 2, - 'indent_char': ' ', - 'wrap_line_length': 78, - 'brace_style': 'expand', - 'preserve_newlines': true, - 'max_preserve_newlines': 5, - 'indent_handlebars': false, - 'extra_liners': ['/html'] - }); -*/ - -(function() { - - function trim(s) { - return s.replace(/^\s+|\s+$/g, ''); - } - - function ltrim(s) { - return s.replace(/^\s+/g, ''); - } - - function rtrim(s) { - return s.replace(/\s+$/g,''); - } - - function style_html(html_source, options, js_beautify, css_beautify) { - //Wrapper function to invoke all the necessary constructors and deal with the output. - - var multi_parser, - indent_inner_html, - indent_size, - indent_character, - wrap_line_length, - brace_style, - unformatted, - preserve_newlines, - max_preserve_newlines, - indent_handlebars, - wrap_attributes, - wrap_attributes_indent_size, - end_with_newline, - extra_liners, - eol; - - options = options || {}; - - // backwards compatibility to 1.3.4 - if ((options.wrap_line_length === undefined || parseInt(options.wrap_line_length, 10) === 0) && - (options.max_char !== undefined && parseInt(options.max_char, 10) !== 0)) { - options.wrap_line_length = options.max_char; - } - - indent_inner_html = (options.indent_inner_html === undefined) ? false : options.indent_inner_html; - indent_size = (options.indent_size === undefined) ? 4 : parseInt(options.indent_size, 10); - indent_character = (options.indent_char === undefined) ? ' ' : options.indent_char; - brace_style = (options.brace_style === undefined) ? 'collapse' : options.brace_style; - wrap_line_length = parseInt(options.wrap_line_length, 10) === 0 ? 32786 : parseInt(options.wrap_line_length || 250, 10); - unformatted = options.unformatted || [ - // https://www.w3.org/TR/html5/dom.html#phrasing-content - 'a', 'abbr', 'area', 'audio', 'b', 'bdi', 'bdo', 'br', 'button', 'canvas', 'cite', - 'code', 'data', 'datalist', 'del', 'dfn', 'em', 'embed', 'i', 'iframe', 'img', - 'input', 'ins', 'kbd', 'keygen', 'label', 'map', 'mark', 'math', 'meter', 'noscript', - 'object', 'output', 'progress', 'q', 'ruby', 's', 'samp', /* 'script', */ 'select', 'small', - 'span', 'strong', 'sub', 'sup', 'svg', 'template', 'textarea', 'time', 'u', 'var', - 'video', 'wbr', 'text', - // prexisting - not sure of full effect of removing, leaving in - 'acronym', 'address', 'big', 'dt', 'ins', 'small', 'strike', 'tt', - 'pre', - 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' - ]; - preserve_newlines = (options.preserve_newlines === undefined) ? true : options.preserve_newlines; - max_preserve_newlines = preserve_newlines ? - (isNaN(parseInt(options.max_preserve_newlines, 10)) ? 32786 : parseInt(options.max_preserve_newlines, 10)) - : 0; - indent_handlebars = (options.indent_handlebars === undefined) ? false : options.indent_handlebars; - wrap_attributes = (options.wrap_attributes === undefined) ? 'auto' : options.wrap_attributes; - wrap_attributes_indent_size = (isNaN(parseInt(options.wrap_attributes_indent_size, 10))) ? indent_size : parseInt(options.wrap_attributes_indent_size, 10); - end_with_newline = (options.end_with_newline === undefined) ? false : options.end_with_newline; - extra_liners = (typeof options.extra_liners == 'object') && options.extra_liners ? - options.extra_liners.concat() : (typeof options.extra_liners === 'string') ? - options.extra_liners.split(',') : 'head,body,/html'.split(','); - eol = options.eol ? options.eol : '\n'; - - if(options.indent_with_tabs){ - indent_character = '\t'; - indent_size = 1; - } - - eol = eol.replace(/\\r/, '\r').replace(/\\n/, '\n') - - function Parser() { - - this.pos = 0; //Parser position - this.token = ''; - this.current_mode = 'CONTENT'; //reflects the current Parser mode: TAG/CONTENT - this.tags = { //An object to hold tags, their position, and their parent-tags, initiated with default values - parent: 'parent1', - parentcount: 1, - parent1: '' - }; - this.tag_type = ''; - this.token_text = this.last_token = this.last_text = this.token_type = ''; - this.newlines = 0; - this.indent_content = indent_inner_html; - - this.Utils = { //Uilities made available to the various functions - whitespace: "\n\r\t ".split(''), - - single_token: [ - // HTLM void elements - aka self-closing tags - aka singletons - // https://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements - 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', - 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr', - // NOTE: Optional tags - are not understood. - // https://www.w3.org/TR/html5/syntax.html#optional-tags - // The rules for optional tags are too complex for a simple list - // Also, the content of these tags should still be indented in many cases. - // 'li' is a good exmple. - - // Doctype and xml elements - '!doctype', '?xml', - // ?php tag - '?php', - // other tags that were in this list, keeping just in case - 'basefont', 'isindex' - ], - extra_liners: extra_liners, //for tags that need a line of whitespace before them - in_array: function(what, arr) { - for (var i = 0; i < arr.length; i++) { - if (what === arr[i]) { - return true; - } - } - return false; - } - }; - - // Return true if the given text is composed entirely of whitespace. - this.is_whitespace = function(text) { - for (var n = 0; n < text.length; n++) { - if (!this.Utils.in_array(text.charAt(n), this.Utils.whitespace)) { - return false; - } - } - return true; - }; - - this.traverse_whitespace = function() { - var input_char = ''; - - input_char = this.input.charAt(this.pos); - if (this.Utils.in_array(input_char, this.Utils.whitespace)) { - this.newlines = 0; - while (this.Utils.in_array(input_char, this.Utils.whitespace)) { - if (preserve_newlines && input_char === '\n' && this.newlines <= max_preserve_newlines) { - this.newlines += 1; - } - - this.pos++; - input_char = this.input.charAt(this.pos); - } - return true; - } - return false; - }; - - // Append a space to the given content (string array) or, if we are - // at the wrap_line_length, append a newline/indentation. - // return true if a newline was added, false if a space was added - this.space_or_wrap = function(content) { - if (this.line_char_count >= this.wrap_line_length) { //insert a line when the wrap_line_length is reached - this.print_newline(false, content); - this.print_indentation(content); - return true; - } else { - this.line_char_count++; - content.push(' '); - return false; - } - }; - - this.get_content = function() { //function to capture regular content between tags - var input_char = '', - content = [], - space = false; //if a space is needed - - while (this.input.charAt(this.pos) !== '<') { - if (this.pos >= this.input.length) { - return content.length ? content.join('') : ['', 'TK_EOF']; - } - - if (this.traverse_whitespace()) { - this.space_or_wrap(content); - continue; - } - - if (indent_handlebars) { - // Handlebars parsing is complicated. - // {{#foo}} and {{/foo}} are formatted tags. - // {{something}} should get treated as content, except: - // {{else}} specifically behaves like {{#if}} and {{/if}} - var peek3 = this.input.substr(this.pos, 3); - if (peek3 === '{{#' || peek3 === '{{/') { - // These are tags and not content. - break; - } else if (peek3 === '{{!') { - return [this.get_tag(), 'TK_TAG_HANDLEBARS_COMMENT']; - } else if (this.input.substr(this.pos, 2) === '{{') { - if (this.get_tag(true) === '{{else}}') { - break; - } - } - } - - input_char = this.input.charAt(this.pos); - this.pos++; - this.line_char_count++; - content.push(input_char); //letter at-a-time (or string) inserted to an array - } - return content.length ? content.join('') : ''; - }; - - this.get_contents_to = function(name) { //get the full content of a script or style to pass to js_beautify - if (this.pos === this.input.length) { - return ['', 'TK_EOF']; - } - var input_char = ''; - var content = ''; - var reg_match = new RegExp('', 'igm'); - reg_match.lastIndex = this.pos; - var reg_array = reg_match.exec(this.input); - var end_script = reg_array ? reg_array.index : this.input.length; //absolute end of script - if (this.pos < end_script) { //get everything in between the script tags - content = this.input.substring(this.pos, end_script); - this.pos = end_script; - } - return content; - }; - - this.record_tag = function(tag) { //function to record a tag and its parent in this.tags Object - if (this.tags[tag + 'count']) { //check for the existence of this tag type - this.tags[tag + 'count']++; - this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level - } else { //otherwise initialize this tag type - this.tags[tag + 'count'] = 1; - this.tags[tag + this.tags[tag + 'count']] = this.indent_level; //and record the present indent level - } - this.tags[tag + this.tags[tag + 'count'] + 'parent'] = this.tags.parent; //set the parent (i.e. in the case of a div this.tags.div1parent) - this.tags.parent = tag + this.tags[tag + 'count']; //and make this the current parent (i.e. in the case of a div 'div1') - }; - - this.retrieve_tag = function(tag) { //function to retrieve the opening tag to the corresponding closer - if (this.tags[tag + 'count']) { //if the openener is not in the Object we ignore it - var temp_parent = this.tags.parent; //check to see if it's a closable tag. - while (temp_parent) { //till we reach '' (the initial value); - if (tag + this.tags[tag + 'count'] === temp_parent) { //if this is it use it - break; - } - temp_parent = this.tags[temp_parent + 'parent']; //otherwise keep on climbing up the DOM Tree - } - if (temp_parent) { //if we caught something - this.indent_level = this.tags[tag + this.tags[tag + 'count']]; //set the indent_level accordingly - this.tags.parent = this.tags[temp_parent + 'parent']; //and set the current parent - } - delete this.tags[tag + this.tags[tag + 'count'] + 'parent']; //delete the closed tags parent reference... - delete this.tags[tag + this.tags[tag + 'count']]; //...and the tag itself - if (this.tags[tag + 'count'] === 1) { - delete this.tags[tag + 'count']; - } else { - this.tags[tag + 'count']--; - } - } - }; - - this.indent_to_tag = function(tag) { - // Match the indentation level to the last use of this tag, but don't remove it. - if (!this.tags[tag + 'count']) { - return; - } - var temp_parent = this.tags.parent; - while (temp_parent) { - if (tag + this.tags[tag + 'count'] === temp_parent) { - break; - } - temp_parent = this.tags[temp_parent + 'parent']; - } - if (temp_parent) { - this.indent_level = this.tags[tag + this.tags[tag + 'count']]; - } - }; - - this.get_tag = function(peek) { //function to get a full tag and parse its type - var input_char = '', - content = [], - comment = '', - space = false, - first_attr = true, - tag_start, tag_end, - tag_start_char, - orig_pos = this.pos, - orig_line_char_count = this.line_char_count; - - peek = peek !== undefined ? peek : false; - - do { - if (this.pos >= this.input.length) { - if (peek) { - this.pos = orig_pos; - this.line_char_count = orig_line_char_count; - } - return content.length ? content.join('') : ['', 'TK_EOF']; - } - - input_char = this.input.charAt(this.pos); - this.pos++; - - if (this.Utils.in_array(input_char, this.Utils.whitespace)) { //don't want to insert unnecessary space - space = true; - continue; - } - - if (input_char === "'" || input_char === '"') { - input_char += this.get_unformatted(input_char); - space = true; - - } - - if (input_char === '=') { //no space before = - space = false; - } - - if (content.length && content[content.length - 1] !== '=' && input_char !== '>' && space) { - //no space after = or before > - var wrapped = this.space_or_wrap(content); - var indentAttrs = wrapped && input_char !== '/' && wrap_attributes !== 'force'; - space = false; - if (!first_attr && wrap_attributes === 'force' && input_char !== '/') { - this.print_newline(false, content); - this.print_indentation(content); - indentAttrs = true; - } - if (indentAttrs) { - //indent attributes an auto or forced line-wrap - for (var count = 0; count < wrap_attributes_indent_size; count++) { - content.push(indent_character); - } - } - for (var i = 0; i < content.length; i++) { - if (content[i] === ' ') { - first_attr = false; - break; - } - } - } - - if (indent_handlebars && tag_start_char === '<') { - // When inside an angle-bracket tag, put spaces around - // handlebars not inside of strings. - if ((input_char + this.input.charAt(this.pos)) === '{{') { - input_char += this.get_unformatted('}}'); - if (content.length && content[content.length - 1] !== ' ' && content[content.length - 1] !== '<') { - input_char = ' ' + input_char; - } - space = true; - } - } - - if (input_char === '<' && !tag_start_char) { - tag_start = this.pos - 1; - tag_start_char = '<'; - } - - if (indent_handlebars && !tag_start_char) { - if (content.length >= 2 && content[content.length - 1] === '{' && content[content.length - 2] === '{') { - if (input_char === '#' || input_char === '/' || input_char === '!') { - tag_start = this.pos - 3; - } else { - tag_start = this.pos - 2; - } - tag_start_char = '{'; - } - } - - this.line_char_count++; - content.push(input_char); //inserts character at-a-time (or string) - - if (content[1] && (content[1] === '!' || content[1] === '?' || content[1] === '%')) { //if we're in a comment, do something special - // We treat all comments as literals, even more than preformatted tags - // we just look for the appropriate close tag - content = [this.get_comment(tag_start)]; - break; - } - - if (indent_handlebars && content[1] && content[1] === '{' && content[2] && content[2] === '!') { //if we're in a comment, do something special - // We treat all comments as literals, even more than preformatted tags - // we just look for the appropriate close tag - content = [this.get_comment(tag_start)]; - break; - } - - if (indent_handlebars && tag_start_char === '{' && content.length > 2 && content[content.length - 2] === '}' && content[content.length - 1] === '}') { - break; - } - } while (input_char !== '>'); - - var tag_complete = content.join(''); - var tag_index; - var tag_offset; - - if (tag_complete.indexOf(' ') !== -1) { //if there's whitespace, thats where the tag name ends - tag_index = tag_complete.indexOf(' '); - } else if (tag_complete.charAt(0) === '{') { - tag_index = tag_complete.indexOf('}'); - } else { //otherwise go with the tag ending - tag_index = tag_complete.indexOf('>'); - } - if (tag_complete.charAt(0) === '<' || !indent_handlebars) { - tag_offset = 1; - } else { - tag_offset = tag_complete.charAt(2) === '#' ? 3 : 2; - } - var tag_check = tag_complete.substring(tag_offset, tag_index).toLowerCase(); - if (tag_complete.charAt(tag_complete.length - 2) === '/' || - this.Utils.in_array(tag_check, this.Utils.single_token)) { //if this tag name is a single tag type (either in the list or has a closing /) - if (!peek) { - this.tag_type = 'SINGLE'; - } - } else if (indent_handlebars && tag_complete.charAt(0) === '{' && tag_check === 'else') { - if (!peek) { - this.indent_to_tag('if'); - this.tag_type = 'HANDLEBARS_ELSE'; - this.indent_content = true; - this.traverse_whitespace(); - } - } else if (this.is_unformatted(tag_check, unformatted)) { // do not reformat the "unformatted" tags - comment = this.get_unformatted('', tag_complete); //...delegate to get_unformatted function - content.push(comment); - tag_end = this.pos - 1; - this.tag_type = 'SINGLE'; - } else if (tag_check === 'script' && - (tag_complete.search('type') === -1 || - (tag_complete.search('type') > -1 && - tag_complete.search(/\b(text|application)\/(x-)?(javascript|ecmascript|jscript|livescript|(ld\+)?json)/) > -1))) { - if (!peek) { - this.record_tag(tag_check); - this.tag_type = 'SCRIPT'; - } - } else if (tag_check === 'style' && - (tag_complete.search('type') === -1 || - (tag_complete.search('type') > -1 && tag_complete.search('text/css') > -1))) { - if (!peek) { - this.record_tag(tag_check); - this.tag_type = 'STYLE'; - } - } else if (tag_check.charAt(0) === '!') { //peek for ', - matched = false; - - this.pos = start_pos; - var input_char = this.input.charAt(this.pos); - this.pos++; - - while (this.pos <= this.input.length) { - comment += input_char; - - // only need to check for the delimiter if the last chars match - if (comment.charAt(comment.length - 1) === delimiter.charAt(delimiter.length - 1) && - comment.indexOf(delimiter) !== -1) { - break; - } - - // only need to search for custom delimiter for the first few characters - if (!matched && comment.length < 10) { - if (comment.indexOf(''; - matched = true; - } else if (comment.indexOf(''; - matched = true; - } else if (comment.indexOf(''; - matched = true; - } else if (comment.indexOf(''; - matched = true; - } else if (comment.indexOf('{{!') === 0) { // {{! handlebars comment - delimiter = '}}'; - matched = true; - } else if (comment.indexOf(''; - matched = true; - } else if (comment.indexOf('<%') === 0) { // {{! handlebars comment - delimiter = '%>'; - matched = true; - } - } - - input_char = this.input.charAt(this.pos); - this.pos++; - } - - return comment; - }; - - function tokenMatcher(delimiter) { - var token = ''; - - var add = function (str) { - var newToken = token + str.toLowerCase(); - token = newToken.length <= delimiter.length ? newToken : newToken.substr(newToken.length - delimiter.length, delimiter.length); - }; - - var doesNotMatch = function () { - return token.indexOf(delimiter) === -1; - }; - - return { - add: add, - doesNotMatch: doesNotMatch - }; - } - - this.get_unformatted = function(delimiter, orig_tag) { //function to return unformatted content in its entirety - if (orig_tag && orig_tag.toLowerCase().indexOf(delimiter) !== -1) { - return ''; - } - var input_char = ''; - var content = ''; - var space = true; - - var delimiterMatcher = tokenMatcher(delimiter); - - do { - - if (this.pos >= this.input.length) { - return content; - } - - input_char = this.input.charAt(this.pos); - this.pos++; - - if (this.Utils.in_array(input_char, this.Utils.whitespace)) { - if (!space) { - this.line_char_count--; - continue; - } - if (input_char === '\n' || input_char === '\r') { - content += '\n'; - /* Don't change tab indention for unformatted blocks. If using code for html editing, this will greatly affect
 tags if they are specified in the 'unformatted array'
-                for (var i=0; i]*>\s*$/);
-
-                // if next_tag comes back but is not an isolated tag, then
-                // let's treat the 'a' tag as having content
-                // and respect the unformatted option
-                if (!tag || this.Utils.in_array(tag, unformatted)) {
-                    return true;
-                } else {
-                    return false;
-                }
-            };
-
-            this.printer = function(js_source, indent_character, indent_size, wrap_line_length, brace_style) { //handles input/output and some other printing functions
-
-                this.input = js_source || ''; //gets the input for the Parser
-
-                // HACK: newline parsing inconsistent. This brute force normalizes the input.
-                this.input = this.input.replace(/\r\n|[\r\u2028\u2029]/g, '\n')
-
-                this.output = [];
-                this.indent_character = indent_character;
-                this.indent_string = '';
-                this.indent_size = indent_size;
-                this.brace_style = brace_style;
-                this.indent_level = 0;
-                this.wrap_line_length = wrap_line_length;
-                this.line_char_count = 0; //count to see if wrap_line_length was exceeded
-
-                for (var i = 0; i < this.indent_size; i++) {
-                    this.indent_string += this.indent_character;
-                }
-
-                this.print_newline = function(force, arr) {
-                    this.line_char_count = 0;
-                    if (!arr || !arr.length) {
-                        return;
-                    }
-                    if (force || (arr[arr.length - 1] !== '\n')) { //we might want the extra line
-                        if ((arr[arr.length - 1] !== '\n')) {
-                            arr[arr.length - 1] = rtrim(arr[arr.length - 1]);
-                        }
-                        arr.push('\n');
-                    }
-                };
-
-                this.print_indentation = function(arr) {
-                    for (var i = 0; i < this.indent_level; i++) {
-                        arr.push(this.indent_string);
-                        this.line_char_count += this.indent_string.length;
-                    }
-                };
-
-                this.print_token = function(text) {
-                    // Avoid printing initial whitespace.
-                    if (this.is_whitespace(text) && !this.output.length) {
-                        return;
-                    }
-                    if (text || text !== '') {
-                        if (this.output.length && this.output[this.output.length - 1] === '\n') {
-                            this.print_indentation(this.output);
-                            text = ltrim(text);
-                        }
-                    }
-                    this.print_token_raw(text);
-                };
-
-                this.print_token_raw = function(text) {
-                    // If we are going to print newlines, truncate trailing
-                    // whitespace, as the newlines will represent the space.
-                    if (this.newlines > 0) {
-                        text = rtrim(text);
-                    }
-
-                    if (text && text !== '') {
-                        if (text.length > 1 && text.charAt(text.length - 1) === '\n') {
-                            // unformatted tags can grab newlines as their last character
-                            this.output.push(text.slice(0, -1));
-                            this.print_newline(false, this.output);
-                        } else {
-                            this.output.push(text);
-                        }
-                    }
-
-                    for (var n = 0; n < this.newlines; n++) {
-                        this.print_newline(n > 0, this.output);
-                    }
-                    this.newlines = 0;
-                };
-
-                this.indent = function() {
-                    this.indent_level++;
-                };
-
-                this.unindent = function() {
-                    if (this.indent_level > 0) {
-                        this.indent_level--;
-                    }
-                };
-            };
-            return this;
-        }
-
-        /*_____________________--------------------_____________________*/
-
-        multi_parser = new Parser(); //wrapping functions Parser
-        multi_parser.printer(html_source, indent_character, indent_size, wrap_line_length, brace_style); //initialize starting values
-
-        while (true) {
-            var t = multi_parser.get_token();
-            multi_parser.token_text = t[0];
-            multi_parser.token_type = t[1];
-
-            if (multi_parser.token_type === 'TK_EOF') {
-                break;
-            }
-
-            switch (multi_parser.token_type) {
-                case 'TK_TAG_START':
-                    multi_parser.print_newline(false, multi_parser.output);
-                    multi_parser.print_token(multi_parser.token_text);
-                    if (multi_parser.indent_content) {
-                        multi_parser.indent();
-                        multi_parser.indent_content = false;
-                    }
-                    multi_parser.current_mode = 'CONTENT';
-                    break;
-                case 'TK_TAG_STYLE':
-                case 'TK_TAG_SCRIPT':
-                    multi_parser.print_newline(false, multi_parser.output);
-                    multi_parser.print_token(multi_parser.token_text);
-                    multi_parser.current_mode = 'CONTENT';
-                    break;
-                case 'TK_TAG_END':
-                    //Print new line only if the tag has no content and has child
-                    if (multi_parser.last_token === 'TK_CONTENT' && multi_parser.last_text === '') {
-                        var tag_name = multi_parser.token_text.match(/\w+/)[0];
-                        var tag_extracted_from_last_output = null;
-                        if (multi_parser.output.length) {
-                            tag_extracted_from_last_output = multi_parser.output[multi_parser.output.length - 1].match(/(?:<|{{#)\s*(\w+)/);
-                        }
-                        if (tag_extracted_from_last_output === null ||
-                            (tag_extracted_from_last_output[1] !== tag_name && !multi_parser.Utils.in_array(tag_extracted_from_last_output[1], unformatted))) {
-                            multi_parser.print_newline(false, multi_parser.output);
-                        }
-                    }
-                    multi_parser.print_token(multi_parser.token_text);
-                    multi_parser.current_mode = 'CONTENT';
-                    break;
-                case 'TK_TAG_SINGLE':
-                    // Don't add a newline before elements that should remain unformatted.
-                    var tag_check = multi_parser.token_text.match(/^\s*<([a-z-]+)/i);
-                    if (!tag_check || !multi_parser.Utils.in_array(tag_check[1], unformatted)) {
-                        multi_parser.print_newline(false, multi_parser.output);
-                    }
-                    multi_parser.print_token(multi_parser.token_text);
-                    multi_parser.current_mode = 'CONTENT';
-                    break;
-                case 'TK_TAG_HANDLEBARS_ELSE':
-                    // Don't add a newline if opening {{#if}} tag is on the current line
-                    var foundIfOnCurrentLine = false;
-                    for (var lastCheckedOutput=multi_parser.output.length-1; lastCheckedOutput>=0; lastCheckedOutput--) {
-		        if (multi_parser.output[lastCheckedOutput] === '\n') {
-		            break;
-                        } else {
-                            if (multi_parser.output[lastCheckedOutput].match(/{{#if/)) {
-                                foundIfOnCurrentLine = true;
-                                break;
-                            }
-                        }
-                    }
-                    if (!foundIfOnCurrentLine) {
-                        multi_parser.print_newline(false, multi_parser.output);
-                    }
-                    multi_parser.print_token(multi_parser.token_text);
-                    if (multi_parser.indent_content) {
-                        multi_parser.indent();
-                        multi_parser.indent_content = false;
-                    }
-                    multi_parser.current_mode = 'CONTENT';
-                    break;
-                case 'TK_TAG_HANDLEBARS_COMMENT':
-                    multi_parser.print_token(multi_parser.token_text);
-                    multi_parser.current_mode = 'TAG';
-                    break;
-                case 'TK_CONTENT':
-                    multi_parser.print_token(multi_parser.token_text);
-                    multi_parser.current_mode = 'TAG';
-                    break;
-                case 'TK_STYLE':
-                case 'TK_SCRIPT':
-                    if (multi_parser.token_text !== '') {
-                        multi_parser.print_newline(false, multi_parser.output);
-                        var text = multi_parser.token_text,
-                            _beautifier,
-                            script_indent_level = 1;
-                        if (multi_parser.token_type === 'TK_SCRIPT') {
-                            _beautifier = typeof js_beautify === 'function' && js_beautify;
-                        } else if (multi_parser.token_type === 'TK_STYLE') {
-                            _beautifier = typeof css_beautify === 'function' && css_beautify;
-                        }
-
-                        if (options.indent_scripts === "keep") {
-                            script_indent_level = 0;
-                        } else if (options.indent_scripts === "separate") {
-                            script_indent_level = -multi_parser.indent_level;
-                        }
-
-                        var indentation = multi_parser.get_full_indent(script_indent_level);
-                        if (_beautifier) {
-
-                            // call the Beautifier if avaliable
-                            var Child_options = function() {
-                                this.eol = '\n';
-                            };
-                            Child_options.prototype = options;
-                            var child_options = new Child_options();
-                            text = _beautifier(text.replace(/^\s*/, indentation), child_options);
-                        } else {
-                            // simply indent the string otherwise
-                            var white = text.match(/^\s*/)[0];
-                            var _level = white.match(/[^\n\r]*$/)[0].split(multi_parser.indent_string).length - 1;
-                            var reindent = multi_parser.get_full_indent(script_indent_level - _level);
-                            text = text.replace(/^\s*/, indentation)
-                                .replace(/\r\n|\r|\n/g, '\n' + reindent)
-                                .replace(/\s+$/, '');
-                        }
-                        if (text) {
-                            multi_parser.print_token_raw(text);
-                            multi_parser.print_newline(true, multi_parser.output);
-                        }
-                    }
-                    multi_parser.current_mode = 'TAG';
-                    break;
-                default:
-                    // We should not be getting here but we don't want to drop input on the floor
-                    // Just output the text and move on
-                    if (multi_parser.token_text !== '') {
-                        multi_parser.print_token(multi_parser.token_text);
-                    }
-                    break;
-            }
-            multi_parser.last_token = multi_parser.token_type;
-            multi_parser.last_text = multi_parser.token_text;
-        }
-        var sweet_code = multi_parser.output.join('').replace(/[\r\n\t ]+$/, '');
-
-        // establish end_with_newline
-        if (end_with_newline) {
-            sweet_code += '\n';
-        }
-
-        if (eol != '\n') {
-            sweet_code = sweet_code.replace(/[\n]/g, eol);
-        }
-
-        return sweet_code;
-    }
-
-    if (typeof define === "function" && define.amd) {
-        // Add support for AMD ( https://github.com/amdjs/amdjs-api/wiki/AMD#defineamd-property- )
-        define(["require", "./beautify", "./beautify-css"], function(requireamd) {
-            var js_beautify =  requireamd("./beautify");
-            var css_beautify =  requireamd("./beautify-css");
-
-            return {
-              html_beautify: function(html_source, options) {
-                return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
-              }
-            };
-        });
-    } else if (typeof exports !== "undefined") {
-        // Add support for CommonJS. Just put this file somewhere on your require.paths
-        // and you will be able to `var html_beautify = require("beautify").html_beautify`.
-        var js_beautify = require('./beautify.js');
-        var css_beautify = require('./beautify-css.js');
-
-        exports.html_beautify = function(html_source, options) {
-            return style_html(html_source, options, js_beautify.js_beautify, css_beautify.css_beautify);
-        };
-    } else if (typeof window !== "undefined") {
-        // If we're running a web page and don't have either of the above, add our one global
-        window.html_beautify = function(html_source, options) {
-            return style_html(html_source, options, window.js_beautify, window.css_beautify);
-        };
-    } else if (typeof global !== "undefined") {
-        // If we don't even have window, try global.
-        global.html_beautify = function(html_source, options) {
-            return style_html(html_source, options, global.js_beautify, global.css_beautify);
-        };
-    }
-
-}());
\ No newline at end of file
diff --git a/extensions/html/server/src/service/lib/beautify-html.license.txt b/extensions/html/server/src/service/lib/beautify-html.license.txt
deleted file mode 100644
index a92a60e9a95..00000000000
--- a/extensions/html/server/src/service/lib/beautify-html.license.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-The MIT License (MIT)
-
-Copyright (c) 2007-2013 Einar Lielmanis and contributors.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/extensions/html/server/src/service/lib/beautify.ts b/extensions/html/server/src/service/lib/beautify.ts
deleted file mode 100644
index 8d56533e2ad..00000000000
--- a/extensions/html/server/src/service/lib/beautify.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-/*
- * Mock for the JS formatter. Ignore formatting of JS content in HTML.
- */
-export function js_beautify(js_source_text: string, options: any) {
-	// no formatting
-	return js_source_text;
-}
\ No newline at end of file
diff --git a/extensions/html/server/src/service/parser/htmlParser.ts b/extensions/html/server/src/service/parser/htmlParser.ts
deleted file mode 100644
index 4b973d958dd..00000000000
--- a/extensions/html/server/src/service/parser/htmlParser.ts
+++ /dev/null
@@ -1,123 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  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 { TokenType, createScanner } from './htmlScanner';
-import { findFirst } from '../utils/arrays';
-import { isEmptyElement, isSameTag } from './htmlTags';
-
-export class Node {
-	public tag: string;
-	public closed: boolean;
-	public endTagStart: number;
-	constructor(public start: number, public end: number, public children: Node[], public parent: Node) {
-
-	}
-	public get firstChild(): Node { return this.children[0]; }
-	public get lastChild(): Node { return this.children.length ? this.children[this.children.length - 1] : void 0; }
-
-	public findNodeBefore(offset: number): Node {
-		let idx = findFirst(this.children, c => offset <= c.start) - 1;
-		if (idx >= 0) {
-			let child = this.children[idx];
-			if (offset > child.start) {
-				if (offset < child.end) {
-					return child.findNodeBefore(offset);
-				}
-				let lastChild = child.lastChild;
-				if (lastChild && lastChild.end === child.end) {
-					return child.findNodeBefore(offset);
-				}
-				return child;
-			}
-		}
-		return this;
-	}
-
-	public findNodeAt(offset: number): Node {
-		let idx = findFirst(this.children, c => offset <= c.start) - 1;
-		if (idx >= 0) {
-			let child = this.children[idx];
-			if (offset > child.start && offset <= child.end) {
-				return child.findNodeAt(offset);
-			}
-		}
-		return this;
-	}
-}
-
-export interface HTMLDocument {
-	roots: Node[];
-	findNodeBefore(offset: number): Node;
-	findNodeAt(offset: number): Node;
-}
-
-export function parse(text: string): HTMLDocument {
-	let scanner = createScanner(text);
-
-	let htmlDocument = new Node(0, text.length, [], null);
-	let curr = htmlDocument;
-	let endTagStart: number = -1;
-	let token = scanner.scan();
-	while (token !== TokenType.EOS) {
-		switch (token) {
-			case TokenType.StartTagOpen:
-				let child = new Node(scanner.getTokenOffset(), text.length, [], curr);
-				curr.children.push(child);
-				curr = child;
-				break;
-			case TokenType.StartTag:
-				curr.tag = scanner.getTokenText();
-				break;
-			case TokenType.StartTagClose:
-				curr.end = scanner.getTokenEnd(); // might be later set to end tag position
-				if (isEmptyElement(curr.tag) && curr !== htmlDocument) {
-					curr.closed = true;
-					curr = curr.parent;
-				}
-				break;
-			case TokenType.EndTagOpen:
-				endTagStart = scanner.getTokenOffset();
-				break;
-			case TokenType.EndTag:
-				let closeTag = scanner.getTokenText();
-				while (!isSameTag(curr.tag, closeTag) && curr !== htmlDocument) {
-					curr.end = endTagStart;
-					curr.closed = false;
-					curr = curr.parent;
-				}
-				if (curr !== htmlDocument) {
-					curr.closed = true;
-					curr.endTagStart = endTagStart;
-				}
-				break;
-			case TokenType.StartTagSelfClose:
-				if (curr !== htmlDocument) {
-					curr.closed = true;
-					curr.end = scanner.getTokenEnd();
-					curr = curr.parent;
-				}
-				break;
-			case TokenType.EndTagClose:
-				if (curr !== htmlDocument) {
-					curr.end = scanner.getTokenEnd();
-					curr = curr.parent;
-				}
-				break;
-		}
-		token = scanner.scan();
-	}
-	while (curr !== htmlDocument) {
-		curr.end = text.length;
-		curr.closed = false;
-		curr = curr.parent;
-	}
-	return {
-		roots: htmlDocument.children,
-		findNodeBefore: htmlDocument.findNodeBefore.bind(htmlDocument),
-		findNodeAt: htmlDocument.findNodeAt.bind(htmlDocument)
-	};
-
-}
\ No newline at end of file
diff --git a/extensions/html/server/src/service/parser/htmlScanner.ts b/extensions/html/server/src/service/parser/htmlScanner.ts
deleted file mode 100644
index 5cfa208f1c2..00000000000
--- a/extensions/html/server/src/service/parser/htmlScanner.ts
+++ /dev/null
@@ -1,451 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  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 nls from 'vscode-nls';
-let localize = nls.loadMessageBundle();
-
-export enum TokenType {
-	StartCommentTag,
-	Comment,
-	EndCommentTag,
-	StartTagOpen,
-	StartTagClose,
-	StartTagSelfClose,
-	StartTag,
-	EndTagOpen,
-	EndTagClose,
-	EndTag,
-	DelimiterAssign,
-	AttributeName,
-	AttributeValue,
-	StartDoctypeTag,
-	Doctype,
-	EndDoctypeTag,
-	Content,
-	Whitespace,
-	Unknown,
-	Script,
-	Styles,
-	EOS
-}
-
-export interface IToken {
-	type: TokenType;
-	offset: number;
-	len: number;
-}
-
-class MultiLineStream {
-
-	private source: string;
-	private len: number;
-	private position: number;
-
-	constructor(source: string, position: number) {
-		this.source = source;
-		this.len = source.length;
-		this.position = position;
-	}
-
-	public eos(): boolean {
-		return this.len <= this.position;
-	}
-
-	public getSource(): string {
-		return this.source;
-	}
-
-	public pos(): number {
-		return this.position;
-	}
-
-	public goBackTo(pos: number): void {
-		this.position = pos;
-	}
-
-	public goBack(n: number): void {
-		this.position -= n;
-	}
-
-	public advance(n: number): void {
-		this.position += n;
-	}
-
-	public goToEnd(): void {
-		this.position = this.source.length;
-	}
-
-	public nextChar(): number {
-		return this.source.charCodeAt(this.position++) || 0;
-	}
-
-	public peekChar(n: number = 0): number {
-		return this.source.charCodeAt(this.position + n) || 0;
-	}
-
-	public advanceIfChar(ch: number): boolean {
-		if (ch === this.source.charCodeAt(this.position)) {
-			this.position++;
-			return true;
-		}
-		return false;
-	}
-
-	public advanceIfChars(ch: number[]): boolean {
-		let i: number;
-		if (this.position + ch.length > this.source.length) {
-			return false;
-		}
-		for (i = 0; i < ch.length; i++) {
-			if (this.source.charCodeAt(this.position + i) !== ch[i]) {
-				return false;
-			}
-		}
-		this.advance(i);
-		return true;
-	}
-
-	public advanceIfRegExp(regex: RegExp): string {
-		let str = this.source.substr(this.position);
-		let match = str.match(regex);
-		if (match) {
-			this.position = this.position + match.index + match[0].length;
-			return match[0];
-		}
-		return '';
-	}
-
-	public advanceUntilRegExp(regex: RegExp): string {
-		let str = this.source.substr(this.position);
-		let match = str.match(regex);
-		if (match) {
-			this.position = this.position + match.index;
-			return match[0];
-		}
-		return '';
-	}
-
-	public advanceUntilChar(ch: number): boolean {
-		while (this.position < this.source.length) {
-			if (this.source.charCodeAt(this.position) === ch) {
-				return true;
-			}
-			this.advance(1);
-		}
-		return false;
-	}
-
-	public advanceUntilChars(ch: number[]): boolean {
-		while (this.position + ch.length < this.source.length) {
-			for (let i = 0; i < ch.length; i++) {
-				if (this.source.charCodeAt(this.position + i) !== ch[i]) {
-					break;
-				}
-				return true;
-			}
-			this.advance(1);
-		}
-		return false;
-	}
-
-	public skipWhitespace(): boolean {
-		let n = this.advanceWhileChar(ch => {
-			return ch === _WSP || ch === _TAB || ch === _NWL || ch === _LFD || ch === _CAR;
-		});
-		return n > 0;
-	}
-
-	public advanceWhileChar(condition: (ch: number) => boolean): number {
-		let posNow = this.position;
-		while (this.position < this.len && condition(this.source.charCodeAt(this.position))) {
-			this.position++;
-		}
-		return this.position - posNow;
-	}
-}
-const _BNG = '!'.charCodeAt(0);
-const _MIN = '-'.charCodeAt(0);
-const _LAN = '<'.charCodeAt(0);
-const _RAN = '>'.charCodeAt(0);
-const _FSL = '/'.charCodeAt(0);
-const _EQS = '='.charCodeAt(0);
-const _DQO = '"'.charCodeAt(0);
-const _SQO = '\''.charCodeAt(0);
-const _NWL = '\n'.charCodeAt(0);
-const _CAR = '\r'.charCodeAt(0);
-const _LFD = '\f'.charCodeAt(0);
-const _WSP = ' '.charCodeAt(0);
-const _TAB = '\t'.charCodeAt(0);
-
-
-export enum ScannerState {
-	WithinContent,
-	AfterOpeningStartTag,
-	AfterOpeningEndTag,
-	WithinDoctype,
-	WithinTag,
-	WithinEndTag,
-	WithinComment,
-	WithinScriptContent,
-	WithinStyleContent,
-	AfterAttributeName,
-	BeforeAttributeValue
-}
-
-export interface Scanner {
-	scan(): TokenType;
-	getTokenType(): TokenType;
-	getTokenOffset(): number;
-	getTokenLength(): number;
-	getTokenEnd(): number;
-	getTokenText(): string;
-	getTokenError(): string;
-	getScannerState(): ScannerState;
-}
-
-const htmlScriptContents = {
-	'text/x-handlebars-template': true
-};
-
-export function createScanner(input: string, initialOffset = 0, initialState: ScannerState = ScannerState.WithinContent): Scanner {
-
-	let stream = new MultiLineStream(input, initialOffset);
-	let state = initialState;
-	let tokenOffset: number = 0;
-	let tokenType: number = void 0;
-	let tokenError: string;
-
-	let hasSpaceAfterTag: boolean;
-	let lastTag: string;
-	let lastAttributeName: string;
-	let lastTypeValue: string;
-
-	function nextElementName(): string {
-		return stream.advanceIfRegExp(/^[_:\w][_:\w-.\d]*/).toLowerCase();
-	}
-
-	function nextAttributeName(): string {
-		return stream.advanceIfRegExp(/^[^\s"'>/=\x00-\x0F\x7F\x80-\x9F]*/).toLowerCase();
-	}
-
-	function finishToken(offset: number, type: TokenType, errorMessage?: string): TokenType {
-		tokenType = type;
-		tokenOffset = offset;
-		tokenError = errorMessage;
-		return type;
-	}
-
-	function scan(): TokenType {
-		let offset = stream.pos();
-		if (stream.eos()) {
-			return finishToken(offset, TokenType.EOS);
-		}
-		let errorMessage;
-
-		switch (state) {
-			case ScannerState.WithinComment:
-				if (stream.advanceIfChars([_MIN, _MIN, _RAN])) { // -->
-					state = ScannerState.WithinContent;
-					return finishToken(offset, TokenType.EndCommentTag);
-				}
-				stream.advanceUntilChars([_MIN, _MIN, _RAN]);  // -->
-				return finishToken(offset, TokenType.Comment);
-			case ScannerState.WithinDoctype:
-				if (stream.advanceIfChar(_RAN)) {
-					state = ScannerState.WithinContent;
-					return finishToken(offset, TokenType.EndDoctypeTag);
-				}
-				stream.advanceUntilChar(_RAN); // >
-				return finishToken(offset, TokenType.Doctype);
-			case ScannerState.WithinContent:
-				if (stream.advanceIfChar(_LAN)) { // <
-					if (!stream.eos() && stream.peekChar() === _BNG) { // !
-						if (stream.advanceIfChars([_BNG, _MIN, _MIN])) { // |<\/?script\s*\/?>?/i);
-					if (match.length === 0) {
-						stream.goToEnd();
-						return finishToken(offset, TokenType.Script);
-					} else if (match === '') {
-						sciptState = 1;
-					} else if (match[1] !== '/') { // ', {
-				items: [
-					{ label: 'div', resultText: '' },
-				]
-			})
-		], testDone);
-	});
-
-	test('Complete aria', function (testDone): any {
-		let expectedAriaAttributes = [
-			{ label: 'aria-activedescendant' },
-			{ label: 'aria-atomic' },
-			{ label: 'aria-autocomplete' },
-			{ label: 'aria-busy' },
-			{ label: 'aria-checked' },
-			{ label: 'aria-colcount' },
-			{ label: 'aria-colindex' },
-			{ label: 'aria-colspan' },
-			{ label: 'aria-controls' },
-			{ label: 'aria-current' },
-			{ label: 'aria-describedat' },
-			{ label: 'aria-describedby' },
-			{ label: 'aria-disabled' },
-			{ label: 'aria-dropeffect' },
-			{ label: 'aria-errormessage' },
-			{ label: 'aria-expanded' },
-			{ label: 'aria-flowto' },
-			{ label: 'aria-grabbed' },
-			{ label: 'aria-haspopup' },
-			{ label: 'aria-hidden' },
-			{ label: 'aria-invalid' },
-			{ label: 'aria-kbdshortcuts' },
-			{ label: 'aria-label' },
-			{ label: 'aria-labelledby' },
-			{ label: 'aria-level' },
-			{ label: 'aria-live' },
-			{ label: 'aria-modal' },
-			{ label: 'aria-multiline' },
-			{ label: 'aria-multiselectable' },
-			{ label: 'aria-orientation' },
-			{ label: 'aria-owns' },
-			{ label: 'aria-placeholder' },
-			{ label: 'aria-posinset' },
-			{ label: 'aria-pressed' },
-			{ label: 'aria-readonly' },
-			{ label: 'aria-relevant' },
-			{ label: 'aria-required' },
-			{ label: 'aria-roledescription' },
-			{ label: 'aria-rowcount' },
-			{ label: 'aria-rowindex' },
-			{ label: 'aria-rowspan' },
-			{ label: 'aria-selected' },
-			{ label: 'aria-setsize' },
-			{ label: 'aria-sort' },
-			{ label: 'aria-valuemax' },
-			{ label: 'aria-valuemin' },
-			{ label: 'aria-valuenow' },
-			{ label: 'aria-valuetext' }
-		];
-		run([
-			testCompletionFor('
', { items: expectedAriaAttributes }), - testCompletionFor(' ', { items: expectedAriaAttributes }), - testCompletionFor(' ', { items: expectedAriaAttributes }) - ], testDone); - }); - - test('Complete Angular', function (testDone): any { - run([ - testCompletionFor(' ', { - items: [ - { label: 'ng-controller', resultText: ' ' }, - { label: 'data-ng-controller', resultText: ' ' }, - ] - }), - testCompletionFor('
  • ', { - items: [ - { label: 'ng-repeat', resultText: '
  • ' }, - { label: 'data-ng-repeat', resultText: '
  • ' }, - ] - }), - testCompletionFor(' ', { - items: [ - { label: 'ng-model', resultText: ' ' }, - { label: 'data-ng-model', resultText: ' ' }, - ] - }) - ], testDone); - }); - - test('Complete Ionic', function (testDone): any { - run([ - // Try some Ionic tags - testCompletionFor('<|', { - items: [ - { label: 'ion-checkbox', resultText: ' ', { - items: [ - { label: 'ng-model', notAvailable: true }, - { label: 'type' }, - ] - }, { html5: true, ionic: false, angular1: false }), - ], testDone); - }); -}) diff --git a/extensions/html/server/src/service/test/highlighting.test.ts b/extensions/html/server/src/service/test/highlighting.test.ts deleted file mode 100644 index 6d1892749d6..00000000000 --- a/extensions/html/server/src/service/test/highlighting.test.ts +++ /dev/null @@ -1,69 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {TextDocument} from 'vscode-languageserver-types'; - -export function assertHighlights(value: string, expectedMatches: number[], elementName: string): void { - 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 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('Single', function (): any { - assertHighlights('|', [], null); - assertHighlights('<|html>', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('|', [], null); - assertHighlights('<|/html>', [], null); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('', [1, 8], 'html'); - assertHighlights('|', [], null); - }); - - test('Nested', function (): any { - assertHighlights('|
    ', [], null); - assertHighlights('<|div>', [7, 13], 'div'); - assertHighlights('
    |
    ', [], null); - assertHighlights('
    ', [7, 13], 'div'); - assertHighlights('
    ', [7, 24], 'div'); - assertHighlights('
    ', [12, 18], 'div'); - assertHighlights('
    ', [12, 18], 'div'); - assertHighlights('
    ', [1, 30], 'html'); - assertHighlights('
    ', [7, 13], 'div'); - assertHighlights('
    ', [18, 24], 'div'); - }); - - test('Selfclosed', function (): any { - assertHighlights('<|div/>', [7], 'div'); - assertHighlights('<|br>', [7], 'br'); - assertHighlights('
    ', [12], 'div'); - }); -}); \ No newline at end of file diff --git a/extensions/html/server/src/service/test/links.test.ts b/extensions/html/server/src/service/test/links.test.ts deleted file mode 100644 index 99afc008c87..00000000000 --- a/extensions/html/server/src/service/test/links.test.ts +++ /dev/null @@ -1,85 +0,0 @@ - -/*--------------------------------------------------------------------------------------------- - * 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 {TextDocument} from 'vscode-languageserver-types'; -import * as htmlLanguageService from '../htmlLanguageService'; - -suite('HTML Link Detection', () => { - - function testLinkCreation(modelUrl: string, rootUrl: string, tokenContent: string, expected: string): void { - let document = TextDocument.create(modelUrl, 'html', 0, ``); - let ls = htmlLanguageService.getLanguageService(); - let links = ls.findDocumentLinks(document, rootUrl); - assert.equal(links[0] && links[0].target, expected); - } - - function testLinkDetection(value: string, expectedLinkLocations: number[]): void { - let document = TextDocument.create('test://test/test.html', 'html', 0, value); - - let ls = htmlLanguageService.getLanguageService(); - let links = ls.findDocumentLinks(document, 'test://test'); - assert.deepEqual(links.map(l => l.range.start.character), expectedLinkLocations); - } - - test('Link creation', () => { - testLinkCreation('inmemory://model/1', null, 'javascript:void;', null); - testLinkCreation('inmemory://model/1', null, ' \tjavascript:alert(7);', null); - testLinkCreation('inmemory://model/1', null, ' #relative', null); - testLinkCreation('inmemory://model/1', null, 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt'); - testLinkCreation('inmemory://model/1', null, 'http://www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', null, 'https://www.microsoft.com/', 'https://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', null, '//www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', null, '../../a.js', 'inmemory://model/a.js'); - - testLinkCreation('inmemory://model/1', 'inmemory://model/', 'javascript:void;', null); - testLinkCreation('inmemory://model/1', 'inmemory://model/', ' \tjavascript:alert(7);', null); - testLinkCreation('inmemory://model/1', 'inmemory://model/', ' #relative', null); - testLinkCreation('inmemory://model/1', 'inmemory://model/', 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt'); - testLinkCreation('inmemory://model/1', 'inmemory://model/', 'http://www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', 'inmemory://model/', 'https://www.microsoft.com/', 'https://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', 'inmemory://model/', ' //www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('inmemory://model/1', 'inmemory://model/', '../../a.js', 'inmemory://model/a.js'); - - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'javascript:void;', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, ' \tjavascript:alert(7);', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, ' #relative', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'http://www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'https://www.microsoft.com/', 'https://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, ' //www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'a.js', 'file:///c:/Alex/src/path/to/a.js'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, '/a.js', 'file:///a.js'); - - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'javascript:void;', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', ' \tjavascript:alert(7);', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', ' #relative', null); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', null, 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'http://www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'https://www.microsoft.com/', 'https://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'https://www.microsoft.com/?q=1#h', 'https://www.microsoft.com/?q=1#h'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', ' //www.microsoft.com/', 'http://www.microsoft.com/'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', 'a.js', 'file:///c:/Alex/src/path/to/a.js'); - testLinkCreation('file:///C:/Alex/src/path/to/file.txt', 'file:///C:/Alex/src/', '/a.js', 'file:///c:/Alex/src/a.js'); - - testLinkCreation('https://www.test.com/path/to/file.txt', null, 'file:///C:\\Alex\\src\\path\\to\\file.txt', 'file:///C:\\Alex\\src\\path\\to\\file.txt'); - testLinkCreation('https://www.test.com/path/to/file.txt', null, '//www.microsoft.com/', 'https://www.microsoft.com/'); - testLinkCreation('https://www.test.com/path/to/file.txt', 'https://www.test.com', '//www.microsoft.com/', 'https://www.microsoft.com/'); - - // invalid uris don't throw - testLinkCreation('https://www.test.com/path/to/file.txt', 'https://www.test.com', '%', 'https://www.test.com/path/to/%'); - - // Bug #18314: Ctrl + Click does not open existing file if folder's name starts with 'c' character - testLinkCreation('file:///c:/Alex/working_dir/18314-link-detection/test.html', 'file:///c:/Alex/working_dir/18314-link-detection/', '/class/class.js', 'file:///c:/Alex/working_dir/18314-link-detection/class/class.js'); - }); - - test('Link detection', () => { - testLinkDetection('', [10]); - testLinkDetection('', [9]); - }); - -}); \ No newline at end of file diff --git a/extensions/html/server/src/service/test/parser.test.ts b/extensions/html/server/src/service/test/parser.test.ts deleted file mode 100644 index 5a553ac77c0..00000000000 --- a/extensions/html/server/src/service/test/parser.test.ts +++ /dev/null @@ -1,85 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {Node, HTMLDocument, parse} from '../parser/htmlParser'; - -suite('HTML Parser', () => { - - function toJSON(node: Node): any { - return { tag: node.tag, start: node.start, end: node.end, endTagStart: node.endTagStart, closed: node.closed, children: node.children.map(toJSON) }; - } - - function assertDocument(input: string, expected: any) { - let document = parse(input); - assert.deepEqual(document.roots.map(toJSON), expected); - } - - function assertNodeBefore(input: string, offset: number, expectedTag: string) { - let document = parse(input); - let node = document.findNodeBefore(offset); - assert.equal(node ? node.tag : '', expectedTag, "offset " + offset); - } - - test('Simple', () => { - assertDocument('', [{ tag: 'html', start: 0, end: 13, endTagStart: 6, closed: true, children: [] }]); - assertDocument('', [{ tag: 'html', start: 0, end: 26, endTagStart: 19, closed: true, children: [{ tag: 'body', start: 6, end: 19, endTagStart: 12, closed: true, children: [] }] }]); - assertDocument('', [{ tag: 'html', start: 0, end: 39, endTagStart: 32, closed: true, children: [{ tag: 'head', start: 6, end: 19, endTagStart: 12, closed: true, children: [] }, { tag: 'body', start: 19, end: 32, endTagStart: 25, closed: true, children: [] }] }]); - }); - - test('SelfClose', () => { - assertDocument('
    ', [{ tag: 'br', start: 0, end: 5, endTagStart: void 0, closed: true, children: [] }]); - assertDocument('

    ', [{ tag: 'div', start: 0, end: 29, endTagStart: 23, closed: true, children: [{ tag: 'br', start: 5, end: 10, endTagStart: void 0, closed: true, children: [] }, { tag: 'span', start: 10, end: 23, endTagStart: 16, closed: true, children: [] }] }]); - }); - - test('EmptyTag', () => { - assertDocument('', [{ tag: 'meta', start: 0, end: 6, endTagStart: void 0, closed: true, children: [] }]); - assertDocument('


    ', [{ - tag: 'div', start: 0, end: 53, endTagStart: 47, closed: true, children: [ - { tag: 'input', start: 5, end: 26, endTagStart: void 0, closed: true, children: [] }, - { tag: 'span', start: 26, end: 47, endTagStart: 40, closed: true, children: [{ tag: 'br', start: 32, end: 36, endTagStart: void 0, closed: true, children: [] }, { tag: 'br', start: 36, end: 40, endTagStart: void 0, closed: true, children: [] }] } - ] - }]); - }); - test('MissingTags', () => { - assertDocument('', []); - assertDocument('
    ', [{ tag: 'div', start: 0, end: 11, endTagStart: 5, closed: true, children: [] }]); - assertDocument('
    ', [{ tag: 'div', start: 0, end: 16, endTagStart: void 0, closed: false, children: [{ tag: 'div', start: 5, end: 16, endTagStart: 10, closed: true, children: [] }] }]); - assertDocument('<div>', [{ tag: 'title', start: 0, end: 20, endTagStart: 12, closed: true, children: [{ tag: 'div', start: 7, end: 12, endTagStart: void 0, closed: false, children: [] }] }]); - assertDocument('

    ', [{ tag: 'h1', start: 0, end: 20, endTagStart: 15, closed: true, children: [{ tag: 'div', start: 4, end: 15, endTagStart: void 0, closed: false, children: [{ tag: 'span', start: 9, end: 15, endTagStart: void 0, closed: false, children: [] }] }] }]); - }); - - - test('FindNodeBefore', () => { - let str = '


    '; - assertNodeBefore(str, 0, void 0); - assertNodeBefore(str, 1, 'div'); - assertNodeBefore(str, 5, 'div'); - assertNodeBefore(str, 6, 'input'); - assertNodeBefore(str, 25, 'input'); - assertNodeBefore(str, 26, 'input'); - assertNodeBefore(str, 27, 'span'); - assertNodeBefore(str, 32, 'span'); - assertNodeBefore(str, 33, 'br'); - assertNodeBefore(str, 36, 'br'); - assertNodeBefore(str, 37, 'hr'); - assertNodeBefore(str, 40, 'hr'); - assertNodeBefore(str, 41, 'hr'); - assertNodeBefore(str, 42, 'hr'); - assertNodeBefore(str, 47, 'span'); - assertNodeBefore(str, 48, 'span'); - assertNodeBefore(str, 52, 'span'); - assertNodeBefore(str, 53, 'div'); - }); - - test('FindNodeBefore - incomplete node', () => { - let str = '

    '; - assertNodeBefore(str, 15, 'br'); - assertNodeBefore(str, 18, 'br'); - assertNodeBefore(str, 21, 'div'); - }); - -}); \ No newline at end of file diff --git a/extensions/html/server/src/service/test/scanner.test.ts b/extensions/html/server/src/service/test/scanner.test.ts deleted file mode 100644 index ae73eb845d1..00000000000 --- a/extensions/html/server/src/service/test/scanner.test.ts +++ /dev/null @@ -1,745 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {Scanner, TokenType, ScannerState, createScanner} from '../parser/htmlScanner'; - -suite('HTML Scanner', () => { - - interface Token { - offset: number; - type: TokenType; - content?: string; - } - - function assertTokens(tests: { input: string; tokens: Token[]; }[]) { - - let scannerState = ScannerState.WithinContent; - for (let t of tests) { - let scanner = createScanner(t.input, 0, scannerState); - let tokenType = scanner.scan(); - let actual: Token[] = []; - while (tokenType !== TokenType.EOS) { - let actualToken: Token = { offset: scanner.getTokenOffset(), type: tokenType }; - if (tokenType == TokenType.StartTag || tokenType == TokenType.EndTag) { - actualToken.content = t.input.substr(scanner.getTokenOffset(), scanner.getTokenLength()); - } - actual.push(actualToken); - tokenType = scanner.scan(); - } - assert.deepEqual(actual, t.tokens); - scannerState = scanner.getScannerState(); - } - } - - test('Open Start Tag #1', () => { - assertTokens([{ - input: ' { - assertTokens([{ - input: ' { - assertTokens([{ - input: '< abc', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.Whitespace }, - { offset: 2, type: TokenType.StartTag, content: 'abc' } - ] - } - ]); - }); - - test('Open Start Tag #3', () => { - assertTokens([{ - input: '< abc>', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.Whitespace }, - { offset: 2, type: TokenType.StartTag, content: 'abc' }, - { offset: 5, type: TokenType.StartTagClose }, - ] - } - ]); - }); - - test('Open Start Tag #4', () => { - assertTokens([{ - input: 'i { - assertTokens([{ - input: '<', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen } - ] - } - ]); - }); - - test('Open End Tag', () => { - assertTokens([{ - input: ' { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Complete Start Tag with Whitespace', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('bug 9809 - Complete Start Tag with Namespaceprefix', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'foo:bar' }, - { offset: 8, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Complete End Tag', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.EndTagOpen }, - { offset: 2, type: TokenType.EndTag, content: 'abc' }, - { offset: 5, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Complete End Tag with Whitespace', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.EndTagOpen }, - { offset: 2, type: TokenType.EndTag, content: 'abc' }, - { offset: 5, type: TokenType.Whitespace }, - { offset: 7, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Empty Tag', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.StartTagSelfClose } - ] - } - ]); - }); - - test('Embedded Content #1', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.Whitespace }, - { offset: 8, type: TokenType.AttributeName }, - { offset: 12, type: TokenType.DelimiterAssign }, - { offset: 13, type: TokenType.AttributeValue }, - { offset: 30, type: TokenType.StartTagClose }, - { offset: 31, type: TokenType.Script }, - { offset: 41, type: TokenType.EndTagOpen }, - { offset: 43, type: TokenType.EndTag, content: 'script' }, - { offset: 49, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #2', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.EndTagOpen }, - { offset: 2, type: TokenType.EndTag, content: 'script' }, - { offset: 8, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #3', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.EndTagOpen }, - { offset: 2, type: TokenType.EndTag, content: 'script' }, - { offset: 8, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #4', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.Script }, - { offset: 10, type: TokenType.EndTagOpen }, - { offset: 12, type: TokenType.EndTag, content: 'script' }, - { offset: 18, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #5', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.Whitespace }, - { offset: 8, type: TokenType.AttributeName }, - { offset: 12, type: TokenType.DelimiterAssign }, - { offset: 13, type: TokenType.AttributeValue }, - { offset: 25, type: TokenType.StartTagClose }, - { offset: 26, type: TokenType.Script }, - { offset: 30, type: TokenType.EndTagOpen }, - { offset: 32, type: TokenType.EndTag, content: 'script' }, - { offset: 38, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #6', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 9, type: TokenType.EndTagOpen }, - { offset: 11, type: TokenType.EndTag, content: 'script' }, - { offset: 17, type: TokenType.EndTagClose }, - { offset: 18, type: TokenType.StartTagOpen }, - { offset: 19, type: TokenType.StartTag, content: 'script' }, - { offset: 25, type: TokenType.StartTagClose }, - { offset: 26, type: TokenType.Script }, - { offset: 27, type: TokenType.EndTagOpen }, - { offset: 29, type: TokenType.EndTag, content: 'script' }, - { offset: 35, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #7', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.Whitespace }, - { offset: 8, type: TokenType.AttributeName }, - { offset: 12, type: TokenType.DelimiterAssign }, - { offset: 13, type: TokenType.AttributeValue }, - { offset: 30, type: TokenType.StartTagClose }, - { offset: 31, type: TokenType.EndTagOpen }, - { offset: 33, type: TokenType.EndTag, content: 'script' }, - { offset: 39, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #8', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 18, type: TokenType.EndTagOpen }, - { offset: 20, type: TokenType.EndTag, content: 'script' }, - { offset: 26, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #9', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.Whitespace }, - { offset: 8, type: TokenType.AttributeName }, - { offset: 12, type: TokenType.DelimiterAssign }, - { offset: 13, type: TokenType.AttributeValue }, - { offset: 30, type: TokenType.Whitespace }, - { offset: 31, type: TokenType.AttributeName }, - { offset: 34, type: TokenType.DelimiterAssign }, - { offset: 35, type: TokenType.AttributeValue }, - { offset: 44, type: TokenType.StartTagClose }, - { offset: 45, type: TokenType.EndTagOpen }, - { offset: 47, type: TokenType.EndTag, content: 'script' }, - { offset: 53, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #10', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 44, type: TokenType.EndTagOpen }, - { offset: 46, type: TokenType.EndTag, content: 'script' }, - { offset: 52, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #11', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 41, type: TokenType.EndTagOpen }, - { offset: 43, type: TokenType.EndTag, content: 'script' }, - { offset: 49, type: TokenType.EndTagClose } - ] - } - ]); - }); - - - test('Embedded Content #12', () => { - assertTokens([{ - input: '"); ', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 20, type: TokenType.EndTagOpen }, - { offset: 22, type: TokenType.EndTag, content: 'script' }, - { offset: 28, type: TokenType.EndTagClose }, - { offset: 29, type: TokenType.Content }, - { offset: 33, type: TokenType.EndTagOpen }, - { offset: 35, type: TokenType.EndTag, content: 'script' }, - { offset: 41, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Embedded Content #13', () => { - assertTokens([{ - input: '"); ', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'script' }, - { offset: 7, type: TokenType.StartTagClose }, - { offset: 8, type: TokenType.Script }, - { offset: 24, type: TokenType.EndTagOpen }, - { offset: 26, type: TokenType.EndTag, content: 'script' }, - { offset: 32, type: TokenType.EndTagClose }, - { offset: 33, type: TokenType.Content }, - { offset: 37, type: TokenType.EndTagOpen }, - { offset: 39, type: TokenType.EndTag, content: 'script' }, - { offset: 45, type: TokenType.EndTagClose } - ] - } - ]); - }); - - test('Tag with Attribute', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.AttributeValue }, - { offset: 14, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Empty Attribute Value', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.AttributeValue }, - { offset: 14, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with empty attributes', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.AttributeValue }, - { offset: 11, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Attributes', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.AttributeValue }, - { offset: 14, type: TokenType.Whitespace }, - { offset: 15, type: TokenType.AttributeName }, - { offset: 18, type: TokenType.DelimiterAssign }, - { offset: 19, type: TokenType.AttributeValue }, - { offset: 24, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Attributes, no quotes', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.AttributeValue }, - { offset: 12, type: TokenType.Whitespace }, - { offset: 13, type: TokenType.AttributeName }, - { offset: 16, type: TokenType.DelimiterAssign }, - { offset: 17, type: TokenType.AttributeValue }, - { offset: 24, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Attribute And Whitespace', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.DelimiterAssign }, - { offset: 9, type: TokenType.Whitespace }, - { offset: 11, type: TokenType.AttributeValue }, - { offset: 16, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Attribute And Whitespace #2', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.Whitespace }, - { offset: 9, type: TokenType.DelimiterAssign }, - { offset: 10, type: TokenType.Whitespace }, - { offset: 11, type: TokenType.AttributeValue }, - { offset: 16, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Name-Only-Attribute #1', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Name-Only-Attribute #2', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 8, type: TokenType.Whitespace }, - { offset: 9, type: TokenType.AttributeName }, - { offset: 12, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Interesting Attribute Name', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 11, type: TokenType.DelimiterAssign }, - { offset: 12, type: TokenType.AttributeValue }, - { offset: 17, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Angular Attribute Name', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartTagOpen }, - { offset: 1, type: TokenType.StartTag, content: 'abc' }, - { offset: 4, type: TokenType.Whitespace }, - { offset: 5, type: TokenType.AttributeName }, - { offset: 13, type: TokenType.Whitespace }, - { offset: 14, type: TokenType.AttributeName }, - { offset: 21, type: TokenType.DelimiterAssign }, - { offset: 22, type: TokenType.AttributeValue }, - { offset: 27, type: TokenType.Whitespace }, - { offset: 28, type: TokenType.AttributeName }, - { offset: 35, type: TokenType.DelimiterAssign }, - { offset: 36, type: TokenType.AttributeValue }, - { offset: 50, type: TokenType.Whitespace }, - { offset: 51, type: TokenType.AttributeName }, - { offset: 56, type: TokenType.DelimiterAssign }, - { offset: 57, type: TokenType.AttributeValue }, - { offset: 72, type: TokenType.StartTagClose } - ] - } - ]); - }); - - test('Tag with Invalid Attribute Value', () => { - assertTokens([{ - input: '', - tokens: [ - { offset: 0, type: TokenType.StartDoctypeTag }, - { offset: 9, type: TokenType.Doctype }, - { offset: 23, type: TokenType.EndDoctypeTag } - ] - } - ]); - }); -}); \ No newline at end of file diff --git a/extensions/html/server/src/service/test/textEditSupport.ts b/extensions/html/server/src/service/test/textEditSupport.ts deleted file mode 100644 index 2c1b94b6cf4..00000000000 --- a/extensions/html/server/src/service/test/textEditSupport.ts +++ /dev/null @@ -1,23 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * 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 {TextDocument, TextEdit} from 'vscode-languageserver-types'; -import * as assert from 'assert'; - -export function applyEdits(document: TextDocument, edits: TextEdit[]): string { - let text = document.getText(); - let sortedEdits = edits.sort((a, b) => document.offsetAt(b.range.start) - document.offsetAt(a.range.start)); - let lastOffset = text.length; - sortedEdits.forEach(e => { - let startOffset = document.offsetAt(e.range.start); - let endOffset = document.offsetAt(e.range.end); - assert.ok(startOffset <= endOffset); - assert.ok(endOffset <= lastOffset); - text = text.substring(0, startOffset) + e.newText + text.substring(endOffset, text.length); - lastOffset = startOffset; - }); - return text; -} \ No newline at end of file diff --git a/extensions/html/server/src/service/utils/arrays.ts b/extensions/html/server/src/service/utils/arrays.ts deleted file mode 100644 index 730134f860c..00000000000 --- a/extensions/html/server/src/service/utils/arrays.ts +++ /dev/null @@ -1,44 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -/** - * Takes a sorted array and a function p. The array is sorted in such a way that all elements where p(x) is false - * are located before all elements where p(x) is true. - * @returns the least x for which p(x) is true or array.length if no element fullfills the given function. - */ -export function findFirst(array: T[], p: (x: T) => boolean): number { - let low = 0, high = array.length; - if (high === 0) { - return 0; // no children - } - while (low < high) { - let mid = Math.floor((low + high) / 2); - if (p(array[mid])) { - high = mid; - } else { - low = mid + 1; - } - } - return low; -} - -export function binarySearch(array: T[], key: T, comparator: (op1: T, op2: T) => number): number { - let low = 0, - high = array.length - 1; - - while (low <= high) { - let mid = ((low + high) / 2) | 0; - let comp = comparator(array[mid], key); - if (comp < 0) { - low = mid + 1; - } else if (comp > 0) { - high = mid - 1; - } else { - return mid; - } - } - return -(low + 1); -} \ No newline at end of file diff --git a/extensions/html/server/src/service/utils/paths.ts b/extensions/html/server/src/service/utils/paths.ts deleted file mode 100644 index bc1247dcae9..00000000000 --- a/extensions/html/server/src/service/utils/paths.ts +++ /dev/null @@ -1,76 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -export const enum CharCode { - Slash = 47, - Backslash = 92 -} - -/** - * @returns the directory name of a path. - */ -export function dirname(path: string): string { - var idx = ~path.lastIndexOf('/') || ~path.lastIndexOf('\\'); - if (idx === 0) { - return '.'; - } else if (~idx === 0) { - return path[0]; - } else { - return path.substring(0, ~idx); - } -} - -/** - * @returns the base name of a path. - */ -export function basename(path: string): string { - var idx = ~path.lastIndexOf('/') || ~path.lastIndexOf('\\'); - if (idx === 0) { - return path; - } else if (~idx === path.length - 1) { - return basename(path.substring(0, path.length - 1)); - } else { - return path.substr(~idx + 1); - } -} - -/** - * @returns {{.far}} from boo.far or the empty string. - */ -export function extname(path: string): string { - path = basename(path); - var idx = ~path.lastIndexOf('.'); - return idx ? path.substring(~idx) : ''; -} - -export const join: (...parts: string[]) => string = function () { - // Not using a function with var-args because of how TS compiles - // them to JS - it would result in 2*n runtime cost instead - // of 1*n, where n is parts.length. - - let value = ''; - for (let i = 0; i < arguments.length; i++) { - let part = arguments[i]; - if (i > 0) { - // add the separater between two parts unless - // there already is one - let last = value.charCodeAt(value.length - 1); - if (last !== CharCode.Slash && last !== CharCode.Backslash) { - let next = part.charCodeAt(0); - if (next !== CharCode.Slash && next !== CharCode.Backslash) { - - value += '/'; - } - } - } - value += part; - } - - return value; -}; - - - diff --git a/extensions/html/server/src/service/utils/strings.ts b/extensions/html/server/src/service/utils/strings.ts deleted file mode 100644 index 9fdf7d9320c..00000000000 --- a/extensions/html/server/src/service/utils/strings.ts +++ /dev/null @@ -1,50 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ -'use strict'; - -export function startsWith(haystack: string, needle: string): boolean { - if (haystack.length < needle.length) { - return false; - } - - for (let i = 0; i < needle.length; i++) { - if (haystack[i] !== needle[i]) { - return false; - } - } - - return true; -} - -/** - * Determines if haystack ends with needle. - */ -export function endsWith(haystack: string, needle: string): boolean { - let diff = haystack.length - needle.length; - if (diff > 0) { - return haystack.lastIndexOf(needle) === diff; - } else if (diff === 0) { - return haystack === needle; - } else { - return false; - } -} - -/** - * @returns the length of the common prefix of the two strings. - */ -export function commonPrefixLength(a: string, b: string): number { - - let i: number, - len = Math.min(a.length, b.length); - - for (i = 0; i < len; i++) { - if (a.charCodeAt(i) !== b.charCodeAt(i)) { - return i; - } - } - - return len; -} \ No newline at end of file