-
Notifications
You must be signed in to change notification settings - Fork 4k
/
list-reducer.js
72 lines (61 loc) · 1.67 KB
/
list-reducer.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
/**
* WordPress dependencies
*/
import { unwrap } from '@wordpress/dom';
function isList( node ) {
return node.nodeName === 'OL' || node.nodeName === 'UL';
}
function shallowTextContent( element ) {
return [ ...element.childNodes ]
.map( ( { nodeValue = '' } ) => nodeValue )
.join( '' );
}
export default function( node ) {
if ( ! isList( node ) ) {
return;
}
const list = node;
const prevElement = node.previousElementSibling;
// Merge with previous list if:
// * There is a previous list of the same type.
// * There is only one list item.
if (
prevElement &&
prevElement.nodeName === node.nodeName &&
list.children.length === 1
) {
// Move all child nodes, including any text nodes, if any.
while ( list.firstChild ) {
prevElement.appendChild( list.firstChild );
}
list.parentNode.removeChild( list );
}
const parentElement = node.parentNode;
// Nested list with empty parent item.
if (
parentElement &&
parentElement.nodeName === 'LI' &&
parentElement.children.length === 1 &&
! /\S/.test( shallowTextContent( parentElement ) )
) {
const parentListItem = parentElement;
const prevListItem = parentListItem.previousElementSibling;
const parentList = parentListItem.parentNode;
if ( prevListItem ) {
prevListItem.appendChild( list );
parentList.removeChild( parentListItem );
} else {
parentList.parentNode.insertBefore( list, parentList );
parentList.parentNode.removeChild( parentList );
}
}
// Invalid: OL/UL > OL/UL.
if ( parentElement && isList( parentElement ) ) {
const prevListItem = node.previousElementSibling;
if ( prevListItem ) {
prevListItem.appendChild( node );
} else {
unwrap( node );
}
}
}