From 0d4a43790a89bed6a0a9057f31f281554b844bf8 Mon Sep 17 00:00:00 2001 From: "Rico Sta. Cruz" Date: Fri, 13 Oct 2017 17:31:32 +0800 Subject: [PATCH] Refactor wrapify() completely without jQuery --- .../__snapshots__/index.test.js.snap | 64 ++++----- _js/wrapify/dom_helpers.js | 61 ++++++++ _js/wrapify/index.js | 135 ++++++++---------- _support/webpack.config.js | 1 - 4 files changed, 149 insertions(+), 112 deletions(-) create mode 100644 _js/wrapify/dom_helpers.js diff --git a/_js/wrapify/__tests__/__snapshots__/index.test.js.snap b/_js/wrapify/__tests__/__snapshots__/index.test.js.snap index 867f5e50f..6e26ba7e5 100644 --- a/_js/wrapify/__tests__/__snapshots__/index.test.js.snap +++ b/_js/wrapify/__tests__/__snapshots__/index.test.js.snap @@ -22,17 +22,17 @@ exports[`h3 with class 1`] = `
+ +

(install)

+ +
- - - - `; @@ -72,9 +72,14 @@ exports[`multiple h2s 1`] = `
+ +

(install)

+ + +
+ +

(usage)

+ + +
- - - - - - - - - -
@@ -135,9 +135,14 @@ exports[`multiple h2s 1`] = `
+ +

(first)

+ + +
+ +

(second)

+ +
- - - - - - - - - `; @@ -204,9 +204,14 @@ exports[`simple usage 1`] = `
+ +

(install)

+ + +
+ +

(usage)

+ +
- - - - - - - - - `; diff --git a/_js/wrapify/dom_helpers.js b/_js/wrapify/dom_helpers.js new file mode 100644 index 000000000..bf94941cb --- /dev/null +++ b/_js/wrapify/dom_helpers.js @@ -0,0 +1,61 @@ +import matches from 'dom101/matches' + +/* + * Just like jQuery.append + */ + +export function appendMany (el, children) { + children.forEach(child => { el.appendChild(child) }) +} + +/* + * Just like jQuery.nextUntil + */ + +export 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 + */ + +export function before (reference, newNode) { + reference.parentNode.insertBefore(newNode, reference) +} + +/* + * Like jQuery.children('selector') + */ + +export function findChildren (el, selector) { + return [].slice.call(el.children) + .filter(child => matches(child, selector)) +} + +/** + * Creates a div + * @private + * + * @example + * + * createDiv({ class: 'foo' }) + */ + +export function createDiv (props) { + const d = document.createElement('div') + Object.keys(props).forEach(key => { + d.setAttribute(key, props[key]) + }) + return d +} diff --git a/_js/wrapify/index.js b/_js/wrapify/index.js index a65f38fca..f0be30497 100644 --- a/_js/wrapify/index.js +++ b/_js/wrapify/index.js @@ -1,63 +1,84 @@ -import $ from 'jquery' import matches from 'dom101/matches' import addClass from 'dom101/add-class' +import { appendMany, nextUntil, before, findChildren, createDiv } from './dom_helpers' -/* +/** * Wraps h2 sections into h2-section. * Wraps h3 sections into h3-section. + * + * @private */ export default function wrapify (root) { - const $root = $(root) + // These are your H2 sections. Returns a list of .h2-section nodes. + const sections = wrapifyH2(root) - const $h2sections = groupify(root, { - tag: 'h2', - wrapper: '
', - 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 - } + // 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) }) }) +} - $($h2sections).each(function () { - const $body = $(this).children('[data-js-h3-section-list]') +/** + * Wraps h2 sections into h2-section. + * Creates and HTML structure like so: + * + * .h2-section + * h2. + * (title) + * .body.h3-section-list. + * (body goes here) + * + * @private + */ - groupify($body[0], { - tag: 'h3', - wrapperFn: () => { - const d = document.createElement('div') - d.className = 'h3-section' - return d - }, - bodyFn: () => { - const d = document.createElement('div') - d.className = 'body' - return d - } +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': '' }) }) } -/* - * Groups stuff +/** + * 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] - const $first = $(first) 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[0], ...sibs ])) + result.push(wrap(first, null, [ first, ...sibs ])) } // Find all h3's inside it @@ -87,47 +108,3 @@ export function groupify (el, { tag, wrapperFn, bodyFn }) { 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)) -} - diff --git a/_support/webpack.config.js b/_support/webpack.config.js index 362017537..79471968c 100644 --- a/_support/webpack.config.js +++ b/_support/webpack.config.js @@ -8,7 +8,6 @@ module.exports = { app: './_js/app.js', vendor: [ // Large 3rd-party libs - 'jquery', 'prismjs', // Prism plugins