|
| 1 | +'use strict'; |
| 2 | + |
| 3 | +module.exports = listItem; |
| 4 | + |
| 5 | +var is = require('hast-util-is-element'); |
| 6 | +var all = require('../all'); |
| 7 | + |
| 8 | +function listItem(h, node, parent) { |
| 9 | + var children = node.children; |
| 10 | + var tail = !parent || parent.children[parent.children.length - 1] === node; |
| 11 | + var head = children[0]; |
| 12 | + var checked = null; |
| 13 | + var loose = false; |
| 14 | + var checkbox; |
| 15 | + var grandchildren; |
| 16 | + var content; |
| 17 | + |
| 18 | + /* Check if this node starts with a checkbox. */ |
| 19 | + if (head && is(head, 'p')) { |
| 20 | + grandchildren = head.children; |
| 21 | + checkbox = grandchildren[0]; |
| 22 | + |
| 23 | + if (checkbox && is(checkbox, 'input') && checkbox.properties.type === 'checkbox') { |
| 24 | + checked = Boolean(checkbox.properties.checked); |
| 25 | + } else { |
| 26 | + checkbox = null; |
| 27 | + } |
| 28 | + } |
| 29 | + |
| 30 | + content = all(h, node); |
| 31 | + |
| 32 | + /* Remove initial spacing if we previously found a checkbox. */ |
| 33 | + if (checked !== null) { |
| 34 | + grandchildren = content[0] && content[0].children; |
| 35 | + head = grandchildren && grandchildren[0]; |
| 36 | + |
| 37 | + if (head && head.type === 'text' && head.value.charAt(0) === ' ') { |
| 38 | + /* Remove text with one space, or remove that one initial space */ |
| 39 | + if (head.value.length === 1) { |
| 40 | + content[0].children = grandchildren.slice(1); |
| 41 | + } else { |
| 42 | + head.value = head.value.slice(1); |
| 43 | + } |
| 44 | + } |
| 45 | + } |
| 46 | + |
| 47 | + if (content.length > 1) { |
| 48 | + /* More than one node is always loose. */ |
| 49 | + loose = true; |
| 50 | + } else if (content.length === 1) { |
| 51 | + head = content[0]; |
| 52 | + |
| 53 | + if (head.type === 'text') { |
| 54 | + /* Wrap `text` in `paragraph` (always tight). */ |
| 55 | + content = [{type: 'paragraph', children: content}]; |
| 56 | + loose = false; |
| 57 | + } else if (head.type === 'paragraph') { |
| 58 | + /* One `paragraph`, always tight. Ensure it isn’t empty. */ |
| 59 | + loose = false; |
| 60 | + |
| 61 | + if (head.children.length === 0) { |
| 62 | + content = []; |
| 63 | + } |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + /* Last list-item is never loose. */ |
| 68 | + if (tail) { |
| 69 | + loose = false; |
| 70 | + } |
| 71 | + |
| 72 | + return h(node, 'listItem', {loose: loose, checked: checked}, content); |
| 73 | +} |
0 commit comments