in lsp-embedded-request-forwarding/client/src/embeddedSupport.ts [52:144]
export function getCSSVirtualContent(
languageService: LanguageService,
documentText: string
): string {
const regions: EmbeddedRegion[] = [];
const scanner = languageService.createScanner(documentText);
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 = documentText[start];
if (firstChar === "'" || firstChar === '"') {
start++;
end--;
}
regions.push({
languageId: attributeLanguageId,
start,
end,
attributeValue: true
});
}
}
lastAttributeName = null;
break;
}
token = scanner.scan();
}
let content = documentText
.split('\n')
.map(line => {
return ' '.repeat(line.length);
}).join('\n');
regions.forEach(r => {
if (r.languageId === 'css') {
content = content.slice(0, r.start) + documentText.slice(r.start, r.end) + content.slice(r.end);
}
});
return content;
}