Skip to content

Commit 1cec53c

Browse files
committed
[html] folding for embedded JavaScript
1 parent 4339277 commit 1cec53c

2 files changed

Lines changed: 105 additions & 0 deletions

File tree

extensions/html/server/src/modes/javascriptMode.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { HTMLDocumentRegions } from './embeddedSupport';
1212

1313
import * as ts from 'typescript';
1414
import { join } from 'path';
15+
import { FoldingRange, FoldingRangeType } from '../protocol/foldingProvider.proposed';
1516

1617
const FILE_NAME = 'vscode://javascript/1'; // the same 'file' is used for all contents
1718
const JQUERY_D_TS = join(__dirname, '../../lib/jquery.d.ts');
@@ -279,6 +280,27 @@ export function getJavascriptMode(documentRegions: LanguageModelCache<HTMLDocume
279280
}
280281
return [];
281282
},
283+
getFoldingRanges(document: TextDocument, range: Range): FoldingRange[] {
284+
updateCurrentTextDocument(document);
285+
let spans = jsLanguageService.getOutliningSpans(FILE_NAME);
286+
let rangeStartLine = range.start.line;
287+
let rangeEndLine = range.end.line;
288+
let ranges: FoldingRange[] = [];
289+
for (let span of spans) {
290+
let curr = convertRange(currentTextDocument, span.textSpan);
291+
let startLine = curr.start.line;
292+
let endLine = curr.end.line;
293+
if (startLine < endLine && startLine >= rangeStartLine && endLine < rangeEndLine) {
294+
let foldingRange: FoldingRange = { startLine, endLine };
295+
let match = document.getText(curr).match(/^\s*\/(\/\s*#(?:end)?region\b)|([\*\/])/);
296+
if (match) {
297+
foldingRange.type = match[1].length ? FoldingRangeType.Region : FoldingRangeType.Comment;
298+
}
299+
ranges.push(foldingRange);
300+
}
301+
}
302+
return ranges;
303+
},
282304
onDocumentRemoved(document: TextDocument) {
283305
jsDocuments.onDocumentRemoved(document);
284306
},

extensions/html/server/src/test/folding.test.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,89 @@ suite('Object Folding', () => {
105105
assertRanges(input, [r(0, 3, 'region'), r(1, 2, 'region')]);
106106
});
107107

108+
test('Embedded JavaScript', () => {
109+
let input = [
110+
/*0*/'<html>',
111+
/*1*/'<head>',
112+
/*2*/'<script>',
113+
/*3*/'function f() {',
114+
/*4*/'}',
115+
/*5*/'</script>',
116+
/*6*/'</head>',
117+
/*7*/'</html>',
118+
];
119+
assertRanges(input, [r(0, 6), r(1, 5), r(2, 4), r(3, 4)]);
120+
});
121+
122+
test('Embedded JavaScript - mutiple areas', () => {
123+
let input = [
124+
/* 0*/'<html>',
125+
/* 1*/'<head>',
126+
/* 2*/'<script>',
127+
/* 3*/' var x = {',
128+
/* 4*/' foo: true,',
129+
/* 5*/' bar: {}',
130+
/* 6*/' };',
131+
/* 7*/'</script>',
132+
/* 8*/'<script>',
133+
/* 9*/' test(() => {',
134+
/*10*/' f();',
135+
/*11*/' });',
136+
/*12*/'</script>',
137+
/*13*/'</head>',
138+
/*14*/'</html>',
139+
];
140+
assertRanges(input, [r(0, 13), r(1, 12), r(2, 6), r(3, 6), r(8, 11), r(9, 11)]);
141+
});
142+
143+
test('Embedded JavaScript - incomplete', () => {
144+
let input = [
145+
/* 0*/'<html>',
146+
/* 1*/'<head>',
147+
/* 2*/'<script>',
148+
/* 3*/' var x = {',
149+
/* 4*/'</script>',
150+
/* 5*/'<script>',
151+
/* 6*/' });',
152+
/* 7*/'</script>',
153+
/* 8*/'</head>',
154+
/* 9*/'</html>',
155+
];
156+
assertRanges(input, [r(0, 8), r(1, 7), r(2, 3), r(5, 6)]);
157+
});
158+
159+
test('Embedded JavaScript - regions', () => {
160+
let input = [
161+
/* 0*/'<html>',
162+
/* 1*/'<head>',
163+
/* 2*/'<script>',
164+
/* 3*/' // #region Lalala',
165+
/* 4*/' // #region',
166+
/* 5*/' x = 9;',
167+
/* 6*/' // #endregion',
168+
/* 7*/' // #endregion Lalala',
169+
/* 8*/'</script>',
170+
/* 9*/'</head>',
171+
/*10*/'</html>',
172+
];
173+
assertRanges(input, [r(0, 9), r(1, 8), r(2, 7), r(3, 7, 'region'), r(4, 6, 'region')]);
174+
});
175+
176+
// test('Embedded JavaScript - mulit line comment', () => {
177+
// let input = [
178+
// /* 0*/'<html>',
179+
// /* 1*/'<head>',
180+
// /* 2*/'<script>',
181+
// /* 3*/' /*',
182+
// /* 4*/' * Hello',
183+
// /* 5*/' */',
184+
// /* 6*/'</script>',
185+
// /* 7*/'</head>',
186+
// /* 8*/'</html>',
187+
// ];
188+
// assertRanges(input, [r(0, 7), r(1, 6), r(2, 5), r(3, 5, 'comment')]);
189+
// });
190+
108191
test('Test limit', () => {
109192
let input = [
110193
/* 0*/'<div>',

0 commit comments

Comments
 (0)