66import 'vs/css!./tree' ;
77import { IDisposable , dispose , Disposable , toDisposable } from 'vs/base/common/lifecycle' ;
88import { IListOptions , List , IIdentityProvider , IMultipleSelectionController } from 'vs/base/browser/ui/list/listWidget' ;
9- import { TreeModel , ITreeNode , ITreeElement } from 'vs/base/browser/ui/tree/treeModel' ;
9+ import { TreeModel , ITreeNode , ITreeElement , getNodeLocation } from 'vs/base/browser/ui/tree/treeModel' ;
1010import { IIterator , empty } from 'vs/base/common/iterator' ;
1111import { IDelegate , IRenderer , IListMouseEvent } from 'vs/base/browser/ui/list/list' ;
1212import { append , $ } from 'vs/base/browser/dom' ;
1313import { Event , Relay , chain } from 'vs/base/common/event' ;
1414import { StandardKeyboardEvent } from 'vs/base/browser/keyboardEvent' ;
1515import { KeyCode } from 'vs/base/common/keyCodes' ;
16+ import { tail2 } from 'vs/base/common/arrays' ;
1617
1718function toTreeListOptions < T > ( options ?: IListOptions < T > ) : IListOptions < ITreeNode < T > > {
1819 if ( ! options ) {
@@ -126,17 +127,6 @@ class TreeRenderer<T, TTemplateData> implements IRenderer<ITreeNode<T>, ITreeLis
126127 }
127128}
128129
129- function getLocation < T > ( node : ITreeNode < T > ) : number [ ] {
130- const location = [ ] ;
131-
132- while ( node . parent ) {
133- location . push ( node . parent . children . indexOf ( node ) ) ;
134- node = node . parent ;
135- }
136-
137- return location . reverse ( ) ;
138- }
139-
140130function isInputElement ( e : HTMLElement ) : boolean {
141131 return e . tagName === 'INPUT' || e . tagName === 'TEXTAREA' ;
142132}
@@ -182,7 +172,7 @@ export class Tree<T> implements IDisposable {
182172
183173 private onMouseClick ( e : IListMouseEvent < ITreeNode < T > > ) : void {
184174 const node = e . element ;
185- const location = getLocation ( node ) ;
175+ const location = getNodeLocation ( node ) ;
186176
187177 this . model . toggleCollapsed ( location ) ;
188178 }
@@ -198,12 +188,17 @@ export class Tree<T> implements IDisposable {
198188 }
199189
200190 const node = nodes [ 0 ] ;
201- const location = getLocation ( node ) ;
202- const didCollapse = this . model . setCollapsed ( location , true ) ;
191+ const location = getNodeLocation ( node ) ;
192+ const didChange = this . model . setCollapsed ( location , true ) ;
203193
204- if ( ! didCollapse ) {
205- console . log ( 'should focus parent' ) ;
206- // this.view.setFocus([]);
194+ if ( ! didChange ) {
195+ if ( location . length === 1 ) {
196+ return ;
197+ }
198+
199+ const [ parentLocation ] = tail2 ( location ) ;
200+ const parentListIndex = this . model . getListIndex ( parentLocation ) ;
201+ this . view . setFocus ( [ parentListIndex ] ) ;
207202 }
208203 }
209204
@@ -218,8 +213,17 @@ export class Tree<T> implements IDisposable {
218213 }
219214
220215 const node = nodes [ 0 ] ;
221- const location = getLocation ( node ) ;
222- this . model . setCollapsed ( location , false ) ;
216+ const location = getNodeLocation ( node ) ;
217+ const didChange = this . model . setCollapsed ( location , false ) ;
218+
219+ if ( ! didChange ) {
220+ if ( node . children . length === 0 ) {
221+ return ;
222+ }
223+
224+ const [ focusedIndex ] = this . view . getFocus ( ) ;
225+ this . view . setFocus ( [ focusedIndex + 1 ] ) ;
226+ }
223227 }
224228
225229 private onSpace ( e : StandardKeyboardEvent ) : void {
@@ -233,7 +237,7 @@ export class Tree<T> implements IDisposable {
233237 }
234238
235239 const node = nodes [ 0 ] ;
236- const location = getLocation ( node ) ;
240+ const location = getNodeLocation ( node ) ;
237241 this . model . toggleCollapsed ( location ) ;
238242 }
239243
0 commit comments