未验证 提交 cb994975 编写于 作者: P Pine 提交者: GitHub

Merge pull request #78207 from microsoft/pine/fast-emmet

Redo emmet change. Fix #70371
{ {
// Use IntelliSense to learn about possible Node.js debug attributes. // Use IntelliSense to learn about possible Node.js debug attributes.
// Hover to view descriptions of existing attributes. // Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"type": "extensionHost", "type": "extensionHost",
"request": "launch", "request": "launch",
"name": "Launch Extension", "name": "Launch Extension",
"runtimeExecutable": "${execPath}", "runtimeExecutable": "${execPath}",
"args": [ "args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"--extensionDevelopmentPath=${workspaceFolder}" "sourceMaps": true,
], "outFiles": ["${workspaceFolder}/out/**/*.js"]
"sourceMaps": true, },
"outFiles": [ {
"${workspaceFolder}/out/**/*.js" "type": "extensionHost",
] "request": "launch",
} "name": "Launch Tests",
] "runtimeExecutable": "${execPath}",
} "args": [
\ No newline at end of file "--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/test",
"--disable-extensions",
"--skip-getting-started",
],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/out/**/*.js"]
}
]
}
...@@ -3,8 +3,8 @@ ...@@ -3,8 +3,8 @@
"displayName": "Emmet", "displayName": "Emmet",
"description": "%description%", "description": "%description%",
"version": "1.0.0", "version": "1.0.0",
"publisher": "vscode", "publisher": "vscode",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"vscode": "^1.13.0" "vscode": "^1.13.0"
}, },
...@@ -450,6 +450,7 @@ ...@@ -450,6 +450,7 @@
"@emmetio/html-matcher": "^0.3.3", "@emmetio/html-matcher": "^0.3.3",
"@emmetio/math-expression": "^0.1.1", "@emmetio/math-expression": "^0.1.1",
"image-size": "^0.5.2", "image-size": "^0.5.2",
"vscode-emmet-helper": "^1.2.15" "vscode-emmet-helper": "^1.2.15",
"vscode-html-languageservice": "^3.0.3"
} }
} }
...@@ -635,7 +635,7 @@ function expandAbbr(input: ExpandAbbreviationInput): string { ...@@ -635,7 +635,7 @@ function expandAbbr(input: ExpandAbbreviationInput): string {
return expandedText; return expandedText;
} }
function getSyntaxFromArgs(args: { [x: string]: string }): string | undefined { export function getSyntaxFromArgs(args: { [x: string]: string }): string | undefined {
const mappedModes = getMappingForIncludedLanguages(); const mappedModes = getMappingForIncludedLanguages();
const language: string = args['language']; const language: string = args['language'];
const parentMode: string = args['parentMode']; const parentMode: string = args['parentMode'];
......
...@@ -5,13 +5,16 @@ ...@@ -5,13 +5,16 @@
import * as vscode from 'vscode'; import * as vscode from 'vscode';
import { Node, Stylesheet } from 'EmmetNode'; import { Node, Stylesheet } from 'EmmetNode';
import { isValidLocationForEmmetAbbreviation } from './abbreviationActions'; import { isValidLocationForEmmetAbbreviation, getSyntaxFromArgs } from './abbreviationActions';
import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, parseDocument, getEmbeddedCssNodeIfAny, isStyleAttribute, getNode } from './util'; import { getEmmetHelper, getMappingForIncludedLanguages, parsePartialStylesheet, getEmmetConfiguration, getEmmetMode, isStyleSheet, parseDocument, getNode, allowedMimeTypesInScriptTag, trimQuotes } from './util';
import { getLanguageService, TextDocument, TokenType } from 'vscode-html-languageservice';
export class DefaultCompletionItemProvider implements vscode.CompletionItemProvider { export class DefaultCompletionItemProvider implements vscode.CompletionItemProvider {
private lastCompletionType: string | undefined; private lastCompletionType: string | undefined;
private htmlLS = getLanguageService();
public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, _: vscode.CancellationToken, context: vscode.CompletionContext): Thenable<vscode.CompletionList | undefined> | undefined { public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, _: vscode.CancellationToken, context: vscode.CompletionContext): Thenable<vscode.CompletionList | undefined> | undefined {
const completionResult = this.provideCompletionItemsInternal(document, position, context); const completionResult = this.provideCompletionItemsInternal(document, position, context);
if (!completionResult) { if (!completionResult) {
...@@ -76,20 +79,55 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi ...@@ -76,20 +79,55 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
} }
if (validateLocation) { if (validateLocation) {
rootNode = parseDocument(document, false); const lsDoc = TextDocument.create(document.uri.toString(), 'html', 0, document.getText());
currentNode = getNode(rootNode, position, true); const parsedLsDoc = this.htmlLS.parseHTMLDocument(lsDoc);
if (isStyleAttribute(currentNode, position)) { const positionOffset = document.offsetAt(position);
const node = parsedLsDoc.findNodeAt(positionOffset);
if (node.tag === 'script') {
if (node.attributes && 'type' in node.attributes) {
const rawTypeAttrValue = node.attributes['type'];
if (rawTypeAttrValue) {
const typeAttrValue = trimQuotes(rawTypeAttrValue);
if (typeAttrValue === 'application/javascript' || typeAttrValue === 'text/javascript') {
if (!getSyntaxFromArgs({ language: 'javascript' })) {
return;
} else {
validateLocation = false;
}
}
else if (allowedMimeTypesInScriptTag.indexOf(trimQuotes(rawTypeAttrValue)) > -1) {
validateLocation = false;
}
}
} else {
return;
}
}
else if (node.tag === 'style') {
syntax = 'css'; syntax = 'css';
validateLocation = false; validateLocation = false;
} else { } else {
const embeddedCssNode = getEmbeddedCssNodeIfAny(document, currentNode, position); if (node.attributes && node.attributes['style']) {
if (embeddedCssNode) { const scanner = this.htmlLS.createScanner(document.getText(), node.start);
currentNode = getNode(embeddedCssNode, position, true); let tokenType = scanner.scan();
syntax = 'css'; let prevAttr = undefined;
while (tokenType !== TokenType.EOS && (scanner.getTokenEnd() <= positionOffset)) {
tokenType = scanner.scan();
if (tokenType === TokenType.AttributeName) {
prevAttr = scanner.getTokenText();
}
}
if (prevAttr === 'style') {
syntax = 'css';
validateLocation = false;
}
} }
} }
} }
} }
const extractAbbreviationResults = helper.extractAbbreviation(document, position, !isStyleSheet(syntax)); const extractAbbreviationResults = helper.extractAbbreviation(document, position, !isStyleSheet(syntax));
......
...@@ -264,16 +264,6 @@ suite('Tests for Expand Abbreviations (HTML)', () => { ...@@ -264,16 +264,6 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
}); });
}); });
test('No expanding text in completion list inside style tag if position is not for property name (HTML)', () => {
return withRandomFileEditor(htmlContents, 'html', (editor, _doc) => {
editor.selection = new Selection(13, 14, 13, 14);
const cancelSrc = new CancellationTokenSource();
const completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token, { triggerKind: CompletionTriggerKind.Invoke });
assert.equal(!completionPromise, true, `Got unexpected comapletion promise instead of undefined`);
return Promise.resolve();
});
});
test('Expand css when inside style attribute (HTML)', () => { test('Expand css when inside style attribute (HTML)', () => {
const styleAttributeContent = '<div style="m10" class="hello"></div>'; const styleAttributeContent = '<div style="m10" class="hello"></div>';
return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => { return withRandomFileEditor(styleAttributeContent, 'html', async (editor, _doc) => {
......
...@@ -608,3 +608,18 @@ export function isStyleAttribute(currentNode: Node | null, position: vscode.Posi ...@@ -608,3 +608,18 @@ export function isStyleAttribute(currentNode: Node | null, position: vscode.Posi
} }
export function trimQuotes(s: string) {
if (s.length <= 1) {
return s.replace(/['"]/, '');
}
if (s[0] === `'` || s[0] === `"`) {
s = s.slice(1);
}
if (s[s.length - 1] === `'` || s[s.length - 1] === `"`) {
s = s.slice(0, -1);
}
return s;
}
\ No newline at end of file
...@@ -2478,11 +2478,35 @@ vscode-emmet-helper@^1.2.15: ...@@ -2478,11 +2478,35 @@ vscode-emmet-helper@^1.2.15:
jsonc-parser "^1.0.0" jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.6.0-next.1" vscode-languageserver-types "^3.6.0-next.1"
vscode-html-languageservice@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz#0aeae18a59000e317447ea34965f72680a2140ef"
integrity sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==
dependencies:
vscode-languageserver-types "^3.15.0-next.2"
vscode-nls "^4.1.1"
vscode-uri "^2.0.3"
vscode-languageserver-types@^3.15.0-next.2:
version "3.15.0-next.2"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.15.0-next.2.tgz#a0601332cdaafac21931f497bb080cfb8d73f254"
integrity sha512-2JkrMWWUi2rlVLSo9OFR2PIGUzdiowEM8NgNYiwLKnXTjpwpjjIrJbNNxDik7Rv4oo9KtikcFQZKXbrKilL/MQ==
vscode-languageserver-types@^3.6.0-next.1: vscode-languageserver-types@^3.6.0-next.1:
version "3.6.0-next.1" version "3.6.0-next.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0-next.1.tgz#98e488d3f87b666b4ee1a3d89f0023e246d358f3" resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.6.0-next.1.tgz#98e488d3f87b666b4ee1a3d89f0023e246d358f3"
integrity sha512-n4G+hCgZwAhtcJSCkwJP153TLdcEBWwrIrb3Su/SpOkhmU7KjDgxaQBLA45hf+QbhB8uKQb+TVStPvbuYFHSMA== integrity sha512-n4G+hCgZwAhtcJSCkwJP153TLdcEBWwrIrb3Su/SpOkhmU7KjDgxaQBLA45hf+QbhB8uKQb+TVStPvbuYFHSMA==
vscode-nls@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-4.1.1.tgz#f9916b64e4947b20322defb1e676a495861f133c"
integrity sha512-4R+2UoUUU/LdnMnFjePxfLqNhBS8lrAFyX7pjb2ud/lqDkrUavFUTcG7wR0HBZFakae0Q6KLBFjMS6W93F403A==
vscode-uri@^2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.0.3.tgz#25e5f37f552fbee3cec7e5f80cef8469cefc6543"
integrity sha512-4D3DI3F4uRy09WNtDGD93H9q034OHImxiIcSq664Hq1Y1AScehlP3qqZyTkX/RWxeu0MRMHGkrxYqm2qlDF/aw==
vscode@1.0.1: vscode@1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.0.1.tgz#3d161200615fe2af1d92ddc650751159411a513b" resolved "https://registry.yarnpkg.com/vscode/-/vscode-1.0.1.tgz#3d161200615fe2af1d92ddc650751159411a513b"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册