提交 ff3c4035 编写于 作者: M Martin Aeschlimann

[html] folding for self-closing tags

上级 294337b0
......@@ -8,6 +8,7 @@ import { LanguageService as HTMLLanguageService, TokenType, Range } from 'vscode
import { FoldingRangeType, FoldingRange, FoldingRangeList } from '../protocol/foldingProvider.proposed';
import { LanguageModes } from './languageModes';
import { binarySearch } from '../utils/arrays';
export function getFoldingRegions(languageModes: LanguageModes, document: TextDocument, maxRanges: number | undefined, cancellationToken: CancellationToken | null): FoldingRangeList {
let htmlMode = languageModes.getMode('html');
......@@ -90,6 +91,11 @@ function limitRanges(ranges: FoldingRange[], maxRanges: number) {
return ranges.filter((r, index) => (typeof nestingLevels[index] === 'number') && nestingLevels[index] < maxLevel);
}
export const EMPTY_ELEMENTS: string[] = ['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', 'meta', 'param', 'source', 'track', 'wbr'];
export function isEmptyElement(e: string): boolean {
return !!e && binarySearch(EMPTY_ELEMENTS, e.toLowerCase(), (s1: string, s2: string) => s1.localeCompare(s2)) >= 0;
}
export function getHTMLFoldingRegions(htmlLanguageService: HTMLLanguageService, document: TextDocument, range: Range): FoldingRange[] {
const scanner = htmlLanguageService.createScanner(document.getText());
......@@ -121,6 +127,11 @@ export function getHTMLFoldingRegions(htmlLanguageService: HTMLLanguageService,
lastTagName = scanner.getTokenText();
break;
}
case TokenType.StartTagClose:
if (!isEmptyElement(lastTagName)) {
break;
}
// fallthrough
case TokenType.EndTagClose:
case TokenType.StartTagSelfClose: {
let name = elementNames.pop();
......
......@@ -69,19 +69,20 @@ suite('Object Folding', () => {
assertRanges(input, [r(0, 6), r(1, 2), r(4, 5)]);
});
// test('Fold self-closing tags', () => {
// let input = [
// /*0*/'<div>',
// /*1*/'<a src="top">',
// /*2*/'<img ',
// /*3*/'</head>',
// /*4*/'<body class="f">',
// /*5*/'Body',
// /*6*/'</body>',
// /*7*/'</html>'
// ];
// assertRanges(input, [r(0, 6), r(1, 2), r(4, 5)]);
// });
test('Fold self-closing tags', () => {
let input = [
/*0*/'<div>',
/*1*/'<a href="top"/>',
/*2*/'<img src="s">',
/*3*/'<br/>',
/*4*/'<br>',
/*5*/'<img class="c"',
/*6*/' src="top"',
/*7*/'>',
/*8*/'</div>'
];
assertRanges(input, [r(0, 7), r(5, 6)]);
});
// test('Fold commment', () => {
// let input = [
......
......@@ -57,3 +57,21 @@ function _divideAndMerge<T>(data: T[], compare: (a: T, b: T) => number): void {
data[i++] = right[rightIdx++];
}
}
export function binarySearch<T>(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);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册