"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.preprocessHTML = exports.parseHTML = void 0; const language_core_1 = require("@volar/language-core"); const html = __importStar(require("vscode-html-languageservice")); const utils_1 = require("../plugins/utils"); const htmlLs = html.getLanguageService(); function parseHTML(fileName, snapshot, frontmatterEnd) { const htmlContent = preprocessHTML(snapshot.getText(0, snapshot.getLength()), frontmatterEnd); return { virtualFile: getHTMLVirtualFile(fileName, htmlContent), htmlDocument: getHTMLDocument(htmlContent), }; } exports.parseHTML = parseHTML; const createScanner = htmlLs.createScanner; /** * scan the text and remove any `>` or `<` that cause the tag to end short */ function preprocessHTML(text, frontmatterEnd) { let content = text.split('').fill(' ', 0, frontmatterEnd).join(''); let scanner = createScanner(content); let token = scanner.scan(); let currentStartTagStart = null; while (token !== html.TokenType.EOS) { const offset = scanner.getTokenOffset(); if (token === html.TokenType.StartTagOpen) { currentStartTagStart = offset; } if (token === html.TokenType.StartTagClose) { if (shouldBlankStartOrEndTagLike(offset)) { blankStartOrEndTagLike(offset); } else { currentStartTagStart = null; } } if (token === html.TokenType.StartTagSelfClose) { currentStartTagStart = null; } // // https://github.com/microsoft/vscode-html-languageservice/blob/71806ef57be07e1068ee40900ef8b0899c80e68a/src/parser/htmlScanner.ts#L327 if (token === html.TokenType.Unknown && scanner.getScannerState() === html.ScannerState.WithinTag && scanner.getTokenText() === '<' && shouldBlankStartOrEndTagLike(offset)) { blankStartOrEndTagLike(offset); } // TODO: Handle TypeScript generics inside expressions / Use the compiler to parse HTML instead? token = scanner.scan(); } return content; function shouldBlankStartOrEndTagLike(offset) { // not null rather than falsy, otherwise it won't work on first tag(0) return (currentStartTagStart !== null && (0, utils_1.isInsideExpression)(content, currentStartTagStart, offset)); } function blankStartOrEndTagLike(offset, state) { content = content.substring(0, offset) + ' ' + content.substring(offset + 1); scanner = createScanner(content, offset, state ?? html.ScannerState.WithinTag); } } exports.preprocessHTML = preprocessHTML; function getHTMLVirtualFile(fileName, preprocessedHTML) { return { fileName: fileName + `.html`, kind: language_core_1.FileKind.TextFile, snapshot: { getText: (start, end) => preprocessedHTML.substring(start, end), getLength: () => preprocessedHTML.length, getChangeRange: () => undefined, }, codegenStacks: [], mappings: [ { sourceRange: [0, preprocessedHTML.length], generatedRange: [0, preprocessedHTML.length], data: language_core_1.FileRangeCapabilities.full, }, ], capabilities: { documentSymbol: true, foldingRange: true, documentFormatting: false, }, embeddedFiles: [], }; } function getHTMLDocument(preprocessedHTML) { return htmlLs.parseHTMLDocument({ getText: () => preprocessedHTML }); } //# sourceMappingURL=parseHTML.js.map