Compare commits
1 commit
main
...
joao/web-w
Author | SHA1 | Date | |
---|---|---|---|
d95ed670c1 |
|
@ -6,7 +6,6 @@
|
|||
import { workspace, extensions, Uri, EventEmitter, Disposable } from 'vscode';
|
||||
import { resolvePath, joinPath } from './requests';
|
||||
|
||||
|
||||
export function getCustomDataSource(toDispose: Disposable[]) {
|
||||
let pathsInWorkspace = getCustomDataPathsInAllWorkspaces();
|
||||
let pathsInExtensions = getCustomDataPathsFromAllExtensions();
|
||||
|
@ -15,7 +14,7 @@ export function getCustomDataSource(toDispose: Disposable[]) {
|
|||
|
||||
toDispose.push(extensions.onDidChange(_ => {
|
||||
const newPathsInExtensions = getCustomDataPathsFromAllExtensions();
|
||||
if (pathsInExtensions.size !== newPathsInExtensions.size || ![...pathsInExtensions].every(path => newPathsInExtensions.has(path))) {
|
||||
if (newPathsInExtensions.length !== pathsInExtensions.length || !newPathsInExtensions.every((val, idx) => val === pathsInExtensions[idx])) {
|
||||
pathsInExtensions = newPathsInExtensions;
|
||||
onChange.fire();
|
||||
}
|
||||
|
@ -27,16 +26,9 @@ export function getCustomDataSource(toDispose: Disposable[]) {
|
|||
}
|
||||
}));
|
||||
|
||||
toDispose.push(workspace.onDidChangeTextDocument(e => {
|
||||
const path = e.document.uri.toString();
|
||||
if (pathsInExtensions.has(path) || pathsInWorkspace.has(path)) {
|
||||
onChange.fire();
|
||||
}
|
||||
}));
|
||||
|
||||
return {
|
||||
get uris() {
|
||||
return [...pathsInWorkspace].concat([...pathsInExtensions]);
|
||||
return pathsInWorkspace.concat(pathsInExtensions);
|
||||
},
|
||||
get onDidChange() {
|
||||
return onChange.event;
|
||||
|
@ -44,31 +36,21 @@ export function getCustomDataSource(toDispose: Disposable[]) {
|
|||
};
|
||||
}
|
||||
|
||||
function isURI(uriOrPath: string) {
|
||||
return /^(?<scheme>\w[\w\d+.-]*):/.test(uriOrPath);
|
||||
}
|
||||
|
||||
|
||||
function getCustomDataPathsInAllWorkspaces(): Set<string> {
|
||||
function getCustomDataPathsInAllWorkspaces(): string[] {
|
||||
const workspaceFolders = workspace.workspaceFolders;
|
||||
|
||||
const dataPaths = new Set<string>();
|
||||
const dataPaths: string[] = [];
|
||||
|
||||
if (!workspaceFolders) {
|
||||
return dataPaths;
|
||||
}
|
||||
|
||||
const collect = (uriOrPaths: string[] | undefined, rootFolder: Uri) => {
|
||||
if (Array.isArray(uriOrPaths)) {
|
||||
for (const uriOrPath of uriOrPaths) {
|
||||
if (typeof uriOrPath === 'string') {
|
||||
if (!isURI(uriOrPath)) {
|
||||
// path in the workspace
|
||||
dataPaths.add(resolvePath(rootFolder, uriOrPath).toString());
|
||||
} else {
|
||||
// external uri
|
||||
dataPaths.add(uriOrPath);
|
||||
}
|
||||
const collect = (paths: string[] | undefined, rootFolder: Uri) => {
|
||||
if (Array.isArray(paths)) {
|
||||
for (const path of paths) {
|
||||
if (typeof path === 'string') {
|
||||
dataPaths.push(resolvePath(rootFolder, path).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,20 +74,13 @@ function getCustomDataPathsInAllWorkspaces(): Set<string> {
|
|||
return dataPaths;
|
||||
}
|
||||
|
||||
function getCustomDataPathsFromAllExtensions(): Set<string> {
|
||||
const dataPaths = new Set<string>();
|
||||
function getCustomDataPathsFromAllExtensions(): string[] {
|
||||
const dataPaths: string[] = [];
|
||||
for (const extension of extensions.all) {
|
||||
const customData = extension.packageJSON?.contributes?.html?.customData;
|
||||
if (Array.isArray(customData)) {
|
||||
for (const uriOrPath of customData) {
|
||||
if (!isURI(uriOrPath)) {
|
||||
// relative path in an extension
|
||||
dataPaths.add(joinPath(extension.extensionUri, uriOrPath).toString());
|
||||
} else {
|
||||
// external uri
|
||||
dataPaths.add(uriOrPath);
|
||||
}
|
||||
|
||||
for (const rp of customData) {
|
||||
dataPaths.push(joinPath(extension.extensionUri, rp).toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature, TextDocumentIdentifier, RequestType0, Range as LspRange, NotificationType, CommonLanguageClient
|
||||
} from 'vscode-languageclient';
|
||||
import { activateTagClosing } from './tagClosing';
|
||||
import { RequestService, serveFileSystemRequests } from './requests';
|
||||
import { RequestService } from './requests';
|
||||
import { getCustomDataSource } from './customData';
|
||||
|
||||
namespace CustomDataChangedNotification {
|
||||
|
@ -120,8 +120,6 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
|
|||
toDispose.push(disposable);
|
||||
client.onReady().then(() => {
|
||||
|
||||
toDispose.push(serveFileSystemRequests(client, runtime));
|
||||
|
||||
client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris);
|
||||
customDataSource.onDidChange(() => {
|
||||
client.sendNotification(CustomDataChangedNotification.type, customDataSource.uris);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Uri, workspace, Disposable } from 'vscode';
|
||||
import { Uri, workspace } from 'vscode';
|
||||
import { RequestType, CommonLanguageClient } from 'vscode-languageclient';
|
||||
import { Runtime } from './htmlClient';
|
||||
|
||||
|
@ -18,9 +18,8 @@ export namespace FsReadDirRequest {
|
|||
export const type: RequestType<string, [string, FileType][], any> = new RequestType('fs/readDir');
|
||||
}
|
||||
|
||||
export function serveFileSystemRequests(client: CommonLanguageClient, runtime: Runtime): Disposable {
|
||||
const disposables = [];
|
||||
disposables.push(client.onRequest(FsContentRequest.type, (param: { uri: string; encoding?: string; }) => {
|
||||
export function serveFileSystemRequests(client: CommonLanguageClient, runtime: Runtime) {
|
||||
client.onRequest(FsContentRequest.type, (param: { uri: string; encoding?: string; }) => {
|
||||
const uri = Uri.parse(param.uri);
|
||||
if (uri.scheme === 'file' && runtime.fs) {
|
||||
return runtime.fs.getContent(param.uri);
|
||||
|
@ -28,22 +27,21 @@ export function serveFileSystemRequests(client: CommonLanguageClient, runtime: R
|
|||
return workspace.fs.readFile(uri).then(buffer => {
|
||||
return new runtime.TextDecoder(param.encoding).decode(buffer);
|
||||
});
|
||||
}));
|
||||
disposables.push(client.onRequest(FsReadDirRequest.type, (uriString: string) => {
|
||||
});
|
||||
client.onRequest(FsReadDirRequest.type, (uriString: string) => {
|
||||
const uri = Uri.parse(uriString);
|
||||
if (uri.scheme === 'file' && runtime.fs) {
|
||||
return runtime.fs.readDirectory(uriString);
|
||||
}
|
||||
return workspace.fs.readDirectory(uri);
|
||||
}));
|
||||
disposables.push(client.onRequest(FsStatRequest.type, (uriString: string) => {
|
||||
});
|
||||
client.onRequest(FsStatRequest.type, (uriString: string) => {
|
||||
const uri = Uri.parse(uriString);
|
||||
if (uri.scheme === 'file' && runtime.fs) {
|
||||
return runtime.fs.stat(uriString);
|
||||
}
|
||||
return workspace.fs.stat(uri);
|
||||
}));
|
||||
return Disposable.from(...disposables);
|
||||
});
|
||||
}
|
||||
|
||||
export enum FileType {
|
||||
|
|
|
@ -87,12 +87,7 @@
|
|||
"language": "markdown",
|
||||
"path": "./snippets/markdown.code-snippets"
|
||||
}
|
||||
],
|
||||
"configurationDefaults": {
|
||||
"[markdown]": {
|
||||
"editor.unicodeHighlight.ambiguousCharacters": false
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin microsoft/vscode-markdown-tm-grammar syntaxes/markdown.tmLanguage ./syntaxes/markdown.tmLanguage.json"
|
||||
|
|
|
@ -73,7 +73,7 @@
|
|||
"keytar": "7.2.0",
|
||||
"minimist": "^1.2.5",
|
||||
"native-is-elevated": "0.4.3",
|
||||
"native-keymap": "3.0.2",
|
||||
"native-keymap": "3.0.1",
|
||||
"native-watchdog": "1.3.0",
|
||||
"node-pty": "0.11.0-beta11",
|
||||
"spdlog": "^0.13.0",
|
||||
|
|
|
@ -899,8 +899,6 @@ export interface ICodeEditor extends editorCommon.IEditor {
|
|||
* @internal
|
||||
*/
|
||||
hasModel(): this is IActiveCodeEditor;
|
||||
|
||||
setBanner(bannerDomNode: HTMLElement | null, height: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -244,8 +244,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||
private _decorationTypeKeysToIds: { [decorationTypeKey: string]: string[] };
|
||||
private _decorationTypeSubtypes: { [decorationTypeKey: string]: { [subtype: string]: boolean } };
|
||||
|
||||
private _bannerDomNode: HTMLElement | null = null;
|
||||
|
||||
constructor(
|
||||
domElement: HTMLElement,
|
||||
_options: Readonly<editorBrowser.IEditorConstructionOptions>,
|
||||
|
@ -1492,19 +1490,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||
Configuration.applyFontInfoSlow(target, this._configuration.options.get(EditorOption.fontInfo));
|
||||
}
|
||||
|
||||
public setBanner(domNode: HTMLElement | null, domNodeHeight: number): void {
|
||||
if (this._bannerDomNode && this._domElement.contains(this._bannerDomNode)) {
|
||||
this._domElement.removeChild(this._bannerDomNode);
|
||||
}
|
||||
|
||||
this._bannerDomNode = domNode;
|
||||
this._configuration.reserveHeight(domNode ? domNodeHeight : 0);
|
||||
|
||||
if (this._bannerDomNode) {
|
||||
this._domElement.prepend(this._bannerDomNode);
|
||||
}
|
||||
}
|
||||
|
||||
protected _attachModel(model: ITextModel | null): void {
|
||||
if (!model) {
|
||||
this._modelData = null;
|
||||
|
@ -1718,9 +1703,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
|||
if (removeDomNode && this._domElement.contains(removeDomNode)) {
|
||||
this._domElement.removeChild(removeDomNode);
|
||||
}
|
||||
if (this._bannerDomNode && this._domElement.contains(this._bannerDomNode)) {
|
||||
this._domElement.removeChild(this._bannerDomNode);
|
||||
}
|
||||
|
||||
return model;
|
||||
}
|
||||
|
|
|
@ -313,7 +313,6 @@ export abstract class CommonEditorConfiguration extends Disposable implements IC
|
|||
private _rawOptions: IEditorOptions;
|
||||
private _readOptions: RawEditorOptions;
|
||||
protected _validatedOptions: ValidatedEditorOptions;
|
||||
private _reservedHeight: number = 0;
|
||||
|
||||
constructor(isSimpleWidget: boolean, _options: Readonly<IEditorOptions>) {
|
||||
super();
|
||||
|
@ -368,7 +367,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements IC
|
|||
const env: IEnvironmentalOptions = {
|
||||
memory: this._computeOptionsMemory,
|
||||
outerWidth: partialEnv.outerWidth,
|
||||
outerHeight: partialEnv.outerHeight - this._reservedHeight,
|
||||
outerHeight: partialEnv.outerHeight,
|
||||
fontInfo: this.readConfiguration(bareFontInfo),
|
||||
extraEditorClassName: partialEnv.extraEditorClassName,
|
||||
isDominatedByLongLines: this._isDominatedByLongLines,
|
||||
|
@ -459,10 +458,6 @@ export abstract class CommonEditorConfiguration extends Disposable implements IC
|
|||
|
||||
protected abstract readConfiguration(styling: BareFontInfo): FontInfo;
|
||||
|
||||
public reserveHeight(height: number) {
|
||||
this._reservedHeight = height;
|
||||
this._recomputeOptions();
|
||||
}
|
||||
}
|
||||
|
||||
export const editorConfigurationBaseNode = Object.freeze<IConfigurationNode>({
|
||||
|
|
|
@ -162,7 +162,6 @@ export interface IConfiguration extends IDisposable {
|
|||
observeReferenceElement(dimension?: IDimension): void;
|
||||
updatePixelRatio(): void;
|
||||
setIsDominatedByLongLines(isDominatedByLongLines: boolean): void;
|
||||
reserveHeight(height: number): void;
|
||||
}
|
||||
|
||||
// --- view
|
||||
|
|
|
@ -10,7 +10,6 @@ import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService';
|
|||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Mimes } from 'vs/base/common/mime';
|
||||
import { IConfigurationRegistry, Extensions as ConfigurationExtensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
|
||||
// Define extension point ids
|
||||
export const Extensions = {
|
||||
|
@ -87,12 +86,3 @@ LanguageConfigurationRegistry.register(PLAINTEXT_MODE_ID, {
|
|||
offSide: true
|
||||
}
|
||||
}, 0);
|
||||
|
||||
Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration)
|
||||
.registerDefaultConfigurations([{
|
||||
overrides: {
|
||||
'[plaintext]': {
|
||||
'editor.unicodeHighlight.ambiguousCharacters': false
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
|
|
@ -6,11 +6,9 @@
|
|||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { Searcher } from 'vs/editor/common/model/textModelSearch';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { assertNever } from 'vs/base/common/types';
|
||||
|
||||
export class UnicodeTextModelHighlighter {
|
||||
public static computeUnicodeHighlights(model: IUnicodeCharacterSearcherTarget, options: UnicodeHighlighterOptions, range?: IRange): IUnicodeHighlightsResult {
|
||||
public static computeUnicodeHighlights(model: IUnicodeCharacterSearcherTarget, options: UnicodeHighlighterOptions, range?: IRange): Range[] {
|
||||
const startLine = range ? range.startLineNumber : 1;
|
||||
const endLine = range ? range.endLineNumber : model.getLineCount();
|
||||
|
||||
|
@ -25,15 +23,8 @@ export class UnicodeTextModelHighlighter {
|
|||
}
|
||||
|
||||
const searcher = new Searcher(null, regex);
|
||||
const ranges: Range[] = [];
|
||||
let hasMore = false;
|
||||
const result: Range[] = [];
|
||||
let m: RegExpExecArray | null;
|
||||
|
||||
let ambiguousCharacterCount = 0;
|
||||
let invisibleCharacterCount = 0;
|
||||
let nonBasicAsciiCharacterCount = 0;
|
||||
|
||||
forLoop:
|
||||
for (let lineNumber = startLine, lineCount = endLine; lineNumber <= lineCount; lineNumber++) {
|
||||
const lineContent = model.getLineContent(lineNumber);
|
||||
const lineLength = lineContent.length;
|
||||
|
@ -60,37 +51,19 @@ export class UnicodeTextModelHighlighter {
|
|||
}
|
||||
}
|
||||
const str = lineContent.substring(startIndex, endIndex);
|
||||
const highlightReason = codePointHighlighter.shouldHighlightNonBasicASCII(str);
|
||||
if (codePointHighlighter.shouldHighlightNonBasicASCII(str) !== SimpleHighlightReason.None) {
|
||||
result.push(new Range(lineNumber, startIndex + 1, lineNumber, endIndex + 1));
|
||||
|
||||
if (highlightReason !== SimpleHighlightReason.None) {
|
||||
if (highlightReason === SimpleHighlightReason.Ambiguous) {
|
||||
ambiguousCharacterCount++;
|
||||
} else if (highlightReason === SimpleHighlightReason.Invisible) {
|
||||
invisibleCharacterCount++;
|
||||
} else if (highlightReason === SimpleHighlightReason.NonBasicASCII) {
|
||||
nonBasicAsciiCharacterCount++;
|
||||
} else {
|
||||
assertNever(highlightReason);
|
||||
const maxResultLength = 1000;
|
||||
if (result.length > maxResultLength) {
|
||||
// TODO@hediet a message should be shown in this case
|
||||
break;
|
||||
}
|
||||
|
||||
const MAX_RESULT_LENGTH = 1000;
|
||||
if (ranges.length >= MAX_RESULT_LENGTH) {
|
||||
hasMore = true;
|
||||
break forLoop;
|
||||
}
|
||||
|
||||
ranges.push(new Range(lineNumber, startIndex + 1, lineNumber, endIndex + 1));
|
||||
}
|
||||
}
|
||||
} while (m);
|
||||
}
|
||||
return {
|
||||
ranges,
|
||||
hasMore,
|
||||
ambiguousCharacterCount,
|
||||
invisibleCharacterCount,
|
||||
nonBasicAsciiCharacterCount
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
public static computeUnicodeHighlightReason(char: string, options: UnicodeHighlighterOptions): UnicodeHighlighterReason | null {
|
||||
|
|
|
@ -18,7 +18,7 @@ import { ensureValidWordDefinition, getWordAtText } from 'vs/editor/common/model
|
|||
import { IInplaceReplaceSupportResult, ILink, TextEdit } from 'vs/editor/common/modes';
|
||||
import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/modes/linkComputer';
|
||||
import { BasicInplaceReplace } from 'vs/editor/common/modes/supports/inplaceReplaceSupport';
|
||||
import { IDiffComputationResult, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IDiffComputationResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { createMonacoBaseAPI } from 'vs/editor/common/standalone/standaloneBase';
|
||||
import * as types from 'vs/base/common/types';
|
||||
import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||
|
@ -372,10 +372,10 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
|
|||
delete this._models[strURL];
|
||||
}
|
||||
|
||||
public async computeUnicodeHighlights(url: string, options: UnicodeHighlighterOptions, range?: IRange): Promise<IUnicodeHighlightsResult> {
|
||||
public async computeUnicodeHighlights(url: string, options: UnicodeHighlighterOptions, range?: IRange): Promise<IRange[]> {
|
||||
const model = this._getModel(url);
|
||||
if (!model) {
|
||||
return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 };
|
||||
return [];
|
||||
}
|
||||
return UnicodeTextModelHighlighter.computeUnicodeHighlights(model, options, range);
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ export interface IEditorWorkerService {
|
|||
readonly _serviceBrand: undefined;
|
||||
|
||||
canComputeUnicodeHighlights(uri: URI): boolean;
|
||||
computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IUnicodeHighlightsResult>;
|
||||
computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IRange[]>;
|
||||
|
||||
computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise<IDiffComputationResult | null>;
|
||||
|
||||
|
@ -38,11 +38,3 @@ export interface IEditorWorkerService {
|
|||
canNavigateValueSet(resource: URI): boolean;
|
||||
navigateValueSet(resource: URI, range: IRange, up: boolean): Promise<IInplaceReplaceSupportResult | null>;
|
||||
}
|
||||
|
||||
export interface IUnicodeHighlightsResult {
|
||||
ranges: IRange[];
|
||||
hasMore: boolean;
|
||||
nonBasicAsciiCharacterCount: number;
|
||||
invisibleCharacterCount: number;
|
||||
ambiguousCharacterCount: number;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@ import { ITextModel } from 'vs/editor/common/model';
|
|||
import * as modes from 'vs/editor/common/modes';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { EditorSimpleWorker } from 'vs/editor/common/services/editorSimpleWorker';
|
||||
import { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
import { regExpFlags } from 'vs/base/common/strings';
|
||||
|
@ -86,7 +86,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
|||
return canSyncModel(this._modelService, uri);
|
||||
}
|
||||
|
||||
public computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IUnicodeHighlightsResult> {
|
||||
public computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IRange[]> {
|
||||
return this._workerManager.withWorker().then(client => client.computedUnicodeHighlights(uri, options, range));
|
||||
}
|
||||
|
||||
|
@ -475,7 +475,7 @@ export class EditorWorkerClient extends Disposable implements IEditorWorkerClien
|
|||
});
|
||||
}
|
||||
|
||||
public computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IUnicodeHighlightsResult> {
|
||||
public computedUnicodeHighlights(uri: URI, options: UnicodeHighlighterOptions, range?: IRange): Promise<IRange[]> {
|
||||
return this._withSyncedResources([uri]).then(proxy => {
|
||||
return proxy.computeUnicodeHighlights(uri.toString(), options, range);
|
||||
});
|
||||
|
|
|
@ -1,85 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
.editor-banner {
|
||||
box-sizing: border-box;
|
||||
cursor: default;
|
||||
width: 100%;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
overflow: visible;
|
||||
|
||||
height: 26px;
|
||||
|
||||
background: var(--vscode-banner-background);
|
||||
}
|
||||
|
||||
|
||||
.editor-banner .icon-container {
|
||||
display: flex;
|
||||
flex-shrink: 0;
|
||||
align-items: center;
|
||||
padding: 0 6px 0 10px;
|
||||
}
|
||||
|
||||
.editor-banner .icon-container.custom-icon {
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: 16px;
|
||||
width: 16px;
|
||||
padding: 0;
|
||||
margin: 0 6px 0 10px;
|
||||
}
|
||||
|
||||
.editor-banner .message-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 26px;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.editor-banner .message-container p {
|
||||
margin-block-start: 0;
|
||||
margin-block-end: 0;
|
||||
}
|
||||
|
||||
.editor-banner .message-actions-container {
|
||||
flex-grow: 1;
|
||||
flex-shrink: 0;
|
||||
line-height: 26px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.editor-banner .message-actions-container a.monaco-button {
|
||||
width: inherit;
|
||||
margin: 2px 8px;
|
||||
padding: 0px 12px;
|
||||
}
|
||||
|
||||
.editor-banner .message-actions-container a {
|
||||
padding: 3px;
|
||||
margin-left: 12px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.editor-banner .action-container {
|
||||
padding: 0 10px 0 6px;
|
||||
}
|
||||
|
||||
.editor-banner {
|
||||
background-color: var(--vscode-banner-background);
|
||||
}
|
||||
|
||||
.editor-banner,
|
||||
.editor-banner .action-container .codicon,
|
||||
.editor-banner .message-actions-container .monaco-link {
|
||||
color: var(--vscode-banner-foreground);
|
||||
}
|
||||
|
||||
.editor-banner .icon-container .codicon {
|
||||
color: var(--vscode-banner-iconForeground);
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import 'vs/css!./bannerController';
|
||||
import { $, append, clearNode } from 'vs/base/browser/dom';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { MarkdownRenderer } from 'vs/editor/browser/core/markdownRenderer';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ILinkDescriptor, Link } from 'vs/platform/opener/browser/link';
|
||||
import { widgetClose } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { ThemeIcon } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
const BANNER_ELEMENT_HEIGHT = 26;
|
||||
|
||||
export class BannerController extends Disposable {
|
||||
private readonly banner: Banner;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.banner = this._register(this.instantiationService.createInstance(Banner));
|
||||
}
|
||||
|
||||
public hide() {
|
||||
this._editor.setBanner(null, 0);
|
||||
this.banner.clear();
|
||||
}
|
||||
|
||||
public show(item: IBannerItem) {
|
||||
this.banner.show({
|
||||
...item,
|
||||
onClose: () => {
|
||||
this.hide();
|
||||
if (item.onClose) {
|
||||
item.onClose();
|
||||
}
|
||||
}
|
||||
});
|
||||
this._editor.setBanner(this.banner.element, BANNER_ELEMENT_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO@hediet: Investigate if this can be reused by the workspace banner (bannerPart.ts).
|
||||
class Banner extends Disposable {
|
||||
public element: HTMLElement;
|
||||
|
||||
private readonly markdownRenderer: MarkdownRenderer;
|
||||
|
||||
private messageActionsContainer: HTMLElement | undefined;
|
||||
|
||||
private actionBar: ActionBar | undefined;
|
||||
|
||||
constructor(
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this.markdownRenderer = this.instantiationService.createInstance(MarkdownRenderer, {});
|
||||
|
||||
this.element = $('div.editor-banner');
|
||||
this.element.tabIndex = 0;
|
||||
}
|
||||
|
||||
private getAriaLabel(item: IBannerItem): string | undefined {
|
||||
if (item.ariaLabel) {
|
||||
return item.ariaLabel;
|
||||
}
|
||||
if (typeof item.message === 'string') {
|
||||
return item.message;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
private getBannerMessage(message: MarkdownString | string): HTMLElement {
|
||||
if (typeof message === 'string') {
|
||||
const element = $('span');
|
||||
element.innerText = message;
|
||||
return element;
|
||||
}
|
||||
|
||||
return this.markdownRenderer.render(message).element;
|
||||
}
|
||||
|
||||
public clear() {
|
||||
clearNode(this.element);
|
||||
}
|
||||
|
||||
public show(item: IBannerItem) {
|
||||
// Clear previous item
|
||||
clearNode(this.element);
|
||||
|
||||
// Banner aria label
|
||||
const ariaLabel = this.getAriaLabel(item);
|
||||
if (ariaLabel) {
|
||||
this.element.setAttribute('aria-label', ariaLabel);
|
||||
}
|
||||
|
||||
// Icon
|
||||
const iconContainer = append(this.element, $('div.icon-container'));
|
||||
iconContainer.setAttribute('aria-hidden', 'true');
|
||||
|
||||
if (item.icon) {
|
||||
iconContainer.appendChild($(`div${ThemeIcon.asCSSSelector(item.icon)}`));
|
||||
}
|
||||
|
||||
// Message
|
||||
const messageContainer = append(this.element, $('div.message-container'));
|
||||
messageContainer.setAttribute('aria-hidden', 'true');
|
||||
messageContainer.appendChild(this.getBannerMessage(item.message));
|
||||
|
||||
// Message Actions
|
||||
this.messageActionsContainer = append(this.element, $('div.message-actions-container'));
|
||||
if (item.actions) {
|
||||
for (const action of item.actions) {
|
||||
this._register(this.instantiationService.createInstance(Link, this.messageActionsContainer, { ...action, tabIndex: -1 }, {}));
|
||||
}
|
||||
}
|
||||
|
||||
// Action
|
||||
const actionBarContainer = append(this.element, $('div.action-container'));
|
||||
this.actionBar = this._register(new ActionBar(actionBarContainer));
|
||||
this.actionBar.push(this._register(
|
||||
new Action(
|
||||
'banner.close',
|
||||
'Close Banner',
|
||||
ThemeIcon.asClassName(widgetClose),
|
||||
true,
|
||||
() => {
|
||||
if (typeof item.onClose === 'function') {
|
||||
item.onClose();
|
||||
}
|
||||
}
|
||||
)
|
||||
), { icon: true, label: false });
|
||||
this.actionBar.setFocusable(false);
|
||||
}
|
||||
}
|
||||
|
||||
export interface IBannerItem {
|
||||
readonly id: string;
|
||||
readonly icon: ThemeIcon | undefined;
|
||||
readonly message: string | MarkdownString;
|
||||
readonly actions?: ILinkDescriptor[];
|
||||
readonly ariaLabel?: string;
|
||||
readonly onClose?: () => void;
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
import { RunOnceScheduler } from 'vs/base/common/async';
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { IMarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { InvisibleCharacters } from 'vs/base/common/strings';
|
||||
|
@ -18,44 +17,32 @@ import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
|||
import { IModelDecoration, IModelDeltaDecoration, ITextModel, MinimapPosition, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { UnicodeHighlighterOptions, UnicodeHighlighterReason, UnicodeHighlighterReasonKind, UnicodeTextModelHighlighter } from 'vs/editor/common/modes/unicodeTextModelHighlighter';
|
||||
import { IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { HoverAnchor, HoverAnchorType, IEditorHover, IEditorHoverParticipant, IEditorHoverStatusBar, IHoverPart } from 'vs/editor/contrib/hover/hoverTypes';
|
||||
import { MarkdownHover, renderMarkdownHovers } from 'vs/editor/contrib/hover/markdownHoverParticipant';
|
||||
import { BannerController } from 'vs/editor/contrib/unicodeHighlighter/bannerController';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
||||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { minimapFindMatch, minimapUnicodeHighlight, overviewRulerFindMatchForeground, overviewRulerUnicodeHighlightForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
|
||||
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/workspaceTrust';
|
||||
|
||||
export const warningIcon = registerIcon('extensions-warning-message', Codicon.warning, nls.localize('warningIcon', 'Icon shown with a warning message in the extensions editor.'));
|
||||
|
||||
export class UnicodeHighlighter extends Disposable implements IEditorContribution {
|
||||
public static readonly ID = 'editor.contrib.unicodeHighlighter';
|
||||
|
||||
private _highlighter: DocumentUnicodeHighlighter | ViewportUnicodeHighlighter | null = null;
|
||||
private _options: InternalUnicodeHighlightOptions;
|
||||
|
||||
private readonly _bannerController: BannerController;
|
||||
private _bannerClosed: boolean = false;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
@IEditorWorkerService private readonly _editorWorkerService: IEditorWorkerService,
|
||||
@IWorkspaceTrustManagementService private readonly _workspaceTrustService: IWorkspaceTrustManagementService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
|
||||
this._bannerController = this._register(instantiationService.createInstance(BannerController, _editor));
|
||||
|
||||
this._register(this._editor.onDidChangeModel(() => {
|
||||
this._bannerClosed = false;
|
||||
this._updateHighlighter();
|
||||
}));
|
||||
|
||||
|
@ -83,57 +70,7 @@ export class UnicodeHighlighter extends Disposable implements IEditorContributio
|
|||
super.dispose();
|
||||
}
|
||||
|
||||
private readonly _updateState = (state: IUnicodeHighlightsResult | null): void => {
|
||||
if (state && state.hasMore) {
|
||||
if (this._bannerClosed) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This document contains many non-basic ASCII characters.
|
||||
const max = Math.max(state.ambiguousCharacterCount, state.nonBasicAsciiCharacterCount, state.invisibleCharacterCount);
|
||||
|
||||
let data;
|
||||
if (state.nonBasicAsciiCharacterCount >= max) {
|
||||
data = {
|
||||
message: nls.localize('unicodeHighlighting.thisDocumentHasManyNonBasicAsciiUnicodeCharacters', 'This document contains many non-basic ASCII unicode characters'),
|
||||
command: new DisableHighlightingOfNonBasicAsciiCharactersAction(),
|
||||
};
|
||||
} else if (state.ambiguousCharacterCount >= max) {
|
||||
data = {
|
||||
message: nls.localize('unicodeHighlighting.thisDocumentHasManyAmbiguousUnicodeCharacters', 'This document contains many ambiguous unicode characters'),
|
||||
command: new DisableHighlightingOfAmbiguousCharactersAction(),
|
||||
};
|
||||
} else if (state.invisibleCharacterCount >= max) {
|
||||
data = {
|
||||
message: nls.localize('unicodeHighlighting.thisDocumentHasManyInvisibleUnicodeCharacters', 'This document contains many invisible unicode characters'),
|
||||
command: new DisableHighlightingOfInvisibleCharactersAction(),
|
||||
};
|
||||
} else {
|
||||
throw new Error('Unreachable');
|
||||
}
|
||||
|
||||
this._bannerController.show({
|
||||
id: 'unicodeHighlightBanner',
|
||||
message: data.message,
|
||||
icon: warningIcon,
|
||||
actions: [
|
||||
{
|
||||
label: data.command.shortLabel,
|
||||
href: `command:${data.command.id}`
|
||||
}
|
||||
],
|
||||
onClose: () => {
|
||||
this._bannerClosed = true;
|
||||
},
|
||||
});
|
||||
} else {
|
||||
this._bannerController.hide();
|
||||
}
|
||||
};
|
||||
|
||||
private _updateHighlighter(): void {
|
||||
this._updateState(null);
|
||||
|
||||
if (this._highlighter) {
|
||||
this._highlighter.dispose();
|
||||
this._highlighter = null;
|
||||
|
@ -163,9 +100,9 @@ export class UnicodeHighlighter extends Disposable implements IEditorContributio
|
|||
};
|
||||
|
||||
if (this._editorWorkerService.canComputeUnicodeHighlights(this._editor.getModel().uri)) {
|
||||
this._highlighter = new DocumentUnicodeHighlighter(this._editor, highlightOptions, this._updateState, this._editorWorkerService);
|
||||
this._highlighter = new DocumentUnicodeHighlighter(this._editor, highlightOptions, this._editorWorkerService);
|
||||
} else {
|
||||
this._highlighter = new ViewportUnicodeHighlighter(this._editor, highlightOptions, this._updateState);
|
||||
this._highlighter = new ViewportUnicodeHighlighter(this._editor, highlightOptions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,7 +156,6 @@ class DocumentUnicodeHighlighter extends Disposable {
|
|||
constructor(
|
||||
private readonly _editor: IActiveCodeEditor,
|
||||
private readonly _options: UnicodeHighlighterOptions,
|
||||
private readonly _updateState: (state: IUnicodeHighlightsResult | null) => void,
|
||||
@IEditorWorkerService private readonly _editorWorkerService: IEditorWorkerService,
|
||||
) {
|
||||
super();
|
||||
|
@ -246,20 +182,14 @@ class DocumentUnicodeHighlighter extends Disposable {
|
|||
const modelVersionId = this._model.getVersionId();
|
||||
this._editorWorkerService
|
||||
.computedUnicodeHighlights(this._model.uri, this._options)
|
||||
.then((info) => {
|
||||
.then((ranges) => {
|
||||
if (this._model.getVersionId() !== modelVersionId) {
|
||||
// model changed in the meantime
|
||||
return;
|
||||
}
|
||||
this._updateState(info);
|
||||
|
||||
const decorations: IModelDeltaDecoration[] = [];
|
||||
if (!info.hasMore) {
|
||||
// Don't show decoration if there are too many.
|
||||
// In this case, a banner is shown.
|
||||
for (const range of info.ranges) {
|
||||
decorations.push({ range: range, options: this._options.includeComments ? DECORATION : DECORATION_HIDE_IN_COMMENTS });
|
||||
}
|
||||
for (const range of ranges) {
|
||||
decorations.push({ range: range, options: this._options.includeComments ? DECORATION : DECORATION_HIDE_IN_COMMENTS });
|
||||
}
|
||||
this._decorationIds = new Set(this._editor.deltaDecorations(
|
||||
Array.from(this._decorationIds),
|
||||
|
@ -288,8 +218,7 @@ class ViewportUnicodeHighlighter extends Disposable {
|
|||
|
||||
constructor(
|
||||
private readonly _editor: IActiveCodeEditor,
|
||||
private readonly _options: UnicodeHighlighterOptions,
|
||||
private readonly _updateState: (state: IUnicodeHighlightsResult | null) => void,
|
||||
private readonly _options: UnicodeHighlighterOptions
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -324,33 +253,12 @@ class ViewportUnicodeHighlighter extends Disposable {
|
|||
|
||||
const ranges = this._editor.getVisibleRanges();
|
||||
const decorations: IModelDeltaDecoration[] = [];
|
||||
const totalResult: IUnicodeHighlightsResult = {
|
||||
ranges: [],
|
||||
ambiguousCharacterCount: 0,
|
||||
invisibleCharacterCount: 0,
|
||||
nonBasicAsciiCharacterCount: 0,
|
||||
hasMore: false,
|
||||
};
|
||||
for (const range of ranges) {
|
||||
const result = UnicodeTextModelHighlighter.computeUnicodeHighlights(this._model, this._options, range);
|
||||
for (const r of result.ranges) {
|
||||
totalResult.ranges.push(r);
|
||||
}
|
||||
totalResult.ambiguousCharacterCount += totalResult.ambiguousCharacterCount;
|
||||
totalResult.invisibleCharacterCount += totalResult.invisibleCharacterCount;
|
||||
totalResult.nonBasicAsciiCharacterCount += totalResult.nonBasicAsciiCharacterCount;
|
||||
totalResult.hasMore = totalResult.hasMore || result.hasMore;
|
||||
}
|
||||
|
||||
if (!totalResult.hasMore) {
|
||||
// Don't show decorations if there are too many.
|
||||
// A banner will be shown instead.
|
||||
for (const range of totalResult.ranges) {
|
||||
const ranges = UnicodeTextModelHighlighter.computeUnicodeHighlights(this._model, this._options, range);
|
||||
for (const range of ranges) {
|
||||
decorations.push({ range, options: this._options.includeComments ? DECORATION : DECORATION_HIDE_IN_COMMENTS });
|
||||
}
|
||||
}
|
||||
this._updateState(totalResult);
|
||||
|
||||
this._decorationIds = new Set(this._editor.deltaDecorations(Array.from(this._decorationIds), decorations));
|
||||
}
|
||||
|
||||
|
@ -448,7 +356,7 @@ export class UnicodeHighlighterHoverParticipant implements IEditorHoverParticipa
|
|||
reason = nls.localize(
|
||||
'unicodeHighlight.characterIsNonBasicAscii',
|
||||
'The character {0} is not a basic ASCII character.',
|
||||
codePointStr
|
||||
codePoint
|
||||
);
|
||||
break;
|
||||
}
|
||||
|
@ -516,82 +424,6 @@ const DECORATION = ModelDecorationOptions.register({
|
|||
}
|
||||
});
|
||||
|
||||
interface IDisableUnicodeHighlightAction {
|
||||
shortLabel: string;
|
||||
}
|
||||
|
||||
export class DisableHighlightingOfAmbiguousCharactersAction extends EditorAction implements IDisableUnicodeHighlightAction {
|
||||
public static ID = 'editor.action.unicodeHighlight.disableHighlightingOfAmbiguousCharacters';
|
||||
public readonly shortLabel = nls.localize('unicodeHighlight.disableHighlightingOfAmbiguousCharacters.shortLabel', '');
|
||||
constructor() {
|
||||
super({
|
||||
id: DisableHighlightingOfAmbiguousCharactersAction.ID,
|
||||
label: nls.localize('action.unicodeHighlight.disableHighlightingOfAmbiguousCharacters', 'Disable Ambiguous Highlight'),
|
||||
alias: 'Disable highlighting of ambiguous characters',
|
||||
precondition: undefined
|
||||
});
|
||||
}
|
||||
|
||||
public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor, args: any): Promise<void> {
|
||||
let configurationService = accessor?.get(IConfigurationService);
|
||||
if (configurationService) {
|
||||
this.runAction(configurationService);
|
||||
}
|
||||
}
|
||||
|
||||
public async runAction(configurationService: IConfigurationService): Promise<void> {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.ambiguousCharacters, false, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
export class DisableHighlightingOfInvisibleCharactersAction extends EditorAction implements IDisableUnicodeHighlightAction {
|
||||
public static ID = 'editor.action.unicodeHighlight.disableHighlightingOfInvisibleCharacters';
|
||||
public readonly shortLabel = nls.localize('unicodeHighlight.disableHighlightingOfInvisibleCharacters.shortLabel', 'Disable Invisible Highlight');
|
||||
constructor() {
|
||||
super({
|
||||
id: DisableHighlightingOfInvisibleCharactersAction.ID,
|
||||
label: nls.localize('action.unicodeHighlight.disableHighlightingOfInvisibleCharacters', 'Disable highlighting of invisible characters'),
|
||||
alias: 'Disable highlighting of invisible characters',
|
||||
precondition: undefined
|
||||
});
|
||||
}
|
||||
|
||||
public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor, args: any): Promise<void> {
|
||||
let configurationService = accessor?.get(IConfigurationService);
|
||||
if (configurationService) {
|
||||
this.runAction(configurationService);
|
||||
}
|
||||
}
|
||||
|
||||
public async runAction(configurationService: IConfigurationService): Promise<void> {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.invisibleCharacters, false, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
export class DisableHighlightingOfNonBasicAsciiCharactersAction extends EditorAction implements IDisableUnicodeHighlightAction {
|
||||
public static ID = 'editor.action.unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters';
|
||||
public readonly shortLabel = nls.localize('unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters.shortLabel', 'Disable Non ASCII Highlight');
|
||||
constructor() {
|
||||
super({
|
||||
id: DisableHighlightingOfNonBasicAsciiCharactersAction.ID,
|
||||
label: nls.localize('action.unicodeHighlight.dhowDisableHighlightingOfNonBasicAsciiCharacters', 'Disable highlighting of non basic ASCII characters'),
|
||||
alias: 'Disable highlighting of non basic ASCII characters',
|
||||
precondition: undefined
|
||||
});
|
||||
}
|
||||
|
||||
public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor, args: any): Promise<void> {
|
||||
let configurationService = accessor?.get(IConfigurationService);
|
||||
if (configurationService) {
|
||||
this.runAction(configurationService);
|
||||
}
|
||||
}
|
||||
|
||||
public async runAction(configurationService: IConfigurationService): Promise<void> {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.nonBasicASCII, false, ConfigurationTarget.USER);
|
||||
}
|
||||
}
|
||||
|
||||
interface ShowExcludeOptionsArgs {
|
||||
codePoint: number;
|
||||
reason: UnicodeHighlighterReason['kind'];
|
||||
|
@ -607,7 +439,6 @@ export class ShowExcludeOptions extends EditorAction {
|
|||
precondition: undefined
|
||||
});
|
||||
}
|
||||
|
||||
public async run(accessor: ServicesAccessor | undefined, editor: ICodeEditor, args: any): Promise<void> {
|
||||
const { codePoint, reason } = args as ShowExcludeOptionsArgs;
|
||||
|
||||
|
@ -639,16 +470,28 @@ export class ShowExcludeOptions extends EditorAction {
|
|||
];
|
||||
|
||||
if (reason === UnicodeHighlighterReasonKind.Ambiguous) {
|
||||
const action = new DisableHighlightingOfAmbiguousCharactersAction();
|
||||
options.push({ label: action.label, run: async () => action.runAction(configurationService) });
|
||||
options.push({
|
||||
label: nls.localize('unicodeHighlight.disableHighlightingOfAmbiguousCharacters', 'Disable highlighting of ambiguous characters'),
|
||||
run: async () => {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.ambiguousCharacters, false, ConfigurationTarget.USER);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (reason === UnicodeHighlighterReasonKind.Invisible) {
|
||||
const action = new DisableHighlightingOfInvisibleCharactersAction();
|
||||
options.push({ label: action.label, run: async () => action.runAction(configurationService) });
|
||||
options.push({
|
||||
label: nls.localize('unicodeHighlight.disableHighlightingOfInvisibleCharacters', 'Disable highlighting of invisible characters'),
|
||||
run: async () => {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.invisibleCharacters, false, ConfigurationTarget.USER);
|
||||
}
|
||||
});
|
||||
}
|
||||
else if (reason === UnicodeHighlighterReasonKind.NonBasicAscii) {
|
||||
const action = new DisableHighlightingOfNonBasicAsciiCharactersAction();
|
||||
options.push({ label: action.label, run: async () => action.runAction(configurationService) });
|
||||
options.push({
|
||||
label: nls.localize('unicodeHighlight.disableHighlightingOfNonBasicAsciiCharacters', 'Disable highlighting of non basic ASCII characters'),
|
||||
run: async () => {
|
||||
await configurationService.updateValue(unicodeHighlightConfigKeys.nonBasicASCII, false, ConfigurationTarget.USER);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
expectNever(reason);
|
||||
}
|
||||
|
@ -668,8 +511,5 @@ function expectNever(value: never) {
|
|||
throw new Error(`Unexpected value: ${value}`);
|
||||
}
|
||||
|
||||
registerEditorAction(DisableHighlightingOfAmbiguousCharactersAction);
|
||||
registerEditorAction(DisableHighlightingOfInvisibleCharactersAction);
|
||||
registerEditorAction(DisableHighlightingOfNonBasicAsciiCharactersAction);
|
||||
registerEditorAction(ShowExcludeOptions);
|
||||
registerEditorContribution(UnicodeHighlighter.ID, UnicodeHighlighter);
|
||||
|
|
1
src/vs/monaco.d.ts
vendored
1
src/vs/monaco.d.ts
vendored
|
@ -5117,7 +5117,6 @@ declare namespace monaco.editor {
|
|||
* Apply the same font settings as the editor to `target`.
|
||||
*/
|
||||
applyFontInfo(target: HTMLElement): void;
|
||||
setBanner(bannerDomNode: HTMLElement | null, height: number): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -136,16 +136,8 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||
*/
|
||||
restricted?: boolean;
|
||||
|
||||
/**
|
||||
* When `false` this property is excluded from the registry. Default is to include.
|
||||
*/
|
||||
included?: boolean;
|
||||
|
||||
/**
|
||||
* List of tags associated to the property.
|
||||
* - A tag can be used for filtering
|
||||
* - Use `experimental` tag for marking the setting as experimental. **Note:** Defaults of experimental settings can be changed by the running experiments.
|
||||
*/
|
||||
tags?: string[];
|
||||
|
||||
/**
|
||||
|
@ -158,9 +150,6 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||
*/
|
||||
disallowSyncIgnore?: boolean;
|
||||
|
||||
/**
|
||||
* Labels for enumeration items
|
||||
*/
|
||||
enumItemLabels?: string[];
|
||||
|
||||
/**
|
||||
|
@ -176,9 +165,9 @@ export interface IConfigurationPropertySchema extends IJSONSchema {
|
|||
order?: number;
|
||||
}
|
||||
|
||||
export interface IExtensionInfo {
|
||||
export interface IConfigurationExtensionInfo {
|
||||
id: string;
|
||||
displayName?: string;
|
||||
restrictedConfigurations?: string[];
|
||||
}
|
||||
|
||||
export interface IConfigurationNode {
|
||||
|
@ -190,22 +179,21 @@ export interface IConfigurationNode {
|
|||
properties?: IStringDictionary<IConfigurationPropertySchema>;
|
||||
allOf?: IConfigurationNode[];
|
||||
scope?: ConfigurationScope;
|
||||
extensionInfo?: IExtensionInfo;
|
||||
restrictedProperties?: string[];
|
||||
extensionInfo?: IConfigurationExtensionInfo;
|
||||
}
|
||||
|
||||
export interface IConfigurationDefaults {
|
||||
overrides: IStringDictionary<any>;
|
||||
source?: IExtensionInfo | string;
|
||||
extensionId?: string;
|
||||
}
|
||||
|
||||
export type IRegisteredConfigurationPropertySchema = IConfigurationPropertySchema & {
|
||||
defaultDefaultValue?: any,
|
||||
source?: IExtensionInfo,
|
||||
defaultValueSource?: IExtensionInfo | string;
|
||||
source?: string,
|
||||
defaultSource?: string
|
||||
};
|
||||
|
||||
export type IConfigurationDefaultOverride = { value: any, source?: IExtensionInfo | string };
|
||||
export type IConfigurationDefaultOverride = { value: any, source?: string };
|
||||
|
||||
export const allSettings: { properties: IStringDictionary<IConfigurationPropertySchema>, patternProperties: IStringDictionary<IConfigurationPropertySchema> } = { properties: {}, patternProperties: {} };
|
||||
export const applicationSettings: { properties: IStringDictionary<IConfigurationPropertySchema>, patternProperties: IStringDictionary<IConfigurationPropertySchema> } = { properties: {}, patternProperties: {} };
|
||||
|
@ -284,26 +272,26 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
const properties: string[] = [];
|
||||
const overrideIdentifiers: string[] = [];
|
||||
|
||||
for (const { overrides, source } of configurationDefaults) {
|
||||
for (const { overrides, extensionId } of configurationDefaults) {
|
||||
for (const key in overrides) {
|
||||
properties.push(key);
|
||||
|
||||
if (OVERRIDE_PROPERTY_REGEX.test(key)) {
|
||||
const defaultValue = { ...(this.configurationDefaultsOverrides.get(key)?.value || {}), ...overrides[key] };
|
||||
this.configurationDefaultsOverrides.set(key, { source, value: defaultValue });
|
||||
this.configurationDefaultsOverrides.set(key, { source: extensionId, value: defaultValue });
|
||||
const property: IRegisteredConfigurationPropertySchema = {
|
||||
type: 'object',
|
||||
default: defaultValue,
|
||||
description: nls.localize('defaultLanguageConfiguration.description', "Configure settings to be overridden for {0} language.", key),
|
||||
$ref: resourceLanguageSettingsSchemaId,
|
||||
defaultDefaultValue: defaultValue,
|
||||
source: types.isString(source) ? undefined : source,
|
||||
source: extensionId,
|
||||
};
|
||||
overrideIdentifiers.push(...overrideIdentifiersFromKey(key));
|
||||
this.configurationProperties[key] = property;
|
||||
this.defaultLanguageConfigurationOverridesNode.properties![key] = property;
|
||||
} else {
|
||||
this.configurationDefaultsOverrides.set(key, { value: overrides[key], source });
|
||||
this.configurationDefaultsOverrides.set(key, { value: overrides[key], source: extensionId });
|
||||
const property = this.configurationProperties[key];
|
||||
if (property) {
|
||||
this.updatePropertyDefaultValue(key, property);
|
||||
|
@ -320,12 +308,9 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
|
||||
public deregisterDefaultConfigurations(defaultConfigurations: IConfigurationDefaults[]): void {
|
||||
const properties: string[] = [];
|
||||
for (const { overrides, source } of defaultConfigurations) {
|
||||
for (const { overrides, extensionId } of defaultConfigurations) {
|
||||
for (const key in overrides) {
|
||||
const configurationDefaultsOverride = this.configurationDefaultsOverrides.get(key);
|
||||
const id = types.isString(source) ? source : source?.id;
|
||||
const configurationDefaultsOverrideSourceId = types.isString(configurationDefaultsOverride?.source) ? configurationDefaultsOverride?.source : configurationDefaultsOverride?.source?.id;
|
||||
if (id !== configurationDefaultsOverrideSourceId) {
|
||||
if (this.configurationDefaultsOverrides.get(key)?.source !== extensionId) {
|
||||
continue;
|
||||
}
|
||||
properties.push(key);
|
||||
|
@ -362,7 +347,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
private doRegisterConfigurations(configurations: IConfigurationNode[], validate: boolean): string[] {
|
||||
const properties: string[] = [];
|
||||
configurations.forEach(configuration => {
|
||||
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo, configuration.restrictedProperties)); // fills in defaults
|
||||
properties.push(...this.validateAndRegisterProperties(configuration, validate, configuration.extensionInfo)); // fills in defaults
|
||||
this.configurationContributors.push(configuration);
|
||||
this.registerJSONConfiguration(configuration);
|
||||
});
|
||||
|
@ -393,7 +378,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
return properties;
|
||||
}
|
||||
|
||||
private validateAndRegisterProperties(configuration: IConfigurationNode, validate: boolean = true, extensionInfo: IExtensionInfo | undefined, restrictedProperties: string[] | undefined, scope: ConfigurationScope = ConfigurationScope.WINDOW): string[] {
|
||||
private validateAndRegisterProperties(configuration: IConfigurationNode, validate: boolean = true, extensionInfo?: IConfigurationExtensionInfo, scope: ConfigurationScope = ConfigurationScope.WINDOW): string[] {
|
||||
scope = types.isUndefinedOrNull(configuration.scope) ? scope : configuration.scope;
|
||||
let propertyKeys: string[] = [];
|
||||
let properties = configuration.properties;
|
||||
|
@ -405,7 +390,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
}
|
||||
|
||||
const property: IRegisteredConfigurationPropertySchema = properties[key];
|
||||
property.source = extensionInfo;
|
||||
property.source = extensionInfo?.id;
|
||||
|
||||
// update default value
|
||||
property.defaultDefaultValue = properties[key].default;
|
||||
|
@ -416,7 +401,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
property.scope = undefined; // No scope for overridable properties `[${identifier}]`
|
||||
} else {
|
||||
property.scope = types.isUndefinedOrNull(property.scope) ? scope : property.scope;
|
||||
property.restricted = types.isUndefinedOrNull(property.restricted) ? !!restrictedProperties?.includes(key) : property.restricted;
|
||||
property.restricted = types.isUndefinedOrNull(property.restricted) ? !!extensionInfo?.restrictedConfigurations?.includes(key) : property.restricted;
|
||||
}
|
||||
|
||||
// Add to properties maps
|
||||
|
@ -440,7 +425,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
let subNodes = configuration.allOf;
|
||||
if (subNodes) {
|
||||
for (let node of subNodes) {
|
||||
propertyKeys.push(...this.validateAndRegisterProperties(node, validate, extensionInfo, restrictedProperties, scope));
|
||||
propertyKeys.push(...this.validateAndRegisterProperties(node, validate, extensionInfo, scope));
|
||||
}
|
||||
}
|
||||
return propertyKeys;
|
||||
|
@ -575,7 +560,7 @@ class ConfigurationRegistry implements IConfigurationRegistry {
|
|||
defaultValue = getDefaultValue(property.type);
|
||||
}
|
||||
property.default = defaultValue;
|
||||
property.defaultValueSource = defaultSource;
|
||||
property.defaultSource = defaultSource;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -144,7 +144,7 @@ const defaultConfigurationExtPoint = ExtensionsRegistry.registerExtensionPoint<I
|
|||
});
|
||||
defaultConfigurationExtPoint.setHandler((extensions, { added, removed }) => {
|
||||
if (removed.length) {
|
||||
const removedDefaultConfigurations = removed.map<IConfigurationDefaults>(extension => ({ overrides: objects.deepClone(extension.value), source: { id: extension.description.identifier.value, displayName: extension.description.displayName } }));
|
||||
const removedDefaultConfigurations = removed.map<IConfigurationDefaults>(extension => ({ overrides: objects.deepClone(extension.value), extensionId: extension.description.identifier.value }));
|
||||
configurationRegistry.deregisterDefaultConfigurations(removedDefaultConfigurations);
|
||||
}
|
||||
if (added.length) {
|
||||
|
@ -161,7 +161,7 @@ defaultConfigurationExtPoint.setHandler((extensions, { added, removed }) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
return { overrides, source: { id: extension.description.identifier.value, displayName: extension.description.displayName } };
|
||||
return { overrides, extensionId: extension.description.identifier.value };
|
||||
});
|
||||
configurationRegistry.registerDefaultConfigurations(addedDefaultConfigurations);
|
||||
}
|
||||
|
@ -212,8 +212,7 @@ configurationExtPoint.setHandler((extensions, { added, removed }) => {
|
|||
validateProperties(configuration, extension);
|
||||
|
||||
configuration.id = node.id || extension.description.identifier.value;
|
||||
configuration.extensionInfo = { id: extension.description.identifier.value, displayName: extension.description.displayName };
|
||||
configuration.restrictedProperties = extension.description.capabilities?.untrustedWorkspaces?.supported === 'limited' ? extension.description.capabilities?.untrustedWorkspaces.restrictedConfigurations : undefined;
|
||||
configuration.extensionInfo = { id: extension.description.identifier.value, restrictedConfigurations: extension.description.capabilities?.untrustedWorkspaces?.supported === 'limited' ? extension.description.capabilities?.untrustedWorkspaces.restrictedConfigurations : undefined };
|
||||
configuration.title = configuration.title || extension.description.displayName || extension.description.identifier.value;
|
||||
configurations.push(configuration);
|
||||
return configurations;
|
||||
|
|
|
@ -98,7 +98,6 @@ export class ExtHostLanguages implements ExtHostLanguagesShape {
|
|||
command: undefined,
|
||||
text: '',
|
||||
detail: '',
|
||||
busy: false
|
||||
};
|
||||
|
||||
let soonHandle: IDisposable | undefined;
|
||||
|
@ -116,8 +115,7 @@ export class ExtHostLanguages implements ExtHostLanguagesShape {
|
|||
detail: data.detail ?? '',
|
||||
severity: data.severity === LanguageStatusSeverity.Error ? Severity.Error : data.severity === LanguageStatusSeverity.Warning ? Severity.Warning : Severity.Info,
|
||||
command: data.command && this._commands.toInternal(data.command, commandDisposables),
|
||||
accessibilityInfo: data.accessibilityInformation,
|
||||
busy: data.busy
|
||||
accessibilityInfo: data.accessibilityInformation
|
||||
});
|
||||
}, 0);
|
||||
};
|
||||
|
@ -180,13 +178,6 @@ export class ExtHostLanguages implements ExtHostLanguagesShape {
|
|||
set command(value) {
|
||||
data.command = value;
|
||||
updateAsync();
|
||||
},
|
||||
get busy() {
|
||||
return data.busy;
|
||||
},
|
||||
set busy(value: boolean) {
|
||||
data.busy = value;
|
||||
updateAsync();
|
||||
}
|
||||
};
|
||||
updateAsync();
|
||||
|
|
|
@ -23,7 +23,7 @@ import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
|||
import { ResolvedKeybinding } from 'vs/base/common/keybindings';
|
||||
import { ExtensionsInput, IExtensionEditorOptions } from 'vs/workbench/contrib/extensions/common/extensionsInput';
|
||||
import { IExtensionsWorkbenchService, IExtensionsViewPaneContainer, VIEWLET_ID, IExtension, ExtensionContainers, ExtensionEditorTab, ExtensionState } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget, PreReleaseIndicatorWidget, ExtensionHoverWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { RatingsWidget, InstallCountWidget, RemoteBadgeWidget, PreReleaseIndicatorWidget } from 'vs/workbench/contrib/extensions/browser/extensionsWidgets';
|
||||
import { IEditorOpenContext } from 'vs/workbench/common/editor';
|
||||
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import {
|
||||
|
@ -68,7 +68,7 @@ import { Delegate } from 'vs/workbench/contrib/extensions/browser/extensionsList
|
|||
import { renderMarkdown } from 'vs/base/browser/markdownRenderer';
|
||||
import { attachKeybindingLabelStyler } from 'vs/platform/theme/common/styler';
|
||||
import { areSameExtensions } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { errorIcon, infoIcon, preReleaseIcon, starEmptyIcon, verifiedPublisherIcon as verifiedPublisherThemeIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
|
||||
import { errorIcon, infoIcon, starEmptyIcon, verifiedPublisherIcon as verifiedPublisherThemeIcon, warningIcon } from 'vs/workbench/contrib/extensions/browser/extensionsIcons';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IPaneCompositePartService } from 'vs/workbench/services/panecomposite/browser/panecomposite';
|
||||
import { ViewContainerLocation } from 'vs/workbench/common/views';
|
||||
|
@ -150,7 +150,6 @@ interface IExtensionEditorTemplate {
|
|||
actionsAndStatusContainer: HTMLElement;
|
||||
extensionActionBar: ActionBar;
|
||||
status: HTMLElement;
|
||||
preReleaseText: HTMLElement;
|
||||
recommendation: HTMLElement;
|
||||
navbar: NavBar;
|
||||
content: HTMLElement;
|
||||
|
@ -272,7 +271,6 @@ export class ExtensionEditor extends EditorPane {
|
|||
}));
|
||||
|
||||
const status = append(actionsAndStatusContainer, $('.status'));
|
||||
const preReleaseText = append(details, $('.pre-release-text'));
|
||||
const recommendation = append(details, $('.recommendation'));
|
||||
|
||||
this._register(Event.chain(extensionActionBar.onDidRun)
|
||||
|
@ -305,7 +303,6 @@ export class ExtensionEditor extends EditorPane {
|
|||
rating,
|
||||
actionsAndStatusContainer,
|
||||
extensionActionBar,
|
||||
preReleaseText,
|
||||
status,
|
||||
recommendation
|
||||
};
|
||||
|
@ -479,7 +476,6 @@ export class ExtensionEditor extends EditorPane {
|
|||
this.transientDisposables.add(disposable);
|
||||
}
|
||||
|
||||
this.setPreReleaseText(extension, template);
|
||||
this.setStatus(extension, extensionStatus, template);
|
||||
this.setRecommendationText(extension, template);
|
||||
|
||||
|
@ -528,30 +524,6 @@ export class ExtensionEditor extends EditorPane {
|
|||
this.editorLoadComplete = true;
|
||||
}
|
||||
|
||||
private setPreReleaseText(extension: IExtension, template: IExtensionEditorTemplate): void {
|
||||
let preReleaseText: string | undefined;
|
||||
reset(template.preReleaseText);
|
||||
const disposables = this.transientDisposables.add(new DisposableStore());
|
||||
const updatePreReleaseText = () => {
|
||||
const newPreReleaseText = ExtensionHoverWidget.getPreReleaseMessage(extension);
|
||||
if (preReleaseText !== newPreReleaseText) {
|
||||
preReleaseText = newPreReleaseText;
|
||||
disposables.clear();
|
||||
reset(template.preReleaseText);
|
||||
if (preReleaseText) {
|
||||
append(template.preReleaseText, $(`span${ThemeIcon.asCSSSelector(preReleaseIcon)}`));
|
||||
disposables.add(this.renderMarkdownText(preReleaseText, template.preReleaseText));
|
||||
}
|
||||
}
|
||||
};
|
||||
updatePreReleaseText();
|
||||
this.transientDisposables.add(this.extensionsWorkbenchService.onChange(e => {
|
||||
if (e && areSameExtensions(e.identifier, extension.identifier)) {
|
||||
updatePreReleaseText();
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private setStatus(extension: IExtension, extensionStatus: ExtensionStatusAction, template: IExtensionEditorTemplate): void {
|
||||
const disposables = new DisposableStore();
|
||||
this.transientDisposables.add(disposables);
|
||||
|
@ -564,7 +536,16 @@ export class ExtensionEditor extends EditorPane {
|
|||
const statusIconActionBar = disposables.add(new ActionBar(template.status, { animated: false }));
|
||||
statusIconActionBar.push(extensionStatus, { icon: true, label: false });
|
||||
}
|
||||
disposables.add(this.renderMarkdownText(status.message.value, append(template.status, $('.status-text'))));
|
||||
const rendered = disposables.add(renderMarkdown(new MarkdownString(status.message.value, { isTrusted: true, supportThemeIcons: true }), {
|
||||
actionHandler: {
|
||||
callback: (content) => {
|
||||
this.openerService.open(content, { allowCommands: true }).catch(onUnexpectedError);
|
||||
},
|
||||
disposables: disposables
|
||||
}
|
||||
}));
|
||||
append(append(template.status, $('.status-text')),
|
||||
rendered.element);
|
||||
}
|
||||
};
|
||||
updateStatus();
|
||||
|
@ -593,20 +574,6 @@ export class ExtensionEditor extends EditorPane {
|
|||
this.transientDisposables.add(this.extensionRecommendationsService.onDidChangeRecommendations(() => updateRecommendationText()));
|
||||
}
|
||||
|
||||
private renderMarkdownText(markdownText: string, parent: HTMLElement): IDisposable {
|
||||
const disposables = new DisposableStore();
|
||||
const rendered = disposables.add(renderMarkdown(new MarkdownString(markdownText, { isTrusted: true, supportThemeIcons: true }), {
|
||||
actionHandler: {
|
||||
callback: (content) => {
|
||||
this.openerService.open(content, { allowCommands: true }).catch(onUnexpectedError);
|
||||
},
|
||||
disposables: disposables
|
||||
}
|
||||
}));
|
||||
append(parent, rendered.element);
|
||||
return disposables;
|
||||
}
|
||||
|
||||
override clearInput(): void {
|
||||
this.contentDisposables.clear();
|
||||
this.transientDisposables.clear();
|
||||
|
@ -1802,6 +1769,7 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
|
|||
if (link) {
|
||||
collector.addRule(`.monaco-workbench .extension-editor .content .details .additional-details-container .resources-container a { color: ${link}; }`);
|
||||
collector.addRule(`.monaco-workbench .extension-editor .content .feature-contributions a { color: ${link}; }`);
|
||||
collector.addRule(`.monaco-workbench .extension-editor > .header > .details > .actions-status-container > .status > .status-text a { color: ${link}; }`);
|
||||
}
|
||||
|
||||
const activeLink = theme.getColor(textLinkActiveForeground);
|
||||
|
@ -1810,6 +1778,9 @@ registerThemingParticipant((theme: IColorTheme, collector: ICssStyleCollector) =
|
|||
.monaco-workbench .extension-editor .content .details .additional-details-container .resources-container a:active { color: ${activeLink}; }`);
|
||||
collector.addRule(`.monaco-workbench .extension-editor .content .feature-contributions a:hover,
|
||||
.monaco-workbench .extension-editor .content .feature-contributions a:active { color: ${activeLink}; }`);
|
||||
collector.addRule(`.monaco-workbench .extension-editor > .header > .details > .actions-status-container > .status > .status-text a:hover,
|
||||
.monaco-workbench .extension-editor > .header > .details > actions-status-container > .status > .status-text a:active { color: ${activeLink}; }`);
|
||||
|
||||
}
|
||||
|
||||
const buttonHoverBackgroundColor = theme.getColor(buttonHoverBackground);
|
||||
|
|
|
@ -176,7 +176,7 @@ export class PreReleaseIndicatorWidget extends ExtensionWidget {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!this.extension.local?.isPreReleaseVersion && !this.extension.gallery?.properties.isPreReleaseVersion) {
|
||||
if (!this.extension.local?.isPreReleaseVersion) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -482,9 +482,9 @@ export class ExtensionHoverWidget extends ExtensionWidget {
|
|||
const markdown = new MarkdownString('', { isTrusted: true, supportThemeIcons: true });
|
||||
|
||||
markdown.appendMarkdown(`**${this.extension.displayName}** _v${this.extension.version}_`);
|
||||
if (this.extension.local?.isPreReleaseVersion || this.extension.gallery?.properties.isPreReleaseVersion) {
|
||||
if (this.extension.state === ExtensionState.Installed && this.extension.local?.isPreReleaseVersion) {
|
||||
const extensionPreReleaseIcon = this.themeService.getColorTheme().getColor(extensionPreReleaseIconColor);
|
||||
markdown.appendMarkdown(` <span style="color:#ffffff;background-color:${extensionPreReleaseIcon ? Color.Format.CSS.formatHex(extensionPreReleaseIcon) : '#ffffff'};"> ${localize('pre-release-label', "Pre-Release")} </span>`);
|
||||
markdown.appendMarkdown(` <span style="color:${extensionPreReleaseIcon ? Color.Format.CSS.formatHex(extensionPreReleaseIcon) : '#ffffff'};">$(${preReleaseIcon.id})</span>`);
|
||||
}
|
||||
markdown.appendText(`\n`);
|
||||
|
||||
|
@ -500,13 +500,18 @@ export class ExtensionHoverWidget extends ExtensionWidget {
|
|||
markdown.appendText(`\n`);
|
||||
}
|
||||
|
||||
const preReleaseMessage = ExtensionHoverWidget.getPreReleaseMessage(this.extension);
|
||||
const preReleaseMessage = this.getPreReleaseMessage(this.extension);
|
||||
if (preReleaseMessage) {
|
||||
markdown.appendMarkdown(preReleaseMessage);
|
||||
markdown.appendText(`\n`);
|
||||
}
|
||||
|
||||
const extensionRuntimeStatus = this.extensionsWorkbenchService.getExtensionStatus(this.extension);
|
||||
const extensionStatus = this.extensionStatusAction.status;
|
||||
const reloadRequiredMessage = this.reloadAction.enabled ? this.reloadAction.tooltip : '';
|
||||
const recommendationMessage = this.getRecommendationMessage(this.extension);
|
||||
|
||||
if (extensionRuntimeStatus || extensionStatus || reloadRequiredMessage || recommendationMessage || preReleaseMessage) {
|
||||
if (extensionRuntimeStatus || extensionStatus || reloadRequiredMessage || recommendationMessage) {
|
||||
|
||||
markdown.appendMarkdown(`---`);
|
||||
markdown.appendText(`\n`);
|
||||
|
@ -549,12 +554,6 @@ export class ExtensionHoverWidget extends ExtensionWidget {
|
|||
markdown.appendText(`\n`);
|
||||
}
|
||||
|
||||
if (preReleaseMessage) {
|
||||
const extensionPreReleaseIcon = this.themeService.getColorTheme().getColor(extensionPreReleaseIconColor);
|
||||
markdown.appendMarkdown(`<span style="color:${extensionPreReleaseIcon ? Color.Format.CSS.formatHex(extensionPreReleaseIcon) : '#ffffff'};">$(${preReleaseIcon.id})</span> ${preReleaseMessage}`);
|
||||
markdown.appendText(`\n`);
|
||||
}
|
||||
|
||||
if (recommendationMessage) {
|
||||
markdown.appendMarkdown(recommendationMessage);
|
||||
markdown.appendText(`\n`);
|
||||
|
@ -576,15 +575,17 @@ export class ExtensionHoverWidget extends ExtensionWidget {
|
|||
return `<span style="color:${bgColor ? Color.Format.CSS.formatHex(bgColor) : '#ffffff'};">$(${starEmptyIcon.id})</span> ${recommendation.reasonText}`;
|
||||
}
|
||||
|
||||
static getPreReleaseMessage(extension: IExtension): string | undefined {
|
||||
private getPreReleaseMessage(extension: IExtension): string | undefined {
|
||||
if (!extension.hasPreReleaseVersion) {
|
||||
return undefined;
|
||||
}
|
||||
if (extension.local?.isPreReleaseVersion || extension.gallery?.properties.isPreReleaseVersion) {
|
||||
if (extension.state === ExtensionState.Installed && extension.local?.isPreReleaseVersion) {
|
||||
return undefined;
|
||||
}
|
||||
const extensionPreReleaseIcon = this.themeService.getColorTheme().getColor(extensionPreReleaseIconColor);
|
||||
const preReleaseVersionLink = `[${localize('Show prerelease version', "Pre-Release version")}](${URI.parse(`command:workbench.extensions.action.showPreReleaseVersion?${encodeURIComponent(JSON.stringify([extension.identifier.id]))}`)})`;
|
||||
return localize('has prerelease', "This extension has a {0} available", preReleaseVersionLink);
|
||||
const message = localize('has prerelease', "This extension has a {0} available", preReleaseVersionLink);
|
||||
return `<span style="color:${extensionPreReleaseIcon ? Color.Format.CSS.formatHex(extensionPreReleaseIcon) : '#ffffff'};">$(${preReleaseIcon.id})</span> ${message}`;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -261,32 +261,13 @@
|
|||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .pre-release-text p,
|
||||
.extension-editor > .header > .details > .actions-status-container > .status > .status-text p {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .pre-release-text a,
|
||||
.extension-editor > .header > .details > .actions-status-container > .status > .status-text a {
|
||||
color: var(--vscode-textLink-foreground)
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .pre-release-text a:hover,
|
||||
.extension-editor > .header > .details > .actions-status-container > .status > .status-text a:hover {
|
||||
text-decoration: underline;
|
||||
color: var(--vscode-textLink-activeForeground)
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .pre-release-text a:active,
|
||||
.extension-editor > .header > .details > .actions-status-container > .status > .status-text a:active {
|
||||
color: var(--vscode-textLink-activeForeground)
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .pre-release-text:not(:empty){
|
||||
margin-top: 5px;
|
||||
display: flex;
|
||||
font-size: 90%;
|
||||
}
|
||||
|
||||
.extension-editor > .header > .details > .recommendation {
|
||||
|
|
|
@ -60,6 +60,6 @@
|
|||
}
|
||||
|
||||
/* codicon colors */
|
||||
.codicon.codicon-extensions-pre-release {
|
||||
.codicon .codicon-extensions-pre-release {
|
||||
color: var(--vscode-extensionIcon-preReleaseForeground);
|
||||
}
|
||||
|
|
|
@ -160,20 +160,18 @@ class EditorStatusContribution implements IWorkbenchContribution {
|
|||
const showSeverity = first.severity >= Severity.Warning;
|
||||
const text = EditorStatusContribution._severityToComboCodicon(first.severity);
|
||||
|
||||
let isOneBusy = false;
|
||||
const ariaLabels: string[] = [];
|
||||
const element = document.createElement('div');
|
||||
for (const status of model.combined) {
|
||||
element.appendChild(this._renderStatus(status, showSeverity, this._renderDisposables));
|
||||
ariaLabels.push(this._asAriaLabel(status));
|
||||
isOneBusy = isOneBusy || status.busy;
|
||||
}
|
||||
const props: IStatusbarEntry = {
|
||||
name: localize('langStatus.name', "Editor Language Status"),
|
||||
ariaLabel: localize('langStatus.aria', "Editor Language Status: {0}", ariaLabels.join(', next: ')),
|
||||
tooltip: element,
|
||||
command: ShowTooltipCommand,
|
||||
text: isOneBusy ? `${text}\u00A0\u00A0$(sync~spin)` : text,
|
||||
text,
|
||||
};
|
||||
if (!this._combinedEntry) {
|
||||
this._combinedEntry = this._statusBarService.addEntry(props, EditorStatusContribution._id, StatusbarAlignment.RIGHT, { id: 'status.editor.mode', alignment: StatusbarAlignment.LEFT, compact: true });
|
||||
|
@ -221,7 +219,7 @@ class EditorStatusContribution implements IWorkbenchContribution {
|
|||
|
||||
const label = document.createElement('span');
|
||||
label.classList.add('label');
|
||||
dom.append(label, ...renderLabelWithIcons(status.busy ? `$(sync~spin)\u00A0\u00A0${status.label}` : status.label));
|
||||
dom.append(label, ...renderLabelWithIcons(status.label));
|
||||
left.appendChild(label);
|
||||
|
||||
const detail = document.createElement('span');
|
||||
|
@ -313,7 +311,7 @@ class EditorStatusContribution implements IWorkbenchContribution {
|
|||
|
||||
return {
|
||||
name: localize('name.pattern', '{0} (Language Status)', item.name),
|
||||
text: item.busy ? `${item.label}\u00A0\u00A0$(sync~spin)` : item.label,
|
||||
text: item.label,
|
||||
ariaLabel: item.accessibilityInfo?.label ?? item.label,
|
||||
role: item.accessibilityInfo?.role,
|
||||
tooltip: item.command?.tooltip || new MarkdownString(item.detail, true),
|
||||
|
|
|
@ -312,7 +312,11 @@ suite('Workbench - Test Results Service', () => {
|
|||
});
|
||||
});
|
||||
|
||||
((isNative && !isElectron) ? test.skip /* TODO@connor4312 https://github.com/microsoft/vscode/issues/137853 */ : test)('resultItemParents', function () {
|
||||
test('resultItemParents', function () {
|
||||
if (isNative && !isElectron) {
|
||||
this.skip(); // TODO@connor4312 https://github.com/microsoft/vscode/issues/137853
|
||||
}
|
||||
|
||||
assert.deepStrictEqual([...resultItemParents(r, r.getStateById(new TestId(['ctrlId', 'id-a', 'id-aa']).toString())!)], [
|
||||
r.getStateById(new TestId(['ctrlId', 'id-a', 'id-aa']).toString()),
|
||||
r.getStateById(new TestId(['ctrlId', 'id-a']).toString()),
|
||||
|
|
|
@ -36,9 +36,6 @@ import { IWorkspaceTrustManagementService } from 'vs/platform/workspace/common/w
|
|||
import { delta, distinct } from 'vs/base/common/arrays';
|
||||
import { forEach, IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IWorkbenchAssignmentService } from 'vs/workbench/services/assignment/common/assignmentService';
|
||||
import { isUndefined } from 'vs/base/common/types';
|
||||
import { localize } from 'vs/nls';
|
||||
|
||||
class Workspace extends BaseWorkspace {
|
||||
initialized: boolean = false;
|
||||
|
@ -1119,45 +1116,6 @@ class ResetConfigurationDefaultsOverridesCache extends Disposable implements IWo
|
|||
}
|
||||
}
|
||||
|
||||
class UpdateExperimentalSettingsDefaults extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
private readonly processedExperimentalSettings = new Set<string>();
|
||||
private readonly configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);
|
||||
|
||||
constructor(
|
||||
@IWorkbenchAssignmentService private readonly workbenchAssignmentService: IWorkbenchAssignmentService
|
||||
) {
|
||||
super();
|
||||
this.processExperimentalSettings(Object.keys(this.configurationRegistry.getConfigurationProperties()));
|
||||
this._register(this.configurationRegistry.onDidUpdateConfiguration(({ properties }) => this.processExperimentalSettings(properties)));
|
||||
}
|
||||
|
||||
private async processExperimentalSettings(properties: string[]): Promise<void> {
|
||||
const overrides: IStringDictionary<any> = {};
|
||||
const allProperties = this.configurationRegistry.getConfigurationProperties();
|
||||
for (const property of properties) {
|
||||
const schema = allProperties[property];
|
||||
if (!schema.tags?.includes('experimental')) {
|
||||
continue;
|
||||
}
|
||||
if (this.processedExperimentalSettings.has(property)) {
|
||||
continue;
|
||||
}
|
||||
this.processedExperimentalSettings.add(property);
|
||||
try {
|
||||
const value = await this.workbenchAssignmentService.getTreatment(`config.${property}`);
|
||||
if (!isUndefined(value) && !equals(value, schema.default)) {
|
||||
overrides[property] = value;
|
||||
}
|
||||
} catch (error) {/*ignore */ }
|
||||
}
|
||||
if (Object.keys(overrides).length) {
|
||||
this.configurationRegistry.registerDefaultConfigurations([{ overrides, source: localize('experimental', "Experiments") }]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(RegisterConfigurationSchemasContribution, LifecyclePhase.Restored);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(ResetConfigurationDefaultsOverridesCache, LifecyclePhase.Ready);
|
||||
workbenchContributionsRegistry.registerWorkbenchContribution(UpdateExperimentalSettingsDefaults, LifecyclePhase.Restored);
|
||||
|
|
|
@ -29,7 +29,7 @@ import { generateUuid } from 'vs/base/common/uuid';
|
|||
import { canceled, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { Barrier } from 'vs/base/common/async';
|
||||
import { ILayoutService } from 'vs/platform/layout/browser/layoutService';
|
||||
import { NewWorkerMessage, TerminateWorkerMessage } from 'vs/workbench/services/extensions/common/polyfillNestedWorker.protocol';
|
||||
import { WorkerMessage, WorkerMessageType } from 'vs/workbench/services/extensions/common/polyfillNestedWorker.protocol';
|
||||
|
||||
export interface IWebWorkerExtensionHostInitData {
|
||||
readonly autoStart: boolean;
|
||||
|
@ -149,7 +149,8 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
}
|
||||
|
||||
private async _startInsideIframe(webWorkerExtensionHostIframeSrc: string): Promise<IMessagePassingProtocol> {
|
||||
const emitter = this._register(new Emitter<VSBuffer>());
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
const barrier = new Barrier();
|
||||
|
||||
const iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('class', 'web-worker-ext-host-iframe');
|
||||
|
@ -159,8 +160,10 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
const vscodeWebWorkerExtHostId = generateUuid();
|
||||
iframe.setAttribute('src', `${webWorkerExtensionHostIframeSrc}&vscodeWebWorkerExtHostId=${vscodeWebWorkerExtHostId}`);
|
||||
|
||||
const barrier = new Barrier();
|
||||
let port!: MessagePort;
|
||||
const iframeLoaded = new Promise(c => iframe.onload = c);
|
||||
this._layoutService.container.appendChild(iframe);
|
||||
this._register(toDisposable(() => iframe.remove()));
|
||||
|
||||
let barrierError: Error | null = null;
|
||||
let barrierHasError = false;
|
||||
let startTimeout: any = null;
|
||||
|
@ -174,8 +177,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
barrier.open();
|
||||
};
|
||||
|
||||
const resolveBarrier = (messagePort: MessagePort) => {
|
||||
port = messagePort;
|
||||
const resolveBarrier = () => {
|
||||
clearTimeout(startTimeout);
|
||||
barrier.open();
|
||||
};
|
||||
|
@ -188,9 +190,11 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
if (event.source !== iframe.contentWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.vscodeWebWorkerExtHostId !== vscodeWebWorkerExtHostId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (event.data.error) {
|
||||
const { name, message, stack } = event.data.error;
|
||||
const err = new Error();
|
||||
|
@ -199,27 +203,33 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
err.stack = stack;
|
||||
return rejectBarrier(ExtensionHostExitCode.UnexpectedError, err);
|
||||
}
|
||||
const { data } = event.data;
|
||||
if (barrier.isOpen() || !(data instanceof MessagePort)) {
|
||||
console.warn('UNEXPECTED message', event);
|
||||
const err = new Error('UNEXPECTED message');
|
||||
return rejectBarrier(ExtensionHostExitCode.UnexpectedError, err);
|
||||
|
||||
if (barrier.isOpen()) {
|
||||
console.warn('UNEXPECTED message after worker ready', event);
|
||||
return;
|
||||
}
|
||||
resolveBarrier(data);
|
||||
|
||||
if (event.data.data.type === WorkerMessageType.Ready) {
|
||||
resolveBarrier();
|
||||
return;
|
||||
}
|
||||
|
||||
console.warn('UNEXPECTED message', event);
|
||||
const err = new Error('UNEXPECTED message');
|
||||
return rejectBarrier(ExtensionHostExitCode.UnexpectedError, err);
|
||||
}));
|
||||
|
||||
this._layoutService.container.appendChild(iframe);
|
||||
this._register(toDisposable(() => iframe.remove()));
|
||||
|
||||
// await MessagePort and use it to directly communicate
|
||||
// with the worker extension host
|
||||
await iframeLoaded;
|
||||
iframe.contentWindow!.postMessage(port2, '*', [port2]);
|
||||
await barrier.wait();
|
||||
|
||||
if (barrierHasError) {
|
||||
throw barrierError;
|
||||
}
|
||||
|
||||
port.onmessage = (event) => {
|
||||
const emitter = this._register(new Emitter<VSBuffer>());
|
||||
|
||||
port1.onmessage = (event) => {
|
||||
const { data } = event;
|
||||
if (!(data instanceof ArrayBuffer)) {
|
||||
console.warn('UNKNOWN data received', data);
|
||||
|
@ -233,7 +243,7 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
onMessage: emitter.event,
|
||||
send: vsbuf => {
|
||||
const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength);
|
||||
port.postMessage(data, [data]);
|
||||
port1.postMessage(data, [data]);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -241,37 +251,25 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
}
|
||||
|
||||
private async _startOutsideIframe(): Promise<IMessagePassingProtocol> {
|
||||
const emitter = new Emitter<VSBuffer>();
|
||||
const { port1, port2 } = new MessageChannel();
|
||||
const barrier = new Barrier();
|
||||
let port!: MessagePort;
|
||||
|
||||
const nestedWorker = new Map<string, Worker>();
|
||||
|
||||
const name = this._environmentService.debugRenderer && this._environmentService.debugExtensionHost ? 'DebugWorkerExtensionHost' : 'WorkerExtensionHost';
|
||||
const worker = new DefaultWorkerFactory(name).create(
|
||||
const worker = this._register(new DefaultWorkerFactory(name).create(
|
||||
'vs/workbench/services/extensions/worker/extensionHostWorker',
|
||||
(data: MessagePort | NewWorkerMessage | TerminateWorkerMessage | any) => {
|
||||
|
||||
if (data instanceof MessagePort) {
|
||||
// receiving a message port which is used to communicate
|
||||
// with the web worker extension host
|
||||
if (barrier.isOpen()) {
|
||||
console.warn('UNEXPECTED message', data);
|
||||
this._onDidExit.fire([ExtensionHostExitCode.UnexpectedError, 'received a message port AFTER opening the barrier']);
|
||||
return;
|
||||
}
|
||||
port = data;
|
||||
(data: WorkerMessage | any /* this `any` is a hack */) => {
|
||||
if (data?.type === WorkerMessageType.Ready) {
|
||||
barrier.open();
|
||||
|
||||
|
||||
} else if (data?.type === '_newWorker') {
|
||||
} else if (data?.type === WorkerMessageType.NewWorker) {
|
||||
// receiving a message to create a new nested/child worker
|
||||
const worker = new Worker((ttPolicyNestedWorker?.createScriptURL(data.url) ?? data.url) as string, data.options);
|
||||
worker.postMessage(data.port, [data.port]);
|
||||
worker.onerror = console.error.bind(console);
|
||||
nestedWorker.set(data.id, worker);
|
||||
|
||||
} else if (data?.type === '_terminateWorker') {
|
||||
} else if (data?.type === WorkerMessageType.TerminateWorker) {
|
||||
// receiving a message to terminate nested/child worker
|
||||
if (nestedWorker.has(data.id)) {
|
||||
nestedWorker.get(data.id)!.terminate();
|
||||
|
@ -293,14 +291,14 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
this._onDidExit.fire([ExtensionHostExitCode.UnexpectedError, event.message || event.error]);
|
||||
}
|
||||
}
|
||||
);
|
||||
));
|
||||
|
||||
// await MessagePort and use it to directly communicate
|
||||
// with the worker extension host
|
||||
worker.postMessage(port2 as any /* this `any` is a hack */, [port2 as any /* this `any` is a hack */]);
|
||||
await barrier.wait();
|
||||
|
||||
port.onmessage = (event) => {
|
||||
const { data } = event;
|
||||
const emitter = this._register(new Emitter<VSBuffer>());
|
||||
|
||||
port1.onmessage = ({ data }) => {
|
||||
if (!(data instanceof ArrayBuffer)) {
|
||||
console.warn('UNKNOWN data received', data);
|
||||
this._onDidExit.fire([77, 'UNKNOWN data received']);
|
||||
|
@ -310,16 +308,11 @@ export class WebWorkerExtensionHost extends Disposable implements IExtensionHost
|
|||
emitter.fire(VSBuffer.wrap(new Uint8Array(data, 0, data.byteLength)));
|
||||
};
|
||||
|
||||
|
||||
// keep for cleanup
|
||||
this._register(emitter);
|
||||
this._register(worker);
|
||||
|
||||
const protocol: IMessagePassingProtocol = {
|
||||
onMessage: emitter.event,
|
||||
send: vsbuf => {
|
||||
const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength);
|
||||
port.postMessage(data, [data]);
|
||||
port1.postMessage(data, [data]);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -3,9 +3,18 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export const enum WorkerMessageType {
|
||||
Ready = '_workerReady',
|
||||
NewWorker = '_newWorker',
|
||||
TerminateWorker = '_terminateWorker'
|
||||
}
|
||||
|
||||
export interface WorkerReadyMessage {
|
||||
type: WorkerMessageType.Ready;
|
||||
}
|
||||
|
||||
export interface NewWorkerMessage {
|
||||
type: '_newWorker';
|
||||
type: WorkerMessageType.NewWorker;
|
||||
id: string;
|
||||
port: any /* MessagePort */;
|
||||
url: string;
|
||||
|
@ -13,6 +22,8 @@ export interface NewWorkerMessage {
|
|||
}
|
||||
|
||||
export interface TerminateWorkerMessage {
|
||||
type: '_terminateWorker';
|
||||
type: WorkerMessageType.TerminateWorker;
|
||||
id: string;
|
||||
}
|
||||
|
||||
export type WorkerMessage = WorkerReadyMessage | NewWorkerMessage | TerminateWorkerMessage;
|
||||
|
|
|
@ -18,6 +18,7 @@ import 'vs/workbench/api/common/extHost.common.services';
|
|||
import 'vs/workbench/api/worker/extHost.worker.services';
|
||||
import { FileAccess } from 'vs/base/common/network';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { WorkerMessageType } from 'vs/workbench/services/extensions/common/polyfillNestedWorker.protocol';
|
||||
|
||||
//#region --- Define, capture, and override some globals
|
||||
|
||||
|
@ -161,16 +162,11 @@ class ExtensionWorker {
|
|||
// protocol
|
||||
readonly protocol: IMessagePassingProtocol;
|
||||
|
||||
constructor() {
|
||||
|
||||
const channel = new MessageChannel();
|
||||
constructor(port: MessagePort) {
|
||||
const emitter = new Emitter<VSBuffer>();
|
||||
let terminating = false;
|
||||
|
||||
// send over port2, keep port1
|
||||
nativePostMessage(channel.port2, [channel.port2]);
|
||||
|
||||
channel.port1.onmessage = event => {
|
||||
port.onmessage = event => {
|
||||
const { data } = event;
|
||||
if (!(data instanceof ArrayBuffer)) {
|
||||
console.warn('UNKNOWN data received', data);
|
||||
|
@ -194,7 +190,7 @@ class ExtensionWorker {
|
|||
send: vsbuf => {
|
||||
if (!terminating) {
|
||||
const data = vsbuf.buffer.buffer.slice(vsbuf.buffer.byteOffset, vsbuf.buffer.byteOffset + vsbuf.buffer.byteLength);
|
||||
channel.port1.postMessage(data, [data]);
|
||||
port.postMessage(data, [data]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -219,18 +215,23 @@ function connectToRenderer(protocol: IMessagePassingProtocol): Promise<IRenderer
|
|||
|
||||
let onTerminate = (reason: string) => nativeClose();
|
||||
|
||||
export function create(): void {
|
||||
const res = new ExtensionWorker();
|
||||
export function create(): { onmessage: (message: any) => void } {
|
||||
performance.mark(`code/extHost/willConnectToRenderer`);
|
||||
connectToRenderer(res.protocol).then(data => {
|
||||
performance.mark(`code/extHost/didWaitForInitData`);
|
||||
const extHostMain = new ExtensionHostMain(
|
||||
data.protocol,
|
||||
data.initData,
|
||||
hostUtil,
|
||||
null,
|
||||
);
|
||||
return {
|
||||
onmessage(port: MessagePort) {
|
||||
const res = new ExtensionWorker(port);
|
||||
nativePostMessage({ type: WorkerMessageType.Ready });
|
||||
connectToRenderer(res.protocol).then(data => {
|
||||
performance.mark(`code/extHost/didWaitForInitData`);
|
||||
const extHostMain = new ExtensionHostMain(
|
||||
data.protocol,
|
||||
data.initData,
|
||||
hostUtil,
|
||||
null,
|
||||
);
|
||||
|
||||
onTerminate = (reason: string) => extHostMain.terminate(reason);
|
||||
});
|
||||
onTerminate = (reason: string) => extHostMain.terminate(reason);
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data: blob:; script-src 'unsafe-eval' 'sha256-cb2sg39EJV8ABaSNFfWu/ou8o1xVXYK7jp90oZ9vpcg=' http: https:; connect-src http: https: ws: wss:" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data: blob:; script-src 'unsafe-eval' 'sha256-K1g7FCERTTCfRLLmc8iHekkF33UnX2QZNtYpH4uQo0E=' http: https:; connect-src http: https: ws: wss:" />
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
@ -47,7 +47,7 @@
|
|||
window.parent.postMessage({
|
||||
vscodeWebWorkerExtHostId,
|
||||
data
|
||||
}, '*', [data]);
|
||||
}, '*');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -55,6 +55,8 @@
|
|||
console.error(event.message, event.error);
|
||||
sendError(event.error);
|
||||
};
|
||||
|
||||
window.addEventListener('message', event => worker.postMessage(event.data, event.ports));
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
sendError(err);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data: blob:; script-src 'unsafe-eval' 'sha256-cb2sg39EJV8ABaSNFfWu/ou8o1xVXYK7jp90oZ9vpcg=' https:; connect-src https: wss:" />
|
||||
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; child-src 'self' data: blob:; script-src 'unsafe-eval' 'sha256-K1g7FCERTTCfRLLmc8iHekkF33UnX2QZNtYpH4uQo0E=' https:; connect-src https: wss:" />
|
||||
</head>
|
||||
<body>
|
||||
<script>
|
||||
|
@ -47,7 +47,7 @@
|
|||
window.parent.postMessage({
|
||||
vscodeWebWorkerExtHostId,
|
||||
data
|
||||
}, '*', [data]);
|
||||
}, '*');
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -55,6 +55,8 @@
|
|||
console.error(event.message, event.error);
|
||||
sendError(event.error);
|
||||
};
|
||||
|
||||
window.addEventListener('message', event => worker.postMessage(event.data, event.ports));
|
||||
} catch(err) {
|
||||
console.error(err);
|
||||
sendError(err);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { NewWorkerMessage, TerminateWorkerMessage } from 'vs/workbench/services/extensions/common/polyfillNestedWorker.protocol';
|
||||
import { NewWorkerMessage, TerminateWorkerMessage, WorkerMessageType } from 'vs/workbench/services/extensions/common/polyfillNestedWorker.protocol';
|
||||
|
||||
declare function postMessage(data: any, transferables?: Transferable[]): void;
|
||||
|
||||
|
@ -75,7 +75,7 @@ export class NestedWorker extends EventTarget implements Worker {
|
|||
const id = blobUrl; // works because blob url is unique, needs ID pool otherwise
|
||||
|
||||
const msg: NewWorkerMessage = {
|
||||
type: '_newWorker',
|
||||
type: WorkerMessageType.NewWorker,
|
||||
id,
|
||||
port: channel.port2,
|
||||
url: blobUrl,
|
||||
|
@ -87,7 +87,7 @@ export class NestedWorker extends EventTarget implements Worker {
|
|||
this.postMessage = channel.port1.postMessage.bind(channel.port1);
|
||||
this.terminate = () => {
|
||||
const msg: TerminateWorkerMessage = {
|
||||
type: '_terminateWorker',
|
||||
type: WorkerMessageType.TerminateWorker,
|
||||
id
|
||||
};
|
||||
channel.port1.postMessage(msg);
|
||||
|
|
|
@ -23,7 +23,6 @@ export interface ILanguageStatus {
|
|||
readonly severity: Severity;
|
||||
readonly label: string;
|
||||
readonly detail: string;
|
||||
readonly busy: boolean;
|
||||
readonly source: string;
|
||||
readonly command: Command | undefined;
|
||||
readonly accessibilityInfo: IAccessibilityInformation | undefined;
|
||||
|
|
|
@ -12,7 +12,7 @@ import { URI } from 'vs/base/common/uri';
|
|||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, EditPresentationTypes, IExtensionInfo } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, EditPresentationTypes, IConfigurationExtensionInfo } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { EditorResolution, IEditorOptions } from 'vs/platform/editor/common/editor';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
|
||||
|
@ -44,7 +44,7 @@ export interface ISettingsGroup {
|
|||
titleRange: IRange;
|
||||
sections: ISettingsSection[];
|
||||
order?: number;
|
||||
extensionInfo?: IExtensionInfo;
|
||||
extensionInfo?: IConfigurationExtensionInfo;
|
||||
}
|
||||
|
||||
export interface ISettingsSection {
|
||||
|
@ -81,7 +81,7 @@ export interface ISetting {
|
|||
tags?: string[];
|
||||
disallowSyncIgnore?: boolean;
|
||||
restricted?: boolean;
|
||||
extensionInfo?: IExtensionInfo;
|
||||
extensionInfo?: IConfigurationExtensionInfo;
|
||||
validator?: (value: any) => string | null;
|
||||
enumItemLabels?: string[];
|
||||
allKeysAreBoolean?: boolean;
|
||||
|
|
|
@ -15,7 +15,7 @@ import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/mod
|
|||
import { ITextEditorModel } from 'vs/editor/common/services/resolverService';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPropertySchema, IConfigurationRegistry, IExtensionInfo, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ConfigurationScope, Extensions, IConfigurationNode, IConfigurationPropertySchema, IConfigurationRegistry, IConfigurationExtensionInfo, OVERRIDE_PROPERTY_REGEX } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { EditorModel } from 'vs/workbench/common/editor/editorModel';
|
||||
|
@ -607,7 +607,7 @@ export class DefaultSettings extends Disposable {
|
|||
return result;
|
||||
}
|
||||
|
||||
private parseSettings(settingsObject: { [path: string]: IConfigurationPropertySchema; }, extensionInfo?: IExtensionInfo): ISetting[] {
|
||||
private parseSettings(settingsObject: { [path: string]: IConfigurationPropertySchema; }, extensionInfo?: IConfigurationExtensionInfo): ISetting[] {
|
||||
const result: ISetting[] = [];
|
||||
for (const key in settingsObject) {
|
||||
const prop = settingsObject[key];
|
||||
|
|
|
@ -132,7 +132,7 @@ import { IEditorResolverService } from 'vs/workbench/services/editor/common/edit
|
|||
import { IWorkingCopyEditorService, WorkingCopyEditorService } from 'vs/workbench/services/workingCopy/common/workingCopyEditorService';
|
||||
import { IElevatedFileService } from 'vs/workbench/services/files/common/elevatedFileService';
|
||||
import { BrowserElevatedFileService } from 'vs/workbench/services/files/browser/elevatedFileService';
|
||||
import { IDiffComputationResult, IEditorWorkerService, IUnicodeHighlightsResult } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { TextEdit, IInplaceReplaceSupportResult } from 'vs/editor/common/modes';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { SideBySideEditorInput } from 'vs/workbench/common/editor/sideBySideEditorInput';
|
||||
|
@ -1866,7 +1866,7 @@ export class TestEditorWorkerService implements IEditorWorkerService {
|
|||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
canComputeUnicodeHighlights(uri: URI): boolean { return false; }
|
||||
async computedUnicodeHighlights(uri: URI): Promise<IUnicodeHighlightsResult> { return { ranges: [], hasMore: false, ambiguousCharacterCount: 0, invisibleCharacterCount: 0, nonBasicAsciiCharacterCount: 0 }; }
|
||||
async computedUnicodeHighlights(uri: URI): Promise<IRange[]> { return []; }
|
||||
async computeDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean, maxComputationTime: number): Promise<IDiffComputationResult | null> { return null; }
|
||||
canComputeDirtyDiff(original: URI, modified: URI): boolean { return false; }
|
||||
async computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null> { return null; }
|
||||
|
|
|
@ -14,59 +14,15 @@ declare module 'vscode' {
|
|||
}
|
||||
|
||||
interface LanguageStatusItem {
|
||||
|
||||
/**
|
||||
* The identifier of this item.
|
||||
*/
|
||||
readonly id: string;
|
||||
|
||||
/**
|
||||
* The short name of this item, like 'Java Language Status', etc.
|
||||
*/
|
||||
name: string | undefined;
|
||||
|
||||
/**
|
||||
* A {@link DocumentSelector selector} that defines for what documents
|
||||
* this item shows.
|
||||
*/
|
||||
selector: DocumentSelector;
|
||||
|
||||
// todo@jrieken replace with boolean ala needsAttention
|
||||
severity: LanguageStatusSeverity;
|
||||
|
||||
/**
|
||||
* The text to show for the entry. You can embed icons in the text by leveraging the syntax:
|
||||
*
|
||||
* `My text $(icon-name) contains icons like $(icon-name) this one.`
|
||||
*
|
||||
* Where the icon-name is taken from the ThemeIcon [icon set](https://code.visualstudio.com/api/references/icons-in-labels#icon-listing), e.g.
|
||||
* `light-bulb`, `thumbsup`, `zap` etc.
|
||||
*/
|
||||
name: string | undefined;
|
||||
text: string;
|
||||
|
||||
/**
|
||||
* Optional, human-readable details for this item.
|
||||
*/
|
||||
detail?: string;
|
||||
|
||||
/**
|
||||
* Controls whether the item is shown as "busy". Defaults to `false`.
|
||||
*/
|
||||
busy: boolean;
|
||||
|
||||
/**
|
||||
* A {@linkcode Command command} for this item.
|
||||
*/
|
||||
command: Command | undefined;
|
||||
|
||||
/**
|
||||
* Accessibility information used when a screen reader interacts with this item
|
||||
*/
|
||||
accessibilityInformation?: AccessibilityInformation;
|
||||
|
||||
/**
|
||||
* Dispose and free associated resources.
|
||||
*/
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
|
|
|
@ -63,7 +63,7 @@ function getBuildOutPath(root: string): string {
|
|||
}
|
||||
}
|
||||
|
||||
async function connect(connectDriver: typeof connectElectronDriver | typeof connectPlaywrightDriver, child: cp.ChildProcess | undefined, outPath: string, handlePath: string, logger: Logger): Promise<Code> {
|
||||
async function connect(connectDriver: typeof connectElectronDriver, child: cp.ChildProcess | undefined, outPath: string, handlePath: string, logger: Logger): Promise<Code> {
|
||||
let errCount = 0;
|
||||
|
||||
while (true) {
|
||||
|
@ -79,7 +79,7 @@ async function connect(connectDriver: typeof connectElectronDriver | typeof conn
|
|||
}
|
||||
|
||||
// retry
|
||||
await new Promise(resolve => setTimeout(resolve, 100));
|
||||
await new Promise(c => setTimeout(c, 100));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -116,12 +116,14 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
|
|||
const handle = await createDriverHandle();
|
||||
|
||||
let child: cp.ChildProcess | undefined;
|
||||
let connectDriver: typeof connectElectronDriver;
|
||||
|
||||
copyExtension(options.extensionsPath, 'vscode-notebook-tests');
|
||||
|
||||
if (options.web) {
|
||||
await launch(options.userDataDir, options.workspacePath, options.codePath, options.extensionsPath, Boolean(options.verbose));
|
||||
return connect(connectPlaywrightDriver.bind(connectPlaywrightDriver, options), child, '', handle, options.logger);
|
||||
connectDriver = connectPlaywrightDriver.bind(connectPlaywrightDriver, options);
|
||||
return connect(connectDriver, child, '', handle, options.logger);
|
||||
}
|
||||
|
||||
const env = { ...process.env };
|
||||
|
@ -197,7 +199,8 @@ export async function spawn(options: SpawnOptions): Promise<Code> {
|
|||
child = cp.spawn(electronPath, args, spawnOptions);
|
||||
instances.add(child);
|
||||
child.once('exit', () => instances.delete(child!));
|
||||
return connect(connectElectronDriver, child, outPath, handle, options.logger);
|
||||
connectDriver = connectElectronDriver;
|
||||
return connect(connectDriver, child, outPath, handle, options.logger);
|
||||
}
|
||||
|
||||
async function copyExtension(extensionsPath: string, extId: string): Promise<void> {
|
||||
|
|
|
@ -57,15 +57,9 @@ class PlaywrightDriver implements IDriver {
|
|||
try {
|
||||
await this._context.tracing.stop({ path: join(logsPath, `playwright-trace-${traceCounter++}.zip`) });
|
||||
} catch (error) {
|
||||
console.warn(`Failed to stop playwright tracing: ${error}`);
|
||||
console.warn(`Failed to stop playwright tracing.`); // do not fail the build when this fails
|
||||
}
|
||||
|
||||
try {
|
||||
await this._browser.close();
|
||||
} catch (error) {
|
||||
console.warn(`Failed to close browser: ${error}`);
|
||||
}
|
||||
|
||||
await this._browser.close();
|
||||
await teardown();
|
||||
|
||||
return false;
|
||||
|
@ -213,9 +207,9 @@ export async function launch(userDataDir: string, _workspacePath: string, codeSe
|
|||
async function teardown(): Promise<void> {
|
||||
if (server) {
|
||||
try {
|
||||
await new Promise<void>((resolve, reject) => kill(server!.pid, err => err ? reject(err) : resolve()));
|
||||
} catch (error) {
|
||||
console.warn(`Error tearing down server: ${error}`);
|
||||
await new Promise<void>((c, e) => kill(server!.pid, err => err ? e(err) : c()));
|
||||
} catch {
|
||||
// noop
|
||||
}
|
||||
|
||||
server = undefined;
|
||||
|
|
|
@ -170,7 +170,7 @@ export function setup(opts: ParsedArgs, testDataPath: string) {
|
|||
await insidersApp.workbench.editor.waitForEditorContents(readmeMd, c => c.indexOf(textToType) > -1);
|
||||
|
||||
await insidersApp.workbench.editors.waitForTab(untitled, true);
|
||||
await insidersApp.workbench.quickaccess.openFile(untitled, textToTypeInUntitled);
|
||||
await insidersApp.workbench.quickaccess.openFile(textToTypeInUntitled);
|
||||
await insidersApp.workbench.editor.waitForEditorContents(untitled, c => c.indexOf(textToTypeInUntitled) > -1);
|
||||
|
||||
await insidersApp.stop();
|
||||
|
|
|
@ -6903,10 +6903,10 @@ native-is-elevated@0.4.3:
|
|||
resolved "https://registry.yarnpkg.com/native-is-elevated/-/native-is-elevated-0.4.3.tgz#f1071c4a821acc71d43f36ff8051d3816d832e1c"
|
||||
integrity sha512-bHS3sCoh+raqFGIxmL/plER3eBQ+IEBy4RH/4uahhToZneTvqNKQrL0PgOTtnpL55XjBd3dy0pNtZMkCk0J48g==
|
||||
|
||||
native-keymap@3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-3.0.2.tgz#eb299a9f1a252be552ee2345ba8a39ff4b2c304a"
|
||||
integrity sha512-1qH2saFkYzwT+c2a1xaawrfgkiT1OJ6H8xZWx9zmhhOkuJto/HaNLSINxCYhSjc7zO0zOydMkoCXehGh3TAWcg==
|
||||
native-keymap@3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/native-keymap/-/native-keymap-3.0.1.tgz#7cc2d30da1e60cbb7d599423e05cb84845d20a8f"
|
||||
integrity sha512-IeHaz5NM1mF3AKIwBxf4YhgrB/hcctVwIqOXaMrR8Hz8v45dCa364YDvEN0004zSycRyhrXh6cNgCQ/v6QUHkA==
|
||||
|
||||
native-watchdog@1.3.0:
|
||||
version "1.3.0"
|
||||
|
|
Loading…
Reference in a new issue