Skip to content
This repository was archived by the owner on Feb 6, 2023. It is now read-only.

Commit 6b83312

Browse files
niveditcfacebook-github-bot
authored andcommitted
Allow insertion at a specific point for updateParentChild
Summary: We need more flexibility for this method, so that the untab method can correctly add a child to the middle of the children array. * insert at position 0 (first child) * insert at len(children) position (last child) * insert somewhere in the middle Reviewed By: flarnie Differential Revision: D9653244 fbshipit-source-id: 7d2bc44a9116d512838c8bbd5fe89a5ae20d5de7
1 parent 4a5ad07 commit 6b83312

File tree

3 files changed

+227
-61
lines changed

3 files changed

+227
-61
lines changed

src/model/modifier/exploration/DraftTreeOperations.js

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ const Immutable = require('immutable');
2323
const invariant = require('invariant');
2424

2525
type SiblingInsertPosition = 'previous' | 'next';
26-
type ChildInsertPosition = 'first' | 'last';
2726

2827
const verifyTree = (tree: BlockMap): void => {
2928
if (__DEV__) {
@@ -32,67 +31,62 @@ const verifyTree = (tree: BlockMap): void => {
3231
};
3332

3433
/**
35-
* This is a utility method for setting B as a first/last child of A, ensuring
34+
* This is a utility method for setting B as a child of A, ensuring
3635
* that parent <-> child operations are correctly mirrored
3736
*
37+
* The child is inserted at 'position' index in the list
38+
*
3839
* The block map returned by this method may not be a valid tree (siblings are
3940
* unaffected)
4041
*/
4142
const updateParentChild = (
4243
blockMap: BlockMap,
4344
parentKey: string,
4445
childKey: string,
45-
position: ChildInsertPosition,
46+
position: number,
4647
): BlockMap => {
4748
const parent = blockMap.get(parentKey);
4849
const child = blockMap.get(childKey);
4950
invariant(
5051
parent != null && child != null,
5152
'parent & child should exist in the block map',
5253
);
53-
const existingChildren = parent.getChildKeys();
5454
const newBlocks = {};
55+
const existingChildren = parent.getChildKeys();
56+
invariant(
57+
existingChildren != null &&
58+
position >= 0 &&
59+
position <= existingChildren.count(),
60+
'position is not valid for the number of children',
61+
);
62+
5563
// add as parent's child
5664
newBlocks[parentKey] = parent.merge({
57-
children:
58-
position === 'first'
59-
? existingChildren.unshift(childKey)
60-
: existingChildren.push(childKey),
65+
children: existingChildren.splice(position, 0, childKey),
6166
});
62-
// add as child's parent
63-
if (existingChildren.count() !== 0) {
64-
// link child as sibling to the existing children
65-
switch (position) {
66-
case 'first':
67-
const nextSiblingKey = existingChildren.first();
68-
newBlocks[childKey] = child.merge({
69-
parent: parentKey,
70-
nextSibling: nextSiblingKey,
71-
prevSibling: null,
72-
});
73-
newBlocks[nextSiblingKey] = blockMap.get(nextSiblingKey).merge({
74-
prevSibling: childKey,
75-
});
76-
break;
77-
case 'last':
78-
const prevSiblingKey = existingChildren.last();
79-
newBlocks[childKey] = child.merge({
80-
parent: parentKey,
81-
prevSibling: prevSiblingKey,
82-
nextSibling: null,
83-
});
84-
newBlocks[prevSiblingKey] = blockMap.get(prevSiblingKey).merge({
85-
nextSibling: childKey,
86-
});
87-
break;
88-
}
89-
} else {
90-
newBlocks[childKey] = child.merge({
91-
parent: parentKey,
92-
prevSibling: null,
93-
nextSibling: null,
67+
68+
let nextSiblingKey = null;
69+
let prevSiblingKey = null;
70+
// link new child as next sibling to the correct existing child
71+
if (position > 0) {
72+
prevSiblingKey = existingChildren.get(position - 1);
73+
newBlocks[prevSiblingKey] = blockMap.get(prevSiblingKey).merge({
74+
nextSibling: childKey,
75+
});
76+
}
77+
// link new child as previous sibling to the correct existing child
78+
if (position < existingChildren.count()) {
79+
nextSiblingKey = existingChildren.get(position);
80+
newBlocks[nextSiblingKey] = blockMap.get(nextSiblingKey).merge({
81+
prevSibling: childKey,
9482
});
9583
}
84+
// add parent & siblings to the child
85+
newBlocks[childKey] = child.merge({
86+
parent: parentKey,
87+
prevSibling: prevSiblingKey,
88+
nextSibling: nextSiblingKey,
89+
});
9690
return blockMap.merge(newBlocks);
9791
};
9892

@@ -181,12 +175,7 @@ const createNewParent = (blockMap: BlockMap, key: string): BlockMap => {
181175
.concat(Immutable.OrderedMap([[newParent.getKey(), newParent]]))
182176
.concat(blockMap.skipUntil(block => block.getKey() === key));
183177
// set parent <-> child connection
184-
newBlockMap = updateParentChild(
185-
newBlockMap,
186-
newParent.getKey(),
187-
key,
188-
'first',
189-
);
178+
newBlockMap = updateParentChild(newBlockMap, newParent.getKey(), key, 0);
190179
// set siblings & parent for the new parent key to child's siblings & parent
191180
const prevSibling = block.getPrevSiblingKey();
192181
const nextSibling = block.getNextSiblingKey();
@@ -239,7 +228,7 @@ const updateAsSiblingsChild = (
239228
let newBlockMap = blockMap;
240229
switch (position) {
241230
case 'next':
242-
newBlockMap = updateParentChild(newBlockMap, newParentKey, key, 'first');
231+
newBlockMap = updateParentChild(newBlockMap, newParentKey, key, 0);
243232
const prevSibling = block.getPrevSiblingKey();
244233
if (prevSibling != null) {
245234
newBlockMap = updateSibling(newBlockMap, prevSibling, newParentKey);
@@ -266,7 +255,12 @@ const updateAsSiblingsChild = (
266255
);
267256
break;
268257
case 'previous':
269-
newBlockMap = updateParentChild(newBlockMap, newParentKey, key, 'last');
258+
newBlockMap = updateParentChild(
259+
newBlockMap,
260+
newParentKey,
261+
key,
262+
newParent.getChildKeys().count(),
263+
);
270264
const nextSibling = block.getNextSiblingKey();
271265
if (nextSibling != null) {
272266
newBlockMap = updateSibling(newBlockMap, newParentKey, nextSibling);

src/model/modifier/exploration/__tests__/DraftTreeOperations-test.js

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ const blockMap1 = Immutable.OrderedMap({
6464
}),
6565
});
6666

67-
test('test adding a last child to parent', () => {
67+
test('test adding a child to parent at position 0 (first)', () => {
6868
let newBlockMap = DraftTreeOperations.updateParentChild(
6969
blockMap1,
7070
'X',
7171
'D',
72-
'last',
72+
0,
7373
);
7474
newBlockMap = newBlockMap.merge({
7575
X: newBlockMap.get('X').merge({
@@ -79,12 +79,27 @@ test('test adding a last child to parent', () => {
7979
expect(newBlockMap).toMatchSnapshot();
8080
});
8181

82-
test('test adding a first child to parent', () => {
82+
test('test adding a child to parent at position 1', () => {
8383
let newBlockMap = DraftTreeOperations.updateParentChild(
8484
blockMap1,
8585
'X',
8686
'D',
87-
'first',
87+
1,
88+
);
89+
newBlockMap = newBlockMap.merge({
90+
X: newBlockMap.get('X').merge({
91+
nextSibling: null,
92+
}),
93+
});
94+
expect(newBlockMap).toMatchSnapshot();
95+
});
96+
97+
test('test adding a child to parent at last position', () => {
98+
let newBlockMap = DraftTreeOperations.updateParentChild(
99+
blockMap1,
100+
'X',
101+
'D',
102+
2,
88103
);
89104
newBlockMap = newBlockMap.merge({
90105
X: newBlockMap.get('X').merge({
@@ -162,7 +177,7 @@ test('test adding an only child to parent', () => {
162177
blockMap2,
163178
'X',
164179
'C',
165-
'first',
180+
0,
166181
);
167182
newBlockMap = newBlockMap.merge({
168183
B: newBlockMap.get('B').merge({

0 commit comments

Comments
 (0)