Merge from vscode 6e530127a1bb8ffbd1bfb77dc680c321dc0d71f5 (#6844)

This commit is contained in:
Anthony Dresser
2019-08-20 21:07:47 -07:00
committed by GitHub
parent 1f00249646
commit ecb80f14f0
221 changed files with 3140 additions and 1552 deletions

View File

@@ -5,30 +5,62 @@
import { onUnexpectedError } from 'vs/base/common/errors';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import * as map from 'vs/base/common/map';
import { startsWith } from 'vs/base/common/strings';
import { URI, UriComponents } from 'vs/base/common/uri';
import * as modes from 'vs/editor/common/modes';
import { localize } from 'vs/nls';
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
import { IOpenerService } from 'vs/platform/opener/common/opener';
import { IProductService } from 'vs/platform/product/common/product';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions } from 'vs/workbench/api/common/extHost.protocol';
import { ExtHostContext, ExtHostWebviewsShape, IExtHostContext, MainContext, MainThreadWebviewsShape, WebviewPanelHandle, WebviewPanelShowOptions, WebviewPanelViewStateData } from 'vs/workbench/api/common/extHost.protocol';
import { editorGroupToViewColumn, EditorViewColumn, viewColumnToEditorGroup } from 'vs/workbench/api/common/shared/editor';
import { Webview } from 'vs/workbench/contrib/webview/browser/webview';
import { WebviewEditorInput } from 'vs/workbench/contrib/webview/browser/webviewEditorInput';
import { ICreateWebViewShowOptions, IWebviewEditorService, WebviewInputOptions } from 'vs/workbench/contrib/webview/browser/webviewEditorService';
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
import { ACTIVE_GROUP, IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { extHostNamedCustomer } from '../common/extHostCustomers';
import { IProductService } from 'vs/platform/product/common/product';
import { startsWith } from 'vs/base/common/strings';
import { Webview } from 'vs/workbench/contrib/webview/common/webview';
interface OldMainThreadWebviewState {
readonly viewType: string;
state: any;
}
/**
* Bi-directional map between webview handles and inputs.
*/
class WebviewHandleStore {
private readonly _handlesToInputs = new Map<string, WebviewEditorInput>();
private readonly _inputsToHandles = new Map<WebviewEditorInput, string>();
public add(handle: string, input: WebviewEditorInput): void {
this._handlesToInputs.set(handle, input);
this._inputsToHandles.set(input, handle);
}
public getHandleForInput(input: WebviewEditorInput): string | undefined {
return this._inputsToHandles.get(input);
}
public getInputForHandle(handle: string): WebviewEditorInput | undefined {
return this._handlesToInputs.get(handle);
}
public delete(handle: string): void {
const input = this.getInputForHandle(handle);
this._handlesToInputs.delete(handle);
if (input) {
this._inputsToHandles.delete(input);
}
}
public get size(): number {
return this._handlesToInputs.size;
}
}
@extHostNamedCustomer(MainContext.MainThreadWebviews)
export class MainThreadWebviews extends Disposable implements MainThreadWebviewsShape {
@@ -43,12 +75,9 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
private static revivalPool = 0;
private readonly _proxy: ExtHostWebviewsShape;
private readonly _webviewEditorInputs = new Map<string, WebviewEditorInput>();
private readonly _webviews = new Map<string, Webview>();
private readonly _webviewEditorInputs = new WebviewHandleStore();
private readonly _revivers = new Map<string, IDisposable>();
private _activeWebview: WebviewPanelHandle | undefined = undefined;
constructor(
context: IExtHostContext,
@IExtensionService extensionService: IExtensionService,
@@ -62,8 +91,8 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
super();
this._proxy = context.getProxy(ExtHostContext.ExtHostWebviews);
this._register(_editorService.onDidActiveEditorChange(this.onActiveEditorChanged, this));
this._register(_editorService.onDidVisibleEditorsChange(this.onVisibleEditorsChanged, this));
this._register(_editorService.onDidActiveEditorChange(this.updateWebviewViewStates, this));
this._register(_editorService.onDidVisibleEditorsChange(this.updateWebviewViewStates, this));
// This reviver's only job is to activate webview extensions
// This should trigger the real reviver to be registered from the extension host side.
@@ -104,8 +133,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
});
this.hookupWebviewEventDelegate(handle, webview);
this._webviewEditorInputs.set(handle, webview);
this._webviews.set(handle, webview.webview);
this._webviewEditorInputs.add(handle, webview);
/* __GDPR__
"webviews:createWebviewPanel" : {
@@ -175,8 +203,7 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
}
const handle = `revival-${MainThreadWebviews.revivalPool++}`;
this._webviewEditorInputs.set(handle, webviewEditorInput);
this._webviews.set(handle, webviewEditorInput.webview);
this._webviewEditorInputs.add(handle, webviewEditorInput);
this.hookupWebviewEventDelegate(handle, webviewEditorInput);
let state = undefined;
@@ -234,7 +261,6 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
input.onDispose(() => {
this._proxy.$onDidDisposeWebviewPanel(handle).finally(() => {
this._webviewEditorInputs.delete(handle);
this._webviews.delete(handle);
});
});
input.webview.onDidUpdateState((newState: any) => {
@@ -246,70 +272,35 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
});
}
private onActiveEditorChanged() {
const activeEditor = this._editorService.activeControl;
let newActiveWebview: { input: WebviewEditorInput, handle: WebviewPanelHandle } | undefined = undefined;
if (activeEditor && activeEditor.input instanceof WebviewEditorInput) {
for (const handle of map.keys(this._webviewEditorInputs)) {
const input = this._webviewEditorInputs.get(handle)!;
if (input.matches(activeEditor.input)) {
newActiveWebview = { input, handle };
break;
}
}
}
if (newActiveWebview && newActiveWebview.handle === this._activeWebview) {
// Webview itself unchanged but position may have changed
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, {
active: true,
visible: true,
position: editorGroupToViewColumn(this._editorGroupService, newActiveWebview.input.group || 0)
});
private updateWebviewViewStates() {
if (!this._webviewEditorInputs.size) {
return;
}
// Broadcast view state update for currently active
if (typeof this._activeWebview !== 'undefined') {
const oldActiveWebview = this._webviewEditorInputs.get(this._activeWebview);
if (oldActiveWebview) {
this._proxy.$onDidChangeWebviewPanelViewState(this._activeWebview, {
active: false,
visible: this._editorService.visibleControls.some(editor => !!editor.input && editor.input.matches(oldActiveWebview)),
position: editorGroupToViewColumn(this._editorGroupService, oldActiveWebview.group || 0),
});
}
}
const activeInput = this._editorService.activeControl && this._editorService.activeControl.input;
const viewStates: WebviewPanelViewStateData = {};
for (const group of this._editorGroupService.groups) {
for (const input of group.editors) {
if (!(input instanceof WebviewEditorInput)) {
continue;
}
// Then for newly active
if (newActiveWebview) {
this._proxy.$onDidChangeWebviewPanelViewState(newActiveWebview.handle, {
active: true,
visible: true,
position: editorGroupToViewColumn(this._editorGroupService, activeEditor ? activeEditor.group : ACTIVE_GROUP),
});
this._activeWebview = newActiveWebview.handle;
} else {
this._activeWebview = undefined;
}
}
input.updateGroup(group.id);
private onVisibleEditorsChanged(): void {
this._webviewEditorInputs.forEach((input, handle) => {
for (const workbenchEditor of this._editorService.visibleControls) {
if (workbenchEditor.input && workbenchEditor.input.matches(input)) {
const editorPosition = editorGroupToViewColumn(this._editorGroupService, workbenchEditor.group!);
input.updateGroup(workbenchEditor.group!.id);
this._proxy.$onDidChangeWebviewPanelViewState(handle, {
active: handle === this._activeWebview,
visible: true,
position: editorPosition
});
break;
const handle = this._webviewEditorInputs.getHandleForInput(input);
if (handle) {
viewStates[handle] = {
visible: input === group.activeEditor,
active: input === activeInput,
position: editorGroupToViewColumn(this._editorGroupService, group.id || 0),
};
}
}
});
}
if (Object.keys(viewStates).length) {
this._proxy.$onDidChangeWebviewPanelViewStates(viewStates);
}
}
private onDidClickLink(handle: WebviewPanelHandle, link: URI): void {
@@ -342,28 +333,19 @@ export class MainThreadWebviews extends Disposable implements MainThreadWebviews
}
private tryGetWebviewEditorInput(handle: WebviewPanelHandle): WebviewEditorInput | undefined {
return this._webviewEditorInputs.get(handle);
return this._webviewEditorInputs.getInputForHandle(handle);
}
private getWebview(handle: WebviewPanelHandle): Webview {
const webview = this.tryGetWebview(handle);
if (!webview) {
throw new Error('Unknown webview handle:' + handle);
}
return webview;
}
private tryGetWebview(handle: WebviewPanelHandle): Webview | undefined {
return this._webviews.get(handle);
return this.getWebviewEditorInput(handle).webview;
}
private static getDeserializationFailedContents(viewType: string) {
return `<!DOCTYPE html>
<html>
<head>
<base href="https://code.visualstudio.com/raw/">
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src https: data:; media-src https:; script-src 'none'; style-src vscode-resource: https: 'unsafe-inline'; child-src 'none'; frame-src 'none';">
<meta http-equiv="Content-Security-Policy" content="default-src 'none';">
</head>
<body>${localize('errorMessage', "An error occurred while restoring view:{0}", viewType)}</body>
</html>`;