Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
ec9a617c
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ec9a617c
编写于
9月 09, 2019
作者:
J
Joao Moreno
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'joao/fix-78388'
上级
f8ba99ba
6921a8c3
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
184 addition
and
32 deletion
+184
-32
src/vs/base/browser/ui/tree/abstractTree.ts
src/vs/base/browser/ui/tree/abstractTree.ts
+12
-6
src/vs/base/browser/ui/tree/asyncDataTree.ts
src/vs/base/browser/ui/tree/asyncDataTree.ts
+11
-2
src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts
src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts
+9
-0
src/vs/base/browser/ui/tree/indexTreeModel.ts
src/vs/base/browser/ui/tree/indexTreeModel.ts
+49
-14
src/vs/base/browser/ui/tree/objectTreeModel.ts
src/vs/base/browser/ui/tree/objectTreeModel.ts
+5
-0
src/vs/base/browser/ui/tree/tree.ts
src/vs/base/browser/ui/tree/tree.ts
+1
-0
src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts
src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts
+34
-0
src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts
src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts
+61
-0
src/vs/workbench/browser/parts/views/customView.ts
src/vs/workbench/browser/parts/views/customView.ts
+2
-10
未找到文件。
src/vs/base/browser/ui/tree/abstractTree.ts
浏览文件 @
ec9a617c
...
...
@@ -1053,13 +1053,15 @@ class TreeNodeListMouseController<T, TFilterData, TRef> extends MouseController<
return
super
.
onPointer
(
e
);
}
const
model
=
((
this
.
tree
as
any
).
model
as
ITreeModel
<
T
,
TFilterData
,
TRef
>
);
// internal
const
location
=
model
.
getNodeLocation
(
node
);
const
recursive
=
e
.
browserEvent
.
altKey
;
model
.
setCollapsed
(
location
,
undefined
,
recursive
);
if
(
node
.
collapsible
)
{
const
model
=
((
this
.
tree
as
any
).
model
as
ITreeModel
<
T
,
TFilterData
,
TRef
>
);
// internal
const
location
=
model
.
getNodeLocation
(
node
);
const
recursive
=
e
.
browserEvent
.
altKey
;
model
.
setCollapsed
(
location
,
undefined
,
recursive
);
if
(
expandOnlyOnTwistieClick
&&
onTwistie
)
{
return
;
if
(
expandOnlyOnTwistieClick
&&
onTwistie
)
{
return
;
}
}
super
.
onPointer
(
e
);
...
...
@@ -1418,6 +1420,10 @@ export abstract class AbstractTree<T, TFilterData, TRef> implements IDisposable
return
this
.
model
.
isCollapsible
(
location
);
}
setCollapsible
(
location
:
TRef
,
collapsible
?:
boolean
):
boolean
{
return
this
.
model
.
setCollapsible
(
location
,
collapsible
);
}
isCollapsed
(
location
:
TRef
):
boolean
{
return
this
.
model
.
isCollapsed
(
location
);
}
...
...
src/vs/base/browser/ui/tree/asyncDataTree.ts
浏览文件 @
ec9a617c
...
...
@@ -451,7 +451,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
const
viewStateContext
=
viewState
&&
{
viewState
,
focus
:
[],
selection
:
[]
}
as
IAsyncDataTreeViewStateContext
<
TInput
,
T
>
;
await
this
.
updateChildren
(
input
,
true
,
viewStateContext
);
await
this
.
_
updateChildren
(
input
,
true
,
viewStateContext
);
if
(
viewStateContext
)
{
this
.
tree
.
setFocus
(
viewStateContext
.
focus
);
...
...
@@ -463,7 +463,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
}
}
async
updateChildren
(
element
:
TInput
|
T
=
this
.
root
.
element
,
recursive
=
true
,
viewStateContext
?:
IAsyncDataTreeViewStateContext
<
TInput
,
T
>
):
Promise
<
void
>
{
async
updateChildren
(
element
:
TInput
|
T
=
this
.
root
.
element
,
recursive
=
true
):
Promise
<
void
>
{
await
this
.
_updateChildren
(
element
,
recursive
);
}
private
async
_updateChildren
(
element
:
TInput
|
T
=
this
.
root
.
element
,
recursive
=
true
,
viewStateContext
?:
IAsyncDataTreeViewStateContext
<
TInput
,
T
>
):
Promise
<
void
>
{
if
(
typeof
this
.
root
.
element
===
'
undefined
'
)
{
throw
new
TreeError
(
this
.
user
,
'
Tree input not set
'
);
}
...
...
@@ -874,6 +878,11 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
private
render
(
node
:
IAsyncDataTreeNode
<
TInput
,
T
>
,
viewStateContext
?:
IAsyncDataTreeViewStateContext
<
TInput
,
T
>
):
void
{
const
children
=
node
.
children
.
map
(
c
=>
asTreeElement
(
c
,
viewStateContext
));
this
.
tree
.
setChildren
(
node
===
this
.
root
?
null
:
node
,
children
);
if
(
node
!==
this
.
root
)
{
this
.
tree
.
setCollapsible
(
node
,
node
.
hasChildren
);
}
this
.
_onDidRender
.
fire
();
}
...
...
src/vs/base/browser/ui/tree/compressedObjectTreeModel.ts
浏览文件 @
ec9a617c
...
...
@@ -231,6 +231,11 @@ export class CompressedTreeModel<T extends NonNullable<any>, TFilterData extends
return
this
.
model
.
isCollapsible
(
compressedNode
);
}
setCollapsible
(
location
:
T
|
null
,
collapsible
?:
boolean
):
boolean
{
const
compressedNode
=
this
.
getCompressedNode
(
location
);
return
this
.
model
.
setCollapsible
(
compressedNode
,
collapsible
);
}
isCollapsed
(
location
:
T
|
null
):
boolean
{
const
compressedNode
=
this
.
getCompressedNode
(
location
);
return
this
.
model
.
isCollapsed
(
compressedNode
);
...
...
@@ -397,6 +402,10 @@ export class CompressedObjectTreeModel<T extends NonNullable<any>, TFilterData e
return
this
.
model
.
isCollapsible
(
location
);
}
setCollapsible
(
location
:
T
|
null
,
collapsed
?:
boolean
):
boolean
{
return
this
.
model
.
setCollapsible
(
location
,
collapsed
);
}
isCollapsed
(
location
:
T
|
null
):
boolean
{
return
this
.
model
.
isCollapsed
(
location
);
}
...
...
src/vs/base/browser/ui/tree/indexTreeModel.ts
浏览文件 @
ec9a617c
...
...
@@ -46,6 +46,21 @@ export interface IIndexTreeModelOptions<T, TFilterData> {
readonly
autoExpandSingleChildren
?:
boolean
;
}
interface
CollapsibleStateUpdate
{
readonly
collapsible
:
boolean
;
}
interface
CollapsedStateUpdate
{
readonly
collapsed
:
boolean
;
readonly
recursive
:
boolean
;
}
type
CollapseStateUpdate
=
CollapsibleStateUpdate
|
CollapsedStateUpdate
;
function
isCollapsibleStateUpdate
(
update
:
CollapseStateUpdate
):
update
is
CollapsibleStateUpdate
{
return
typeof
(
update
as
any
).
collapsible
===
'
boolean
'
;
}
export
class
IndexTreeModel
<
T
extends
Exclude
<
any
,
undefined
>
,
TFilterData
=
void
>
implements
ITreeModel
<
T
,
TFilterData
,
number
[]
>
{
readonly
rootRef
=
[];
...
...
@@ -205,6 +220,17 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
return
this
.
getTreeNode
(
location
).
collapsible
;
}
setCollapsible
(
location
:
number
[],
collapsible
?:
boolean
):
boolean
{
const
node
=
this
.
getTreeNode
(
location
);
if
(
typeof
collapsible
===
'
undefined
'
)
{
collapsible
=
!
node
.
collapsible
;
}
const
update
:
CollapsibleStateUpdate
=
{
collapsible
};
return
this
.
eventBufferer
.
bufferEvents
(()
=>
this
.
_setCollapseState
(
location
,
update
));
}
isCollapsed
(
location
:
number
[]):
boolean
{
return
this
.
getTreeNode
(
location
).
collapsed
;
}
...
...
@@ -216,15 +242,16 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
collapsed
=
!
node
.
collapsed
;
}
return
this
.
eventBufferer
.
bufferEvents
(()
=>
this
.
_setCollapsed
(
location
,
collapsed
!
,
recursive
));
const
update
:
CollapsedStateUpdate
=
{
collapsed
,
recursive
:
recursive
||
false
};
return
this
.
eventBufferer
.
bufferEvents
(()
=>
this
.
_setCollapseState
(
location
,
update
));
}
private
_setCollapse
d
(
location
:
number
[],
collapsed
:
boolean
,
recursive
?:
boolean
):
boolean
{
private
_setCollapse
State
(
location
:
number
[],
update
:
CollapseStateUpdate
):
boolean
{
const
{
node
,
listIndex
,
revealed
}
=
this
.
getTreeNodeWithListIndex
(
location
);
const
result
=
this
.
_setListNodeCollapse
d
(
node
,
listIndex
,
revealed
,
collapsed
!
,
recursive
||
fals
e
);
const
result
=
this
.
_setListNodeCollapse
State
(
node
,
listIndex
,
revealed
,
updat
e
);
if
(
node
!==
this
.
root
&&
this
.
autoExpandSingleChildren
&&
!
collapsed
!
&&
!
recursive
)
{
if
(
node
!==
this
.
root
&&
this
.
autoExpandSingleChildren
&&
result
&&
!
isCollapsibleStateUpdate
(
update
)
&&
node
.
collapsible
&&
!
node
.
collapsed
&&
!
update
.
recursive
)
{
let
onlyVisibleChildIndex
=
-
1
;
for
(
let
i
=
0
;
i
<
node
.
children
.
length
;
i
++
)
{
...
...
@@ -241,15 +268,15 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
}
if
(
onlyVisibleChildIndex
>
-
1
)
{
this
.
_setCollapse
d
([...
location
,
onlyVisibleChildIndex
],
false
,
fals
e
);
this
.
_setCollapse
State
([...
location
,
onlyVisibleChildIndex
],
updat
e
);
}
}
return
result
;
}
private
_setListNodeCollapse
d
(
node
:
IMutableTreeNode
<
T
,
TFilterData
>
,
listIndex
:
number
,
revealed
:
boolean
,
collapsed
:
boolean
,
recursive
:
boolean
):
boolean
{
const
result
=
this
.
_setNodeCollapse
d
(
node
,
collapsed
,
recursiv
e
,
false
);
private
_setListNodeCollapse
State
(
node
:
IMutableTreeNode
<
T
,
TFilterData
>
,
listIndex
:
number
,
revealed
:
boolean
,
update
:
CollapseStateUpdate
):
boolean
{
const
result
=
this
.
_setNodeCollapse
State
(
node
,
updat
e
,
false
);
if
(
!
revealed
||
!
node
.
visible
)
{
return
result
;
...
...
@@ -263,20 +290,28 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
return
result
;
}
private
_setNodeCollapse
d
(
node
:
IMutableTreeNode
<
T
,
TFilterData
>
,
collapsed
:
boolean
,
recursive
:
boolean
,
deep
:
boolean
):
boolean
{
let
result
=
node
.
collapsible
&&
node
.
collapsed
!==
collapsed
;
private
_setNodeCollapse
State
(
node
:
IMutableTreeNode
<
T
,
TFilterData
>
,
update
:
CollapseStateUpdate
,
deep
:
boolean
):
boolean
{
let
result
:
boolean
;
if
(
node
.
collapsible
)
{
node
.
collapsed
=
collapsed
;
if
(
node
===
this
.
root
)
{
result
=
false
;
}
else
{
if
(
isCollapsibleStateUpdate
(
update
))
{
result
=
node
.
collapsible
!==
update
.
collapsible
;
node
.
collapsible
=
update
.
collapsible
;
}
else
{
result
=
node
.
collapsed
!==
update
.
collapsed
;
node
.
collapsed
=
update
.
collapsed
;
}
if
(
result
)
{
this
.
_onDidChangeCollapseState
.
fire
({
node
,
deep
});
}
}
if
(
recursive
)
{
if
(
!
isCollapsibleStateUpdate
(
update
)
&&
update
.
recursive
)
{
for
(
const
child
of
node
.
children
)
{
result
=
this
.
_setNodeCollapse
d
(
child
,
collapsed
,
tru
e
,
true
)
||
result
;
result
=
this
.
_setNodeCollapse
State
(
child
,
updat
e
,
true
)
||
result
;
}
}
...
...
@@ -292,7 +327,7 @@ export class IndexTreeModel<T extends Exclude<any, undefined>, TFilterData = voi
location
=
location
.
slice
(
0
,
location
.
length
-
1
);
if
(
node
.
collapsed
)
{
this
.
_setCollapse
d
(
location
,
false
);
this
.
_setCollapse
State
(
location
,
{
collapsed
:
false
,
recursive
:
false
}
);
}
}
});
...
...
src/vs/base/browser/ui/tree/objectTreeModel.ts
浏览文件 @
ec9a617c
...
...
@@ -216,6 +216,11 @@ export class ObjectTreeModel<T extends NonNullable<any>, TFilterData extends Non
return
this
.
model
.
isCollapsible
(
location
);
}
setCollapsible
(
element
:
T
|
null
,
collapsible
?:
boolean
):
boolean
{
const
location
=
this
.
getElementLocation
(
element
);
return
this
.
model
.
setCollapsible
(
location
,
collapsible
);
}
isCollapsed
(
element
:
T
|
null
):
boolean
{
const
location
=
this
.
getElementLocation
(
element
);
return
this
.
model
.
isCollapsed
(
location
);
...
...
src/vs/base/browser/ui/tree/tree.ts
浏览文件 @
ec9a617c
...
...
@@ -120,6 +120,7 @@ export interface ITreeModel<T, TFilterData, TRef> {
getLastElementAncestor
(
location
?:
TRef
):
T
|
undefined
;
isCollapsible
(
location
:
TRef
):
boolean
;
setCollapsible
(
location
:
TRef
,
collapsible
?:
boolean
):
boolean
;
isCollapsed
(
location
:
TRef
):
boolean
;
setCollapsed
(
location
:
TRef
,
collapsed
?:
boolean
,
recursive
?:
boolean
):
boolean
;
expandTo
(
location
:
TRef
):
void
;
...
...
src/vs/base/test/browser/ui/tree/asyncDataTree.test.ts
浏览文件 @
ec9a617c
...
...
@@ -355,4 +355,38 @@ suite('AsyncDataTree', function () {
race
=
await
Promise
.
race
([
pExpandA
.
then
(()
=>
'
expand
'
),
timeout
(
1
).
then
(()
=>
'
timeout
'
)]);
assert
.
equal
(
race
,
'
expand
'
,
'
expand(a) should now be done
'
);
});
test
(
'
issue #78388 - tree should react to hasChildren toggles
'
,
async
()
=>
{
const
container
=
document
.
createElement
(
'
div
'
);
const
model
=
new
Model
({
id
:
'
root
'
,
children
:
[{
id
:
'
a
'
}]
});
const
tree
=
new
AsyncDataTree
<
Element
,
Element
>
(
'
test
'
,
container
,
new
VirtualDelegate
(),
[
new
Renderer
()],
new
DataSource
(),
{
identityProvider
:
new
IdentityProvider
()
});
tree
.
layout
(
200
);
await
tree
.
setInput
(
model
.
root
);
assert
.
equal
(
container
.
querySelectorAll
(
'
.monaco-list-row
'
).
length
,
1
);
let
twistie
=
container
.
querySelector
(
'
.monaco-list-row:first-child .monaco-tl-twistie
'
)
as
HTMLElement
;
assert
(
!
hasClass
(
twistie
,
'
collapsible
'
));
assert
(
!
hasClass
(
twistie
,
'
collapsed
'
));
model
.
get
(
'
a
'
).
children
=
[{
id
:
'
aa
'
}];
await
tree
.
updateChildren
(
model
.
get
(
'
a
'
),
false
);
assert
.
equal
(
container
.
querySelectorAll
(
'
.monaco-list-row
'
).
length
,
1
);
twistie
=
container
.
querySelector
(
'
.monaco-list-row:first-child .monaco-tl-twistie
'
)
as
HTMLElement
;
assert
(
hasClass
(
twistie
,
'
collapsible
'
));
assert
(
hasClass
(
twistie
,
'
collapsed
'
));
model
.
get
(
'
a
'
).
children
=
[];
await
tree
.
updateChildren
(
model
.
get
(
'
a
'
),
false
);
assert
.
equal
(
container
.
querySelectorAll
(
'
.monaco-list-row
'
).
length
,
1
);
twistie
=
container
.
querySelector
(
'
.monaco-list-row:first-child .monaco-tl-twistie
'
)
as
HTMLElement
;
assert
(
!
hasClass
(
twistie
,
'
collapsible
'
));
assert
(
!
hasClass
(
twistie
,
'
collapsed
'
));
});
});
src/vs/base/test/browser/ui/tree/indexTreeModel.test.ts
浏览文件 @
ec9a617c
...
...
@@ -333,6 +333,67 @@ suite('IndexTreeModel', function () {
assert
.
deepEqual
(
toArray
(
list
),
[
1
,
11
,
2
]);
});
test
(
'
setCollapsible
'
,
()
=>
{
const
list
:
ITreeNode
<
number
>
[]
=
[];
const
model
=
new
IndexTreeModel
<
number
>
(
'
test
'
,
toSpliceable
(
list
),
-
1
);
model
.
splice
([
0
],
0
,
Iterator
.
fromArray
([
{
element
:
0
,
children
:
Iterator
.
fromArray
([
{
element
:
10
}
])
}
]));
assert
.
deepEqual
(
list
.
length
,
2
);
model
.
setCollapsible
([
0
],
false
);
assert
.
deepEqual
(
list
.
length
,
2
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
false
);
assert
.
deepEqual
(
list
[
1
].
element
,
10
);
assert
.
deepEqual
(
list
[
1
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
1
].
collapsed
,
false
);
model
.
setCollapsed
([
0
],
true
);
assert
.
deepEqual
(
list
.
length
,
1
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
true
);
model
.
setCollapsed
([
0
],
false
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
false
);
assert
.
deepEqual
(
list
[
1
].
element
,
10
);
assert
.
deepEqual
(
list
[
1
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
1
].
collapsed
,
false
);
model
.
setCollapsible
([
0
],
true
);
assert
.
deepEqual
(
list
.
length
,
2
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
true
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
false
);
assert
.
deepEqual
(
list
[
1
].
element
,
10
);
assert
.
deepEqual
(
list
[
1
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
1
].
collapsed
,
false
);
model
.
setCollapsed
([
0
],
true
);
assert
.
deepEqual
(
list
.
length
,
1
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
true
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
true
);
model
.
setCollapsed
([
0
],
false
);
assert
.
deepEqual
(
list
[
0
].
element
,
0
);
assert
.
deepEqual
(
list
[
0
].
collapsible
,
true
);
assert
.
deepEqual
(
list
[
0
].
collapsed
,
false
);
assert
.
deepEqual
(
list
[
1
].
element
,
10
);
assert
.
deepEqual
(
list
[
1
].
collapsible
,
false
);
assert
.
deepEqual
(
list
[
1
].
collapsed
,
false
);
});
test
(
'
simple filter
'
,
function
()
{
const
list
:
ITreeNode
<
number
>
[]
=
[];
const
filter
=
new
class
implements
ITreeFilter
<
number
>
{
...
...
src/vs/workbench/browser/parts/views/customView.ts
浏览文件 @
ec9a617c
...
...
@@ -597,16 +597,8 @@ export class CustomTreeView extends Disposable implements ITreeView {
const
tree
=
this
.
tree
;
if
(
tree
)
{
this
.
refreshing
=
true
;
const
parents
:
Set
<
ITreeItem
>
=
new
Set
<
ITreeItem
>
();
elements
.
forEach
(
element
=>
{
if
(
element
!==
this
.
root
)
{
const
parent
=
tree
.
getParentElement
(
element
);
parents
.
add
(
parent
);
}
else
{
parents
.
add
(
element
);
}
});
await
Promise
.
all
(
Array
.
from
(
parents
.
values
()).
map
(
element
=>
tree
.
updateChildren
(
element
,
true
)));
await
Promise
.
all
(
elements
.
map
(
element
=>
tree
.
updateChildren
(
element
,
true
)));
elements
.
map
(
element
=>
tree
.
rerender
(
element
));
this
.
refreshing
=
false
;
this
.
updateContentAreas
();
if
(
this
.
focused
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录