diff --git a/src/sql/base/browser/ui/panel/panel.ts b/src/sql/base/browser/ui/panel/panel.ts index 21c3b207a7..e2680be62d 100644 --- a/src/sql/base/browser/ui/panel/panel.ts +++ b/src/sql/base/browser/ui/panel/panel.ts @@ -63,7 +63,7 @@ export class TabbedPanel extends Disposable implements IThemable { private tabHistory: string[] = []; - constructor(private container: HTMLElement, private options: IPanelOptions = defaultOptions) { + constructor(container: HTMLElement, private options: IPanelOptions = defaultOptions) { super(); this.parent = $('.tabbedPanel'); container.appendChild(this.parent); @@ -87,6 +87,13 @@ export class TabbedPanel extends Disposable implements IThemable { this.parent.appendChild(this.body); } + public dispose() { + this.header.remove(); + this.tabList.remove(); + this.body.remove(); + this.parent.remove(); + } + public contains(tab: IPanelTab): boolean { return this._tabMap.has(tab.identifier); } diff --git a/src/sql/parts/query/editor/charting/chartTab.ts b/src/sql/parts/query/editor/charting/chartTab.ts index 11bfc8d433..f3e5a1d199 100644 --- a/src/sql/parts/query/editor/charting/chartTab.ts +++ b/src/sql/parts/query/editor/charting/chartTab.ts @@ -18,7 +18,7 @@ export class ChartTab implements IPanelTab { public readonly identifier = 'ChartTab'; public readonly view: ChartView; - constructor(@IInstantiationService instantiationService: IInstantiationService) { + constructor( @IInstantiationService instantiationService: IInstantiationService) { this.view = instantiationService.createInstance(ChartView); } @@ -26,7 +26,11 @@ export class ChartTab implements IPanelTab { this.view.queryRunner = runner; } - public chart(dataId: { batchId: number, resultId: number}): void { + public chart(dataId: { batchId: number, resultId: number }): void { this.view.chart(dataId); } + + public dispose() { + this.view.dispose(); + } } diff --git a/src/sql/parts/query/editor/charting/chartView.ts b/src/sql/parts/query/editor/charting/chartView.ts index c96ea26bbb..728469c6be 100644 --- a/src/sql/parts/query/editor/charting/chartView.ts +++ b/src/sql/parts/query/editor/charting/chartView.ts @@ -24,7 +24,7 @@ import { SelectBox } from 'vs/base/browser/ui/selectBox/selectBox'; import { IContextViewService, IContextMenuService } from 'vs/platform/contextview/browser/contextView'; import { InputBox } from 'vs/base/browser/ui/inputbox/inputBox'; import { Builder } from 'vs/base/browser/builder'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { attachSelectBoxStyler, attachInputBoxStyler } from 'vs/platform/theme/common/styler'; import { IThemeService } from 'vs/platform/theme/common/themeService'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -43,7 +43,7 @@ declare class Proxy { const insightRegistry = Registry.as(Extensions.InsightContribution); -export class ChartView implements IPanelView { +export class ChartView extends Disposable implements IPanelView { private insight: Insight; private _queryRunner: QueryRunner; private _data: IInsightData; @@ -82,6 +82,7 @@ export class ChartView implements IPanelView { @IInstantiationService private _instantiationService: IInstantiationService, @IContextMenuService contextMenuService: IContextMenuService ) { + super(); this.taskbarContainer = $('div.taskbar-container'); this.taskbar = new Taskbar(this.taskbarContainer, contextMenuService); this.optionsControl = $('div.options-container'); diff --git a/src/sql/parts/query/editor/queryResultsView.ts b/src/sql/parts/query/editor/queryResultsView.ts index 0bcbec8fee..1272e27ad3 100644 --- a/src/sql/parts/query/editor/queryResultsView.ts +++ b/src/sql/parts/query/editor/queryResultsView.ts @@ -18,9 +18,9 @@ import { PanelViewlet } from 'vs/workbench/browser/parts/views/panelViewlet'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import * as DOM from 'vs/base/browser/dom'; import { once, anyEvent } from 'vs/base/common/event'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; -class ResultsView implements IPanelView { +class ResultsView extends Disposable implements IPanelView { private panelViewlet: PanelViewlet; private gridPanel: GridPanel; private messagePanel: MessagePanel; @@ -30,10 +30,10 @@ class ResultsView implements IPanelView { private _state: ResultsViewState; constructor(private instantiationService: IInstantiationService) { - - this.panelViewlet = this.instantiationService.createInstance(PanelViewlet, 'resultsView', { showHeaderInTitleWhenSingleView: false }); - this.gridPanel = this.instantiationService.createInstance(GridPanel, { title: nls.localize('gridPanel', 'Results'), id: 'gridPanel' }); - this.messagePanel = this.instantiationService.createInstance(MessagePanel, { title: nls.localize('messagePanel', 'Messages'), minimumBodySize: 0, id: 'messagePanel' }); + super(); + this.panelViewlet = this._register(this.instantiationService.createInstance(PanelViewlet, 'resultsView', { showHeaderInTitleWhenSingleView: false })); + this.gridPanel = this._register(this.instantiationService.createInstance(GridPanel, { title: nls.localize('gridPanel', 'Results'), id: 'gridPanel' })); + this.messagePanel = this._register(this.instantiationService.createInstance(MessagePanel, { title: nls.localize('messagePanel', 'Messages'), minimumBodySize: 0, id: 'messagePanel' })); this.gridPanel.render(); this.messagePanel.render(); this.panelViewlet.create(this.container).then(() => { @@ -147,9 +147,13 @@ class ResultsTab implements IPanelTab { public set queryRunner(runner: QueryRunner) { this.view.queryRunner = runner; } + + public dispose() { + dispose(this.view); + } } -export class QueryResultsView { +export class QueryResultsView extends Disposable { private _panelView: TabbedPanel; private _input: QueryResultsInput; private resultsTab: ResultsTab; @@ -163,16 +167,17 @@ export class QueryResultsView { @IInstantiationService instantiationService: IInstantiationService, @IQueryModelService private queryModelService: IQueryModelService ) { - this.resultsTab = new ResultsTab(instantiationService); - this.chartTab = new ChartTab(instantiationService); - this._panelView = new TabbedPanel(container, { showHeaderWhenSingleView: false }); - this.qpTab = new QueryPlanTab(); + super(); + this.resultsTab = this._register(new ResultsTab(instantiationService)); + this.chartTab = this._register(new ChartTab(instantiationService)); + this._panelView = this._register(new TabbedPanel(container, { showHeaderWhenSingleView: false })); + this.qpTab = this._register(new QueryPlanTab()); this._panelView.pushTab(this.resultsTab); - this._panelView.onTabChange(e => { + this._register(this._panelView.onTabChange(e => { if (this.input) { this.input.state.activeTab = e; } - }); + })); } public style() { diff --git a/src/sql/parts/queryPlan/queryPlan.ts b/src/sql/parts/queryPlan/queryPlan.ts index 607b9d4bb1..390b600ebb 100644 --- a/src/sql/parts/queryPlan/queryPlan.ts +++ b/src/sql/parts/queryPlan/queryPlan.ts @@ -10,8 +10,8 @@ import { IPanelView, IPanelTab } from 'sql/base/browser/ui/panel/panel'; import { Dimension } from 'vs/base/browser/dom'; import { localize } from 'vs/nls'; -import * as UUID from 'vs/base/common/uuid'; import { Builder } from 'vs/base/browser/builder'; +import { dispose, Disposable } from 'vs/base/common/lifecycle'; export class QueryPlanState { xml: string; @@ -25,6 +25,10 @@ export class QueryPlanTab implements IPanelTab { constructor() { this.view = new QueryPlanView(); } + + public dispose() { + dispose(this.view); + } } export class QueryPlanView implements IPanelView { @@ -44,6 +48,12 @@ export class QueryPlanView implements IPanelView { this.container.style.overflow = 'scroll'; } + dispose() { + this.container.remove(); + this.qp = undefined; + this.container = undefined; + } + public layout(dimension: Dimension): void { this.container.style.width = dimension.width + 'px'; this.container.style.height = dimension.height + 'px';