diff --git a/src/sql/base/browser/ui/panel/panel.ts b/src/sql/base/browser/ui/panel/panel.ts index 8778a60f7b..2aaab2264b 100644 --- a/src/sql/base/browser/ui/panel/panel.ts +++ b/src/sql/base/browser/ui/panel/panel.ts @@ -46,7 +46,8 @@ interface IInternalPanelTab { header: HTMLElement; disposables: IDisposable[]; label: HTMLElement; - body: HTMLElement; + body?: HTMLElement; + destoryTabBody?: boolean; } const defaultOptions: IPanelOptions = { @@ -111,9 +112,10 @@ export class TabbedPanel extends Disposable { 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; internalTab.disposables = []; + internalTab.destoryTabBody = destoryTabBody; this._tabMap.set(tab.identifier, internalTab); this._createTab(internalTab, index); if (!this._shownTabId) { @@ -175,13 +177,21 @@ export class TabbedPanel extends Disposable { DOM.removeClass(shownTab.label, 'active'); DOM.removeClass(shownTab.header, 'active'); shownTab.header.setAttribute('aria-selected', 'false'); - shownTab.body.remove(); + if (shownTab.body) { + shownTab.body.remove(); + } } } this._shownTabId = 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 + + if (tab.destoryTabBody && tab.body) { + tab.body.remove(); + tab.body = undefined; + } + if (!tab.body) { tab.body = DOM.$('.tab-container'); tab.body.style.width = '100%'; @@ -308,7 +318,7 @@ export class TabbedPanel extends Disposable { private _layoutCurrentTab(dimension: DOM.Dimension): void { if (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.height = dimension.height + 'px'; tab.tab.view.layout(dimension); diff --git a/src/sql/workbench/electron-browser/modelComponents/webview.component.ts b/src/sql/workbench/electron-browser/modelComponents/webview.component.ts index b9b26d186c..37c588fbdd 100644 --- a/src/sql/workbench/electron-browser/modelComponents/webview.component.ts +++ b/src/sql/workbench/electron-browser/modelComponents/webview.component.ts @@ -41,6 +41,7 @@ export default class WebViewComponent extends ComponentBase implements IComponen private _webview: WebviewElement; private _renderedHtml: string; private _extensionLocationUri: URI; + private _ready: Promise; protected contextKey: IContextKey; protected findInputFocusContextKey: IContextKey; @@ -74,15 +75,28 @@ export default class WebViewComponent extends ComponentBase implements IComponen this._webview.mountTo(this._el.nativeElement); - this._register(this._webview.onDidClickLink(link => this.onDidClickLink(link))); + this._ready = new Promise(resolve => { + let webview = (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.fireEvent({ - eventType: ComponentEventType.onMessage, - args: e - }); - })); - this.setHtml(); + this._ready.then(() => { + this._register(this._webview.onDidClickLink(link => this.onDidClickLink(link))); + + this._register(this._webview.onMessage(e => { + this.fireEvent({ + eventType: ComponentEventType.onMessage, + args: e + }); + })); + + this.setHtml(); + }); } ngOnDestroy(): void { @@ -125,9 +139,13 @@ export default class WebViewComponent extends ComponentBase implements IComponen /// IComponent implementation public layout(): void { - let element = this._el.nativeElement; - element.style.position = this.position; - this._webview.layout(); + if (this._ready) { + this._ready.then(() => { + let element = this._el.nativeElement; + element.style.position = this.position; + this._webview.layout(); + }); + } } public setLayout(layout: any): void { @@ -136,18 +154,21 @@ export default class WebViewComponent extends ComponentBase implements IComponen } public setProperties(properties: { [key: string]: any; }): void { - super.setProperties(properties); - if (this.options) { - this._webview.options = this.getExtendedOptions(); + if (this._ready) { + this._ready.then(() => { + 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 diff --git a/src/sql/workbench/parts/query/browser/queryResultsView.ts b/src/sql/workbench/parts/query/browser/queryResultsView.ts index f979f71d10..67bea61658 100644 --- a/src/sql/workbench/parts/query/browser/queryResultsView.ts +++ b/src/sql/workbench/parts/query/browser/queryResultsView.ts @@ -249,7 +249,7 @@ export class QueryResultsView extends Disposable { tab.view._componentId = parts[2]; this.dynamicModelViewTabs.push(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); if (!this._panelView.contains(tab)) { - this._panelView.pushTab(tab); + this._panelView.pushTab(tab, undefined, true); } } }