Merge from vscode 966b87dd4013be1a9c06e2b8334522ec61905cc2 (#4696)

This commit is contained in:
Anthony Dresser
2019-03-26 11:43:38 -07:00
committed by GitHub
parent b1393ae615
commit 0d8ef9583b
268 changed files with 5947 additions and 3422 deletions

View File

@@ -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
},
{});

View File

@@ -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> {

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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 = {