mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 09:18:59 +00:00
[html] folding for self-closing tags
This commit is contained in:
parent
294337b0dc
commit
ff3c40353b
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue