Skip to content

Commit 1d5f8f2

Browse files
authored
Merge pull request #116 from Coding/hackape/pane-tabGroup-fix
address coding/WebIDE#180
2 parents 5b5f9ee + 7ba6251 commit 1d5f8f2

File tree

2 files changed

+85
-63
lines changed

2 files changed

+85
-63
lines changed

app/commons/Pane/state.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { extendObservable, observable, computed } from 'mobx'
2+
3+
function PaneScope () {
4+
const state = observable({
5+
entities: observable.map({})
6+
})
7+
8+
class BasePane {
9+
constructor (paneConfig) {
10+
const defaults = {
11+
flexDirection: 'row',
12+
size: 100,
13+
parentId: '',
14+
index: 0,
15+
}
16+
17+
paneConfig = { ...defaults, ...paneConfig }
18+
extendObservable(this, paneConfig)
19+
state.entities.set(this.id, this)
20+
}
21+
22+
@computed
23+
get isRoot () {
24+
return !Boolean(this.parentId)
25+
}
26+
27+
@computed
28+
get parent () {
29+
const parent = state.entities.get(this.parentId)
30+
if (parent === this) throw Error(`Pane/Panel ${this.id} is parent of itself.`)
31+
return parent
32+
}
33+
34+
@computed
35+
get views () {
36+
return state.entities.values()
37+
.filter(pane => pane.parentId === this.id)
38+
.sort((a, b) => a.index - b.index)
39+
}
40+
41+
@computed
42+
get siblings () {
43+
if (!this.parent) return [this]
44+
return this.parent.views
45+
}
46+
47+
@computed
48+
get leafChildren () {
49+
if (!this.views.length) return [this]
50+
return this.views.reduce((acc, child) =>
51+
acc.concat(child.leafChildren)
52+
, [])
53+
}
54+
55+
@computed
56+
get prev () {
57+
return this.siblings[this.index - 1]
58+
}
59+
60+
@computed
61+
get next () {
62+
return this.siblings[this.index + 1]
63+
}
64+
}
65+
66+
return { BasePane, state }
67+
}
68+
69+
export default PaneScope

app/components/Pane/state.js

Lines changed: 16 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
import uniqueId from 'lodash/uniqueId'
22
import { extendObservable, observable, computed, action, autorun, autorunAsync } from 'mobx'
33
import EditorTabState, { TabGroup } from 'components/Editor/state'
4+
import PaneScope from 'commons/Pane/state'
45

5-
const state = observable({
6-
panes: observable.map({}),
6+
const { state, BasePane } = PaneScope()
7+
8+
extendObservable(state, {
9+
get panes () { return this.entities },
710
activePaneId: null,
8-
rootPaneId: null,
911
autoCloseEmptyPane: true,
1012
get rootPane () {
11-
const rootPane = this.panes.get(this.rootPaneId)
13+
const rootPane = this.panes.values().find(pane => pane.isRoot)
1214
return rootPane || this.panes.values()[0]
1315
},
1416
get activePane () {
@@ -17,51 +19,9 @@ const state = observable({
1719
},
1820
})
1921

20-
class BasePane {
21-
constructor (paneConfig) {
22-
const defaults = {
23-
id: uniqueId('pane_view_'),
24-
flexDirection: 'row',
25-
size: 100,
26-
parentId: '',
27-
index: 0,
28-
}
29-
30-
paneConfig = Object.assign({}, defaults, paneConfig)
31-
extendObservable(this, paneConfig)
32-
state.panes.set(this.id, this)
33-
}
34-
35-
@computed
36-
get parent () {
37-
return state.panes.get(this.parentId)
38-
}
39-
40-
@computed
41-
get views () {
42-
return state.panes.values()
43-
.filter(pane => pane.parentId === this.id)
44-
.sort((a, b) => a.index - b.index)
45-
}
46-
47-
@computed
48-
get siblings () {
49-
return this.parent.views
50-
}
51-
52-
@computed
53-
get prev () {
54-
return this.siblings[this.index - 1]
55-
}
56-
57-
@computed
58-
get next () {
59-
return this.siblings[this.index + 1]
60-
}
61-
}
62-
6322
class Pane extends BasePane {
6423
constructor (paneConfig) {
24+
if (!paneConfig.id) paneConfig.id = uniqueId('pane_view_')
6525
super(paneConfig)
6626
this.contentType = 'tabGroup'
6727
const tabGroup = this.tabGroup || new TabGroup()
@@ -76,14 +36,6 @@ class Pane extends BasePane {
7636
return EditorTabState.tabGroups.get(this.contentId)
7737
}
7838

79-
@computed
80-
get leafChildren () {
81-
if (!this.views.length) return [this]
82-
return this.views.reduce((acc, pane) => {
83-
return acc.concat(pane.leafChildren)
84-
}, [])
85-
}
86-
8739
@action
8840
destroy () {
8941
if (this.isRoot) return
@@ -110,29 +62,30 @@ class Pane extends BasePane {
11062
}
11163

11264
const rootPane = new Pane({
113-
id: 'pane_view_1',
11465
flexDirection: 'row',
11566
size: 100,
116-
isRoot: true,
11767
})
11868

11969
state.panes.set(rootPane.id, rootPane)
120-
state.rootPaneId = rootPane.id
12170

122-
autorun(() => {
71+
autorun('normalize pane indexes', () => {
12372
state.panes.forEach(parentPane =>
12473
parentPane.views.forEach((pane, index) => {
12574
if (pane.index !== index) pane.index = index
12675
})
12776
)
12877
})
12978

130-
autorunAsync(() => {
79+
autorunAsync('short-circuit unnecessary internal pane node', () => {
80+
// pane.parent -> pane -> lonelyChild
81+
// => pane.panret -> lonelyChild
82+
// delete pane
13183
state.panes.forEach(pane => {
132-
if (!pane || pane.isRoot) return
84+
if (!pane) return
13385
if (pane.views.length === 1) {
134-
pane.contentId = pane.views[0].contentId
135-
state.panes.delete(pane.views[0].id)
86+
const lonelyChild = pane.views[0]
87+
lonelyChild.parentId = pane.parentId
88+
state.panes.delete(pane.id)
13689
}
13790
})
13891
})

0 commit comments

Comments
 (0)