From 99c739652fe50d3cf3c36449be59a100ec4ee9b3 Mon Sep 17 00:00:00 2001 From: bendera Date: Sat, 19 Jul 2025 21:18:50 +0200 Subject: [PATCH 1/5] Rewrite the indent guide highlighting logic --- src/vscode-tree-item/vscode-tree-item.ts | 12 +++-- src/vscode-tree/tree-context.ts | 4 +- src/vscode-tree/vscode-tree.ts | 65 +++++++++++------------- 3 files changed, 38 insertions(+), 43 deletions(-) diff --git a/src/vscode-tree-item/vscode-tree-item.ts b/src/vscode-tree-item/vscode-tree-item.ts index 9b20439ca..46733ca9b 100644 --- a/src/vscode-tree-item/vscode-tree-item.ts +++ b/src/vscode-tree-item/vscode-tree-item.ts @@ -120,7 +120,6 @@ export class VscodeTreeItem extends VscElement { hasBranchItem: false, rootElement: null, activeItem: null, - highlightedItems: [], }; @consume({context: configContext, subscribe: true}) @@ -335,9 +334,16 @@ export class VscodeTreeItem extends VscElement { if (isShiftDown && this._configContext.multiSelect) { this._selectRange(); this._treeContextState.emitSelectEvent?.(); + + this.updateComplete.then(() => { + this._treeContextState.highlightIndentGuides?.(); + }); } else { this._selectItem(isCtrlDown); this._treeContextState.emitSelectEvent?.(); + this.updateComplete.then(() => { + this._treeContextState.highlightIndentGuides?.(); + }); if (this._configContext.expandMode === ExpandMode.singleClick) { if (this.branch && !(this._configContext.multiSelect && isCtrlDown)) { @@ -351,10 +357,6 @@ export class VscodeTreeItem extends VscElement { if (!isShiftDown) { this._treeContextState.prevFocusedItem = this; } - - this.updateComplete.then(() => { - this._treeContextState.highlightGuides?.(); - }); } private _handleDoubleClick(ev: MouseEvent) { diff --git a/src/vscode-tree/tree-context.ts b/src/vscode-tree/tree-context.ts index e22a5fa63..870434f73 100644 --- a/src/vscode-tree/tree-context.ts +++ b/src/vscode-tree/tree-context.ts @@ -15,8 +15,8 @@ export interface TreeContext { hasBranchItem: boolean; rootElement: VscodeTree | null; activeItem: VscodeTreeItem | null; - highlightedItems: VscodeTreeItem[]; - highlightGuides?: () => void; + highlightedItems?: Set; + highlightIndentGuides?: () => void; emitSelectEvent?: () => void; } diff --git a/src/vscode-tree/vscode-tree.ts b/src/vscode-tree/vscode-tree.ts index a26efb741..914a1077f 100644 --- a/src/vscode-tree/vscode-tree.ts +++ b/src/vscode-tree/vscode-tree.ts @@ -160,9 +160,9 @@ export class VscodeTree extends VscElement { prevFocusedItem: null, hasBranchItem: false, rootElement: this, - highlightedItems: [], - highlightGuides: () => { - this._highlightGuides(); + highlightedItems: new Set(), + highlightIndentGuides: () => { + this._highlightIndentGuides(); }, emitSelectEvent: () => { this._emitSelectEvent(); @@ -258,43 +258,33 @@ export class VscodeTree extends VscElement { this.dispatchEvent(ev); } - private _highlightGuides() { - const {activeItem, highlightedItems, selectedItems} = - this._treeContextState; - - highlightedItems.forEach((i) => (i.highlightedGuides = false)); - - if (activeItem) { - this._treeContextState.highlightedItems = []; - - if (activeItem.branch && activeItem.open) { - activeItem.highlightedGuides = true; - this._treeContextState.highlightedItems.push(activeItem); - } else { - const parent = findParentItem(activeItem); + private _highlightIndentGuideOfItem(item: VscodeTreeItem) { + if (item.branch && item.open) { + item.highlightedGuides = true; + this._treeContextState.highlightedItems?.add(item); + } else { + const parent = findParentItem(item); - if (parent && parent.branch) { - parent.highlightedGuides = true; - this._treeContextState.highlightedItems.push(parent); - } + if (parent) { + parent.highlightedGuides = true; + this._treeContextState.highlightedItems?.add(parent); } } + } - if (selectedItems) { - selectedItems.forEach((item) => { - if (item.branch && item.open) { - item.highlightedGuides = true; - this._treeContextState.highlightedItems.push(item); - } else { - const parent = findParentItem(item); - - if (parent && parent.branch) { - parent.highlightedGuides = true; - this._treeContextState.highlightedItems.push(item); - } - } - }); + private _highlightIndentGuides() { + this._treeContextState.highlightedItems?.forEach( + (i) => (i.highlightedGuides = false) + ); + this._treeContextState.highlightedItems?.clear(); + + if (this._treeContextState.activeItem) { + this._highlightIndentGuideOfItem(this._treeContextState.activeItem); } + + this._treeContextState.selectedItems.forEach((item) => { + this._highlightIndentGuideOfItem(item); + }); } private _updateConfigContext(changedProperties: PropertyValues) { @@ -326,6 +316,7 @@ export class VscodeTree extends VscElement { item.updateComplete.then(() => { item.focus(); + this._highlightIndentGuides(); }); } @@ -430,6 +421,8 @@ export class VscodeTree extends VscElement { this._treeContextState.selectedItems.forEach( (li) => (li.selected = false) ); + this._treeContextState.selectedItems.clear(); + this._highlightIndentGuides(); focusedItem.selected = true; this._emitSelectEvent(); @@ -497,7 +490,7 @@ export class VscodeTree extends VscElement { } } - this._highlightGuides(); + // this._highlightGuides(); }); }; From af74b35a2b33a469fab9361b8e1888c00bd27489 Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 20 Jul 2025 00:58:29 +0200 Subject: [PATCH 2/5] Update tests --- src/vscode-tree/helpers.test.ts | 129 ++++++++++++++++++++++++++++++-- 1 file changed, 124 insertions(+), 5 deletions(-) diff --git a/src/vscode-tree/helpers.test.ts b/src/vscode-tree/helpers.test.ts index 9a92873a9..2c6375be5 100644 --- a/src/vscode-tree/helpers.test.ts +++ b/src/vscode-tree/helpers.test.ts @@ -1,5 +1,5 @@ import {expect, fixture, html} from '@open-wc/testing'; -import {findLastChildItem, findPrevItem} from './helpers'; +import {findLastChildItem, findNextItem, findPrevItem} from './helpers'; import {VscodeTreeItem} from '../vscode-tree-item'; import '../vscode-tree-item/vscode-tree-item.js'; import {VscodeTree} from './vscode-tree'; @@ -66,7 +66,7 @@ describe('vscode-tree helpers', () => { expect(findPrevItem(item2)).to.eq(item1); }); - it('returns last children of the opened branch', async () => { + it('returns last child of the opened branch', async () => { const el = await fixture(html` @@ -114,16 +114,135 @@ describe('vscode-tree helpers', () => { 1 1.1 - 1.2 + 1.2 + + 1.3 + 1.3.1 + 1.3.2 + 1.3.3 + 2 `); const item1 = el.querySelector('#item1')!; - const item1_2 = el.querySelector('#item1_2')!; + const item1_3_3 = el.querySelector('#item1_3_3')!; + + expect(findLastChildItem(item1)).to.eq(item1_3_3); + }); + + it('does not traverse the closed branches', async () => { + const el = await fixture(html` + + + 1 + 1.1 + 1.2 + + 1.3 + 1.3.1 + 1.3.2 + 1.3.3 + + + 2 + + `); + + const item1 = el.querySelector('#item1')!; + const item1_3 = el.querySelector('#item1_3')!; + + expect(findLastChildItem(item1)).to.eq(item1_3); + }); + + it('returns the passed item if it is not a tree-item', async () => { + const el = await fixture(html`
`); + + expect(findLastChildItem(el as VscodeTreeItem)).to.eq(el); + }); + + it('returns the passed item if it does not have a child', async () => { + await fixture( + html` + leaf + ` + ); + + const item = document.getElementById('leaf')! as VscodeTreeItem; + + expect(findLastChildItem(item)).to.eq(item); + }); + }); + + describe('findNextItem()', () => { + it('returns null if does not have parent element', () => { + const el = document.createElement('vscode-tree-item'); + + expect(findNextItem(el)).to.be.null; + }); + + it('returns null if it is not a tree item', async () => { + const el = await fixture( + html`
` + ); + + expect(findNextItem(el.querySelector('#item') as VscodeTreeItem)).to.be + .null; + }); + + it('returns last children of the opened branch', async () => { + const el = await fixture(html` + + + 1 + 1.1 + 1.2 + + 2 + + `); + + const item1 = el.querySelector('#item1')!; + const item1_1 = el.querySelector('#item1_1')!; + + expect(findNextItem(item1)).to.eq(item1_1); + }); + + it('returns the next sibling if the opened branch does not contain any item', async () => { + const el = await fixture(html` + + 1 + 2 + + `); + + const item1 = el.querySelector('#item1')!; + const item2 = el.querySelector('#item2')!; + + expect(findNextItem(item1)).to.eq(item2); + }); + + it('returns the next ancestor', async () => { + const el = await fixture(html` + + + 1 + + 1.1 + + 1.1.1 + + + + 2 + + `); + + const item1_1_1 = el.querySelector('#item1_1_1')!; + const item2 = el.querySelector('#item2')!; - expect(findLastChildItem(item1)).to.eq(item1_2); + expect(findNextItem(item1_1_1)).to.eq(item2); }); }); }); From 6753f26bf1b3ab7efa989194678d5f90988ad2bc Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 20 Jul 2025 01:21:36 +0200 Subject: [PATCH 3/5] Skip indent guide highlighting if possible --- src/vscode-tree/vscode-tree.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/vscode-tree/vscode-tree.ts b/src/vscode-tree/vscode-tree.ts index 914a1077f..3248efe93 100644 --- a/src/vscode-tree/vscode-tree.ts +++ b/src/vscode-tree/vscode-tree.ts @@ -273,6 +273,10 @@ export class VscodeTree extends VscElement { } private _highlightIndentGuides() { + if (this.indentGuides === IndentGuides.none) { + return; + } + this._treeContextState.highlightedItems?.forEach( (i) => (i.highlightedGuides = false) ); From 7a2467f991873fa5c20b8e777c41dcd6374b93db Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 20 Jul 2025 01:23:30 +0200 Subject: [PATCH 4/5] Remove commented out code --- src/vscode-tree/vscode-tree.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vscode-tree/vscode-tree.ts b/src/vscode-tree/vscode-tree.ts index 3248efe93..733650640 100644 --- a/src/vscode-tree/vscode-tree.ts +++ b/src/vscode-tree/vscode-tree.ts @@ -493,8 +493,6 @@ export class VscodeTree extends VscElement { firstChild.active = true; } } - - // this._highlightGuides(); }); }; From 957a64e8b827c773d89269d5707648dbc1535e21 Mon Sep 17 00:00:00 2001 From: bendera Date: Sun, 20 Jul 2025 01:24:32 +0200 Subject: [PATCH 5/5] Prettier fix --- src/vscode-tree/helpers.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/vscode-tree/helpers.test.ts b/src/vscode-tree/helpers.test.ts index 2c6375be5..fbc665d92 100644 --- a/src/vscode-tree/helpers.test.ts +++ b/src/vscode-tree/helpers.test.ts @@ -230,9 +230,7 @@ describe('vscode-tree helpers', () => { 1 1.1 - - 1.1.1 - + 1.1.1 2