Begin refactor of wrapify

This commit is contained in:
Rico Sta. Cruz 2017-10-13 17:18:41 +08:00
parent b8ee6a8171
commit 7bc780c5a0
No known key found for this signature in database
GPG Key ID: CAAD38AE2962619A
1 changed files with 97 additions and 27 deletions

View File

@ -1,4 +1,6 @@
import $ from 'jquery' import $ from 'jquery'
import matches from 'dom101/matches'
import addClass from 'dom101/add-class'
/* /*
* Wraps h2 sections into h2-section. * Wraps h2 sections into h2-section.
@ -7,19 +9,38 @@ import $ from 'jquery'
export default function wrapify (root) { export default function wrapify (root) {
const $root = $(root) const $root = $(root)
const $h2sections = groupify($root, {
const $h2sections = groupify(root, {
tag: 'h2', tag: 'h2',
wrapper: '<div class="h2-section">', wrapper: '<div class="h2-section">',
body: '<div class="body h3-section-list" data-js-h3-section-list>' wrapperFn: () => {
const d = document.createElement('div')
d.className = 'h2-section'
return d
},
bodyFn: () => {
const d = document.createElement('div')
d.className = 'body h3-section-list'
d.setAttribute('data-js-h3-section-list', '')
return d
}
}) })
$h2sections.each(function () { $($h2sections).each(function () {
const $body = $(this).children('[data-js-h3-section-list]') const $body = $(this).children('[data-js-h3-section-list]')
groupify($body, { groupify($body[0], {
tag: 'h3', tag: 'h3',
wrapper: '<div class="h3-section">', wrapperFn: () => {
body: '<div class="body">' const d = document.createElement('div')
d.className = 'h3-section'
return d
},
bodyFn: () => {
const d = document.createElement('div')
d.className = 'body'
return d
}
}) })
}) })
} }
@ -28,36 +49,85 @@ export default function wrapify (root) {
* Groups stuff * Groups stuff
*/ */
export function groupify ($this, { tag, wrapper, body }) { export function groupify (el, { tag, wrapperFn, bodyFn }) {
const $first = $this.children(':first-child') const first = el.children[0]
let $result = $() const $first = $(first)
let result = []
// Handle the markup before the first h2 // Handle the markup before the first h2
if (!$first.is(tag)) { if (first && !matches(first, tag)) {
const $sibs = $first.nextUntil(tag) const sibs = nextUntil(first, tag)
$result = $result.add(wrap($first, null, $first.add($sibs))) result.push(wrap(first, null, [ $first[0], ...sibs ]))
} }
$this.children(tag).each(function () { // Find all h3's inside it
const $sibs = $(this).nextUntil(tag) const children = findChildren(el, tag)
const $heading = $(this)
$result = $result.add(wrap($heading, $heading, $sibs)) children.forEach(child => {
const sibs = nextUntil(child, tag)
result.push(wrap(child, child, sibs))
}) })
return $result return result
function wrap ($pivot, $first, $sibs) { function wrap (pivot, first, sibs) {
const $wrap = $(wrapper) const wrap = wrapperFn()
$wrap.addClass($pivot.attr('class'))
$pivot.before($wrap)
const $body = $(body) const pivotClass = pivot.className
$body.addClass($pivot.attr('class')) if (pivotClass) addClass(wrap, pivotClass)
$body.append($sibs) before(pivot, wrap)
if ($first) $wrap.append($first) const body = bodyFn()
$wrap.append($body) if (pivotClass) addClass(body, pivotClass)
appendMany(body, sibs)
return $wrap if (first) wrap.appendChild(first)
wrap.appendChild(body)
return wrap
} }
} }
/*
* Just like jQuery.append
*/
function appendMany (el, children) {
children.forEach(child => { el.appendChild(child) })
}
/*
* Just like jQuery.nextUntil
*/
function nextUntil (el, selector) {
const nextEl = el.nextSibling
return nextUntilTick(nextEl, selector, [])
}
function nextUntilTick (el, selector, acc) {
if (!el) return acc
const isMatch = matches(el, selector)
if (isMatch) return acc
return nextUntilTick(el.nextSibling, selector, [ ...acc, el ])
}
/*
* Just like jQuery.before
*/
function before (reference, newNode) {
reference.parentNode.insertBefore(newNode, reference)
}
/*
* Like jQuery.children('selector')
*/
function findChildren (el, selector) {
return [].slice.call(el.children)
.filter(child => matches(child, selector))
}