Fix modelview webview to work in query tab (#6119)

* WIP

* Rebuild webview when switching tabs

* Remove unneeded code

* Make ready promise private

* Undo edit in sendMessage

* Add null check prior to using ready promise

* Remove extra whitespace

* Rename parameter and fix strict null check errors
This commit is contained in:
Karl Burtram
2019-06-20 16:28:32 -07:00
committed by GitHub
parent 77b351adf3
commit 1411ad4503
3 changed files with 59 additions and 28 deletions

View File

@@ -46,7 +46,8 @@ interface IInternalPanelTab {
header: HTMLElement; header: HTMLElement;
disposables: IDisposable[]; disposables: IDisposable[];
label: HTMLElement; label: HTMLElement;
body: HTMLElement; body?: HTMLElement;
destoryTabBody?: boolean;
} }
const defaultOptions: IPanelOptions = { const defaultOptions: IPanelOptions = {
@@ -111,9 +112,10 @@ export class TabbedPanel extends Disposable {
return this._tabMap.has(tab.identifier); return this._tabMap.has(tab.identifier);
} }
public pushTab(tab: IPanelTab, index?: number): PanelTabIdentifier { public pushTab(tab: IPanelTab, index?: number, destoryTabBody?: boolean): PanelTabIdentifier {
let internalTab = { tab } as IInternalPanelTab; let internalTab = { tab } as IInternalPanelTab;
internalTab.disposables = []; internalTab.disposables = [];
internalTab.destoryTabBody = destoryTabBody;
this._tabMap.set(tab.identifier, internalTab); this._tabMap.set(tab.identifier, internalTab);
this._createTab(internalTab, index); this._createTab(internalTab, index);
if (!this._shownTabId) { if (!this._shownTabId) {
@@ -175,13 +177,21 @@ export class TabbedPanel extends Disposable {
DOM.removeClass(shownTab.label, 'active'); DOM.removeClass(shownTab.label, 'active');
DOM.removeClass(shownTab.header, 'active'); DOM.removeClass(shownTab.header, 'active');
shownTab.header.setAttribute('aria-selected', 'false'); shownTab.header.setAttribute('aria-selected', 'false');
shownTab.body.remove(); if (shownTab.body) {
shownTab.body.remove();
}
} }
} }
this._shownTabId = id; this._shownTabId = id;
this.tabHistory.push(id); this.tabHistory.push(id);
const tab = this._tabMap.get(this._shownTabId)!; // @anthonydresser we know this can't be undefined since we check further up if the map contains the id const tab = this._tabMap.get(this._shownTabId)!; // @anthonydresser we know this can't be undefined since we check further up if the map contains the id
if (tab.destoryTabBody && tab.body) {
tab.body.remove();
tab.body = undefined;
}
if (!tab.body) { if (!tab.body) {
tab.body = DOM.$('.tab-container'); tab.body = DOM.$('.tab-container');
tab.body.style.width = '100%'; tab.body.style.width = '100%';
@@ -308,7 +318,7 @@ export class TabbedPanel extends Disposable {
private _layoutCurrentTab(dimension: DOM.Dimension): void { private _layoutCurrentTab(dimension: DOM.Dimension): void {
if (this._shownTabId) { if (this._shownTabId) {
const tab = this._tabMap.get(this._shownTabId); const tab = this._tabMap.get(this._shownTabId);
if (tab) { if (tab && tab.body) {
tab.body.style.width = dimension.width + 'px'; tab.body.style.width = dimension.width + 'px';
tab.body.style.height = dimension.height + 'px'; tab.body.style.height = dimension.height + 'px';
tab.tab.view.layout(dimension); tab.tab.view.layout(dimension);

View File

@@ -41,6 +41,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen
private _webview: WebviewElement; private _webview: WebviewElement;
private _renderedHtml: string; private _renderedHtml: string;
private _extensionLocationUri: URI; private _extensionLocationUri: URI;
private _ready: Promise<void>;
protected contextKey: IContextKey<boolean>; protected contextKey: IContextKey<boolean>;
protected findInputFocusContextKey: IContextKey<boolean>; protected findInputFocusContextKey: IContextKey<boolean>;
@@ -74,15 +75,28 @@ export default class WebViewComponent extends ComponentBase implements IComponen
this._webview.mountTo(this._el.nativeElement); this._webview.mountTo(this._el.nativeElement);
this._register(this._webview.onDidClickLink(link => this.onDidClickLink(link))); this._ready = new Promise(resolve => {
let webview = (<any>this._webview)._webview;
const subscription = this._register(addDisposableListener(webview, 'ipc-message', (event) => {
if (event.channel === 'webview-ready') {
subscription.dispose();
resolve();
}
}));
});
this._register(this._webview.onMessage(e => { this._ready.then(() => {
this.fireEvent({ this._register(this._webview.onDidClickLink(link => this.onDidClickLink(link)));
eventType: ComponentEventType.onMessage,
args: e this._register(this._webview.onMessage(e => {
}); this.fireEvent({
})); eventType: ComponentEventType.onMessage,
this.setHtml(); args: e
});
}));
this.setHtml();
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
@@ -125,9 +139,13 @@ export default class WebViewComponent extends ComponentBase implements IComponen
/// IComponent implementation /// IComponent implementation
public layout(): void { public layout(): void {
let element = <HTMLElement>this._el.nativeElement; if (this._ready) {
element.style.position = this.position; this._ready.then(() => {
this._webview.layout(); let element = <HTMLElement>this._el.nativeElement;
element.style.position = this.position;
this._webview.layout();
});
}
} }
public setLayout(layout: any): void { public setLayout(layout: any): void {
@@ -136,18 +154,21 @@ export default class WebViewComponent extends ComponentBase implements IComponen
} }
public setProperties(properties: { [key: string]: any; }): void { public setProperties(properties: { [key: string]: any; }): void {
super.setProperties(properties); if (this._ready) {
if (this.options) { this._ready.then(() => {
this._webview.options = this.getExtendedOptions(); super.setProperties(properties);
if (this.options) {
this._webview.options = this.getExtendedOptions();
}
if (this.html !== this._renderedHtml) {
this.setHtml();
}
if (this.extensionLocation) {
this._extensionLocationUri = URI.revive(this.extensionLocation);
}
this.sendMessage();
});
} }
if (this.html !== this._renderedHtml) {
this.setHtml();
}
if (this.extensionLocation) {
this._extensionLocationUri = URI.revive(this.extensionLocation);
}
this.sendMessage();
} }
// CSS-bound properties // CSS-bound properties

View File

@@ -249,7 +249,7 @@ export class QueryResultsView extends Disposable {
tab.view._componentId = parts[2]; tab.view._componentId = parts[2];
this.dynamicModelViewTabs.push(tab); this.dynamicModelViewTabs.push(tab);
if (!this._panelView.contains(tab)) { if (!this._panelView.contains(tab)) {
this._panelView.pushTab(tab); this._panelView.pushTab(tab, undefined, true);
} }
} }
} }
@@ -393,7 +393,7 @@ export class QueryResultsView extends Disposable {
this.input.state.visibleTabs.add('querymodelview;' + title + ';' + componentId); this.input.state.visibleTabs.add('querymodelview;' + title + ';' + componentId);
if (!this._panelView.contains(tab)) { if (!this._panelView.contains(tab)) {
this._panelView.pushTab(tab); this._panelView.pushTab(tab, undefined, true);
} }
} }
} }