diff --git a/extensions/emmet/src/selectItemHTML.ts b/extensions/emmet/src/selectItemHTML.ts
index f818f5783a3..6400913396c 100644
--- a/extensions/emmet/src/selectItemHTML.ts
+++ b/extensions/emmet/src/selectItemHTML.ts
@@ -19,7 +19,7 @@ export function nextItemHTML(document: vscode.TextDocument, selectionStart: vsco
if (currentNode.type !== 'comment') {
// If cursor is in the tag name, select tag
if (currentNode.open &&
- selectionEndOffset < currentNode.open.start + currentNode.name.length) {
+ selectionEndOffset <= currentNode.open.start + currentNode.name.length) {
return getSelectionFromNode(document, currentNode);
}
diff --git a/extensions/emmet/src/util.ts b/extensions/emmet/src/util.ts
index 831414126cd..572037fd8fd 100644
--- a/extensions/emmet/src/util.ts
+++ b/extensions/emmet/src/util.ts
@@ -376,32 +376,36 @@ export const allowedMimeTypesInScriptTag = ['text/html', 'text/plain', 'text/x-t
* If position is inside a script tag of type template, then it will be parsed to find the inner HTML node as well
*/
export function getHtmlFlatNode(documentText: string, root: FlatNode | undefined, offset: number, includeNodeBoundary: boolean): HtmlFlatNode | undefined {
- const currentNode: HtmlFlatNode | undefined = getFlatNode(root, offset, includeNodeBoundary);
+ let currentNode: HtmlFlatNode | undefined = getFlatNode(root, offset, includeNodeBoundary);
if (!currentNode) { return; }
- const isTemplateScript = currentNode.name === 'script' &&
- (currentNode.attributes &&
- currentNode.attributes.some(x => x.name.toString() === 'type'
- && allowedMimeTypesInScriptTag.includes(x.value.toString())));
- if (isTemplateScript
- && currentNode.open
- && offset > currentNode.open.end
- && (!currentNode.close || offset < currentNode.close.start)) {
- // blank out the rest of the document and search for the node within
- const beforePadding = ' '.repeat(currentNode.open.end);
- const endToUse = currentNode.close ? currentNode.close.start : currentNode.end;
- const scriptBodyText = beforePadding + documentText.substring(currentNode.open.end, endToUse);
- const innerRoot: HtmlFlatNode = parse(scriptBodyText);
- const scriptBodyNode = getHtmlFlatNode(scriptBodyText, innerRoot, offset, includeNodeBoundary);
- if (scriptBodyNode) {
- scriptBodyNode.parent = currentNode;
- currentNode.children.push(scriptBodyNode);
- return scriptBodyNode;
- }
+ // If the currentNode is a script one, first set up its subtree and then find HTML node.
+ if (currentNode.name === 'script' && currentNode.children.length === 0) {
+ setUpScriptNodeSubtree(documentText, currentNode);
+ currentNode = getFlatNode(currentNode, offset, includeNodeBoundary) ?? currentNode;
}
return currentNode;
}
+export function setUpScriptNodeSubtree(documentText: string, scriptNode: HtmlFlatNode): void {
+ const isTemplateScript = scriptNode.name === 'script' &&
+ (scriptNode.attributes &&
+ scriptNode.attributes.some(x => x.name.toString() === 'type'
+ && allowedMimeTypesInScriptTag.includes(x.value.toString())));
+ if (isTemplateScript
+ && scriptNode.open) {
+ // blank out the rest of the document and generate the subtree.
+ const beforePadding = ' '.repeat(scriptNode.open.end);
+ const endToUse = scriptNode.close ? scriptNode.close.start : scriptNode.end;
+ const scriptBodyText = beforePadding + documentText.substring(scriptNode.open.end, endToUse);
+ const innerRoot: HtmlFlatNode = parse(scriptBodyText);
+ innerRoot.children.forEach(child => {
+ scriptNode.children.push(child);
+ child.parent = scriptNode;
+ });
+ }
+}
+
export function isOffsetInsideOpenOrCloseTag(node: FlatNode, offset: number): boolean {
const htmlNode = node as HtmlFlatNode;
if ((htmlNode.open && offset > htmlNode.open.start && offset < htmlNode.open.end)