120 lines
2.4 KiB
JavaScript
120 lines
2.4 KiB
JavaScript
import matches from 'dom101/matches'
|
|
import addClass from 'dom101/add-class'
|
|
import {
|
|
appendMany,
|
|
nextUntil,
|
|
before,
|
|
findChildren,
|
|
createDiv
|
|
} from '../helpers/dom'
|
|
|
|
/**
|
|
* Wraps h2 sections into h2-section.
|
|
* Wraps h3 sections into h3-section.
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
export default function wrapify(root) {
|
|
// These are your H2 sections. Returns a list of .h2-section nodes.
|
|
const sections = wrapifyH2(root)
|
|
|
|
// For each h2 section, wrap the H3's in them
|
|
sections.forEach((section) => {
|
|
const bodies = findChildren(section, '[data-js-h3-section-list]')
|
|
bodies.forEach((body) => {
|
|
wrapifyH3(body)
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Wraps h2 sections into h2-section.
|
|
* Creates and HTML structure like so:
|
|
*
|
|
* .h2-section
|
|
* h2.
|
|
* (title)
|
|
* .body.h3-section-list.
|
|
* (body goes here)
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
function wrapifyH2(root) {
|
|
return groupify(root, {
|
|
tag: 'h2',
|
|
wrapperFn: () => createDiv({ class: 'h2-section' }),
|
|
bodyFn: () =>
|
|
createDiv({
|
|
class: 'body h3-section-list',
|
|
'data-js-h3-section-list': ''
|
|
})
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Wraps h3 sections into h3-section.
|
|
* Creates and HTML structure like so:
|
|
*
|
|
* .h3-section
|
|
* h3.
|
|
* (title)
|
|
* .body.
|
|
* (body goes here)
|
|
*
|
|
* @private
|
|
*/
|
|
|
|
function wrapifyH3(root) {
|
|
return groupify(root, {
|
|
tag: 'h3',
|
|
wrapperFn: () => createDiv({ class: 'h3-section' }),
|
|
bodyFn: () => createDiv({ class: 'body' })
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Groups all headings (a `tag` selector) under wrappers like `.h2-section`
|
|
* (build by `wrapperFn()`).
|
|
* @private
|
|
*/
|
|
|
|
export function groupify(el, { tag, wrapperFn, bodyFn }) {
|
|
const first = el.children[0]
|
|
let result = []
|
|
|
|
// Handle the markup before the first h2
|
|
if (first && !matches(first, tag)) {
|
|
const sibs = nextUntil(first, tag)
|
|
result.push(wrap(first, null, [first, ...sibs]))
|
|
}
|
|
|
|
// Find all h3's inside it
|
|
const children = findChildren(el, tag)
|
|
|
|
children.forEach((child) => {
|
|
const sibs = nextUntil(child, tag)
|
|
result.push(wrap(child, child, sibs))
|
|
})
|
|
|
|
return result
|
|
|
|
function wrap(pivot, first, sibs) {
|
|
const wrap = wrapperFn()
|
|
|
|
const pivotClass = pivot.className
|
|
if (pivotClass) addClass(wrap, pivotClass)
|
|
before(pivot, wrap)
|
|
|
|
const body = bodyFn()
|
|
if (pivotClass) addClass(body, pivotClass)
|
|
appendMany(body, sibs)
|
|
|
|
if (first) wrap.appendChild(first)
|
|
wrap.appendChild(body)
|
|
|
|
return wrap
|
|
}
|
|
}
|