diff --git a/.vscodeignore b/.vscodeignore index cc82124a..7451f6ac 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -9,7 +9,6 @@ package-lock.json .config/ img/ node_modules/ -!node_modules/vscode-webhint/dist/src/server.js !node_modules/@vscode/codicons/dist/codicon.css !node_modules/@vscode/codicons/dist/codicon.ttf out/edge/ diff --git a/package-lock.json b/package-lock.json index 316aa2f1..e381dccc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,6 @@ "puppeteer-core": "25.9.0", "utf-8-validate": "6.0.6", "vscode-chrome-debug-core": "6.8.11", - "vscode-webhint": "2.1.15", "ws": "8.21.3", "xmlhttprequest": "1.8.0" }, @@ -43,7 +42,6 @@ "typescript": "6.0.3", "uglify-js": "3.19.3", "unzipper": "0.12.5", - "vscode-languageclient": "10.1.1", "webpack": "5.110.3", "webpack-cli": "7.2.3" }, @@ -13959,96 +13957,6 @@ "integrity": "sha512-dzKWTMMyebIMPF1VYMuuQj7gGFq7guR8AFya0mKacu+ayptJfaRuM0mdHCqiOth4FnRP8mPhEroFPx6Ift8wHA==", "deprecated": "This package has been renamed to @vscode/debugprotocol, please update to the new name" }, - "node_modules/vscode-jsonrpc": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-9.0.2.tgz", - "integrity": "sha1-CGt2xPlPGwdD3urE4LV8nEpV6B0=", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/vscode-languageclient": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-10.1.1.tgz", - "integrity": "sha1-zVBsX5AQ8D5GAEiH8WR8lEVMtiI=", - "dev": true, - "license": "MIT", - "dependencies": { - "minimatch": "^10.2.6", - "semver": "^7.8.1", - "vscode-languageserver-protocol": "3.18.3", - "vscode-languageserver-textdocument": "1.0.14" - }, - "engines": { - "vscode": "^1.91.0" - } - }, - "node_modules/vscode-languageclient/node_modules/balanced-match": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha1-v7EGYv7tgZaixi58aOF3IMJ0F5o=", - "dev": true, - "license": "MIT", - "engines": { - "node": "18 || 20 || >=22" - } - }, - "node_modules/vscode-languageclient/node_modules/brace-expansion": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", - "integrity": "sha1-fHJDiAm1+lur9UGZofHCgaaYT88=", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^4.0.2" - }, - "engines": { - "node": "20 || >=22" - } - }, - "node_modules/vscode-languageclient/node_modules/minimatch": { - "version": "10.2.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz", - "integrity": "sha1-/ZVrvgt3JB6fFaxdzLHGOAYJaO8=", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "brace-expansion": "^5.0.8" - }, - "engines": { - "node": "18 || 20 || >=22" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/vscode-languageserver-protocol": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.18.3.tgz", - "integrity": "sha1-Y5OggGD7lPVSkkP6O+BWxnY5ghE=", - "dev": true, - "license": "MIT", - "dependencies": { - "vscode-jsonrpc": "9.0.2", - "vscode-languageserver-types": "3.18.3" - } - }, - "node_modules/vscode-languageserver-textdocument": { - "version": "1.0.14", - "resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.14.tgz", - "integrity": "sha1-dzG4CLoakH41YNXkMXvNFLr4Gc4=", - "dev": true, - "license": "MIT" - }, - "node_modules/vscode-languageserver-types": { - "version": "3.18.3", - "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.18.3.tgz", - "integrity": "sha1-6ylsQv1lk3WoKVG5zDPnZyup7+c=", - "dev": true, - "license": "MIT" - }, "node_modules/vscode-nls": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz", @@ -14059,15 +13967,6 @@ "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.2.tgz", "integrity": "sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==" }, - "node_modules/vscode-webhint": { - "version": "2.1.15", - "resolved": "https://registry.npmjs.org/vscode-webhint/-/vscode-webhint-2.1.15.tgz", - "integrity": "sha512-sRveRRdhbjqZqdNhk9dpLT5LU69VzMfEOJEv7jDHEqpRsXGeYEP/cgyV0tbfuXZWNePzJQwpi+Owkn4FHZabwQ==", - "engines": { - "node": ">=14.0.0", - "vscode": "^1.86.1" - } - }, "node_modules/w3c-xmlserializer": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", diff --git a/package.json b/package.json index c2b8ec92..a7879a5c 100644 --- a/package.json +++ b/package.json @@ -37,18 +37,7 @@ "main": "./out/extension", "sideEffects": false, "activationEvents": [ - "onStartupFinished", - "onLanguage:css", - "onLanguage:html", - "onLanguage:javascript", - "onLanguage:javascriptreact", - "onLanguage:json", - "onLanguage:jsonc", - "onLanguage:less", - "onLanguage:sass", - "onLanguage:scss", - "onLanguage:typescript", - "onLanguage:typescriptreact" + "onStartupFinished" ], "capabilities": { "untrustedWorkspaces": { @@ -273,16 +262,6 @@ "Microsoft Edge Tools for VS Code will use Microsoft Edge Dev version", "Microsoft Edge Tools for VS Code will use Microsoft Edge Canary version" ] - }, - "vscode-edge-devtools.webhint": { - "type": "boolean", - "default": true, - "description": "Enable feedback from webhint on source files to improve accessibility, compatibility, security and more." - }, - "vscode-edge-devtools.webhintInstallNotification": { - "type": "boolean", - "default": false, - "description": "Turn off notification for webhint installation failures." } } }, @@ -686,7 +665,6 @@ "puppeteer-core": "25.9.0", "utf-8-validate": "6.0.6", "vscode-chrome-debug-core": "6.8.11", - "vscode-webhint": "2.1.15", "ws": "8.21.3", "xmlhttprequest": "1.8.0" }, @@ -713,7 +691,6 @@ "uglify-js": "3.19.3", "unzipper": "0.12.5", "jest-environment-jsdom": "^30.5.1", - "vscode-languageclient": "10.1.1", "webpack": "5.110.3", "webpack-cli": "7.2.3" } diff --git a/src/extension.ts b/src/extension.ts index ac1ba7ec..b3f1594e 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -13,14 +13,12 @@ import { LaunchDebugProvider } from './launchDebugProvider'; import { sendTaxonomyErrorEvent, sendTaxonomyEvent } from './telemetryTaxonomy'; import { buttonCode, - checkWithinHoverRange, createTelemetryReporter, fixRemoteWebSocket, getBrowserPath, getListOfTargets, getRemoteEndpointSettings, getRuntimeConfig, - getSupportedStaticAnalysisFileTypes, IRemoteTargetJson, IUserConfig, launchBrowser, @@ -41,43 +39,16 @@ import { import { LaunchConfigManager, providedHeadlessDebugConfig, providedLaunchDevToolsConfig } from './launchConfigManager'; import { ErrorReporter } from './errorReporter'; import { ErrorCodes } from './common/errorCodes'; -import type { - LanguageClientOptions, - ServerOptions, -} from 'vscode-languageclient/node'; -import { - LanguageClient, - TransportKind, -} from 'vscode-languageclient/node'; -import type { installFailed, showOutput } from 'vscode-webhint/dist/src/utils/notifications'; let telemetryReporter: Readonly; let browserInstance: Browser; let cdpTargetsProvider: CDPTargetsProvider; -// Keep a reference to the client to stop it when deactivating. -let client: LanguageClient; -const languageServerName = 'Microsoft Edge Tools'; - -type DiagnosticCodeType = { value: string; target: vscode.Uri; }; - export function activate(context: vscode.ExtensionContext): void { if (!telemetryReporter) { telemetryReporter = createTelemetryReporter(context); } - vscode.languages.registerHoverProvider(getSupportedStaticAnalysisFileTypes(), { - provideHover(document, position) { - const documentDiagnostics = vscode.languages.getDiagnostics(document.uri); - for (const diagnostic of documentDiagnostics) { - if (diagnostic.source === languageServerName && checkWithinHoverRange(position, diagnostic.range) && diagnostic.code as DiagnosticCodeType) { - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'hover' }, { 'hint': (diagnostic.code as DiagnosticCodeType).value }); - } - } - return null; - }, - }); - // Check if launch.json exists and has supported config to populate side pane welcome message LaunchConfigManager.instance.updateLaunchConfig(); context.subscriptions.push(vscode.commands.registerCommand(`${SETTINGS_STORE_NAME}.attach`, (): void => { @@ -265,20 +236,6 @@ export function activate(context: vscode.ExtensionContext): void { void reportFileExtensionTypes(telemetryReporter); reportExtensionSettings(telemetryReporter); vscode.workspace.onDidChangeConfiguration(event => reportChangedExtensionSetting(event, telemetryReporter)); - - const settingsConfig = vscode.workspace.getConfiguration(SETTINGS_STORE_NAME); - if (settingsConfig.get('webhint')) { - void startWebhint(context); - } - vscode.workspace.onDidChangeConfiguration(event => { - if (event.affectsConfiguration(`${SETTINGS_STORE_NAME}.webhint`)) { - if (vscode.workspace.getConfiguration(SETTINGS_STORE_NAME).get('webhint')) { - void startWebhint(context); - } else { - void stopWebhint(); - } - } - }); } export async function launchHtml(fileUri: vscode.Uri): Promise { @@ -314,113 +271,6 @@ export async function launchScreencast(context: vscode.ExtensionContext, fileUri } } -async function startWebhint(context: vscode.ExtensionContext): Promise { - const args = [context.globalStoragePath, languageServerName]; - const module = context.asAbsolutePath('node_modules/vscode-webhint/dist/src/server.js'); - const transport = TransportKind.ipc; - const serverOptions: ServerOptions = { - debug: { - args, - module, - options: { execArgv: ['--nolazy', '--inspect=6009'] }, - transport, - }, - run: { - args, - module, - transport, - }, - }; - - const clientOptions: LanguageClientOptions = { - documentSelector: getSupportedStaticAnalysisFileTypes(), - synchronize: { - // Notify the server if a webhint-related configuration changes. - fileEvents: vscode.workspace.createFileSystemWatcher('**/.hintrc'), - }, - middleware: { - executeCommand: (command, args, next) => { - const hintName = args[0] as string; - const featureName = args[1] as string; - - if (!telemetryReporter) { - telemetryReporter = createTelemetryReporter(context); - } - - switch (command) { - case 'vscode-webhint/ignore-hint-project': { - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'quickfix', detail: 'disable-hint' }, { hint: hintName }); - break; - } - case 'vscode-webhint/ignore-feature-project': { - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'quickfix', detail: 'disable-rule' }, { hint: hintName, value: featureName }); - break; - } - case 'vscode-webhint/edit-hintrc-project': { - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'quickfix', detail: 'edit-hintrc' }); - break; - } - case 'vscode-webhint/ignore-browsers-project': { - if (args.length > 1) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - const browserList = args[2]['browsers'] as any[]; // eslint-disable-line @typescript-eslint/no-unsafe-member-access - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'quickfix', detail: 'ignore-browsers' }, { hint: hintName, value: browserList.join(',') }); - } - break; - } - case 'vscode-webhint/apply-code-fix': { - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'quickfix', detail: 'apply-code-fix' }, {value: featureName }); - break; - } - } - - return next(command, args); // eslint-disable-line @typescript-eslint/no-unsafe-return - }, - }, - }; - - // Create and start the client (also starts the server). - client = new LanguageClient('Microsoft Edge Tools', serverOptions, clientOptions); - // Listen for notification that the webhint install failed. - const installFailedNotification: typeof installFailed = 'vscode-webhint/install-failed'; - const disableInstallFailedNotification = vscode.workspace.getConfiguration(SETTINGS_STORE_NAME).get('webhintInstallNotification'); - client.onNotification(installFailedNotification, () => { - if (!telemetryReporter) { - telemetryReporter = createTelemetryReporter(context); - } - sendTaxonomyEvent(telemetryReporter, { area: 'user', feature: 'webhint', action: 'install', outcome: 'error' }); - if (!disableInstallFailedNotification) { - const message = 'Ensure `node` and `npm` are installed to enable automatically reporting issues in source files pertaining to accessibility, compatibility, security, and more.'; - void vscode.window.showInformationMessage(message, 'Remind me Later', 'Don\'t show again', 'Disable Extension').then(button => { - if (button === 'Disable Extension') { - void vscode.workspace.getConfiguration(SETTINGS_STORE_NAME).update('webhint', false, vscode.ConfigurationTarget.Global); - } - if (button === 'Don\'t show again') { - void vscode.workspace.getConfiguration(SETTINGS_STORE_NAME).update('webhintInstallNotification', true, vscode.ConfigurationTarget.Global); - } - }); - } - }); - - // Listen for requests to show the output panel for this extension. - const showOutputNotification: typeof showOutput = 'vscode-webhint/show-output'; - client.onNotification(showOutputNotification, () => { - client.outputChannel.clear(); - client.outputChannel.show(true); - }); - await client.start(); -} - -async function stopWebhint(): Promise { - if (client) { - await client.stop(); - } -} - -export const deactivate = (): Thenable => { - return stopWebhint(); -}; - export async function attach( context: vscode.ExtensionContext, attachUrl?: string, config?: Partial, useRetry?: boolean, screencastOnly?: boolean): Promise { if (!telemetryReporter) { diff --git a/src/utils.ts b/src/utils.ts index 8ebe9529..1476636b 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -813,31 +813,6 @@ export async function reportFileExtensionTypes(telemetryReporter: Readonly= range.start.line && position.line <= range.end.line) { - // We need to add a 1 char buffer on each side since hover events are triggered if the cursor is - // 1 char away from a diagnostic line. - if (position.line === range.start.line && position.character + 1 < range.start.character) { - return false; - } - if (position.line === range.end.line && position.character > range.end.character) { - return false; - } - return true; - } - return false; -} - -export function getSupportedStaticAnalysisFileTypes(): string[] { - const supportedFileTypes = []; - for (const event of packageJson.activationEvents) { - if (event.startsWith('onLanguage:')) { - supportedFileTypes.push(event.substring(11)); - } - } - return supportedFileTypes; -} - (function initialize() { // insertion order matters. msEdgeBrowserMapping.set('Stable', { diff --git a/test/extension.test.ts b/test/extension.test.ts index 2d421dce..0bd860d7 100644 --- a/test/extension.test.ts +++ b/test/extension.test.ts @@ -3,7 +3,7 @@ import { ExtensionContext, Uri} from "vscode"; import { TelemetryReporter } from "@vscode/extension-telemetry"; -import { createFakeExtensionContext, createFakeTelemetryReporter, createFakeVSCode, createFakeLanguageClient, Mocked } from "./helpers/helpers"; +import { createFakeExtensionContext, createFakeTelemetryReporter, createFakeVSCode, Mocked } from "./helpers/helpers"; import { buttonCode, IRemoteTargetJson, @@ -15,7 +15,6 @@ import { } from "../src/utils"; jest.mock("vscode", () => createFakeVSCode(), { virtual: true }); -jest.mock("vscode-languageclient/node", () => createFakeLanguageClient(), { virtual: true }); describe("extension", () => { const fakeRuntimeConfig: Partial = {}; @@ -38,12 +37,10 @@ describe("extension", () => { buttonCode, SETTINGS_STORE_NAME, SETTINGS_VIEW_NAME, - checkWithinHoverRange: jest.fn(), createTelemetryReporter: jest.fn((_: ExtensionContext) => createFakeTelemetryReporter()), getListOfTargets: jest.fn().mockReturnValue([]), getRemoteEndpointSettings: jest.fn(), getRuntimeConfig: jest.fn(), - getSupportedStaticAnalysisFileTypes: jest.fn(), removeTrailingSlash: jest.fn(removeTrailingSlash), getJsDebugCDPProxyWebsocketUrl: jest.fn(), getActiveDebugSessionId: jest.fn(), @@ -62,9 +59,6 @@ describe("extension", () => { }; }); - const mockLanguageClient = createFakeLanguageClient() - jest.doMock("vscode-languageclient/node", () => mockLanguageClient, { virtual: true }); - // Mock out vscode command registration const mockVSCode = createFakeVSCode(); commandMock = mockVSCode.commands.registerCommand; @@ -418,7 +412,6 @@ describe("extension", () => { useHttps: false, userDataDir: "profile" }), - getSupportedStaticAnalysisFileTypes: jest.fn(), getRuntimeConfig: jest.fn().mockReturnValue(fakeRuntimeConfig), launchBrowser: jest.fn().mockResolvedValue(fakeBrowser), openNewTab: jest.fn().mockResolvedValue(null), diff --git a/test/helpers/helpers.ts b/test/helpers/helpers.ts index 2e6c1212..b0ce6c5a 100644 --- a/test/helpers/helpers.ts +++ b/test/helpers/helpers.ts @@ -246,18 +246,3 @@ export function getFirstCallback(mock: jest.Mock, callbackArgIndex: number = 0): return { callback: mock.mock.calls[0][callbackArgIndex], thisObj: mock.mock.instances[0] }; } -export function createFakeLanguageClient() { - const createFakeLanguageClient = jest.fn().mockImplementation(() => { - return { - LanguageClient: function LanguageClient() { /* constructor */ } - } - }); - const createFakeLTransportKind = jest.fn().mockImplementation(() => { - return { - TransportKind: function TransportKind() { /* constructor */ } - } - }); - return { LanguageClient: createFakeLanguageClient, - TransportKind: createFakeLTransportKind - } -}