mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
[html] script end tag is not correctly indented. Fixes #16650
This commit is contained in:
@@ -208,7 +208,6 @@ connection.onDocumentRangeFormatting(formatParams => {
|
||||
ranges.forEach(r => {
|
||||
let mode = r.mode;
|
||||
if (mode && mode.format && enabledModes[mode.getId()] && !r.attributeValue) {
|
||||
console.log(mode.getId());
|
||||
let edits = mode.format(document, r, formatParams.options);
|
||||
pushAll(result, edits);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
import { LanguageModelCache, getLanguageModelCache } from '../languageModelCache';
|
||||
import { SymbolInformation, SymbolKind, CompletionItem, Location, SignatureHelp, SignatureInformation, ParameterInformation, Definition, TextEdit, TextDocument, Diagnostic, DiagnosticSeverity, Range, CompletionItemKind, Hover, MarkedString, DocumentHighlight, DocumentHighlightKind, CompletionList, Position, FormattingOptions } from 'vscode-languageserver-types';
|
||||
import { LanguageMode } from './languageModes';
|
||||
import { getWordAtText, startsWith } from '../utils/strings';
|
||||
import { getWordAtText, startsWith, isWhitespaceOnly, repeat } from '../utils/strings';
|
||||
import { HTMLDocumentRegions } from './embeddedSupport';
|
||||
|
||||
import * as ts from 'typescript';
|
||||
@@ -235,10 +235,15 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
|
||||
},
|
||||
format(document: TextDocument, range: Range, formatParams: FormattingOptions): TextEdit[] {
|
||||
currentTextDocument = jsDocuments.get(document);
|
||||
let initialIndentLevel = computeInitialIndent(document, range, formatParams) + 1;
|
||||
let formatSettings = convertOptions(formatParams, settings && settings.format, initialIndentLevel);
|
||||
let initialIndentLevel = computeInitialIndent(document, range, formatParams);
|
||||
let formatSettings = convertOptions(formatParams, settings && settings.format, initialIndentLevel + 1);
|
||||
let start = currentTextDocument.offsetAt(range.start);
|
||||
let end = currentTextDocument.offsetAt(range.end);
|
||||
let lastLineRange = null;
|
||||
if (range.end.character === 0 || isWhitespaceOnly(currentTextDocument.getText().substr(end - range.end.character, range.end.character))) {
|
||||
end -= range.end.character;
|
||||
lastLineRange = Range.create(Position.create(range.end.line, 0), range.end);
|
||||
}
|
||||
let edits = jsLanguageService.getFormattingEditsForRange(FILE_NAME, start, end, formatSettings);
|
||||
if (edits) {
|
||||
let result = [];
|
||||
@@ -250,6 +255,12 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
|
||||
});
|
||||
}
|
||||
}
|
||||
if (lastLineRange) {
|
||||
result.push({
|
||||
range: lastLineRange,
|
||||
newText: generateIndent(initialIndentLevel, formatParams)
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
@@ -370,4 +381,12 @@ function computeInitialIndent(document: TextDocument, range: Range, options: For
|
||||
i++;
|
||||
}
|
||||
return Math.floor(nChars / tabSize);
|
||||
}
|
||||
|
||||
function generateIndent(level: number, options: FormattingOptions) {
|
||||
if (options.insertSpaces) {
|
||||
return repeat(' ', level * options.tabSize);
|
||||
} else {
|
||||
return repeat('\t', level);
|
||||
}
|
||||
}
|
||||
@@ -53,12 +53,16 @@ suite('HTML Embedded Formatting', () => {
|
||||
test('HTML & Scripts', function (): any {
|
||||
assertFormat('<html><head><script></script></head></html>', '<html>\n\n<head>\n <script></script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head><script>var x=1;</script></head></html>', '<html>\n\n<head>\n <script>var x = 1;</script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head><script>\nvar x=1;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n</script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head>\n <script>\nvar x=1;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n</script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head>\n <script>\nvar x=1;\nconsole.log("Hi");\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 1;\n console.log("Hi");\n</script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head><script>\nvar x=2;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 2;\n</script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head>\n <script>\nvar x=3;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 3;\n </script>\n</head>\n\n</html>');
|
||||
assertFormat('<html><head>\n <script>\nvar x=4;\nconsole.log("Hi");\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 4;\n console.log("Hi");\n </script>\n</head>\n\n</html>');
|
||||
|
||||
assertFormat('<html><head>\n |<script>\nvar x=1;\n</script>|</head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
|
||||
assertFormat('<html><head>\n <script>\n|var x=1;|\n</script></head></html>', '<html><head>\n <script>\n var x = 1;\n</script></head></html>');
|
||||
assertFormat('<html><head>\n |<script>\nvar x=5;\n</script>|</head></html>', '<html><head>\n <script>\n var x = 5;\n </script></head></html>');
|
||||
assertFormat('<html><head>\n <script>\n|var x=6;|\n</script></head></html>', '<html><head>\n <script>\n var x = 6;\n</script></head></html>');
|
||||
});
|
||||
|
||||
test('Script end tag', function (): any {
|
||||
assertFormat('<html>\n<head>\n <script>\nvar x = 0;\n</script></head></html>', '<html>\n\n<head>\n <script>\n var x = 0;\n </script>\n</head>\n\n</html>');
|
||||
});
|
||||
|
||||
test('HTML & Multiple Scripts', function (): any {
|
||||
@@ -94,7 +98,13 @@ function pushAll<T>(to: T[], from: T[]) {
|
||||
|
||||
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 sortedEdits = edits.sort((a, b) => {
|
||||
let startDiff = document.offsetAt(b.range.start) - document.offsetAt(a.range.start);
|
||||
if (startDiff === 0) {
|
||||
return document.offsetAt(b.range.end) - document.offsetAt(a.range.end);
|
||||
}
|
||||
return startDiff;
|
||||
});
|
||||
let lastOffset = text.length;
|
||||
sortedEdits.forEach(e => {
|
||||
let startOffset = document.offsetAt(e.range.start);
|
||||
|
||||
@@ -41,6 +41,22 @@ export function startsWith(haystack: string, needle: string): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
export function repeat(value: string, count: number) {
|
||||
var s = '';
|
||||
while (count > 0) {
|
||||
if ((count & 1) === 1) {
|
||||
s += value;
|
||||
}
|
||||
value += value;
|
||||
count = count >>> 1;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
export function isWhitespaceOnly(str: string) {
|
||||
return /^\s*$/.test(str);
|
||||
}
|
||||
|
||||
|
||||
const CR = '\r'.charCodeAt(0);
|
||||
const NL = '\n'.charCodeAt(0);
|
||||
|
||||
Reference in New Issue
Block a user