-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
88 lines (69 loc) · 2.11 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import {is} from 'unist-util-is';
function replaceAllBetween(parent, start, end, function_) {
if (!parent || !parent.type || !parent.children) {
throw new Error('Expected parent node');
}
const {children} = parent;
const isStart = (node) => is(node, start);
const isEnd = (node) => is(node, end);
/**
* @type {Array<{start: number, end: number}>}
*/
const ranges = children.reduce((previous, child, i) => {
const lastPrevious = previous[previous.length - 1];
if (isStart(children[i])) {
if (lastPrevious && lastPrevious.end === undefined) {
console.error(
'Attempted to start a replacement before the first one was cleaned up'
);
throw new Error(
'Attempted to start a replacement before the first one was cleaned up'
);
}
previous.push({
start: i
});
return previous;
}
if (isEnd(children[i])) {
if (!lastPrevious || (lastPrevious && lastPrevious.start === undefined)) {
console.error(
'Attempted to end a replacement before finding the start',
i,
lastPrevious
);
throw new Error(
'Attempted to end a replacement before finding the start'
);
}
lastPrevious.end = i;
}
return previous;
}, []);
// Nothing found to replace
if (ranges.length === 0) {
return children;
}
if (!ranges[ranges.length - 1].end) {
console.error('No ending value was found');
throw new Error('No ending value was found');
}
// The function will return a different length than the original
// This offset is used to correct
let offset = 0;
ranges.map(({start, end}) => {
const offsetStart = start + offset;
const offsetEnd = end + offset;
const replaced = children.slice(offsetStart, offsetEnd + 1);
const changedArray = function_(replaced);
const diff = children.splice(
offsetStart,
offsetEnd - offsetStart + 1,
...changedArray
);
offset -= diff.length - changedArray.length;
return changedArray;
});
return children;
}
export default replaceAllBetween;