Skip to content

Commit 5eff0b6

Browse files
committed
Refactor some code
1 parent 183cbf9 commit 5eff0b6

File tree

1 file changed

+52
-36
lines changed

1 file changed

+52
-36
lines changed

lib/handlers/li.js

+52-36
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
* @typedef {import('../state.js').State} State
77
*/
88

9+
/**
10+
* @typedef ExtractResult
11+
* Result of extracting a leading checkbox.
12+
* @property {Element | undefined} checkbox
13+
* The checkbox that was removed, if any.
14+
* @property {Element} rest
15+
* If there was a leading checkbox, a deep clone of the node w/o the leading
16+
* checkbox; otherwise a reference to the given, untouched, node.
17+
*/
18+
919
import {phrasing} from 'hast-util-phrasing'
1020

1121
/**
@@ -19,15 +29,14 @@ import {phrasing} from 'hast-util-phrasing'
1929
export function li(state, node) {
2030
// If the list item starts with a checkbox, remove the checkbox and mark the
2131
// list item as a GFM task list item.
22-
const {cleanNode, checkbox} = extractLeadingCheckbox(node)
23-
const checked = checkbox && Boolean(checkbox.properties.checked)
24-
25-
const spread = spreadout(cleanNode)
26-
const children = state.toFlow(state.all(cleanNode))
32+
const {rest, checkbox} = extractLeadingCheckbox(node)
33+
const checked = checkbox ? Boolean(checkbox.properties.checked) : null
34+
const spread = spreadout(rest)
35+
const children = state.toFlow(state.all(rest))
2736

2837
/** @type {ListItem} */
2938
const result = {type: 'listItem', spread, checked, children}
30-
state.patch(cleanNode, result)
39+
state.patch(node, result)
3140
return result
3241
}
3342

@@ -75,23 +84,36 @@ function spreadout(node) {
7584
}
7685

7786
/**
78-
* If the first bit of content in an element is a checkbox, create a copy of
79-
* the element that does not include the checkbox and return the cleaned up
80-
* copy alongside the checkbox that was removed. If there was no leading
81-
* checkbox, this returns the original element unaltered (not a copy).
87+
* Extract a leading checkbox from a list item.
88+
*
89+
* If there was a leading checkbox, makes a deep clone of the node w/o the
90+
* leading checkbox; otherwise a reference to the given, untouched, node is
91+
* given back.
92+
*
93+
* So for example:
94+
*
95+
* ```html
96+
* <li><input type="checkbox">Text</li>
97+
* ```
8298
*
83-
* This detects trees like:
84-
* `<li><input type="checkbox">Text</li>`
85-
* And returns a tree like:
86-
* `<li>Text</li>`
99+
* …becomes:
87100
*
88-
* Or with nesting:
89-
* `<li><p><input type="checkbox">Text</p></li>`
90-
* Which returns a tree like:
91-
* `<li><p>Text</p></li>`
101+
* ```html
102+
* <li>Text</li>
103+
* ```
104+
*
105+
* ```html
106+
* <li><p><input type="checkbox">Text</p></li>
107+
* ```
108+
*
109+
* …becomes:
110+
*
111+
* ```html
112+
* <li><p>Text</p></li>
113+
* ```
92114
*
93115
* @param {Readonly<Element>} node
94-
* @returns {{cleanNode: Element, checkbox: Element | null}}
116+
* @returns {ExtractResult}
95117
*/
96118
function extractLeadingCheckbox(node) {
97119
const head = node.children[0]
@@ -103,31 +125,25 @@ function extractLeadingCheckbox(node) {
103125
head.properties &&
104126
(head.properties.type === 'checkbox' || head.properties.type === 'radio')
105127
) {
106-
return {
107-
cleanNode: {...node, children: node.children.slice(1)},
108-
checkbox: head
109-
}
128+
const rest = {...node, children: node.children.slice(1)}
129+
return {checkbox: head, rest}
110130
}
111131

112-
// The checkbox may be nested in another element. If the first element has
113-
// children, look for a leading checkbox inside it.
132+
// The checkbox may be nested in another element.
133+
// If the first element has children, look for a leading checkbox inside it.
114134
//
115-
// NOTE: this only handles nesting in `<p>` elements, which is most common.
116-
// It's possible a leading checkbox might be nested in other types of flow or
135+
// This only handles nesting in `<p>` elements, which is most common.
136+
// Its possible a leading checkbox might be nested in other types of flow or
117137
// phrasing elements (and *deeply* nested, which is not possible with `<p>`).
118138
// Limiting things to `<p>` elements keeps this simpler for now.
119139
if (head && head.type === 'element' && head.tagName === 'p') {
120-
const {cleanNode: cleanHead, checkbox} = extractLeadingCheckbox(head)
140+
const {checkbox, rest: restHead} = extractLeadingCheckbox(head)
141+
121142
if (checkbox) {
122-
return {
123-
cleanNode: {
124-
...node,
125-
children: [cleanHead, ...node.children.slice(1)]
126-
},
127-
checkbox
128-
}
143+
const rest = {...node, children: [restHead, ...node.children.slice(1)]}
144+
return {checkbox, rest}
129145
}
130146
}
131147

132-
return {cleanNode: node, checkbox: null}
148+
return {checkbox: undefined, rest: node}
133149
}

0 commit comments

Comments
 (0)