mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)
This commit is contained in:
@@ -257,9 +257,9 @@ export class WebviewEditor extends BaseEditor {
|
||||
|
||||
private getDefaultLocalResourceRoots(): URI[] {
|
||||
const rootPaths = this._contextService.getWorkspace().folders.map(x => x.uri);
|
||||
const extensionLocation = (this.input as WebviewEditorInput).extensionLocation;
|
||||
if (extensionLocation) {
|
||||
rootPaths.push(extensionLocation);
|
||||
const extension = (this.input as WebviewEditorInput).extension;
|
||||
if (extension) {
|
||||
rootPaths.push(extension.location);
|
||||
}
|
||||
return rootPaths;
|
||||
}
|
||||
@@ -283,7 +283,7 @@ export class WebviewEditor extends BaseEditor {
|
||||
this._layoutService.getContainer(Parts.EDITOR_PART),
|
||||
{
|
||||
allowSvgs: true,
|
||||
extensionLocation: input.extensionLocation,
|
||||
extension: input.extension,
|
||||
enableFindWidget: input.options.enableFindWidget
|
||||
},
|
||||
{});
|
||||
|
||||
@@ -7,6 +7,7 @@ import { Emitter } from 'vs/base/common/event';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { EditorInput, EditorModel, GroupIdentifier, IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IWorkbenchLayoutService, Parts } from 'vs/workbench/services/layout/browser/layoutService';
|
||||
import { WebviewEvents, WebviewInputOptions } from './webviewEditorService';
|
||||
@@ -63,7 +64,10 @@ export class WebviewEditorInput extends EditorInput {
|
||||
private _scrollYPercentage: number = 0;
|
||||
private _state: any;
|
||||
|
||||
public readonly extensionLocation: URI | undefined;
|
||||
public readonly extension?: {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier;
|
||||
};
|
||||
private readonly _id: number;
|
||||
|
||||
constructor(
|
||||
@@ -73,7 +77,10 @@ export class WebviewEditorInput extends EditorInput {
|
||||
options: WebviewInputOptions,
|
||||
state: any,
|
||||
events: WebviewEvents,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier;
|
||||
},
|
||||
@IWorkbenchLayoutService private readonly _layoutService: IWorkbenchLayoutService,
|
||||
) {
|
||||
super();
|
||||
@@ -89,7 +96,7 @@ export class WebviewEditorInput extends EditorInput {
|
||||
this._options = options;
|
||||
this._events = events;
|
||||
this._state = state;
|
||||
this.extensionLocation = extensionLocation;
|
||||
this.extension = extension;
|
||||
}
|
||||
|
||||
public getTypeId(): string {
|
||||
@@ -313,11 +320,14 @@ export class RevivedWebviewEditorInput extends WebviewEditorInput {
|
||||
options: WebviewInputOptions,
|
||||
state: any,
|
||||
events: WebviewEvents,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI;
|
||||
readonly id: ExtensionIdentifier
|
||||
},
|
||||
public readonly reviver: (input: WebviewEditorInput) => Promise<void>,
|
||||
@IWorkbenchLayoutService partService: IWorkbenchLayoutService,
|
||||
) {
|
||||
super(viewType, id, name, options, state, events, extensionLocation, partService);
|
||||
super(viewType, id, name, options, state, events, extension, partService);
|
||||
}
|
||||
|
||||
public async resolve(): Promise<IEditorModel> {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IEditorInputFactory } from 'vs/workbench/common/editor';
|
||||
import { WebviewEditorInput } from './webviewEditorInput';
|
||||
import { IWebviewEditorService, WebviewInputOptions } from './webviewEditorService';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
interface SerializedIconPath {
|
||||
light: string | UriComponents;
|
||||
@@ -20,6 +21,7 @@ interface SerializedWebview {
|
||||
readonly title: string;
|
||||
readonly options: WebviewInputOptions;
|
||||
readonly extensionLocation: string | UriComponents | undefined;
|
||||
readonly extensionId: string | undefined;
|
||||
readonly state: any;
|
||||
readonly iconPath: SerializedIconPath | undefined;
|
||||
readonly group?: number;
|
||||
@@ -45,7 +47,8 @@ export class WebviewEditorInputFactory implements IEditorInputFactory {
|
||||
id: input.getId(),
|
||||
title: input.getName(),
|
||||
options: input.options,
|
||||
extensionLocation: input.extensionLocation,
|
||||
extensionLocation: input.extension ? input.extension.location : undefined,
|
||||
extensionId: input.extension ? input.extension.id.value : undefined,
|
||||
state: input.state,
|
||||
iconPath: input.iconPath ? { light: input.iconPath.light, dark: input.iconPath.dark, } : undefined,
|
||||
group: input.group
|
||||
@@ -64,8 +67,12 @@ export class WebviewEditorInputFactory implements IEditorInputFactory {
|
||||
): WebviewEditorInput {
|
||||
const data: SerializedWebview = JSON.parse(serializedEditorInput);
|
||||
const extensionLocation = reviveUri(data.extensionLocation);
|
||||
const extensionId = data.extensionId ? new ExtensionIdentifier(data.extensionId) : undefined;
|
||||
const iconPath = reviveIconPath(data.iconPath);
|
||||
return this._webviewService.reviveWebview(data.viewType, data.id, data.title, iconPath, data.state, data.options, extensionLocation, data.group);
|
||||
return this._webviewService.reviveWebview(data.viewType, data.id, data.title, iconPath, data.state, data.options, extensionLocation ? {
|
||||
location: extensionLocation,
|
||||
id: extensionId
|
||||
} : undefined, data.group);
|
||||
}
|
||||
}
|
||||
function reviveIconPath(data: SerializedIconPath | undefined) {
|
||||
|
||||
@@ -7,12 +7,13 @@ import { equals } from 'vs/base/common/arrays';
|
||||
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { values } from 'vs/base/common/map';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IWebviewOptions, IWebviewPanelOptions } from 'vs/editor/common/modes';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { GroupIdentifier } from 'vs/workbench/common/editor';
|
||||
import { IEditorGroup, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { ACTIVE_GROUP_TYPE, IEditorService, SIDE_GROUP_TYPE } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { RevivedWebviewEditorInput, WebviewEditorInput } from './webviewEditorInput';
|
||||
import { IWebviewOptions, IWebviewPanelOptions } from 'vs/editor/common/modes';
|
||||
|
||||
export const IWebviewEditorService = createDecorator<IWebviewEditorService>('webviewEditorService');
|
||||
|
||||
@@ -29,7 +30,10 @@ export interface IWebviewEditorService {
|
||||
title: string,
|
||||
showOptions: ICreateWebViewShowOptions,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
location: URI,
|
||||
id: ExtensionIdentifier
|
||||
},
|
||||
events: WebviewEvents
|
||||
): WebviewEditorInput;
|
||||
|
||||
@@ -40,7 +44,10 @@ export interface IWebviewEditorService {
|
||||
iconPath: { light: URI, dark: URI } | undefined,
|
||||
state: any,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
readonly location: URI,
|
||||
readonly id?: ExtensionIdentifier
|
||||
},
|
||||
group: number | undefined
|
||||
): WebviewEditorInput;
|
||||
|
||||
@@ -130,10 +137,13 @@ export class WebviewEditorService implements IWebviewEditorService {
|
||||
title: string,
|
||||
showOptions: ICreateWebViewShowOptions,
|
||||
options: IWebviewOptions,
|
||||
extensionLocation: URI | undefined,
|
||||
extension: undefined | {
|
||||
location: URI,
|
||||
id: ExtensionIdentifier
|
||||
},
|
||||
events: WebviewEvents
|
||||
): WebviewEditorInput {
|
||||
const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, undefined, title, options, {}, events, extensionLocation);
|
||||
const webviewInput = this._instantiationService.createInstance(WebviewEditorInput, viewType, undefined, title, options, {}, events, extension);
|
||||
this._editorService.openEditor(webviewInput, { pinned: true, preserveFocus: showOptions.preserveFocus }, showOptions.group);
|
||||
return webviewInput;
|
||||
}
|
||||
@@ -160,10 +170,13 @@ export class WebviewEditorService implements IWebviewEditorService {
|
||||
iconPath: { light: URI, dark: URI } | undefined,
|
||||
state: any,
|
||||
options: WebviewInputOptions,
|
||||
extensionLocation: URI,
|
||||
extension: undefined | {
|
||||
readonly location: URI,
|
||||
readonly id?: ExtensionIdentifier
|
||||
},
|
||||
group: number | undefined,
|
||||
): WebviewEditorInput {
|
||||
const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, id, title, options, state, {}, extensionLocation, async (webview: WebviewEditorInput): Promise<void> => {
|
||||
const webviewInput = this._instantiationService.createInstance(RevivedWebviewEditorInput, viewType, id, title, options, state, {}, extension, async (webview: WebviewEditorInput): Promise<void> => {
|
||||
const didRevive = await this.tryRevive(webview);
|
||||
if (didRevive) {
|
||||
return Promise.resolve(undefined);
|
||||
|
||||
@@ -19,6 +19,8 @@ import { DARK, ITheme, IThemeService, LIGHT } from 'vs/platform/theme/common/the
|
||||
import { registerFileProtocol, WebviewProtocol } from 'vs/workbench/contrib/webview/electron-browser/webviewProtocols';
|
||||
import { areWebviewInputOptionsEqual } from './webviewEditorService';
|
||||
import { WebviewFindWidget } from './webviewFindWidget';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
|
||||
export interface WebviewPortMapping {
|
||||
readonly port: number;
|
||||
@@ -32,7 +34,10 @@ export interface WebviewPortMapping {
|
||||
|
||||
export interface WebviewOptions {
|
||||
readonly allowSvgs?: boolean;
|
||||
readonly extensionLocation?: URI;
|
||||
readonly extension?: {
|
||||
readonly location: URI;
|
||||
readonly id?: ExtensionIdentifier;
|
||||
};
|
||||
readonly enableFindWidget?: boolean;
|
||||
}
|
||||
|
||||
@@ -145,10 +150,14 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
|
||||
constructor(
|
||||
session: WebviewSession,
|
||||
mappings: () => ReadonlyArray<WebviewPortMapping>
|
||||
mappings: () => ReadonlyArray<WebviewPortMapping>,
|
||||
extensionId: ExtensionIdentifier | undefined,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
|
||||
let hasLogged = false;
|
||||
|
||||
session.onBeforeRequest(async (details) => {
|
||||
const uri = URI.parse(details.url);
|
||||
if (uri.scheme !== 'http' && uri.scheme !== 'https') {
|
||||
@@ -157,6 +166,17 @@ class WebviewPortMappingProvider extends Disposable {
|
||||
|
||||
const localhostMatch = /^localhost:(\d+)$/.exec(uri.authority);
|
||||
if (localhostMatch) {
|
||||
if (!hasLogged && extensionId) {
|
||||
hasLogged = true;
|
||||
|
||||
/* __GDPR__
|
||||
"webview.accessLocalhost" : {
|
||||
"extension" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('webview.accessLocalhost', { extension: extensionId.value });
|
||||
}
|
||||
|
||||
const port = +localhostMatch[1];
|
||||
for (const mapping of mappings()) {
|
||||
if (mapping.port === port && mapping.port !== mapping.resolvedPort) {
|
||||
@@ -317,6 +337,7 @@ export class WebviewElement extends Disposable {
|
||||
@IThemeService themeService: IThemeService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IFileService fileService: IFileService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
) {
|
||||
super();
|
||||
this._webview = document.createElement('webview');
|
||||
@@ -348,15 +369,16 @@ export class WebviewElement extends Disposable {
|
||||
|
||||
this._register(new WebviewProtocolProvider(
|
||||
this._webview,
|
||||
this._options.extensionLocation,
|
||||
this._options.extension ? this._options.extension.location : undefined,
|
||||
() => (this._contentOptions.localResourceRoots || []),
|
||||
environmentService,
|
||||
fileService));
|
||||
|
||||
this._register(new WebviewPortMappingProvider(
|
||||
session,
|
||||
() => (this._contentOptions.portMappings || [])
|
||||
));
|
||||
() => (this._contentOptions.portMappings || []),
|
||||
_options.extension ? _options.extension.id : undefined,
|
||||
telemetryService));
|
||||
|
||||
|
||||
if (!this._options.allowSvgs) {
|
||||
@@ -556,7 +578,7 @@ export class WebviewElement extends Disposable {
|
||||
colors['vscode-' + entry.id.replace('.', '-')] = color.toString();
|
||||
}
|
||||
return colors;
|
||||
}, {});
|
||||
}, {} as { [key: string]: string });
|
||||
|
||||
|
||||
const styles = {
|
||||
|
||||
Reference in New Issue
Block a user