export function getDocumentRegions()

in lsp-embedded-request-forwarding/client/src/embeddedSupport.ts [147:234]


export function getDocumentRegions(
	languageService: LanguageService,
	document: TextDocument
): HTMLDocumentRegions {
	const regions: EmbeddedRegion[] = [];
	const scanner = languageService.createScanner(document.getText());
	let lastTagName = '';
	let lastAttributeName: string | null = null;
	let languageIdFromType: string | undefined = undefined;
	const importedScripts: string[] = [];

	let token = scanner.scan();
	while (token !== TokenType.EOS) {
		switch (token) {
			case TokenType.StartTag:
				lastTagName = scanner.getTokenText();
				lastAttributeName = null;
				languageIdFromType = 'javascript';
				break;
			case TokenType.Styles:
				regions.push({
					languageId: 'css',
					start: scanner.getTokenOffset(),
					end: scanner.getTokenEnd()
				});
				break;
			case TokenType.Script:
				regions.push({
					languageId: languageIdFromType,
					start: scanner.getTokenOffset(),
					end: scanner.getTokenEnd()
				});
				break;
			case TokenType.AttributeName:
				lastAttributeName = scanner.getTokenText();
				break;
			case TokenType.AttributeValue:
				if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
					let value = scanner.getTokenText();
					if (value[0] === "'" || value[0] === '"') {
						value = value.substr(1, value.length - 1);
					}
					importedScripts.push(value);
				} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
					if (
						/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(
							scanner.getTokenText()
						)
					) {
						languageIdFromType = 'javascript';
					} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
						languageIdFromType = 'typescript';
					} else {
						languageIdFromType = undefined;
					}
				} else {
					const attributeLanguageId = getAttributeLanguage(lastAttributeName!);
					if (attributeLanguageId) {
						let start = scanner.getTokenOffset();
						let end = scanner.getTokenEnd();
						const firstChar = document.getText()[start];
						if (firstChar === "'" || firstChar === '"') {
							start++;
							end--;
						}
						regions.push({
							languageId: attributeLanguageId,
							start,
							end,
							attributeValue: true
						});
					}
				}
				lastAttributeName = null;
				break;
		}
		token = scanner.scan();
	}
	return {
		getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
		getEmbeddedDocument: (languageId: string, ignoreAttributeValues: boolean) =>
			getEmbeddedDocument(document, regions, languageId, ignoreAttributeValues),
		getLanguageAtPosition: (position: Position) =>
			getLanguageAtPosition(document, regions, position),
		getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
		getImportedScripts: () => importedScripts
	};
}