diff --git a/package.json b/package.json index 84b9627..da40bf3 100644 --- a/package.json +++ b/package.json @@ -53,8 +53,7 @@ }, "homepage": "http://download.github.io/preact-layout", "dependencies": { - "preact": "^6.3.0", - "preact-render-to-string": "^3.2.1" + "preact": "^10.0.0" }, "devDependencies": { "babel-cli": "^6.16.0", @@ -90,7 +89,7 @@ "glob": "^7.1.1", "jest": "^17.0.0", "loose-envify": "^1.1.0", - "preact-render-to-string": "^3.1.1", + "preact-render-to-string": "^6.1.0", "rimraf": "^2.3.4", "touch": "^1.0.0", "uevents": "^1.0.0", diff --git a/src/index.jsx b/src/index.jsx index 94e7afd..5e1cefa 100644 --- a/src/index.jsx +++ b/src/index.jsx @@ -1,79 +1,93 @@ -import { h, Component } from 'preact' +// @ts-nocheck +import { h, Component, toChildArray } from 'preact'; +function getChildren(node) { + return ((node || {}).props || {}).children || (node || {}).children; +} -function Layout({className, recurse, children, ...props}, context) { - const { main, sections } = getSections(children) - processNode(main, sections, { ...context }, recurse) - return children && children.length === 1 ? children[0] : ( -
{children}
- ) +function getComponentType(node) { + return (node || {}).type || (node || {}).nodeName; } -function Section({type, children, ...props}, context) {return ( - children && (children.length === 1) ? children[0] : ( -
{children}
- ) -)} +function getProps(node) { + return (node || {}).props || (node || {}).attributes; +} -function getSections(n, result) { - if (!result) result = {sections:[]} - if (n.nodeName === Section) { - if (n.attributes && n.attributes.type) result.sections.push(n) - else result.main = n - } - const children = Array.isArray(n) ? n : n.children - children && children.forEach(c => { - getSections(c, result) - }) - return result +function getPropsType(node) { + return (getProps(node) || {}).type; } -function processNode(node, sections, context, recurse, collectOnly, results) { - const leftovers = [], postProcess = !results - context = context || {} - if (recurse === undefined) recurse = 9 - results = results || {} - sections.forEach(s => results[s.attributes.type] = results[s.attributes.type] || s.children || []) - node && node.children && node.children.forEach(n => { - if (isContribution(n, sections)) { - if (! results[n.nodeName]) results[n.nodeName] = [] - if (n.attributes && n.attributes.append) results[n.nodeName].push.apply(results[n.nodeName], n.children || []) - else if (n.attributes && n.attributes.prepend) results[n.nodeName].unshift.apply(results[n.nodeName], n.children || []) - else results[n.nodeName] = n.children || [] - return // continue - } - leftovers.push(n) - if (typeof n.nodeName == 'function' && recurse) { - let props = { ...n.nodeName.defaultProps, ...n.attributes, children:n.children } - if (n.nodeName.prototype && typeof n.nodeName.prototype.render == 'function') { - let rn, c = new n.nodeName(props, context); - c.props = props; - c.context = context; - if (c.componentWillMount) c.componentWillMount(); - n = c.render(c.props, c.state, c.context); - if (c.getChildContext) context = { ...context, ...c.getChildContext() } - } - else n = n.nodeName(props, context) - recurse-- - } - processNode(n, sections, context, recurse, collectOnly, results) - }) - if (! collectOnly) { - if (node.children) node.children = leftovers - if (postProcess) sections.forEach(s => s.children = results[s.attributes.type]) - } - return results +function Layout({ className, recurse, children, ...props }, context) { + const { main, sections } = getSections(children); + processNode(main, sections, { ...context }, recurse); + const arr = toChildArray(children); + return children && arr.length === 1 ? arr[0] :
{children}
; } -function isContribution(n, sections) { - return sections.filter(s => n.nodeName === s.attributes.type).length > 0 +function Section({ type, children, ...props }, context) { + const arr = toChildArray(children); + return children && arr.length === 1 ? arr[0] :
{children}
; } +function getSections(n, result) { + if (!result) result = { sections: [] }; + if (getComponentType(n) === Section) { + if (n.props && n.props.type) result.sections.push(n); + else result.main = n; + } + const children = n ? (Array.isArray(n) ? n : getChildren(n)) : undefined; + children && + toChildArray(children).forEach(c => { + getSections(c, result); + }); + return result; +} -export { - Layout, - Section, +function processNode(node, sections, context, recurse, collectOnly, results) { + const leftovers = [], + postProcess = !results; + context = context || {}; + if (recurse === undefined) recurse = 9; + results = results || new Map(); + sections.forEach(s => results.set(s.props.type, results.get(s.props.type) || s.props.children || [])); + getChildren(node) && + toChildArray(getChildren(node)).forEach(n => { + if (isContribution(n, sections)) { + if (!results.has(n.type)) results.set(n.type, []); + if (n.props && n.props.append) results.get(n.type).push.apply(results.get(n.type), n.props.children || []); + else if (n.props && n.props.prepend) + results.get(n.type).unshift.apply(results.get(n.type), n.props.children || []); + else results.set(n.type, n.props.children || []); + return; // continue + } + leftovers.push(n); + if (getComponentType(n) && recurse) { + let props = { ...n.type.defaultProps, ...n.props, children: n.props.children }; + if (n.type.prototype && typeof n.type.prototype.render == 'function') { + let rn, + c = new n.type(props, context); + c.props = props; + c.context = context; + if (c.componentWillMount) c.componentWillMount(); + n = c.render(c.props, c.state, c.context); + if (c.getChildContext) context = { ...context, ...c.getChildContext() }; + } else if (typeof n.type === 'string') { + n = h(n.type, props, getChildren(props)); + } else { + n = n.type(props, context); + } + recurse--; + } + processNode(n, sections, context, recurse, collectOnly, results); + }); + if (!collectOnly) { + if (getChildren(node)) node.props.children = leftovers; + if (postProcess) sections.forEach(s => (s.props.children = results.get(s.props.type))); + } + return results; +} - getSections, - isContribution, - processNode +function isContribution(n, sections) { + return sections.filter(s => getComponentType(n) === getPropsType(s)).length > 0; } + +export { Layout, Section, getSections, isContribution, processNode };