From ee8372c0c798f116b6bced5ee1b61223ec5255dd Mon Sep 17 00:00:00 2001 From: Kostya Bushuev Date: Sun, 31 Mar 2019 10:17:39 +0500 Subject: [PATCH 01/93] Fixed #71134 --- src/vs/base/browser/ui/list/listWidget.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/vs/base/browser/ui/list/listWidget.ts b/src/vs/base/browser/ui/list/listWidget.ts index 0869c52c0d2..a6e058d9b67 100644 --- a/src/vs/base/browser/ui/list/listWidget.ts +++ b/src/vs/base/browser/ui/list/listWidget.ts @@ -330,6 +330,7 @@ export function mightProducePrintableCharacter(event: IKeyboardEvent): boolean { return (event.keyCode >= KeyCode.KEY_A && event.keyCode <= KeyCode.KEY_Z) || (event.keyCode >= KeyCode.KEY_0 && event.keyCode <= KeyCode.KEY_9) + || (event.keyCode >= KeyCode.NUMPAD_0 && event.keyCode <= KeyCode.NUMPAD_9) || (event.keyCode >= KeyCode.US_SEMICOLON && event.keyCode <= KeyCode.US_QUOTE); } From 01a1c9941c4571a272b9c653785555175f12fdf1 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Tue, 9 Jul 2019 12:24:04 +0200 Subject: [PATCH 02/93] cleanup build cache paths --- build/.cachesalt | 2 +- build/azure-pipelines/darwin/product-build-darwin.yml | 4 ++-- .../linux/product-build-linux-multiarch.yml | 4 ++-- build/azure-pipelines/linux/product-build-linux.yml | 4 ++-- build/azure-pipelines/product-compile.yml | 8 ++++---- build/azure-pipelines/win32/product-build-win32.yml | 4 ++-- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/build/.cachesalt b/build/.cachesalt index 56a6051ca2b..1d0bd9164e8 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -1 \ No newline at end of file +2019-07-09T10:22:14.653Z diff --git a/build/azure-pipelines/darwin/product-build-darwin.yml b/build/azure-pipelines/darwin/product-build-darwin.yml index cdf7eb2f1df..01bb333120a 100644 --- a/build/azure-pipelines/darwin/product-build-darwin.yml +++ b/build/azure-pipelines/darwin/product-build-darwin.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/linux/product-build-linux-multiarch.yml b/build/azure-pipelines/linux/product-build-linux-multiarch.yml index 66b6bbff713..139d926bf73 100644 --- a/build/azure-pipelines/linux/product-build-linux-multiarch.yml +++ b/build/azure-pipelines/linux/product-build-linux-multiarch.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/linux/product-build-linux.yml b/build/azure-pipelines/linux/product-build-linux.yml index 1e48713cd86..fd0f4347d4a 100644 --- a/build/azure-pipelines/linux/product-build-linux.yml +++ b/build/azure-pipelines/linux/product-build-linux.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/product-compile.yml b/build/azure-pipelines/product-compile.yml index cc2639f139c..27a8362dd3e 100644 --- a/build/azure-pipelines/product-compile.yml +++ b/build/azure-pipelines/product-compile.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' @@ -112,8 +112,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.SaveCacheV1.SaveCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' diff --git a/build/azure-pipelines/win32/product-build-win32.yml b/build/azure-pipelines/win32/product-build-win32.yml index 66d8bf4af32..89c85d866ad 100644 --- a/build/azure-pipelines/win32/product-build-win32.yml +++ b/build/azure-pipelines/win32/product-build-win32.yml @@ -6,8 +6,8 @@ steps: - task: 1ESLighthouseEng.PipelineArtifactCaching.RestoreCacheV1.RestoreCache@1 inputs: - keyfile: '.build/commit' - targetfolder: '.build, **/out-build, **/out-vscode-min, **/out-vscode-reh-min, **/out-vscode-web-min' + keyfile: 'build/.cachesalt, .build/commit' + targetfolder: '.build, out-build, out-vscode-min, out-vscode-reh-min, out-vscode-web-min' vstsFeed: 'npm-vscode' platformIndependent: true alias: 'Compilation' From 5826f17dda00ec56c0812d145b84db5d98356a4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Wed, 10 Jul 2019 07:02:51 +0200 Subject: [PATCH 03/93] Update .cachesalt --- build/.cachesalt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.cachesalt b/build/.cachesalt index 1d0bd9164e8..d9e527ad8ae 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2019-07-09T10:22:14.653Z +2019-07-10T05:02:42.950Z From f857d0456d93615677be4223c304d5db61c2fcc9 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 10 Jul 2019 11:01:24 +0200 Subject: [PATCH 04/93] splitview: make ViewItem a class --- src/vs/base/browser/ui/splitview/splitview.ts | 129 +++++++++++------- 1 file changed, 80 insertions(+), 49 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index fc104cc5543..99ba9e0d68f 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -57,12 +57,49 @@ interface ISashEvent { alt: boolean; } -interface IViewItem { - view: IView; - size: number; - container: HTMLElement; - disposable: IDisposable; - layout(): void; +abstract class ViewItem { + + set size(size: number) { + this._size = size; + } + + get size(): number { + return this._size; + } + + get minimumSize(): number { return this.view.minimumSize; } + get maximumSize(): number { return this.view.maximumSize; } + get onDidChange(): Event { return this.view.onDidChange; } + get priority(): LayoutPriority | undefined { return this.view.priority; } + + constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) { } + + abstract layout(): void; + + layoutView(orientation: Orientation): void { + this.view.layout(this.size, orientation); + } + + dispose(): IView { + this.disposable.dispose(); + return this.view; + } +} + +class VerticalViewItem extends ViewItem { + + layout(): void { + this.container.style.height = `${this.size}px`; + this.layoutView(Orientation.VERTICAL); + } +} + +class HorizontalViewItem extends ViewItem { + + layout(): void { + this.container.style.width = `${this.size}px`; + this.layoutView(Orientation.HORIZONTAL); + } } interface ISashItem { @@ -104,7 +141,7 @@ export class SplitView extends Disposable { private size = 0; private contentSize = 0; private proportions: undefined | number[] = undefined; - private viewItems: IViewItem[] = []; + private viewItems: ViewItem[] = []; private sashItems: ISashItem[] = []; private sashDragState: ISashDragState; private state: State = State.Idle; @@ -122,11 +159,11 @@ export class SplitView extends Disposable { } get minimumSize(): number { - return this.viewItems.reduce((r, item) => r + item.view.minimumSize, 0); + return this.viewItems.reduce((r, item) => r + item.minimumSize, 0); } get maximumSize(): number { - return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.view.maximumSize, 0); + return this.length === 0 ? Number.POSITIVE_INFINITY : this.viewItems.reduce((r, item) => r + item.maximumSize, 0); } private _orthogonalStartSash: Sash | undefined; @@ -201,15 +238,6 @@ export class SplitView extends Disposable { const containerDisposable = toDisposable(() => this.viewContainer.removeChild(container)); const disposable = combinedDisposable(onChangeDisposable, containerDisposable); - const layoutContainer = this.orientation === Orientation.VERTICAL - ? () => item.container.style.height = `${item.size}px` - : () => item.container.style.width = `${item.size}px`; - - const layout = () => { - layoutContainer(); - item.view.layout(item.size, this.orientation); - }; - let viewSize: number; if (typeof size === 'number') { @@ -220,7 +248,10 @@ export class SplitView extends Disposable { viewSize = view.minimumSize; } - const item: IViewItem = { view, container, size: viewSize, layout, disposable }; + const item = this.orientation === Orientation.VERTICAL + ? new VerticalViewItem(container, view, viewSize, disposable) + : new HorizontalViewItem(container, view, viewSize, disposable); + this.viewItems.splice(index, 0, item); // Add sash @@ -280,7 +311,7 @@ export class SplitView extends Disposable { // Remove view const viewItem = this.viewItems.splice(index, 1)[0]; - viewItem.disposable.dispose(); + const view = viewItem.dispose(); // Remove sash if (this.viewItems.length >= 1) { @@ -296,7 +327,7 @@ export class SplitView extends Disposable { this.distributeViewSizes(); } - return viewItem.view; + return view; } moveView(from: number, to: number): void { @@ -344,14 +375,14 @@ export class SplitView extends Disposable { if (!this.proportions) { const indexes = range(this.viewItems.length); - const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.Low); - const highPriorityIndexes = indexes.filter(i => this.viewItems[i].view.priority === LayoutPriority.High); + const lowPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.Low); + const highPriorityIndexes = indexes.filter(i => this.viewItems[i].priority === LayoutPriority.High); this.resize(this.viewItems.length - 1, size - previousSize, undefined, lowPriorityIndexes, highPriorityIndexes); } else { for (let i = 0; i < this.viewItems.length; i++) { const item = this.viewItems[i]; - item.size = clamp(Math.round(this.proportions[i] * size), item.view.minimumSize, item.view.maximumSize); + item.size = clamp(Math.round(this.proportions[i] * size), item.minimumSize, item.maximumSize); } } @@ -391,12 +422,12 @@ export class SplitView extends Disposable { if (isLastSash) { const viewItem = this.viewItems[index]; - minDelta = (viewItem.view.minimumSize - viewItem.size) / 2; - maxDelta = (viewItem.view.maximumSize - viewItem.size) / 2; + minDelta = (viewItem.minimumSize - viewItem.size) / 2; + maxDelta = (viewItem.maximumSize - viewItem.size) / 2; } else { const viewItem = this.viewItems[index + 1]; - minDelta = (viewItem.size - viewItem.view.maximumSize) / 2; - maxDelta = (viewItem.size - viewItem.view.minimumSize) / 2; + minDelta = (viewItem.size - viewItem.maximumSize) / 2; + maxDelta = (viewItem.size - viewItem.minimumSize) / 2; } } @@ -418,8 +449,8 @@ export class SplitView extends Disposable { const newSizes = this.viewItems.map(i => i.size); const viewItemIndex = isLastSash ? index : index + 1; const viewItem = this.viewItems[viewItemIndex]; - const newMinDelta = viewItem.size - viewItem.view.maximumSize; - const newMaxDelta = viewItem.size - viewItem.view.minimumSize; + const newMinDelta = viewItem.size - viewItem.maximumSize; + const newMaxDelta = viewItem.size - viewItem.minimumSize; const resizeIndex = isLastSash ? index - 1 : index + 1; this.resize(resizeIndex, -newDelta, newSizes, undefined, undefined, newMinDelta, newMaxDelta); @@ -435,7 +466,7 @@ export class SplitView extends Disposable { this.saveProportions(); } - private onViewChange(item: IViewItem, size: number | undefined): void { + private onViewChange(item: ViewItem, size: number | undefined): void { const index = this.viewItems.indexOf(item); if (index < 0 || index >= this.viewItems.length) { @@ -443,7 +474,7 @@ export class SplitView extends Disposable { } size = typeof size === 'number' ? size : item.size; - size = clamp(size, item.view.minimumSize, item.view.maximumSize); + size = clamp(size, item.minimumSize, item.maximumSize); if (this.inverseAltBehavior && index > 0) { // In this case, we want the view to grow or shrink both sides equally @@ -470,13 +501,13 @@ export class SplitView extends Disposable { const item = this.viewItems[index]; size = Math.round(size); - size = clamp(size, item.view.minimumSize, item.view.maximumSize); + size = clamp(size, item.minimumSize, item.maximumSize); let delta = size - item.size; if (delta !== 0 && index < this.viewItems.length - 1) { const downIndexes = range(index + 1, this.viewItems.length); - const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0); - const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0); + const collapseDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0); + const expandDown = downIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0); const deltaDown = clamp(delta, -expandDown, collapseDown); this.resize(index, deltaDown); @@ -485,8 +516,8 @@ export class SplitView extends Disposable { if (delta !== 0 && index > 0) { const upIndexes = range(index - 1, -1); - const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].view.minimumSize), 0); - const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - this.viewItems[i].size), 0); + const collapseUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].size - this.viewItems[i].minimumSize), 0); + const expandUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - this.viewItems[i].size), 0); const deltaUp = clamp(-delta, -collapseUp, expandUp); this.resize(index - 1, deltaUp); @@ -550,10 +581,10 @@ export class SplitView extends Disposable { const downItems = downIndexes.map(i => this.viewItems[i]); const downSizes = downIndexes.map(i => sizes[i]); - const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.minimumSize - sizes[i]), 0); - const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].view.maximumSize - sizes[i]), 0); - const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.minimumSize), 0); - const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].view.maximumSize), 0); + const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0); + const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - sizes[i]), 0); + const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0); + const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].maximumSize), 0); const minDelta = Math.max(minDeltaUp, minDeltaDown, overloadMinDelta); const maxDelta = Math.min(maxDeltaDown, maxDeltaUp, overloadMaxDelta); @@ -561,7 +592,7 @@ export class SplitView extends Disposable { for (let i = 0, deltaUp = delta; i < upItems.length; i++) { const item = upItems[i]; - const size = clamp(upSizes[i] + deltaUp, item.view.minimumSize, item.view.maximumSize); + const size = clamp(upSizes[i] + deltaUp, item.minimumSize, item.maximumSize); const viewDelta = size - upSizes[i]; deltaUp -= viewDelta; @@ -570,7 +601,7 @@ export class SplitView extends Disposable { for (let i = 0, deltaDown = delta; i < downItems.length; i++) { const item = downItems[i]; - const size = clamp(downSizes[i] - deltaDown, item.view.minimumSize, item.view.maximumSize); + const size = clamp(downSizes[i] - deltaDown, item.minimumSize, item.maximumSize); const viewDelta = size - downSizes[i]; deltaDown += viewDelta; @@ -586,7 +617,7 @@ export class SplitView extends Disposable { for (let i = this.viewItems.length - 1; emptyDelta !== 0 && i >= 0; i--) { const item = this.viewItems[i]; - const size = clamp(item.size + emptyDelta, item.view.minimumSize, item.view.maximumSize); + const size = clamp(item.size + emptyDelta, item.minimumSize, item.maximumSize); const viewDelta = size - item.size; emptyDelta -= viewDelta; @@ -606,17 +637,17 @@ export class SplitView extends Disposable { // Update sashes enablement let previous = false; - const collapsesDown = this.viewItems.map(i => previous = (i.size - i.view.minimumSize > 0) || previous); + const collapsesDown = this.viewItems.map(i => previous = (i.size - i.minimumSize > 0) || previous); previous = false; - const expandsDown = this.viewItems.map(i => previous = (i.view.maximumSize - i.size > 0) || previous); + const expandsDown = this.viewItems.map(i => previous = (i.maximumSize - i.size > 0) || previous); const reverseViews = [...this.viewItems].reverse(); previous = false; - const collapsesUp = reverseViews.map(i => previous = (i.size - i.view.minimumSize > 0) || previous).reverse(); + const collapsesUp = reverseViews.map(i => previous = (i.size - i.minimumSize > 0) || previous).reverse(); previous = false; - const expandsUp = reverseViews.map(i => previous = (i.view.maximumSize - i.size > 0) || previous).reverse(); + const expandsUp = reverseViews.map(i => previous = (i.maximumSize - i.size > 0) || previous).reverse(); this.sashItems.forEach((s, i) => { const min = !(collapsesDown[i] && expandsUp[i + 1]); @@ -651,7 +682,7 @@ export class SplitView extends Disposable { dispose(): void { super.dispose(); - this.viewItems.forEach(i => i.disposable.dispose()); + this.viewItems.forEach(i => i.dispose()); this.viewItems = []; this.sashItems.forEach(i => i.disposable.dispose()); From a861b8bfd25a902a848088ee279c224386cfcaaf Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 10 Jul 2019 12:06:14 +0200 Subject: [PATCH 05/93] splitview: visibility --- .../base/browser/ui/splitview/splitview.css | 4 + src/vs/base/browser/ui/splitview/splitview.ts | 66 +++- test/splitview/package.json | 13 + test/splitview/public/index.html | 73 ++++ test/splitview/server.js | 19 + test/splitview/yarn.lock | 341 ++++++++++++++++++ 6 files changed, 508 insertions(+), 8 deletions(-) create mode 100644 test/splitview/package.json create mode 100644 test/splitview/public/index.html create mode 100644 test/splitview/server.js create mode 100644 test/splitview/yarn.lock diff --git a/src/vs/base/browser/ui/splitview/splitview.css b/src/vs/base/browser/ui/splitview/splitview.css index 7479f5178d7..6fb8f1c61d0 100644 --- a/src/vs/base/browser/ui/splitview/splitview.css +++ b/src/vs/base/browser/ui/splitview/splitview.css @@ -41,6 +41,10 @@ position: relative; } +.monaco-split-view2 > .split-view-container > .split-view-view:not(.visible) { + display: none; +} + .monaco-split-view2.vertical > .split-view-container > .split-view-view { width: 100%; } diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 99ba9e0d68f..82a9c66042a 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -67,12 +67,35 @@ abstract class ViewItem { return this._size; } - get minimumSize(): number { return this.view.minimumSize; } - get maximumSize(): number { return this.view.maximumSize; } - get onDidChange(): Event { return this.view.onDidChange; } + private cachedSize: number | undefined = undefined; + + get visible(): boolean { + return typeof this.cachedSize === 'undefined'; + } + + set visible(visible: boolean) { + if (visible === this.visible) { + return; + } + + if (visible) { + this.size = this.cachedSize!; + this.cachedSize = undefined; + } else { + this.cachedSize = this.size; + this.size = 0; + } + + dom.toggleClass(this.container, 'visible', visible); + } + + get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; } + get maximumSize(): number { return this.visible ? this.view.maximumSize : 0; } get priority(): LayoutPriority | undefined { return this.view.priority; } - constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) { } + constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) { + dom.addClass(container, 'visible'); + } abstract layout(): void; @@ -358,6 +381,27 @@ export class SplitView extends Disposable { this.addView(fromView, toSize, to); } + isViewVisible(index: number): boolean { + if (index < 0 || index >= this.viewItems.length) { + throw new Error('Index out of bounds'); + } + + const viewItem = this.viewItems[index]; + return viewItem.visible; + } + + setViewVisible(index: number, visible: boolean): void { + if (index < 0 || index >= this.viewItems.length) { + throw new Error('Index out of bounds'); + } + + const viewItem = this.viewItems[index]; + viewItem.visible = visible; + + this.distributeEmptySpace(index); + this.layoutViews(); + } + private relayout(lowPriorityIndex?: number, highPriorityIndex?: number): void { const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); const lowPriorityIndexes = typeof lowPriorityIndex === 'number' ? [lowPriorityIndex] : undefined; @@ -611,12 +655,18 @@ export class SplitView extends Disposable { return delta; } - private distributeEmptySpace(): void { - let contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); + private distributeEmptySpace(lowPriorityIndex?: number): void { + const contentSize = this.viewItems.reduce((r, i) => r + i.size, 0); let emptyDelta = this.size - contentSize; - for (let i = this.viewItems.length - 1; emptyDelta !== 0 && i >= 0; i--) { - const item = this.viewItems[i]; + const indexes = range(this.viewItems.length - 1, -1); + + if (typeof lowPriorityIndex === 'number') { + pushToEnd(indexes, lowPriorityIndex); + } + + for (let i = 0; emptyDelta !== 0 && i < indexes.length; i++) { + const item = this.viewItems[indexes[i]]; const size = clamp(item.size + emptyDelta, item.minimumSize, item.maximumSize); const viewDelta = size - item.size; diff --git a/test/splitview/package.json b/test/splitview/package.json new file mode 100644 index 00000000000..d6ce0c37374 --- /dev/null +++ b/test/splitview/package.json @@ -0,0 +1,13 @@ +{ + "name": "splitview", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "devDependencies": { + "koa": "^2.5.1", + "koa-mount": "^3.0.0", + "koa-route": "^3.2.0", + "koa-static": "^5.0.0", + "mz": "^2.7.0" + } +} \ No newline at end of file diff --git a/test/splitview/public/index.html b/test/splitview/public/index.html new file mode 100644 index 00000000000..2493353844c --- /dev/null +++ b/test/splitview/public/index.html @@ -0,0 +1,73 @@ + + + + + SplitView + + + + +
+ + + + + + \ No newline at end of file diff --git a/test/splitview/server.js b/test/splitview/server.js new file mode 100644 index 00000000000..67f25363671 --- /dev/null +++ b/test/splitview/server.js @@ -0,0 +1,19 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const fs = require('mz/fs'); +const path = require('path'); +const Koa = require('koa'); +const _ = require('koa-route'); +const serve = require('koa-static'); +const mount = require('koa-mount'); + +const app = new Koa(); + +app.use(serve('public')); +app.use(mount('/static', serve('../../out'))); + +app.listen(3000); +console.log('http://localhost:3000'); \ No newline at end of file diff --git a/test/splitview/yarn.lock b/test/splitview/yarn.lock new file mode 100644 index 00000000000..237201a684e --- /dev/null +++ b/test/splitview/yarn.lock @@ -0,0 +1,341 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +accepts@^1.2.2: + version "1.3.5" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.5.tgz#eb777df6011723a3b14e8a72c0805c8e86746bd2" + integrity sha1-63d99gEXI6OxTopywIBcjoZ0a9I= + dependencies: + mime-types "~2.1.18" + negotiator "0.6.1" + +any-promise@^1.0.0, any-promise@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ= + +content-disposition@~0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + integrity sha1-DPaLud318r55YcOoUXjLhdunjLQ= + +content-type@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" + integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== + +cookies@~0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/cookies/-/cookies-0.7.1.tgz#7c8a615f5481c61ab9f16c833731bcb8f663b99b" + integrity sha1-fIphX1SBxhq58WyDNzG8uPZjuZs= + dependencies: + depd "~1.1.1" + keygrip "~1.0.2" + +debug@*, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.6.1: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + +deep-equal@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + integrity sha1-9dJgKStmDghO/0zbyfCK0yR0SLU= + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= + +depd@^1.1.0, depd@~1.1.1, depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= + +destroy@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= + +error-inject@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/error-inject/-/error-inject-1.0.0.tgz#e2b3d91b54aed672f309d950d154850fa11d4f37" + integrity sha1-4rPZG1Su1nLzCdlQ0VSFD6EdTzc= + +escape-html@~1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg= + +fresh@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= + +http-assert@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/http-assert/-/http-assert-1.3.0.tgz#a31a5cf88c873ecbb5796907d4d6f132e8c01e4a" + integrity sha1-oxpc+IyHPsu1eWkH1NbxMujAHko= + dependencies: + deep-equal "~1.0.1" + http-errors "~1.6.1" + +http-errors@^1.2.8, http-errors@^1.6.3, http-errors@~1.6.1, http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0= + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + +inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + +is-generator-function@^1.0.3: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.7.tgz#d2132e529bb0000a7f80794d4bdf5cd5e5813522" + integrity sha512-YZc5EwyO4f2kWCax7oegfuSr9mFz1ZvieNYBEjmukLxgXfBUbxAWGVF7GZf0zidYtoBl3WvC07YK0wT76a+Rtw== + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8= + +keygrip@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/keygrip/-/keygrip-1.0.2.tgz#ad3297c557069dea8bcfe7a4fa491b75c5ddeb91" + integrity sha1-rTKXxVcGneqLz+ek+kkbdcXd65E= + +koa-compose@^3.0.0, koa-compose@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-3.2.1.tgz#a85ccb40b7d986d8e5a345b3a1ace8eabcf54de7" + integrity sha1-qFzLQLfZhtjlo0Wzoazo6rz1Tec= + dependencies: + any-promise "^1.1.0" + +koa-compose@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/koa-compose/-/koa-compose-4.1.0.tgz#507306b9371901db41121c812e923d0d67d3e877" + integrity sha512-8ODW8TrDuMYvXRwra/Kh7/rJo9BtOfPc6qO8eAfC80CnCvSjSl0bkRM24X6/XBBEyj0v1nRUQ1LyOy3dbqOWXw== + +koa-convert@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/koa-convert/-/koa-convert-1.2.0.tgz#da40875df49de0539098d1700b50820cebcd21d0" + integrity sha1-2kCHXfSd4FOQmNFwC1CCDOvNIdA= + dependencies: + co "^4.6.0" + koa-compose "^3.0.0" + +koa-is-json@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/koa-is-json/-/koa-is-json-1.0.0.tgz#273c07edcdcb8df6a2c1ab7d59ee76491451ec14" + integrity sha1-JzwH7c3Ljfaiwat9We52SRRR7BQ= + +koa-mount@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/koa-mount/-/koa-mount-3.0.0.tgz#08cab3b83d31442ed8b7e75c54b1abeb922ec197" + integrity sha1-CMqzuD0xRC7Yt+dcVLGr65IuwZc= + dependencies: + debug "^2.6.1" + koa-compose "^3.2.1" + +koa-route@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/koa-route/-/koa-route-3.2.0.tgz#76298b99a6bcfa9e38cab6fe5c79a8733e758bce" + integrity sha1-dimLmaa8+p44yrb+XHmocz51i84= + dependencies: + debug "*" + methods "~1.1.0" + path-to-regexp "^1.2.0" + +koa-send@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-send/-/koa-send-5.0.0.tgz#5e8441e07ef55737734d7ced25b842e50646e7eb" + integrity sha512-90ZotV7t0p3uN9sRwW2D484rAaKIsD8tAVtypw/aBU+ryfV+fR2xrcAwhI8Wl6WRkojLUs/cB9SBSCuIb+IanQ== + dependencies: + debug "^3.1.0" + http-errors "^1.6.3" + mz "^2.7.0" + resolve-path "^1.4.0" + +koa-static@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/koa-static/-/koa-static-5.0.0.tgz#5e92fc96b537ad5219f425319c95b64772776943" + integrity sha512-UqyYyH5YEXaJrf9S8E23GoJFQZXkBVJ9zYYMPGz919MSX1KuvAcycIuS0ci150HCoPf4XQVhQ84Qf8xRPWxFaQ== + dependencies: + debug "^3.1.0" + koa-send "^5.0.0" + +koa@^2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/koa/-/koa-2.5.1.tgz#79f8b95f8d72d04fe9a58a8da5ebd6d341103f9c" + integrity sha512-cchwbMeG2dv3E2xTAmheDAuvR53tPgJZN/Hf1h7bTzJLSPcFZp8/t5+bNKJ6GaQZoydhZQ+1GNruhKdj3lIrug== + dependencies: + accepts "^1.2.2" + content-disposition "~0.5.0" + content-type "^1.0.0" + cookies "~0.7.0" + debug "*" + delegates "^1.0.0" + depd "^1.1.0" + destroy "^1.0.3" + error-inject "~1.0.0" + escape-html "~1.0.1" + fresh "^0.5.2" + http-assert "^1.1.0" + http-errors "^1.2.8" + is-generator-function "^1.0.3" + koa-compose "^4.0.0" + koa-convert "^1.2.0" + koa-is-json "^1.0.0" + mime-types "^2.0.7" + on-finished "^2.1.0" + only "0.0.2" + parseurl "^1.3.0" + statuses "^1.2.0" + type-is "^1.5.5" + vary "^1.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= + +methods@~1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= + +mime-db@~1.33.0: + version "1.33.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" + integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ== + +mime-types@^2.0.7, mime-types@~2.1.18: + version "2.1.18" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" + integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ== + dependencies: + mime-db "~1.33.0" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + integrity sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk= + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + +on-finished@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + dependencies: + ee-first "1.1.1" + +only@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/only/-/only-0.0.2.tgz#2afde84d03e50b9a8edc444e30610a70295edfb4" + integrity sha1-Kv3oTQPlC5qO3EROMGEKcCle37Q= + +parseurl@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.2.tgz#fc289d4ed8993119460c156253262cdc8de65bf3" + integrity sha1-/CidTtiZMRlGDBViUyYs3I3mW/M= + +path-is-absolute@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= + +path-to-regexp@^1.2.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" + integrity sha1-Wf3g9DW62suhA6hOnTvGTpa5k30= + dependencies: + isarray "0.0.1" + +resolve-path@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/resolve-path/-/resolve-path-1.4.0.tgz#c4bda9f5efb2fce65247873ab36bb4d834fe16f7" + integrity sha1-xL2p9e+y/OZSR4c6s2u02DT+Fvc= + dependencies: + http-errors "~1.6.2" + path-is-absolute "1.0.1" + +setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + +"statuses@>= 1.4.0 < 2", statuses@^1.2.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.0" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.0.tgz#e69e38a1babe969b0108207978b9f62b88604839" + integrity sha1-5p44obq+lpsBCCB5eLn2K4hgSDk= + dependencies: + any-promise "^1.0.0" + +type-is@^1.5.5: + version "1.6.16" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" + integrity sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.18" + +vary@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= From 912da28814068fa8e433f7262911fb7c881f72e8 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 10 Jul 2019 13:35:06 +0200 Subject: [PATCH 06/93] debug --- test/splitview/public/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/splitview/public/index.html b/test/splitview/public/index.html index 2493353844c..f20c7961519 100644 --- a/test/splitview/public/index.html +++ b/test/splitview/public/index.html @@ -64,8 +64,8 @@ splitview.addView(view2, Sizing.Distribute); splitview.addView(view3, Sizing.Distribute); - const index = 2; - setInterval(() => splitview.setViewVisible(index, !splitview.isViewVisible(index)), 1000); + // const index = 2; + // setInterval(() => splitview.setViewVisible(index, !splitview.isViewVisible(index)), 1000); }); From 89397197c9328ef55b84ea764678ff0ef1c2c6fd Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 10 Jul 2019 13:40:39 +0200 Subject: [PATCH 07/93] splitview: view.setVisible --- src/vs/base/browser/ui/splitview/splitview.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 82a9c66042a..412c7856cec 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -48,6 +48,7 @@ export interface IView { readonly onDidChange: Event; readonly priority?: LayoutPriority; layout(size: number, orientation: Orientation): void; + setVisible?(visible: boolean): void; } interface ISashEvent { @@ -87,6 +88,10 @@ abstract class ViewItem { } dom.toggleClass(this.container, 'visible', visible); + + if (this.view.setVisible) { + this.view.setVisible(visible); + } } get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; } From 972de4151e1abf318cc9fcaaf798e2f270fdb328 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Wed, 10 Jul 2019 15:52:31 +0200 Subject: [PATCH 08/93] splitview: snap out behaviour --- src/vs/base/browser/ui/splitview/splitview.ts | 52 +++++++++++++++++-- test/splitview/public/index.html | 10 ++-- 2 files changed, 53 insertions(+), 9 deletions(-) diff --git a/src/vs/base/browser/ui/splitview/splitview.ts b/src/vs/base/browser/ui/splitview/splitview.ts index 412c7856cec..90cb255f1c6 100644 --- a/src/vs/base/browser/ui/splitview/splitview.ts +++ b/src/vs/base/browser/ui/splitview/splitview.ts @@ -47,6 +47,7 @@ export interface IView { readonly maximumSize: number; readonly onDidChange: Event; readonly priority?: LayoutPriority; + readonly snap?: boolean; layout(size: number, orientation: Orientation): void; setVisible?(visible: boolean): void; } @@ -97,6 +98,7 @@ abstract class ViewItem { get minimumSize(): number { return this.visible ? this.view.minimumSize : 0; } get maximumSize(): number { return this.visible ? this.view.maximumSize : 0; } get priority(): LayoutPriority | undefined { return this.view.priority; } + get snap(): boolean { return !!this.view.snap; } constructor(protected container: HTMLElement, private view: IView, private _size: number, private disposable: IDisposable) { dom.addClass(container, 'visible'); @@ -143,6 +145,8 @@ interface ISashDragState { minDelta: number; maxDelta: number; alt: boolean; + snapIndex: number | undefined; + snapLimitDelta: number | undefined; disposable: IDisposable; } @@ -480,18 +484,40 @@ export class SplitView extends Disposable { } } - this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, disposable }; + let snapIndex: number | undefined; + let snapLimitDelta: number | undefined; + + if (!alt) { + const upIndexes = range(index, -1); + const downIndexes = range(index + 1, this.viewItems.length); + const minDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].minimumSize - sizes[i]), 0); + const maxDeltaUp = upIndexes.reduce((r, i) => r + (this.viewItems[i].maximumSize - sizes[i]), 0); + const maxDeltaDown = downIndexes.length === 0 ? Number.POSITIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].minimumSize), 0); + const minDeltaDown = downIndexes.length === 0 ? Number.NEGATIVE_INFINITY : downIndexes.reduce((r, i) => r + (sizes[i] - this.viewItems[i].maximumSize), 0); + const minDelta = Math.max(minDeltaUp, minDeltaDown); + const maxDelta = Math.min(maxDeltaDown, maxDeltaUp); + + if (this.viewItems[index].snap) { + snapIndex = index; + snapLimitDelta = minDelta - (this.viewItems[index].minimumSize / 2); + } else if (this.viewItems[index + 1].snap) { + snapIndex = index + 1; + snapLimitDelta = maxDelta + (this.viewItems[index + 1].minimumSize / 2); + } + } + + this.sashDragState = { start, current: start, index, sizes, minDelta, maxDelta, alt, snapIndex, snapLimitDelta, disposable }; }; resetSashDragState(start, alt); } private onSashChange({ current }: ISashEvent): void { - const { index, start, sizes, alt, minDelta, maxDelta } = this.sashDragState; + const { index, start, sizes, alt, minDelta, maxDelta, snapIndex, snapLimitDelta } = this.sashDragState; this.sashDragState.current = current; const delta = current - start; - const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta); + const newDelta = this.resize(index, delta, sizes, undefined, undefined, minDelta, maxDelta, snapIndex, snapLimitDelta); if (alt) { const isLastSash = index === this.sashItems.length - 1; @@ -601,7 +627,9 @@ export class SplitView extends Disposable { lowPriorityIndexes?: number[], highPriorityIndexes?: number[], overloadMinDelta: number = Number.NEGATIVE_INFINITY, - overloadMaxDelta: number = Number.POSITIVE_INFINITY + overloadMaxDelta: number = Number.POSITIVE_INFINITY, + snapIndex?: number, + snapLimitDelta?: number ): number { if (index < 0 || index >= this.viewItems.length) { return 0; @@ -637,6 +665,22 @@ export class SplitView extends Disposable { const minDelta = Math.max(minDeltaUp, minDeltaDown, overloadMinDelta); const maxDelta = Math.min(maxDeltaDown, maxDeltaUp, overloadMaxDelta); + if (typeof snapIndex === 'number' && typeof snapLimitDelta === 'number') { + const snapView = this.viewItems[snapIndex]; + + if (snapIndex === index) { // up + if (delta >= snapLimitDelta) { + snapView.visible = true; + } else { + snapView.visible = false; + } + } else { // down + snapView.visible = delta < snapLimitDelta; + } + + return this.resize(index, delta, sizes, lowPriorityIndexes, highPriorityIndexes, overloadMinDelta, overloadMaxDelta); + } + delta = clamp(delta, minDelta, maxDelta); for (let i = 0, deltaUp = delta; i < upItems.length; i++) { diff --git a/test/splitview/public/index.html b/test/splitview/public/index.html index f20c7961519..dfb7e88bd4b 100644 --- a/test/splitview/public/index.html +++ b/test/splitview/public/index.html @@ -36,7 +36,7 @@ class View { static ID = 0; - constructor() { + constructor(snap) { this.element = document.createElement('div'); this.element.className = 'view'; this.element.style.backgroundColor = `hsl(${rand(1, 360)}, 50%, 70%)`; @@ -44,7 +44,7 @@ this.minimumSize = 100; this.maximumSize = Number.POSITIVE_INFINITY; this.onDidChange = Event.None; - this.snap = true; + this.snap = snap; } layout(size, orientation) { @@ -56,9 +56,9 @@ const splitview = new SplitView(container, {}); splitview.layout(600); - const view1 = new View(); - const view2 = new View(); - const view3 = new View(); + const view1 = new View(true); + const view2 = new View(false); + const view3 = new View(true); splitview.addView(view1, Sizing.Distribute); splitview.addView(view2, Sizing.Distribute); From 557a38f352bd7a3590c2cc1a3a9a572a33c3c42e Mon Sep 17 00:00:00 2001 From: Connor Peet Date: Wed, 10 Jul 2019 10:35:14 -0700 Subject: [PATCH 09/93] fix(sash): dragging being difficult with iframe-containing extensions It appears that (running querySelector, getElementByTagName) that the contents of electron's ``, which contain the iframe, are inaccessible. We were already disabling pointer events on iframes, this PR makes sure we do so on webviews as well. --- src/vs/base/browser/ui/sash/sash.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 3e0efee82c9..18c4b4a4903 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -212,7 +212,13 @@ export class Sash extends Disposable { return; } - const iframes = getElementsByTagName('iframe'); + // Select both iframes and webviews; internally Electron nests an iframe + // in its component, but this isn't queryable. + const iframes = [ + ...getElementsByTagName('iframe'), + ...getElementsByTagName('webview'), + ]; + for (const iframe of iframes) { iframe.style.pointerEvents = 'none'; // disable mouse events on iframes as long as we drag the sash } From 3731042835fb46a8db846d921c8f28b5b81a1633 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Jul 2019 10:34:00 -0700 Subject: [PATCH 10/93] Don't show quick fix link in hovers until we know we have quick fixes Fixes #71579 **Bug** We currently always show the `quick fix` button in problem hovers. This has confused a lot of users (see #71579) because we lead them to think that every error has a quick fix **Fix** Only show the quick fix button when we have known quick fixes --- .../contrib/codeAction/codeActionCommands.ts | 2 +- .../editor/contrib/codeAction/codeActionUi.ts | 10 +-- .../editor/contrib/hover/modesContentHover.ts | 62 ++++++++++--------- 3 files changed, 36 insertions(+), 38 deletions(-) diff --git a/src/vs/editor/contrib/codeAction/codeActionCommands.ts b/src/vs/editor/contrib/codeAction/codeActionCommands.ts index 4484c4405dc..1b76fa157ee 100644 --- a/src/vs/editor/contrib/codeAction/codeActionCommands.ts +++ b/src/vs/editor/contrib/codeAction/codeActionCommands.ts @@ -80,7 +80,7 @@ export class QuickFixController extends Disposable implements IEditorContributio this._ui.update(newState); } - public showCodeActions(actions: Promise, at: IAnchor | IPosition) { + public showCodeActions(actions: CodeActionSet, at: IAnchor | IPosition) { return this._ui.showCodeActionList(actions, at); } diff --git a/src/vs/editor/contrib/codeAction/codeActionUi.ts b/src/vs/editor/contrib/codeAction/codeActionUi.ts index 8b5bf92538d..a496f3e708f 100644 --- a/src/vs/editor/contrib/codeAction/codeActionUi.ts +++ b/src/vs/editor/contrib/codeAction/codeActionUi.ts @@ -95,15 +95,7 @@ export class CodeActionUi extends Disposable { } } - public async showCodeActionList(codeActions: Promise, at?: IAnchor | IPosition): Promise { - let actions: CodeActionSet; - try { - actions = await codeActions; - } catch (e) { - onUnexpectedError(e); - return; - } - + public async showCodeActionList(actions: CodeActionSet, at?: IAnchor | IPosition): Promise { this._codeActionWidget.show(actions, at); } diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index 356cc653aff..bea566d9403 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -13,7 +13,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ModelDecorationOptions } from 'vs/editor/common/model/textModel'; -import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor, CodeAction } from 'vs/editor/common/modes'; +import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor } from 'vs/editor/common/modes'; import { getColorPresentations } from 'vs/editor/contrib/colorPicker/color'; import { ColorDetector } from 'vs/editor/contrib/colorPicker/colorDetector'; import { ColorPickerModel } from 'vs/editor/contrib/colorPicker/colorPickerModel'; @@ -518,21 +518,6 @@ export class ModesContentHoverWidget extends ContentHoverWidget { const hoverElement = $('div.hover-row.status-bar'); const disposables = new DisposableStore(); const actionsElement = dom.append(hoverElement, $('div.actions')); - disposables.add(this.renderAction(actionsElement, { - label: nls.localize('quick fixes', "Quick Fix..."), - commandId: QuickFixAction.Id, - run: async (target) => { - const codeActionsPromise = this.getCodeActions(markerHover.marker); - disposables.add(toDisposable(() => codeActionsPromise.cancel())); - - const controller = QuickFixController.get(this._editor); - const elementPosition = dom.getDomNodePagePosition(target); - controller.showCodeActions(codeActionsPromise, { - x: elementPosition.left + 6, - y: elementPosition.top + elementPosition.height + 6 - }); - } - })); if (markerHover.marker.severity === MarkerSeverity.Error || markerHover.marker.severity === MarkerSeverity.Warning || markerHover.marker.severity === MarkerSeverity.Info) { disposables.add(this.renderAction(actionsElement, { label: nls.localize('peek problem', "Peek Problem"), @@ -544,27 +529,48 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } })); } + + const codeActionsPromise = this.getCodeActions(markerHover.marker); + disposables.add(toDisposable(() => codeActionsPromise.cancel())); + codeActionsPromise.then(actions => { + if (!actions.actions.length) { + actions.dispose(); + return; + } + let showing = false; + + disposables.add(toDisposable(() => { + if (!showing) { + actions.dispose(); + } + })); + + disposables.add(this.renderAction(actionsElement, { + label: nls.localize('quick fixes', "Quick Fix..."), + commandId: QuickFixAction.Id, + run: (target) => { + showing = true; + const controller = QuickFixController.get(this._editor); + const elementPosition = dom.getDomNodePagePosition(target); + controller.showCodeActions(actions, { + x: elementPosition.left + 6, + y: elementPosition.top + elementPosition.height + 6 + }); + } + })); + }); + this.renderDisposable.value = disposables; return hoverElement; } private getCodeActions(marker: IMarker): CancelablePromise { - const noAction: CodeAction = { - title: nls.localize('editor.action.quickFix.noneMessage', "No code actions available"), - kind: CodeActionKind.QuickFix.value, - }; - return createCancelablePromise(async (cancellationToken): Promise => { - const result = await getCodeActions( + return createCancelablePromise(cancellationToken => { + return getCodeActions( this._editor.getModel()!, new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn), { type: 'manual', filter: { kind: CodeActionKind.QuickFix } }, cancellationToken); - - return { - actions: result.actions.length ? result.actions : [noAction], - hasAutoFix: result.hasAutoFix, - dispose: () => result.dispose(), - }; }); } From f9517d6e5d5b1f635ed1e4e2034afe4c0c752e8b Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Jul 2019 11:44:28 -0700 Subject: [PATCH 11/93] Add progress indicator --- src/vs/editor/contrib/hover/modesContentHover.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index bea566d9403..f3590e2f3c4 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -530,15 +530,21 @@ export class ModesContentHoverWidget extends ContentHoverWidget { })); } + const quickfixPlaceholderElement = dom.append(actionsElement, $('div')); + quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."); + disposables.add(toDisposable(() => quickfixPlaceholderElement.remove())); + const codeActionsPromise = this.getCodeActions(markerHover.marker); disposables.add(toDisposable(() => codeActionsPromise.cancel())); codeActionsPromise.then(actions => { if (!actions.actions.length) { actions.dispose(); + quickfixPlaceholderElement.textContent = nls.localize('noQuickFixes', "No quick fixes available"); return; } - let showing = false; + quickfixPlaceholderElement.remove(); + let showing = false; disposables.add(toDisposable(() => { if (!showing) { actions.dispose(); From 24cd503cbd6f4a859fe6630a73303970b0233a69 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Jul 2019 13:56:21 -0700 Subject: [PATCH 12/93] Add slight delay + fade in for quick fix message --- src/vs/editor/contrib/hover/modesContentHover.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/vs/editor/contrib/hover/modesContentHover.ts b/src/vs/editor/contrib/hover/modesContentHover.ts index f3590e2f3c4..5e8ccc2801d 100644 --- a/src/vs/editor/contrib/hover/modesContentHover.ts +++ b/src/vs/editor/contrib/hover/modesContentHover.ts @@ -531,12 +531,19 @@ export class ModesContentHoverWidget extends ContentHoverWidget { } const quickfixPlaceholderElement = dom.append(actionsElement, $('div')); + quickfixPlaceholderElement.style.opacity = '0'; + quickfixPlaceholderElement.style.transition = 'opacity 0.2s'; + setTimeout(() => quickfixPlaceholderElement.style.opacity = '1', 200); quickfixPlaceholderElement.textContent = nls.localize('checkingForQuickFixes', "Checking for quick fixes..."); disposables.add(toDisposable(() => quickfixPlaceholderElement.remove())); + const codeActionsPromise = this.getCodeActions(markerHover.marker); disposables.add(toDisposable(() => codeActionsPromise.cancel())); codeActionsPromise.then(actions => { + quickfixPlaceholderElement.style.transition = ''; + quickfixPlaceholderElement.style.opacity = '1'; + if (!actions.actions.length) { actions.dispose(); quickfixPlaceholderElement.textContent = nls.localize('noQuickFixes', "No quick fixes available"); From 924cda47bddf9844b7834b02795082a3536c8019 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Jul 2019 15:37:33 -0700 Subject: [PATCH 13/93] Make sure we handle the Disposable returned from showActivity --- src/vs/workbench/contrib/markers/browser/markers.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/markers/browser/markers.ts b/src/vs/workbench/contrib/markers/browser/markers.ts index a8eeb539c22..4b27488a458 100644 --- a/src/vs/workbench/contrib/markers/browser/markers.ts +++ b/src/vs/workbench/contrib/markers/browser/markers.ts @@ -5,7 +5,7 @@ import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import { MarkersModel, compareMarkersByUri } from './markersModel'; -import { Disposable } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable, IDisposable } from 'vs/base/common/lifecycle'; import { IMarkerService, MarkerSeverity, IMarker } from 'vs/platform/markers/common/markers'; import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity'; import { localize } from 'vs/nls'; @@ -59,6 +59,8 @@ export class MarkersWorkbenchService extends Disposable implements IMarkersWorkb export class ActivityUpdater extends Disposable implements IWorkbenchContribution { + private readonly activity = this._register(new MutableDisposable()); + constructor( @IActivityService private readonly activityService: IActivityService, @IMarkerService private readonly markerService: IMarkerService @@ -72,6 +74,6 @@ export class ActivityUpdater extends Disposable implements IWorkbenchContributio const { errors, warnings, infos } = this.markerService.getStatistics(); const total = errors + warnings + infos; const message = localize('totalProblems', 'Total {0} Problems', total); - this.activityService.showActivity(Constants.MARKERS_PANEL_ID, new NumberBadge(total, () => message)); + this.activity.value = this.activityService.showActivity(Constants.MARKERS_PANEL_ID, new NumberBadge(total, () => message)); } } \ No newline at end of file From 4278033408310514dd485fdd09740b833ab405e1 Mon Sep 17 00:00:00 2001 From: Matt Bierner Date: Wed, 10 Jul 2019 16:25:17 -0700 Subject: [PATCH 14/93] Avoid using untracked IDisposables in workbench/contrib/extensions - Use DisposableStore for tracking lists of disposables - Use MutableDisposable to track a value that should be disposed of when the value changes - Extend Disposable where it makes sense or use existing `_register` method - Remove unused disposable member --- .../extensionProfileService.ts | 11 ++-- .../electron-browser/extensionTipsService.ts | 9 +--- .../electron-browser/extensionsViewlet.ts | 54 ++++++------------- .../electron-browser/extensionsWidgets.ts | 28 ++++------ 4 files changed, 32 insertions(+), 70 deletions(-) diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts index 65cbc3a44b1..283c3406d8f 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionProfileService.ts @@ -7,7 +7,7 @@ import * as nls from 'vs/nls'; import { Event, Emitter } from 'vs/base/common/event'; import { IInstantiationService, ServiceIdentifier } from 'vs/platform/instantiation/common/instantiation'; import { IExtensionHostProfile, ProfileSession, IExtensionService } from 'vs/workbench/services/extensions/common/extensions'; -import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { onUnexpectedError } from 'vs/base/common/errors'; import { StatusbarAlignment, IStatusbarService, IStatusbarEntryAccessor, IStatusbarEntry } from 'vs/platform/statusbar/common/statusbar'; import { IExtensionHostProfileService, ProfileSessionState } from 'vs/workbench/contrib/extensions/electron-browser/runtimeExtensionsEditor'; @@ -37,7 +37,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio private _state: ProfileSessionState; private profilingStatusBarIndicator: IStatusbarEntryAccessor | undefined; - private profilingStatusBarIndicatorLabelUpdater: IDisposable | undefined; + private readonly profilingStatusBarIndicatorLabelUpdater = this._register(new MutableDisposable()); public get state() { return this._state; } public get lastProfile() { return this._profile; } @@ -77,10 +77,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio } private updateProfilingStatusBarIndicator(visible: boolean): void { - if (this.profilingStatusBarIndicatorLabelUpdater) { - this.profilingStatusBarIndicatorLabelUpdater.dispose(); - this.profilingStatusBarIndicatorLabelUpdater = undefined; - } + this.profilingStatusBarIndicatorLabelUpdater.clear(); if (visible) { const indicator: IStatusbarEntry = { @@ -95,7 +92,7 @@ export class ExtensionHostProfileService extends Disposable implements IExtensio this.profilingStatusBarIndicator.update({ ...indicator, text: nls.localize('profilingExtensionHostTime', "$(sync~spin) Profiling Extension Host ({0} sec)", Math.round((new Date().getTime() - timeStarted) / 1000)), }); } }, 1000); - this.profilingStatusBarIndicatorLabelUpdater = toDisposable(() => clearInterval(handle)); + this.profilingStatusBarIndicatorLabelUpdater.value = toDisposable(() => clearInterval(handle)); if (!this.profilingStatusBarIndicator) { this.profilingStatusBarIndicator = this._statusbarService.addEntry(indicator, 'status.profiler', nls.localize('status.profiler', "Extension Profiler"), StatusbarAlignment.RIGHT); diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts index f192f1c16d9..32c06169ab1 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionTipsService.ts @@ -6,7 +6,7 @@ import { localize } from 'vs/nls'; import { join } from 'vs/base/common/path'; import { forEach } from 'vs/base/common/collections'; -import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; +import { Disposable } from 'vs/base/common/lifecycle'; import { match } from 'vs/base/common/glob'; import * as json from 'vs/base/common/json'; import { @@ -83,7 +83,6 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private _globallyIgnoredRecommendations: string[] = []; private _workspaceIgnoredRecommendations: string[] = []; private _extensionsRecommendationsUrl: string; - private _disposables: IDisposable[] = []; public loadWorkspaceConfigPromise: Promise; private proactiveRecommendationsFetched: boolean = false; @@ -135,7 +134,7 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe this.loadWorkspaceConfigPromise = this.getWorkspaceRecommendations().then(() => { this.promptWorkspaceRecommendations(); - this._modelService.onModelAdded(this.promptFiletypeBasedRecommendations, this, this._disposables); + this._register(this._modelService.onModelAdded(this.promptFiletypeBasedRecommendations, this)); this._modelService.getModels().forEach(model => this.promptFiletypeBasedRecommendations(model)); }); @@ -1035,8 +1034,4 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe private isExtensionAllowedToBeRecommended(id: string): boolean { return this._allIgnoredRecommendations.indexOf(id.toLowerCase()) === -1; } - - dispose() { - this._disposables = dispose(this._disposables); - } } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts index 3523014aa0b..08345f64cf9 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsViewlet.ts @@ -8,7 +8,7 @@ import { localize } from 'vs/nls'; import { timeout, Delayer } from 'vs/base/common/async'; import { isPromiseCanceledError } from 'vs/base/common/errors'; import { IWorkbenchContribution } from 'vs/workbench/common/contributions'; -import { IDisposable, dispose } from 'vs/base/common/lifecycle'; +import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle'; import { Event as EventOf, Emitter } from 'vs/base/common/event'; import { IAction } from 'vs/base/common/actions'; import { Separator } from 'vs/base/browser/ui/actionbar/actionbar'; @@ -339,7 +339,6 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio private extensionsBox: HTMLElement; private primaryActions: IAction[]; private secondaryActions: IAction[] | null; - private disposables: IDisposable[] = []; private readonly searchViewletState: MementoObject; constructor( @@ -374,14 +373,14 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.recommendedExtensionsContextKey = RecommendedExtensionsContext.bindTo(contextKeyService); this.defaultRecommendedExtensionsContextKey = DefaultRecommendedExtensionsContext.bindTo(contextKeyService); this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); - this.disposables.push(this.viewletService.onDidViewletOpen(this.onViewletOpen, this, this.disposables)); + this._register(this.viewletService.onDidViewletOpen(this.onViewletOpen, this)); this.searchViewletState = this.getMemento(StorageScope.WORKSPACE); this.extensionManagementService.getInstalled(ExtensionType.User).then(result => { this.hasInstalledExtensionsContextKey.set(result.length > 0); }); - this.configurationService.onDidChangeConfiguration(e => { + this._register(this.configurationService.onDidChangeConfiguration(e => { if (e.affectsConfiguration(AutoUpdateConfigurationKey)) { this.secondaryActions = null; this.updateTitleArea(); @@ -389,7 +388,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio if (e.affectedKeys.indexOf(ShowRecommendationsOnlyOnDemandKey) > -1) { this.defaultRecommendedExtensionsContextKey.set(!this.configurationService.getValue(ShowRecommendationsOnlyOnDemandKey)); } - }, this, this.disposables); + }, this)); } create(parent: HTMLElement): void { @@ -401,7 +400,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio const placeholder = localize('searchExtensions', "Search Extensions in Marketplace"); const searchValue = this.searchViewletState['query.value'] ? this.searchViewletState['query.value'] : ''; - this.searchBox = this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { + this.searchBox = this._register(this.instantiationService.createInstance(SuggestEnabledInput, `${VIEWLET_ID}.searchbox`, header, { triggerCharacters: ['@'], sortKey: (item: string) => { if (item.indexOf(':') === -1) { return 'a'; } @@ -410,24 +409,22 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio else { return 'd'; } }, provideResults: (query: string) => Query.suggestions(query) - }, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue }); + }, placeholder, 'extensions:searchinput', { placeholderText: placeholder, value: searchValue })); if (this.searchBox.getValue()) { this.triggerSearch(); } - this.disposables.push(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService)); - - this.disposables.push(this.searchBox); + this._register(attachSuggestEnabledInputBoxStyler(this.searchBox, this.themeService)); const _searchChange = new Emitter(); this.onSearchChange = _searchChange.event; - this.searchBox.onInputDidChange(() => { + this._register(this.searchBox.onInputDidChange(() => { this.triggerSearch(); _searchChange.fire(this.searchBox.getValue()); - }, this, this.disposables); + }, this)); - this.searchBox.onShouldFocusResults(() => this.focusListView(), this, this.disposables); + this._register(this.searchBox.onShouldFocusResults(() => this.focusListView(), this)); this._register(this.onDidChangeVisibility(visible => { if (visible) { @@ -614,52 +611,39 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio this.notificationService.error(err); } - - dispose(): void { - this.disposables = dispose(this.disposables); - super.dispose(); - } } -export class StatusUpdater implements IWorkbenchContribution { +export class StatusUpdater extends Disposable implements IWorkbenchContribution { - private disposables: IDisposable[]; - private badgeHandle: IDisposable; + private readonly badgeHandle = this._register(new MutableDisposable()); constructor( @IActivityService private readonly activityService: IActivityService, @IExtensionsWorkbenchService private readonly extensionsWorkbenchService: IExtensionsWorkbenchService, @IExtensionEnablementService private readonly extensionEnablementService: IExtensionEnablementService ) { - extensionsWorkbenchService.onChange(this.onServiceChange, this, this.disposables); + super(); + this._register(extensionsWorkbenchService.onChange(this.onServiceChange, this)); } private onServiceChange(): void { - - dispose(this.badgeHandle); + this.badgeHandle.clear(); if (this.extensionsWorkbenchService.local.some(e => e.state === ExtensionState.Installing)) { - this.badgeHandle = this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge'); + this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, new ProgressBadge(() => localize('extensions', "Extensions")), 'extensions-badge progress-badge'); return; } const outdated = this.extensionsWorkbenchService.outdated.reduce((r, e) => r + (this.extensionEnablementService.isEnabled(e.local!) ? 1 : 0), 0); if (outdated > 0) { const badge = new NumberBadge(outdated, n => localize('outdatedExtensions', '{0} Outdated Extensions', n)); - this.badgeHandle = this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge'); + this.badgeHandle.value = this.activityService.showActivity(VIEWLET_ID, badge, 'extensions-badge count-badge'); } } - - dispose(): void { - this.disposables = dispose(this.disposables); - dispose(this.badgeHandle); - } } export class MaliciousExtensionChecker implements IWorkbenchContribution { - private disposables: IDisposable[]; - constructor( @IExtensionManagementService private readonly extensionsManagementService: IExtensionManagementService, @IWindowService private readonly windowService: IWindowService, @@ -704,8 +688,4 @@ export class MaliciousExtensionChecker implements IWorkbenchContribution { }).then(() => undefined); }, err => this.logService.error(err)); } - - dispose(): void { - this.disposables = dispose(this.disposables); - } } diff --git a/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts b/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts index c34a342320f..71dff9e58e8 100644 --- a/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts +++ b/src/vs/workbench/contrib/extensions/electron-browser/extensionsWidgets.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import 'vs/css!./media/extensionsWidgets'; -import { Disposable, IDisposable, dispose, toDisposable } from 'vs/base/common/lifecycle'; +import { Disposable, toDisposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle'; import { IExtension, IExtensionsWorkbenchService, IExtensionContainer, ExtensionState } from '../common/extensions'; import { append, $, addClass } from 'vs/base/browser/dom'; import * as platform from 'vs/base/common/platform'; @@ -196,7 +196,7 @@ export class TooltipWidget extends ExtensionWidget { export class RecommendationWidget extends ExtensionWidget { private element?: HTMLElement; - private disposables: IDisposable[] = []; + private readonly disposables = this._register(new DisposableStore()); private _tooltip: string; get tooltip(): string { return this._tooltip; } @@ -227,7 +227,7 @@ export class RecommendationWidget extends ExtensionWidget { this.parent.removeChild(this.element); } this.element = undefined; - this.disposables = dispose(this.disposables); + this.disposables.clear(); } render(): void { @@ -256,8 +256,7 @@ export class RecommendationWidget extends ExtensionWidget { export class RemoteBadgeWidget extends ExtensionWidget { - private remoteBadge: RemoteBadge | null; - private disposables: IDisposable[] = []; + private readonly remoteBadge = this._register(new MutableDisposable()); private element: HTMLElement; @@ -274,12 +273,10 @@ export class RemoteBadgeWidget extends ExtensionWidget { } private clear(): void { - if (this.remoteBadge) { - this.element.removeChild(this.remoteBadge.element); - this.remoteBadge.dispose(); + if (this.remoteBadge.value) { + this.element.removeChild(this.remoteBadge.value.element); } - this.remoteBadge = null; - this.disposables = dispose(this.disposables); + this.remoteBadge.clear(); } render(): void { @@ -288,17 +285,10 @@ export class RemoteBadgeWidget extends ExtensionWidget { return; } if (this.extension.server === this.extensionManagementServerService.remoteExtensionManagementServer) { - this.remoteBadge = this.instantiationService.createInstance(RemoteBadge, this.tooltip); - append(this.element, this.remoteBadge.element); + this.remoteBadge.value = this.instantiationService.createInstance(RemoteBadge, this.tooltip); + append(this.element, this.remoteBadge.value.element); } } - - dispose(): void { - if (this.remoteBadge) { - this.remoteBadge.dispose(); - } - super.dispose(); - } } class RemoteBadge extends Disposable { From c41ecdf384dc3e6dcad12beecb5bd09fd6f6bd95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Moreno?= Date: Thu, 11 Jul 2019 07:47:15 +0200 Subject: [PATCH 15/93] Update .cachesalt --- build/.cachesalt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/.cachesalt b/build/.cachesalt index d9e527ad8ae..105ce86ae3c 100644 --- a/build/.cachesalt +++ b/build/.cachesalt @@ -1 +1 @@ -2019-07-10T05:02:42.950Z +2019-07-11T05:47:05.444Z From bd087c156a8e6bdbd3a7402fca87abb973786956 Mon Sep 17 00:00:00 2001 From: Joao Moreno Date: Thu, 11 Jul 2019 08:06:31 +0200 Subject: [PATCH 16/93] sash: debug --- src/vs/base/browser/ui/sash/sash.ts | 2 +- test/splitview/public/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/base/browser/ui/sash/sash.ts b/src/vs/base/browser/ui/sash/sash.ts index 3e0efee82c9..fb76ba6bd9a 100644 --- a/src/vs/base/browser/ui/sash/sash.ts +++ b/src/vs/base/browser/ui/sash/sash.ts @@ -14,7 +14,7 @@ import { Event, Emitter } from 'vs/base/common/event'; import { getElementsByTagName, EventHelper, createStyleSheet, addDisposableListener, append, $, addClass, removeClass, toggleClass } from 'vs/base/browser/dom'; import { domEvent } from 'vs/base/browser/event'; -const DEBUG = false; +const DEBUG = true; export interface ISashLayoutProvider { } diff --git a/test/splitview/public/index.html b/test/splitview/public/index.html index dfb7e88bd4b..c1a7fcfca89 100644 --- a/test/splitview/public/index.html +++ b/test/splitview/public/index.html @@ -2,7 +2,7 @@ - SplitView + Splitview