Merge from vscode 1ce89e2cb720d69c496c2815c4696ee4fd4429a6 (#6779)
* Merge from vscode 1ce89e2cb720d69c496c2815c4696ee4fd4429a6 * redisable accounts because of issues
@@ -29,13 +29,14 @@ export abstract class SimpleFindWidget extends Widget {
|
||||
private readonly _findInput: FindInput;
|
||||
private readonly _domNode: HTMLElement;
|
||||
private readonly _innerDomNode: HTMLElement;
|
||||
private _isVisible: boolean = false;
|
||||
private readonly _focusTracker: dom.IFocusTracker;
|
||||
private readonly _findInputFocusTracker: dom.IFocusTracker;
|
||||
private readonly _updateHistoryDelayer: Delayer<void>;
|
||||
private prevBtn: SimpleButton;
|
||||
private nextBtn: SimpleButton;
|
||||
private foundMatch: boolean;
|
||||
private readonly prevBtn: SimpleButton;
|
||||
private readonly nextBtn: SimpleButton;
|
||||
|
||||
private _isVisible: boolean = false;
|
||||
private foundMatch: boolean = false;
|
||||
|
||||
constructor(
|
||||
@IContextViewService private readonly _contextViewService: IContextViewService,
|
||||
|
||||
@@ -144,7 +144,8 @@ export class CallStackView extends ViewletPanel {
|
||||
|
||||
return nls.localize('showMoreStackFrames2', "Show More Stack Frames");
|
||||
}
|
||||
}
|
||||
},
|
||||
expandOnlyOnTwistieClick: true
|
||||
});
|
||||
|
||||
this.tree.setInput(this.debugService.getModel()).then(undefined, onUnexpectedError);
|
||||
@@ -576,7 +577,7 @@ function isDebugModel(obj: any): obj is IDebugModel {
|
||||
}
|
||||
|
||||
function isDebugSession(obj: any): obj is IDebugSession {
|
||||
return typeof obj.getAllThreads === 'function';
|
||||
return obj && typeof obj.getAllThreads === 'function';
|
||||
}
|
||||
|
||||
function isDeemphasized(frame: IStackFrame): boolean {
|
||||
@@ -608,6 +609,10 @@ class CallStackDataSource implements IAsyncDataSource<IDebugModel, CallStackItem
|
||||
} else if (isDebugSession(element)) {
|
||||
const childSessions = this.debugService.getModel().getSessions().filter(s => s.parentSession === element);
|
||||
const threads: CallStackItem[] = element.getAllThreads();
|
||||
if (threads.length === 1 && childSessions.length === 0) {
|
||||
// Do not show thread when there is only one to be compact.
|
||||
return this.getThreadChildren(<Thread>threads[0]);
|
||||
}
|
||||
|
||||
return Promise.resolve(threads.concat(childSessions));
|
||||
} else {
|
||||
|
||||
@@ -35,19 +35,23 @@ class ToggleBreakpointAction extends EditorAction {
|
||||
}
|
||||
|
||||
public run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<any> {
|
||||
const debugService = accessor.get(IDebugService);
|
||||
|
||||
const position = editor.getPosition();
|
||||
if (editor.hasModel() && position) {
|
||||
if (editor.hasModel()) {
|
||||
const debugService = accessor.get(IDebugService);
|
||||
const modelUri = editor.getModel().uri;
|
||||
const bps = debugService.getModel().getBreakpoints({ lineNumber: position.lineNumber, uri: modelUri });
|
||||
const canSet = debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel());
|
||||
// Does not account for multi line selections, Set to remove multiple cursor on the same line
|
||||
const lineNumbers = [...new Set(editor.getSelections().map(s => s.getPosition().lineNumber))];
|
||||
|
||||
if (bps.length) {
|
||||
return Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId())));
|
||||
}
|
||||
if (debugService.getConfigurationManager().canSetBreakpointsIn(editor.getModel())) {
|
||||
return debugService.addBreakpoints(modelUri, [{ lineNumber: position.lineNumber }], 'debugEditorActions.toggleBreakpointAction');
|
||||
}
|
||||
return Promise.all(lineNumbers.map(line => {
|
||||
const bps = debugService.getModel().getBreakpoints({ lineNumber: line, uri: modelUri });
|
||||
if (bps.length) {
|
||||
return Promise.all(bps.map(bp => debugService.removeBreakpoints(bp.getId())));
|
||||
} else if (canSet) {
|
||||
return (debugService.addBreakpoints(modelUri, [{ lineNumber: line }], 'debugEditorActions.toggleBreakpointAction'));
|
||||
} else {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return Promise.resolve();
|
||||
|
||||
@@ -175,7 +175,7 @@ export class DebugSession implements IDebugSession {
|
||||
|
||||
return this.raw!.initialize({
|
||||
clientID: 'vscode',
|
||||
clientName: this.productService.productConfiguration.nameLong,
|
||||
clientName: this.productService.nameLong,
|
||||
adapterID: this.configuration.type,
|
||||
pathFormat: 'path',
|
||||
linesStartAt1: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient {
|
||||
|
||||
constructor(
|
||||
@IRemoteAgentService remoteAgentService: IRemoteAgentService,
|
||||
//@IWindowService windowService: IWindowService,
|
||||
// @IWindowService windowService: IWindowService, // TODO@weinand TODO@isidorn cyclic dependency?
|
||||
@IEnvironmentService environmentService: IEnvironmentService
|
||||
) {
|
||||
const connection = remoteAgentService.getConnection();
|
||||
@@ -30,13 +30,11 @@ class BrowserExtensionHostDebugService extends ExtensionHostDebugChannelClient {
|
||||
|
||||
this._register(this.onReload(event => {
|
||||
if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) {
|
||||
//windowService.reloadWindow();
|
||||
window.location.reload();
|
||||
}
|
||||
}));
|
||||
this._register(this.onClose(event => {
|
||||
if (environmentService.isExtensionDevelopment && environmentService.debugExtensionHost.debugId === event.sessionId) {
|
||||
//this._windowService.closeWindow();
|
||||
window.close();
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -16,6 +16,7 @@ import { ParsedArgs } from 'vs/platform/environment/common/environment';
|
||||
import { IWindowsService } from 'vs/platform/windows/common/windows';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IProcessEnvironment } from 'vs/base/common/platform';
|
||||
import { env as processEnv } from 'vs/base/common/process';
|
||||
|
||||
/**
|
||||
* This interface represents a single command line argument split into a "prefix" and a "path" half.
|
||||
@@ -594,10 +595,7 @@ export class RawDebugSession {
|
||||
let env: IProcessEnvironment = {};
|
||||
if (vscodeArgs.env) {
|
||||
// merge environment variables into a copy of the process.env
|
||||
if (typeof process === 'object' && process.env) {
|
||||
env = objects.mixin(env, process.env);
|
||||
}
|
||||
env = objects.mixin(env, vscodeArgs.env);
|
||||
env = objects.mixin(processEnv, vscodeArgs.env);
|
||||
// and delete some if necessary
|
||||
Object.keys(env).filter(k => env[k] === null).forEach(key => delete env[key]);
|
||||
}
|
||||
|
||||
@@ -227,14 +227,14 @@ export class Expression extends ExpressionContainer implements IExpression {
|
||||
const response = await session.evaluate(this.name, stackFrame ? stackFrame.frameId : undefined, context);
|
||||
this.available = !!(response && response.body);
|
||||
if (response && response.body) {
|
||||
this.value = response.body.result;
|
||||
this.value = response.body.result || '';
|
||||
this.reference = response.body.variablesReference;
|
||||
this.namedVariables = response.body.namedVariables;
|
||||
this.indexedVariables = response.body.indexedVariables;
|
||||
this.type = response.body.type || this.type;
|
||||
}
|
||||
} catch (e) {
|
||||
this.value = e.message;
|
||||
this.value = e.message || '';
|
||||
this.available = false;
|
||||
this.reference = 0;
|
||||
}
|
||||
@@ -256,7 +256,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
||||
reference: number | undefined,
|
||||
public name: string,
|
||||
public evaluateName: string | undefined,
|
||||
value: string,
|
||||
value: string | undefined,
|
||||
namedVariables: number | undefined,
|
||||
indexedVariables: number | undefined,
|
||||
public presentationHint: DebugProtocol.VariablePresentationHint | undefined,
|
||||
@@ -265,7 +265,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
||||
startOfVariables = 0
|
||||
) {
|
||||
super(session, reference, `variable:${parent.getId()}:${name}`, namedVariables, indexedVariables, startOfVariables);
|
||||
this.value = value;
|
||||
this.value = value || '';
|
||||
}
|
||||
|
||||
async setVariable(value: string): Promise<any> {
|
||||
@@ -276,7 +276,7 @@ export class Variable extends ExpressionContainer implements IExpression {
|
||||
try {
|
||||
const response = await this.session.setVariable((<ExpressionContainer>this.parent).reference, this.name, value);
|
||||
if (response && response.body) {
|
||||
this.value = response.body.value;
|
||||
this.value = response.body.value || '';
|
||||
this.type = response.body.type || this.type;
|
||||
this.reference = response.body.variablesReference;
|
||||
this.namedVariables = response.body.namedVariables;
|
||||
|
||||
@@ -170,10 +170,10 @@ export class ExperimentService extends Disposable implements IExperimentService
|
||||
}
|
||||
|
||||
protected getExperiments(): Promise<IRawExperiment[]> {
|
||||
if (!this.productService.productConfiguration.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) {
|
||||
if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
return this.requestService.request({ type: 'GET', url: this.productService.productConfiguration.experimentsUrl }, CancellationToken.None).then(context => {
|
||||
return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => {
|
||||
if (context.res.statusCode !== 200) {
|
||||
return Promise.resolve(null);
|
||||
}
|
||||
|
||||
@@ -54,6 +54,7 @@ import { IWebviewService, Webview } from 'vs/workbench/contrib/webview/common/we
|
||||
import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
import { renderDashboardContributions } from 'sql/workbench/parts/extensions/browser/contributionRenders'; // {{SQL CARBON EDIT}}
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
import { platform } from 'vs/base/common/process';
|
||||
|
||||
function removeEmbeddedSVGs(documentContent: string): string {
|
||||
const newDocument = new DOMParser().parseFromString(documentContent, 'text/html');
|
||||
@@ -582,9 +583,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
{
|
||||
enableFindWidget: true,
|
||||
},
|
||||
{
|
||||
svgWhiteList: this.extensionsWorkbenchService.allowedBadgeProviders,
|
||||
});
|
||||
{});
|
||||
webviewElement.mountTo(template.content);
|
||||
this.contentDisposables.add(webviewElement.onDidFocus(() => this.fireOnDidFocus()));
|
||||
const removeLayoutParticipant = arrays.insert(this.layoutParticipants, webviewElement);
|
||||
@@ -1287,7 +1286,7 @@ export class ExtensionEditor extends BaseEditor {
|
||||
private resolveKeybinding(rawKeyBinding: IKeyBinding): ResolvedKeybinding | null {
|
||||
let key: string | undefined;
|
||||
|
||||
switch (process.platform) {
|
||||
switch (platform) {
|
||||
case 'win32': key = rawKeyBinding.win; break;
|
||||
case 'linux': key = rawKeyBinding.linux; break;
|
||||
case 'darwin': key = rawKeyBinding.mac; break;
|
||||
|
||||
@@ -27,9 +27,7 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IExtensionsConfiguration, ConfigurationKey, ShowRecommendationsOnlyOnDemandKey, IExtensionsViewlet, IExtensionsWorkbenchService, EXTENSIONS_CONFIG, ExtensionsPolicyKey, ExtensionsPolicy } from 'vs/workbench/contrib/extensions/common/extensions';
|
||||
import { IConfigurationService, ConfigurationTarget } from 'vs/platform/configuration/common/configuration';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import * as os from 'os';
|
||||
import { flatten, distinct, shuffle, coalesce } from 'vs/base/common/arrays';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { guessMimeTypes, MIME_UNKNOWN } from 'vs/base/common/mime';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IRequestService, asJson } from 'vs/platform/request/common/request';
|
||||
@@ -49,6 +47,9 @@ import { timeout } from 'vs/base/common/async';
|
||||
import { IAdsTelemetryService } from 'sql/platform/telemetry/common/telemetry'; // {{SQL CARBON EDIT}}
|
||||
import * as TelemetryKeys from 'sql/platform/telemetry/common/telemetryKeys'; // {{SQL CARBON EDIT}}
|
||||
import { IWorkspaceStatsService } from 'vs/workbench/contrib/stats/common/workspaceStats';
|
||||
import { Platform, setImmediate } from 'vs/base/common/platform';
|
||||
import { platform, env as processEnv } from 'vs/base/common/process';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
|
||||
const milliSecondsInADay = 1000 * 60 * 60 * 24;
|
||||
const choiceNever = localize('neverShowAgain', "Don't Show Again");
|
||||
@@ -106,7 +107,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IEnvironmentService private readonly environmentService: IEnvironmentService,
|
||||
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
||||
@IExtensionService private readonly extensionService: IExtensionService,
|
||||
@IRequestService private readonly requestService: IRequestService,
|
||||
@IViewletService private readonly viewletService: IViewletService,
|
||||
@@ -126,8 +127,8 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.productService.productConfiguration.extensionsGallery && this.productService.productConfiguration.extensionsGallery.recommendationsUrl) {
|
||||
this._extensionsRecommendationsUrl = this.productService.productConfiguration.extensionsGallery.recommendationsUrl;
|
||||
if (this.productService.extensionsGallery && this.productService.extensionsGallery.recommendationsUrl) {
|
||||
this._extensionsRecommendationsUrl = this.productService.extensionsGallery.recommendationsUrl;
|
||||
}
|
||||
|
||||
this.sessionSeed = +new Date();
|
||||
@@ -256,7 +257,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
getKeymapRecommendations(): IExtensionRecommendation[] {
|
||||
return (this.productService.productConfiguration.keymapExtensionTips || [])
|
||||
return (this.productService.keymapExtensionTips || [])
|
||||
.filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId))
|
||||
.map(extensionId => (<IExtensionRecommendation>{ extensionId, sources: ['application'] }));
|
||||
}
|
||||
@@ -613,10 +614,10 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
return Object.keys(this._fileBasedRecommendations)
|
||||
.sort((a, b) => {
|
||||
if (this._fileBasedRecommendations[a].recommendedTime === this._fileBasedRecommendations[b].recommendedTime) {
|
||||
if (!this.productService.productConfiguration.extensionImportantTips || caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, a)) {
|
||||
if (!this.productService.extensionImportantTips || caseInsensitiveGet(this.productService.extensionImportantTips, a)) {
|
||||
return -1;
|
||||
}
|
||||
if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, b)) {
|
||||
if (caseInsensitiveGet(this.productService.extensionImportantTips, b)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@@ -627,13 +628,13 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse all file based recommendations from this.productService.productConfiguration.extensionTips
|
||||
* Retire existing recommendations if they are older than a week or are not part of this.productService.productConfiguration.extensionTips anymore
|
||||
* Parse all file based recommendations from this.productService.extensionTips
|
||||
* Retire existing recommendations if they are older than a week or are not part of this.productService.extensionTips anymore
|
||||
*/
|
||||
private fetchFileBasedRecommendations() {
|
||||
const extensionTips = this.productService.productConfiguration.extensionTips;
|
||||
const extensionTips = this.productService.extensionTips;
|
||||
// {{SQL CARBON EDIT}}
|
||||
this._recommendations = this.productService.productConfiguration.recommendedExtensions;
|
||||
this._recommendations = this.productService.recommendedExtensions;
|
||||
if (!extensionTips) {
|
||||
return;
|
||||
}
|
||||
@@ -650,7 +651,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
});
|
||||
|
||||
forEach(this.productService.productConfiguration.extensionImportantTips, entry => {
|
||||
forEach(this.productService.extensionImportantTips, entry => {
|
||||
let { key: id, value } = entry;
|
||||
const { pattern } = value;
|
||||
let ids = this._availableRecommendations[pattern];
|
||||
@@ -712,7 +713,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
let { key: pattern, value: ids } = entry;
|
||||
if (match(pattern, model.uri.toString())) {
|
||||
for (let id of ids) {
|
||||
if (caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id)) {
|
||||
if (caseInsensitiveGet(this.productService.extensionImportantTips, id)) {
|
||||
recommendationsToSuggest.push(id);
|
||||
}
|
||||
const filedBasedRecommendation = this._fileBasedRecommendations[id.toLowerCase()] || { recommendedTime: now, sources: [] };
|
||||
@@ -766,7 +767,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
const id = recommendationsToSuggest[0];
|
||||
const entry = caseInsensitiveGet(this.productService.productConfiguration.extensionImportantTips, id);
|
||||
const entry = caseInsensitiveGet(this.productService.extensionImportantTips, id);
|
||||
if (!entry) {
|
||||
return false;
|
||||
}
|
||||
@@ -992,13 +993,15 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
}
|
||||
|
||||
/**
|
||||
* If user has any of the tools listed in this.productService.productConfiguration.exeBasedExtensionTips, fetch corresponding recommendations
|
||||
* If user has any of the tools listed in this.productService.exeBasedExtensionTips, fetch corresponding recommendations
|
||||
*/
|
||||
private fetchExecutableRecommendations(important: boolean): Promise<void> {
|
||||
const homeDir = os.homedir();
|
||||
let foundExecutables: Set<string> = new Set<string>();
|
||||
private async fetchExecutableRecommendations(important: boolean): Promise<void> {
|
||||
if (Platform.Web) {
|
||||
return;
|
||||
}
|
||||
|
||||
let findExecutable = (exeName: string, tip: IExeBasedExtensionTip, path: string) => {
|
||||
const foundExecutables: Set<string> = new Set<string>();
|
||||
const findExecutable = (exeName: string, tip: IExeBasedExtensionTip, path: string) => {
|
||||
return this.fileService.exists(URI.file(path)).then(exists => {
|
||||
if (exists && !foundExecutables.has(exeName)) {
|
||||
foundExecutables.add(exeName);
|
||||
@@ -1014,9 +1017,9 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
});
|
||||
};
|
||||
|
||||
let promises: Promise<void>[] = [];
|
||||
const promises: Promise<void>[] = [];
|
||||
// Loop through recommended extensions
|
||||
forEach(this.productService.productConfiguration.exeBasedExtensionTips, entry => {
|
||||
forEach(this.productService.exeBasedExtensionTips, entry => {
|
||||
if (typeof entry.value !== 'object' || !Array.isArray(entry.value['recommendations'])) {
|
||||
return;
|
||||
}
|
||||
@@ -1024,24 +1027,24 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
return;
|
||||
}
|
||||
const exeName = entry.key;
|
||||
if (process.platform === 'win32') {
|
||||
if (platform === 'win32') {
|
||||
let windowsPath = entry.value['windowsPath'];
|
||||
if (!windowsPath || typeof windowsPath !== 'string') {
|
||||
return;
|
||||
}
|
||||
windowsPath = windowsPath.replace('%USERPROFILE%', process.env['USERPROFILE']!)
|
||||
.replace('%ProgramFiles(x86)%', process.env['ProgramFiles(x86)']!)
|
||||
.replace('%ProgramFiles%', process.env['ProgramFiles']!)
|
||||
.replace('%APPDATA%', process.env['APPDATA']!)
|
||||
.replace('%WINDIR%', process.env['WINDIR']!);
|
||||
windowsPath = windowsPath.replace('%USERPROFILE%', processEnv['USERPROFILE']!)
|
||||
.replace('%ProgramFiles(x86)%', processEnv['ProgramFiles(x86)']!)
|
||||
.replace('%ProgramFiles%', processEnv['ProgramFiles']!)
|
||||
.replace('%APPDATA%', processEnv['APPDATA']!)
|
||||
.replace('%WINDIR%', processEnv['WINDIR']!);
|
||||
promises.push(findExecutable(exeName, entry.value, windowsPath));
|
||||
} else {
|
||||
promises.push(findExecutable(exeName, entry.value, join('/usr/local/bin', exeName)));
|
||||
promises.push(findExecutable(exeName, entry.value, join(homeDir, exeName)));
|
||||
promises.push(findExecutable(exeName, entry.value, join(this.environmentService.userHome, exeName)));
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.all(promises).then(() => undefined);
|
||||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1155,7 +1158,6 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
private isExtensionAllowedToBeRecommended(id: string): boolean {
|
||||
return this._allIgnoredRecommendations.indexOf(id.toLowerCase()) === -1;
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
promptRecommendedExtensionsByScenario(scenarioType: string): void {
|
||||
const storageKey = 'extensionAssistant/RecommendationsIgnore/' + scenarioType;
|
||||
@@ -1246,7 +1248,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
|
||||
return Promise.reject(new Error(localize('scenarioTypeUndefined', 'The scenario type for extension recommendations must be provided.')));
|
||||
}
|
||||
|
||||
return Promise.resolve((this.productService.productConfiguration.recommendedExtensionsByScenario[scenarioType] || [])
|
||||
return Promise.resolve((this.productService.recommendedExtensionsByScenario[scenarioType] || [])
|
||||
.filter(extensionId => this.isExtensionAllowedToBeRecommended(extensionId))
|
||||
.map(extensionId => (<IExtensionRecommendation>{ extensionId, sources: ['application'] })));
|
||||
}
|
||||
@@ -10,7 +10,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { ExtensionsLabel, ExtensionsChannelId, PreferencesLabel, IExtensionManagementService, IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServerService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IOutputChannelRegistry, Extensions as OutputExtensions } from 'vs/workbench/contrib/output/common/output';
|
||||
@@ -45,9 +45,11 @@ import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { ExtensionType } from 'vs/platform/extensions/common/extensions';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { RemoteExtensionsInstaller } from 'vs/workbench/contrib/extensions/browser/remoteExtensionsInstaller';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
|
||||
// Singletons
|
||||
registerSingleton(IExtensionsWorkbenchService, ExtensionsWorkbenchService);
|
||||
registerSingleton(IExtensionTipsService, ExtensionTipsService);
|
||||
|
||||
Registry.as<IOutputChannelRegistry>(OutputExtensions.OutputChannels)
|
||||
.registerChannel({ id: ExtensionsChannelId, label: ExtensionsLabel, log: false });
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
|
||||
// Singletons
|
||||
registerSingleton(IExtensionTipsService, ExtensionTipsService);
|
||||
@@ -79,10 +79,10 @@ export function toExtensionDescription(local: ILocalExtension): IExtensionDescri
|
||||
|
||||
const promptDownloadManually = (extension: IGalleryExtension | undefined, message: string, error: Error,
|
||||
instantiationService: IInstantiationService, notificationService: INotificationService, openerService: IOpenerService, productService: IProductService) => {
|
||||
if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.productConfiguration.extensionsGallery) {
|
||||
if (!extension || error.name === INSTALL_ERROR_INCOMPATIBLE || error.name === INSTALL_ERROR_MALICIOUS || !productService.extensionsGallery) {
|
||||
return Promise.reject(error);
|
||||
} else {
|
||||
const downloadUrl = `${productService.productConfiguration.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`;
|
||||
const downloadUrl = `${productService.extensionsGallery.serviceUrl}/publishers/${extension.publisher}/vsextensions/${extension.name}/${extension.version}/vspackage`;
|
||||
notificationService.prompt(Severity.Error, message, [{
|
||||
label: localize('download', "Download Manually"),
|
||||
run: () => openerService.open(URI.parse(downloadUrl)).then(() => {
|
||||
|
||||
@@ -435,7 +435,7 @@ export class ExtensionsListView extends ViewletPanel {
|
||||
// {{SQL CARBON EDIT}}
|
||||
if (this.productService) {
|
||||
let promiseRecommendedExtensionsByScenario: Promise<IPagedModel<IExtension>> | undefined;
|
||||
Object.keys(this.productService.productConfiguration.recommendedExtensionsByScenario).forEach(scenarioType => {
|
||||
Object.keys(this.productService.recommendedExtensionsByScenario).forEach(scenarioType => {
|
||||
let re = new RegExp('@' + scenarioType, 'i');
|
||||
if (re.test(query.value)) {
|
||||
promiseRecommendedExtensionsByScenario = this.getRecommendedExtensionsByScenario(token, scenarioType);
|
||||
|
||||
@@ -118,16 +118,16 @@ class Extension implements IExtension {
|
||||
}
|
||||
|
||||
get url(): string | undefined {
|
||||
if (!this.productService.productConfiguration.extensionsGallery || !this.gallery) {
|
||||
if (!this.productService.extensionsGallery || !this.gallery) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return `${this.productService.productConfiguration.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`;
|
||||
return `${this.productService.extensionsGallery.itemUrl}?itemName=${this.publisher}.${this.name}`;
|
||||
}
|
||||
|
||||
// {{SQL CARBON EDIT}}
|
||||
get downloadPage(): string {
|
||||
if (!this.productService.productConfiguration.extensionsGallery) {
|
||||
if (!this.productService.extensionsGallery) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -499,7 +499,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
private readonly _onChange: Emitter<IExtension | undefined> = new Emitter<IExtension | undefined>();
|
||||
get onChange(): Event<IExtension | undefined> { return this._onChange.event; }
|
||||
|
||||
private _extensionAllowedBadgeProviders: string[] | undefined;
|
||||
private installing: IExtension[] = [];
|
||||
|
||||
constructor(
|
||||
@@ -631,7 +630,7 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
text = text.replace(extensionRegex, (m, ext) => {
|
||||
|
||||
// Get curated keywords
|
||||
const lookup = this.productService.productConfiguration.extensionKeywords || {};
|
||||
const lookup = this.productService.extensionKeywords || {};
|
||||
const keywords = lookup[ext] || [];
|
||||
|
||||
// Get mode name
|
||||
@@ -831,9 +830,9 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
// This is the execution path for install/update extension from marketplace.
|
||||
// Check both the vscode version and azure data studio version
|
||||
// The check is added here because we want to fail fast instead of downloading the VSIX and then fail.
|
||||
if (gallery.properties.engine && (!isEngineValid(gallery.properties.engine, this.productService.productConfiguration.vscodeVersion)
|
||||
|| (gallery.properties.azDataEngine && !isEngineValid(gallery.properties.azDataEngine, this.productService.productConfiguration.version)))) {
|
||||
return Promise.reject(new Error(nls.localize('incompatible2', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, this.productService.productConfiguration.version, gallery.version)));
|
||||
if (gallery.properties.engine && (!isEngineValid(gallery.properties.engine, this.productService.vscodeVersion)
|
||||
|| (gallery.properties.azDataEngine && !isEngineValid(gallery.properties.azDataEngine, this.productService.version)))) {
|
||||
return Promise.reject(new Error(nls.localize('incompatible2', "Unable to install version '{2}' of extension '{0}' as it is not compatible with Azure Data Studio '{1}'.", extension.gallery!.identifier.id, this.productService.version, gallery.version)));
|
||||
}
|
||||
|
||||
return this.installWithProgress(async () => {
|
||||
@@ -1074,13 +1073,6 @@ export class ExtensionsWorkbenchService extends Disposable implements IExtension
|
||||
return changed;
|
||||
}
|
||||
|
||||
get allowedBadgeProviders(): string[] {
|
||||
if (!this._extensionAllowedBadgeProviders) {
|
||||
this._extensionAllowedBadgeProviders = (this.productService.productConfiguration.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase());
|
||||
}
|
||||
return this._extensionAllowedBadgeProviders;
|
||||
}
|
||||
|
||||
private _activityCallBack: (() => void) | null = null;
|
||||
private updateActivity(): void {
|
||||
if ((this.localExtensions && this.localExtensions.local.some(e => e.state === ExtensionState.Installing || e.state === ExtensionState.Uninstalling))
|
||||
|
||||
@@ -93,7 +93,6 @@ export interface IExtensionsWorkbenchService {
|
||||
setEnablement(extensions: IExtension | IExtension[], enablementState: EnablementState): Promise<void>;
|
||||
open(extension: IExtension, sideByside?: boolean): Promise<any>;
|
||||
checkForUpdates(): Promise<void>;
|
||||
allowedBadgeProviders: string[];
|
||||
}
|
||||
|
||||
export const ConfigurationKey = 'extensions';
|
||||
|
||||
@@ -7,9 +7,7 @@ import { localize } from 'vs/nls';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { SyncActionDescriptor, MenuRegistry, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { IWorkbenchActionRegistry, Extensions as WorkbenchActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService';
|
||||
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
@@ -25,7 +23,6 @@ import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ExtensionsAutoProfiler } from 'vs/workbench/contrib/extensions/electron-browser/extensionsAutoProfiler';
|
||||
|
||||
// Singletons
|
||||
registerSingleton(IExtensionTipsService, ExtensionTipsService);
|
||||
registerSingleton(IExtensionHostProfileService, ExtensionHostProfileService, true);
|
||||
|
||||
const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
|
||||
@@ -134,4 +131,4 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
|
||||
},
|
||||
group: 'navigation',
|
||||
when: ContextKeyExpr.and(ActiveEditorContext.isEqualTo(RuntimeExtensionsEditor.ID))
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
|
||||
@@ -15,14 +15,14 @@ import {
|
||||
DidInstallExtensionEvent, DidUninstallExtensionEvent, InstallExtensionEvent, IExtensionIdentifier
|
||||
} from 'vs/platform/extensionManagement/common/extensionManagement';
|
||||
import { IExtensionEnablementService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock';
|
||||
import { Emitter } from 'vs/base/common/event';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { TestContextService, TestLifecycleService, TestSharedProcessService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestContextService, TestLifecycleService, TestSharedProcessService, productService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -36,7 +36,6 @@ import { ConfigurationKey } from 'vs/workbench/contrib/extensions/common/extensi
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
import product from 'vs/platform/product/node/product';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionManagementServer, IExtensionTipsService, ExtensionRecommendationReason } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
|
||||
@@ -17,7 +17,7 @@ import {
|
||||
import { IExtensionEnablementService, EnablementState, IExtensionManagementServerService, IExtensionTipsService } from 'vs/workbench/services/extensionManagement/common/extensionManagement';
|
||||
import { getGalleryExtensionId } from 'vs/platform/extensionManagement/common/extensionManagementUtil';
|
||||
import { ExtensionManagementService } from 'vs/platform/extensionManagement/node/extensionManagementService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/electron-browser/extensionTipsService';
|
||||
import { ExtensionTipsService } from 'vs/workbench/contrib/extensions/browser/extensionTipsService';
|
||||
import { TestExtensionEnablementService } from 'vs/workbench/services/extensionManagement/test/electron-browser/extensionEnablementService.test';
|
||||
import { ExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionGalleryService';
|
||||
import { IURLService } from 'vs/platform/url/common/url';
|
||||
|
||||
@@ -73,8 +73,8 @@ export class FeedbackDropdown extends Dropdown {
|
||||
this.feedbackDelegate = options.feedbackService;
|
||||
this.maxFeedbackCharacters = this.feedbackDelegate.getCharacterLimit(this.sentiment);
|
||||
|
||||
if (productService.productConfiguration.sendASmile) {
|
||||
this.requestFeatureLink = productService.productConfiguration.sendASmile.requestFeatureUrl;
|
||||
if (productService.sendASmile) {
|
||||
this.requestFeatureLink = productService.sendASmile.requestFeatureUrl;
|
||||
}
|
||||
|
||||
this.integrityService.isPure().then(result => {
|
||||
|
||||
@@ -58,7 +58,7 @@ export class FeedbackStatusbarConribution extends Disposable implements IWorkben
|
||||
) {
|
||||
super();
|
||||
|
||||
if (productService.productConfiguration.sendASmile) {
|
||||
if (productService.sendASmile) {
|
||||
this.entry = this._register(statusbarService.addEntry(this.getStatusEntry(), 'status.feedback', localize('status.feedback', "Tweet Feedback"), StatusbarAlignment.RIGHT, -100 /* towards the end of the right hand side */));
|
||||
|
||||
CommandsRegistry.registerCommand('_feedback.open', () => this.toggleFeedback());
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#C5C5C5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4315 3.3232L5.96154 13.3232L5.17083 13.2874L1.82083 8.5174L2.63918 7.94268L5.617 12.1827L13.6685 2.67688L14.4315 3.3232Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 295 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#424242"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4315 3.3232L5.96154 13.3232L5.17083 13.2874L1.82083 8.5174L2.63918 7.94268L5.617 12.1827L13.6685 2.67688L14.4315 3.3232Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 295 B |
@@ -148,7 +148,7 @@ export class ExplorerItem {
|
||||
return this === this.root;
|
||||
}
|
||||
|
||||
static create(raw: IFileStat, parent: ExplorerItem | undefined, resolveTo?: URI[]): ExplorerItem {
|
||||
static create(raw: IFileStat, parent: ExplorerItem | undefined, resolveTo?: readonly URI[]): ExplorerItem {
|
||||
const stat = new ExplorerItem(raw.resource, parent, raw.isDirectory, raw.isSymbolicLink, raw.isReadonly, raw.name, raw.mtime);
|
||||
|
||||
// Recursively add children if present
|
||||
|
||||
@@ -13,7 +13,7 @@ import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
import { WorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issueService';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { IIssueService } from 'vs/platform/issue/common/issue';
|
||||
import { IIssueService } from 'vs/platform/issue/node/issue';
|
||||
|
||||
const helpCategory = { value: nls.localize('help', "Help"), original: 'Help' };
|
||||
const workbenchActionsRegistry = Registry.as<IWorkbenchActionRegistry>(Extensions.WorkbenchActions);
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IssueReporterData } from 'vs/platform/issue/common/issue';
|
||||
import { IssueReporterData } from 'vs/platform/issue/node/issue';
|
||||
|
||||
export const IWorkbenchIssueService = createDecorator<IWorkbenchIssueService>('workbenchIssueService');
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import * as nls from 'vs/nls';
|
||||
import { IssueType } from 'vs/platform/issue/common/issue';
|
||||
import { IssueType } from 'vs/platform/issue/node/issue';
|
||||
import { IWorkbenchIssueService } from 'vs/workbench/contrib/issue/electron-browser/issue';
|
||||
|
||||
export class OpenProcessExplorer extends Action {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IssueReporterStyles, IIssueService, IssueReporterData, ProcessExplorerData, IssueReporterExtensionData } from 'vs/platform/issue/common/issue';
|
||||
import { IssueReporterStyles, IIssueService, IssueReporterData, ProcessExplorerData, IssueReporterExtensionData } from 'vs/platform/issue/node/issue';
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { textLinkForeground, inputBackground, inputBorder, inputForeground, buttonBackground, buttonHoverBackground, buttonForeground, inputValidationErrorBorder, foreground, inputActiveOptionBorder, scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground, editorBackground, editorForeground, listHoverBackground, listHoverForeground, listHighlightForeground, textLinkActiveForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { SIDE_BAR_BACKGROUND } from 'vs/workbench/common/theme';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#C5C5C5"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4315 3.3232L5.96154 13.3232L5.17083 13.2874L1.82083 8.5174L2.63918 7.94268L5.617 12.1827L13.6685 2.67688L14.4315 3.3232Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 295 B |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 3.76345L5.80687 11.9351L5.08584 11.8927L1 7.29614L1.76345 6.61752L5.50997 10.8324L14.3214 3L15 3.76345Z" fill="#424242"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4315 3.3232L5.96154 13.3232L5.17083 13.2874L1.82083 8.5174L2.63918 7.94268L5.617 12.1827L13.6685 2.67688L14.4315 3.3232Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 295 B |
@@ -25,6 +25,7 @@ import { nullRange } from 'vs/workbench/services/preferences/common/preferencesM
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IStringDictionary } from 'vs/base/common/collections';
|
||||
import { IProductService } from 'vs/platform/product/common/product';
|
||||
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
|
||||
export interface IEndpointDetails {
|
||||
urlBase?: string;
|
||||
@@ -73,7 +74,7 @@ export class PreferencesSearchService extends Disposable implements IPreferences
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
urlBase: this.productService.productConfiguration.settingsSearchUrl
|
||||
urlBase: this.productService.settingsSearchUrl
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -364,7 +365,7 @@ class RemoteSearchProvider implements ISearchProvider {
|
||||
const extensions = await this.installedExtensions;
|
||||
const filters = this.options.newExtensionsOnly ?
|
||||
[`diminish eq 'latest'`] :
|
||||
this.getVersionFilters(extensions, this.productService.productConfiguration.settingsSearchBuildId);
|
||||
this.getVersionFilters(extensions, this.productService.settingsSearchBuildId);
|
||||
|
||||
const filterStr = filters
|
||||
.slice(filterPage * RemoteSearchProvider.MAX_REQUEST_FILTERS, (filterPage + 1) * RemoteSearchProvider.MAX_REQUEST_FILTERS)
|
||||
@@ -564,3 +565,5 @@ export class SettingMatches {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IPreferencesSearchService, PreferencesSearchService, true);
|
||||
|
||||
@@ -159,7 +159,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor
|
||||
constructor(
|
||||
@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
|
||||
@IExtensionService extensionService: IExtensionService,
|
||||
@IWindowService windowSevice: IWindowService,
|
||||
@IWindowService windowService: IWindowService,
|
||||
@IWorkbenchEnvironmentService environmentService: IWorkbenchEnvironmentService
|
||||
) {
|
||||
super();
|
||||
@@ -170,7 +170,7 @@ export class WorkspaceChangeExtHostRelauncher extends Disposable implements IWor
|
||||
}
|
||||
|
||||
if (environmentService.configuration.remoteAuthority) {
|
||||
windowSevice.reloadWindow(); // TODO@aeschli, workaround
|
||||
windowService.reloadWindow(); // TODO@aeschli, workaround
|
||||
} else {
|
||||
extensionService.restartExtensionHost();
|
||||
}
|
||||
|
||||
@@ -386,6 +386,10 @@ export class RemoteViewlet extends ViewContainerViewlet implements IViewModel {
|
||||
}
|
||||
|
||||
private _handleRemoteInfoExtensionPoint(extension: IExtensionPointUser<HelpInformation>, helpInformation: HelpInformation[]) {
|
||||
if (!extension.description.enableProposedApi) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!extension.value.documentation && !extension.value.feedback && !extension.value.getStarted && !extension.value.issues) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { DialogChannel } from 'vs/platform/dialogs/node/dialogIpc';
|
||||
import { DownloadServiceChannel } from 'vs/platform/download/common/downloadIpc';
|
||||
import { LogLevelSetterChannel } from 'vs/platform/log/common/logIpc';
|
||||
import { ipcRenderer as ipc } from 'electron';
|
||||
import { IDiagnosticInfoOptions, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { IDiagnosticInfoOptions, IRemoteDiagnosticInfo } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IProgressService, IProgress, IProgressStep, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { PersistentConnectionEventType } from 'vs/platform/remote/common/remoteAgentConnection';
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" stroke="#C5C5C5" stroke-linejoin="bevel"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4167 6.5C13.4167 6.54043 13.4162 6.58073 13.4151 6.6209C13.7562 6.80943 14.073 7.03667 14.3594 7.29667C14.3972 7.03657 14.4167 6.77057 14.4167 6.5C14.4167 3.46243 11.9543 1 8.9167 1C5.87913 1 3.41669 3.46243 3.41669 6.5C3.41669 7.89885 3.93892 9.17573 4.79905 10.1463L1 13.8386L1.75006 14.5L5.52761 10.8321C5.67974 10.9512 5.8383 11.0626 6.00269 11.1655C6.0009 11.1105 6 11.0554 6 11C6 10.6605 6.03384 10.3288 6.09834 10.0083C5.07293 9.18351 4.41669 7.91839 4.41669 6.5C4.41669 4.01472 6.43141 2 8.9167 2C11.402 2 13.4167 4.01472 13.4167 6.5ZM11 14C11.6479 14 12.2478 13.7946 12.7382 13.4454L8.55459 9.26177C8.20537 9.75217 7.99999 10.3521 7.99999 11C7.99999 12.6569 9.34313 14 11 14ZM9.26168 8.55465L13.4453 12.7383C13.7946 12.2479 14 11.6479 14 11C14 9.34315 12.6568 8 11 8C10.3521 8 9.7521 8.20541 9.26168 8.55465ZM11 15C13.2091 15 15 13.2091 15 11C15 8.79086 13.2091 7 11 7C8.79085 7 6.99999 8.79086 6.99999 11C6.99999 13.2091 8.79085 15 11 15Z" fill="#C5C5C5"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 1.1 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" stroke="white" stroke-linejoin="bevel"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4167 6.5C13.4167 6.54043 13.4162 6.58073 13.4151 6.6209C13.7562 6.80943 14.073 7.03667 14.3594 7.29667C14.3972 7.03657 14.4167 6.77057 14.4167 6.5C14.4167 3.46243 11.9543 1 8.9167 1C5.87913 1 3.41669 3.46243 3.41669 6.5C3.41669 7.89885 3.93892 9.17573 4.79905 10.1463L1 13.8386L1.75006 14.5L5.52761 10.8321C5.67974 10.9512 5.8383 11.0626 6.00269 11.1655C6.0009 11.1105 6 11.0554 6 11C6 10.6605 6.03384 10.3288 6.09834 10.0083C5.07293 9.18351 4.41669 7.91839 4.41669 6.5C4.41669 4.01472 6.43141 2 8.9167 2C11.402 2 13.4167 4.01472 13.4167 6.5ZM11 14C11.6479 14 12.2478 13.7946 12.7382 13.4454L8.55459 9.26177C8.20537 9.75217 7.99999 10.3521 7.99999 11C7.99999 12.6569 9.34313 14 11 14ZM9.26168 8.55465L13.4453 12.7383C13.7946 12.2479 14 11.6479 14 11C14 9.34315 12.6568 8 11 8C10.3521 8 9.7521 8.20541 9.26168 8.55465ZM11 15C13.2091 15 15 13.2091 15 11C15 8.79086 13.2091 7 11 7C8.79085 7 6.99999 8.79086 6.99999 11C6.99999 13.2091 8.79085 15 11 15Z" fill="white"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 189 B After Width: | Height: | Size: 1.1 KiB |
@@ -1,3 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect x="2.5" y="2.5" width="11" height="11" stroke="#424242" stroke-linejoin="bevel"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.4167 6.5C13.4167 6.54043 13.4162 6.58073 13.4151 6.6209C13.7562 6.80943 14.073 7.03667 14.3594 7.29667C14.3972 7.03657 14.4167 6.77057 14.4167 6.5C14.4167 3.46243 11.9543 1 8.9167 1C5.87913 1 3.41669 3.46243 3.41669 6.5C3.41669 7.89885 3.93892 9.17573 4.79905 10.1463L1 13.8386L1.75006 14.5L5.52761 10.8321C5.67974 10.9512 5.8383 11.0626 6.00269 11.1655C6.0009 11.1105 6 11.0554 6 11C6 10.6605 6.03384 10.3288 6.09834 10.0083C5.07293 9.18351 4.41669 7.91839 4.41669 6.5C4.41669 4.01472 6.43141 2 8.9167 2C11.402 2 13.4167 4.01472 13.4167 6.5ZM11 14C11.6479 14 12.2478 13.7946 12.7382 13.4454L8.55459 9.26177C8.20537 9.75217 7.99999 10.3521 7.99999 11C7.99999 12.6569 9.34313 14 11 14ZM9.26168 8.55465L13.4453 12.7383C13.7946 12.2479 14 11.6479 14 11C14 9.34315 12.6568 8 11 8C10.3521 8 9.7521 8.20541 9.26168 8.55465ZM11 15C13.2091 15 15 13.2091 15 11C15 8.79086 13.2091 7 11 7C8.79085 7 6.99999 8.79086 6.99999 11C6.99999 13.2091 8.79085 15 11 15Z" fill="#424242"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 191 B After Width: | Height: | Size: 1.1 KiB |
@@ -14,6 +14,7 @@ import { IFolderQuery, IPatternInfo, QueryType, ITextQuery, IFileQuery } from 'v
|
||||
import { IWorkspaceContextService, toWorkspaceFolder, Workspace, toWorkspaceFolders } from 'vs/platform/workspace/common/workspace';
|
||||
import { ISearchPathsInfo, QueryBuilder } from 'vs/workbench/contrib/search/common/queryBuilder';
|
||||
import { TestContextService, TestEnvironmentService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { isWindows } from 'vs/base/common/platform';
|
||||
|
||||
const DEFAULT_EDITOR_CONFIG = {};
|
||||
const DEFAULT_USER_CONFIG = { useRipgrep: true, useIgnoreFiles: true, useGlobalIgnoreFiles: true };
|
||||
@@ -1032,7 +1033,7 @@ function getUri(...slashPathParts: string[]): uri {
|
||||
}
|
||||
|
||||
function fixPath(...slashPathParts: string[]): string {
|
||||
if (process.platform === 'win32' && slashPathParts.length && !slashPathParts[0].match(/^c:/i)) {
|
||||
if (isWindows && slashPathParts.length && !slashPathParts[0].match(/^c:/i)) {
|
||||
slashPathParts.unshift('c:');
|
||||
}
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ import { IFileMatch, IFileSearchStats, IFolderQuery, ISearchComplete, ISearchPro
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { SearchModel } from 'vs/workbench/contrib/search/common/searchModel';
|
||||
import * as process from 'vs/base/common/process';
|
||||
|
||||
const nullEvent = new class {
|
||||
id: number;
|
||||
|
||||
@@ -15,7 +15,7 @@ import { endsWith } from 'vs/base/common/strings';
|
||||
import { ITextFileService, } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { IWorkspaceStatsService, Tags } from 'vs/workbench/contrib/stats/common/workspaceStats';
|
||||
import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnosticsService';
|
||||
import { IWorkspaceInformation } from 'vs/platform/diagnostics/common/diagnostics';
|
||||
|
||||
const SshProtocolMatcher = /^([^@:]+@)?([^:]+):/;
|
||||
const SshUrlMatcher = /^([^@:]+@)?([^:]+):(.+)$/;
|
||||
|
||||
@@ -12,6 +12,7 @@ import { RunOnOptions, Task, TaskRunSource } from 'vs/workbench/contrib/tasks/co
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { IQuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
|
||||
const ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE = 'tasks.run.allowAutomatic';
|
||||
|
||||
@@ -131,38 +132,27 @@ export class RunAutomaticTasks extends Disposable implements IWorkbenchContribut
|
||||
|
||||
}
|
||||
|
||||
export class AllowAutomaticTaskRunning extends Action {
|
||||
export class ManageAutomaticTaskRunning extends Action {
|
||||
|
||||
public static readonly ID = 'workbench.action.tasks.allowAutomaticRunning';
|
||||
public static readonly LABEL = nls.localize('workbench.action.tasks.allowAutomaticRunning', "Allow Automatic Tasks in Folder");
|
||||
public static readonly ID = 'workbench.action.tasks.manageAutomaticRunning';
|
||||
public static readonly LABEL = nls.localize('workbench.action.tasks.manageAutomaticRunning', "Manage Automatic Tasks in Folder");
|
||||
|
||||
constructor(
|
||||
id: string, label: string,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
@IStorageService private readonly storageService: IStorageService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
public run(event?: any): Promise<any> {
|
||||
this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, true, StorageScope.WORKSPACE);
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
export class DisallowAutomaticTaskRunning extends Action {
|
||||
|
||||
public static readonly ID = 'workbench.action.tasks.disallowAutomaticRunning';
|
||||
public static readonly LABEL = nls.localize('workbench.action.tasks.disallowAutomaticRunning', "Disallow Automatic Tasks in Folder");
|
||||
|
||||
constructor(
|
||||
id: string, label: string,
|
||||
@IStorageService private readonly storageService: IStorageService
|
||||
) {
|
||||
super(id, label);
|
||||
}
|
||||
|
||||
public run(event?: any): Promise<any> {
|
||||
this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, false, StorageScope.WORKSPACE);
|
||||
return Promise.resolve(undefined);
|
||||
public async run(event?: any): Promise<any> {
|
||||
const allowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.allowAutomaticTasks', "Allow Automatic Tasks in Folder") };
|
||||
const disallowItem: IQuickPickItem = { label: nls.localize('workbench.action.tasks.disallowAutomaticTasks', "Disallow Automatic Tasks in Folder") };
|
||||
const value = await this.quickInputService.pick([allowItem, disallowItem], { canPickMany: false });
|
||||
if (!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.storageService.store(ARE_AUTOMATIC_TASKS_ALLOWED_IN_WORKSPACE, value === allowItem, StorageScope.WORKSPACE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import { QuickOpenActionContributor } from '../browser/quickOpen';
|
||||
|
||||
import { Extensions as WorkbenchExtensions, IWorkbenchContributionsRegistry, IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
|
||||
import { RunAutomaticTasks, AllowAutomaticTaskRunning, DisallowAutomaticTaskRunning } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks';
|
||||
import { RunAutomaticTasks, ManageAutomaticTaskRunning } from 'vs/workbench/contrib/tasks/browser/runAutomaticTasks';
|
||||
|
||||
let tasksCategory = nls.localize('tasksCategory', "Tasks");
|
||||
|
||||
@@ -40,8 +40,7 @@ const workbenchRegistry = Registry.as<IWorkbenchContributionsRegistry>(Workbench
|
||||
workbenchRegistry.registerWorkbenchContribution(RunAutomaticTasks, LifecyclePhase.Eventually);
|
||||
|
||||
const actionRegistry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(AllowAutomaticTaskRunning, AllowAutomaticTaskRunning.ID, AllowAutomaticTaskRunning.LABEL), 'Tasks: Allow Automatic Tasks in Folder', tasksCategory);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(DisallowAutomaticTaskRunning, DisallowAutomaticTaskRunning.ID, DisallowAutomaticTaskRunning.LABEL), 'Tasks: Disallow Automatic Tasks in Folder', tasksCategory);
|
||||
actionRegistry.registerWorkbenchAction(new SyncActionDescriptor(ManageAutomaticTaskRunning, ManageAutomaticTaskRunning.ID, ManageAutomaticTaskRunning.LABEL), 'Tasks: Manage Automatic Tasks in Folder', tasksCategory);
|
||||
|
||||
export class TaskStatusBarContributions extends Disposable implements IWorkbenchContribution {
|
||||
private runningTasksStatusItem: IStatusbarEntryAccessor | undefined;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import * as terminalEnvironment from 'vs/workbench/contrib/terminal/common/terminalEnvironment';
|
||||
import { env as processEnv } from 'vs/base/common/process';
|
||||
import { ProcessState, ITerminalProcessManager, IShellLaunchConfig, ITerminalConfigHelper, ITerminalChildProcess, IBeforeProcessDataEvent, ITerminalEnvironment, ITerminalDimensions } from 'vs/workbench/contrib/terminal/common/terminal';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
@@ -225,8 +226,8 @@ export class TerminalProcessManager extends Disposable implements ITerminalProce
|
||||
const envFromConfigValue = this._workspaceConfigurationService.inspect<ITerminalEnvironment | undefined>(`terminal.integrated.env.${platformKey}`);
|
||||
const isWorkspaceShellAllowed = this._configHelper.checkWorkspaceShellPermissions();
|
||||
this._configHelper.showRecommendations(shellLaunchConfig);
|
||||
const baseEnv = this._configHelper.config.inheritEnv ? process.env as platform.IProcessEnvironment : await this._terminalInstanceService.getMainProcessParentEnv();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.productConfiguration.version, this._configHelper.config.setLocaleVariables, baseEnv);
|
||||
const baseEnv = this._configHelper.config.inheritEnv ? processEnv : await this._terminalInstanceService.getMainProcessParentEnv();
|
||||
const env = terminalEnvironment.createTerminalEnvironment(shellLaunchConfig, lastActiveWorkspace, envFromConfigValue, this._configurationResolverService, isWorkspaceShellAllowed, this._productService.version, this._configHelper.config.setLocaleVariables, baseEnv);
|
||||
|
||||
const useConpty = this._configHelper.config.windowsEnableConpty && !isScreenReaderModeEnabled;
|
||||
return this._terminalInstanceService.createTerminalProcess(shellLaunchConfig, initialCwd, cols, rows, env, useConpty);
|
||||
|
||||
@@ -285,6 +285,12 @@
|
||||
|
||||
applyStyles(newDocument, newDocument.body);
|
||||
|
||||
// Check for CSP
|
||||
const csp = newDocument.querySelector('meta[http-equiv="Content-Security-Policy"]');
|
||||
if (!csp) {
|
||||
host.postMessage('no-csp-found');
|
||||
}
|
||||
|
||||
// set DOCTYPE for newDocument explicitly as DOMParser.parseFromString strips it off
|
||||
// and DOCTYPE is needed in the iframe to ensure that the user agent stylesheet is correctly overridden
|
||||
return '<!DOCTYPE html>\n' + newDocument.documentElement.outerHTML;
|
||||
|
||||
@@ -244,7 +244,6 @@ export class WebviewEditorService implements IWebviewEditorService {
|
||||
|
||||
private createWebiew(id: string, extension: { location: URI; id: ExtensionIdentifier; } | undefined, options: WebviewInputOptions) {
|
||||
return this._webviewService.createWebviewEditorOverlay(id, {
|
||||
allowSvgs: true,
|
||||
extension: extension,
|
||||
enableFindWidget: options.enableFindWidget,
|
||||
retainContextWhenHidden: options.retainContextWhenHidden
|
||||
|
||||
@@ -213,7 +213,7 @@ export class IFrameWebview extends Disposable implements Webview {
|
||||
}
|
||||
}
|
||||
|
||||
initialScrollProgress: number;
|
||||
initialScrollProgress: number = 0;
|
||||
|
||||
private readonly _onDidFocus = this._register(new Emitter<void>());
|
||||
public readonly onDidFocus = this._onDidFocus.event;
|
||||
|
||||
@@ -41,7 +41,6 @@ export interface IWebviewService {
|
||||
export const WebviewResourceScheme = 'vscode-resource';
|
||||
|
||||
export interface WebviewOptions {
|
||||
readonly allowSvgs?: boolean;
|
||||
readonly extension?: {
|
||||
readonly location: URI;
|
||||
readonly id?: ExtensionIdentifier;
|
||||
@@ -53,7 +52,6 @@ export interface WebviewOptions {
|
||||
|
||||
export interface WebviewContentOptions {
|
||||
readonly allowScripts?: boolean;
|
||||
readonly svgWhiteList?: string[];
|
||||
readonly localResourceRoots?: ReadonlyArray<URI>;
|
||||
readonly portMapping?: ReadonlyArray<modes.IWebviewPortMapping>;
|
||||
readonly enableCommandUris?: boolean;
|
||||
|
||||
@@ -9,13 +9,14 @@ import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { endsWith } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ITunnelService } from 'vs/platform/remote/common/tunnel';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { WebviewPortMappingManager } from 'vs/workbench/contrib/webview/common/portMapping';
|
||||
import { getWebviewThemeData } from 'vs/workbench/contrib/webview/common/themeing';
|
||||
@@ -135,51 +136,6 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
class SvgBlocker extends Disposable {
|
||||
|
||||
private readonly _onDidBlockSvg = this._register(new Emitter<void>());
|
||||
public readonly onDidBlockSvg = this._onDidBlockSvg.event;
|
||||
|
||||
constructor(
|
||||
session: WebviewSession,
|
||||
private readonly _options: WebviewContentOptions,
|
||||
) {
|
||||
super();
|
||||
|
||||
session.onBeforeRequest(async (details) => {
|
||||
if (details.url.indexOf('.svg') > 0) {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri && !uri.scheme.match(/file/i) && endsWith(uri.path, '.svg') && !this.isAllowedSvg(uri)) {
|
||||
this._onDidBlockSvg.fire();
|
||||
return { cancel: true };
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
|
||||
session.onHeadersReceived((details) => {
|
||||
const headers: any = details.responseHeaders;
|
||||
const contentType: string[] = headers['content-type'] || headers['Content-Type'];
|
||||
if (contentType && Array.isArray(contentType) && contentType.some(x => x.toLowerCase().indexOf('image/svg') >= 0)) {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri && !this.isAllowedSvg(uri)) {
|
||||
this._onDidBlockSvg.fire();
|
||||
return { cancel: true };
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
});
|
||||
}
|
||||
|
||||
private isAllowedSvg(uri: URI): boolean {
|
||||
if (this._options.svgWhiteList) {
|
||||
return this._options.svgWhiteList.indexOf(uri.authority.toLowerCase()) >= 0;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class WebviewKeyboardHandler extends Disposable {
|
||||
|
||||
private _ignoreMenuShortcut = false;
|
||||
@@ -284,6 +240,8 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview {
|
||||
@IFileService fileService: IFileService,
|
||||
@ITunnelService tunnelService: ITunnelService,
|
||||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
@IEnvironmentService private readonly _environementService: IEnvironmentService,
|
||||
) {
|
||||
super();
|
||||
this.content = {
|
||||
@@ -331,11 +289,6 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview {
|
||||
tunnelService,
|
||||
));
|
||||
|
||||
if (!this._options.allowSvgs) {
|
||||
const svgBlocker = this._register(new SvgBlocker(session, this.content.options));
|
||||
svgBlocker.onDidBlockSvg(() => this.onDidBlockSvg());
|
||||
}
|
||||
|
||||
this._register(new WebviewKeyboardHandler(this._webview));
|
||||
|
||||
this._register(addDisposableListener(this._webview, 'console-message', function (e: { level: number; message: string; line: number; sourceId: string; }) {
|
||||
@@ -412,6 +365,10 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview {
|
||||
case 'did-blur':
|
||||
this.handleFocusChange(false);
|
||||
return;
|
||||
|
||||
case 'no-csp-found':
|
||||
this.handleNoCspFound();
|
||||
return;
|
||||
}
|
||||
}));
|
||||
this._register(addDisposableListener(this._webview, 'devtools-opened', () => {
|
||||
@@ -546,14 +503,34 @@ export class ElectronWebviewBasedWebview extends Disposable implements Webview {
|
||||
}
|
||||
}
|
||||
|
||||
public sendMessage(data: any): void {
|
||||
this._send('message', data);
|
||||
private _hasAlertedAboutMissingCsp = false;
|
||||
|
||||
private handleNoCspFound(): void {
|
||||
if (this._hasAlertedAboutMissingCsp) {
|
||||
return;
|
||||
}
|
||||
this._hasAlertedAboutMissingCsp = true;
|
||||
|
||||
if (this._options.extension && this._options.extension.id) {
|
||||
if (this._environementService.isExtensionDevelopment) {
|
||||
console.warn(`${this._options.extension.id.value} created a webview without a content security policy: https://aka.ms/vscode-webview-missing-csp`);
|
||||
}
|
||||
|
||||
type TelemetryClassification = {
|
||||
extension?: { classification: 'SystemMetaData', purpose: 'FeatureInsight' }
|
||||
};
|
||||
type TelemetryData = {
|
||||
extension?: string,
|
||||
};
|
||||
|
||||
this._telemetryService.publicLog2<TelemetryData, TelemetryClassification>('webviewMissingCsp', {
|
||||
extension: this._options.extension.id.value
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private onDidBlockSvg() {
|
||||
this.sendMessage({
|
||||
name: 'vscode-did-block-svg'
|
||||
});
|
||||
public sendMessage(data: any): void {
|
||||
this._send('message', data);
|
||||
}
|
||||
|
||||
private style(theme: ITheme): void {
|
||||
|
||||