2020-02-03 10:24:25 +01:00
|
|
|
import { setupBinding } from "../state/stateBinding"
|
|
|
|
import { split, last } from "lodash/fp"
|
|
|
|
import { $ } from "../core/common"
|
|
|
|
import { renderComponent } from "./renderComponent"
|
2020-02-10 16:51:09 +01:00
|
|
|
import { isScreenSlot } from "./builtinComponents"
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-14 12:51:45 +01:00
|
|
|
export const attachChildren = initialiseOpts => (htmlElement, options) => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const {
|
|
|
|
uiFunctions,
|
|
|
|
bb,
|
|
|
|
coreApi,
|
|
|
|
store,
|
|
|
|
componentLibraries,
|
|
|
|
treeNode,
|
2020-02-10 22:35:51 +01:00
|
|
|
frontendDefinition,
|
2020-02-10 16:51:09 +01:00
|
|
|
onScreenSlotRendered,
|
2020-02-03 10:24:25 +01:00
|
|
|
} = initialiseOpts
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-14 12:51:45 +01:00
|
|
|
const anchor = options && options.anchor ? options.anchor : null
|
|
|
|
const force = options ? options.force : false
|
|
|
|
const hydrate = options ? options.hydrate : true
|
|
|
|
|
|
|
|
if (!force && treeNode.children.length > 0) return treeNode.children
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
for (let childNode of treeNode.children) {
|
2020-02-10 16:51:09 +01:00
|
|
|
childNode.destroy()
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2020-01-30 00:01:14 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
if (hydrate) {
|
|
|
|
while (htmlElement.firstChild) {
|
|
|
|
htmlElement.removeChild(htmlElement.firstChild)
|
2020-01-30 00:01:14 +01:00
|
|
|
}
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
htmlElement.classList.add(`lay-${treeNode.props._id}`)
|
|
|
|
|
|
|
|
const renderedComponents = []
|
2020-02-14 12:51:45 +01:00
|
|
|
for (let childProps of treeNode.props._children) {
|
2020-02-03 10:24:25 +01:00
|
|
|
const { componentName, libName } = splitName(childProps._component)
|
|
|
|
|
|
|
|
if (!componentName || !libName) return
|
|
|
|
|
|
|
|
const { initialProps, bind } = setupBinding(
|
|
|
|
store,
|
|
|
|
childProps,
|
|
|
|
coreApi,
|
2020-02-10 22:35:51 +01:00
|
|
|
frontendDefinition.appRootPath
|
2020-02-03 10:24:25 +01:00
|
|
|
)
|
2020-01-30 00:01:14 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const componentConstructor = componentLibraries[libName][componentName]
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const renderedComponentsThisIteration = renderComponent({
|
|
|
|
props: childProps,
|
|
|
|
parentNode: treeNode,
|
|
|
|
componentConstructor,
|
|
|
|
uiFunctions,
|
|
|
|
htmlElement,
|
|
|
|
anchor,
|
|
|
|
initialProps,
|
|
|
|
bb,
|
|
|
|
})
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-10 16:51:09 +01:00
|
|
|
if (
|
|
|
|
onScreenSlotRendered &&
|
|
|
|
isScreenSlot(childProps._component) &&
|
|
|
|
renderedComponentsThisIteration.length > 0
|
|
|
|
) {
|
|
|
|
// assuming there is only ever one screen slot
|
|
|
|
onScreenSlotRendered(renderedComponentsThisIteration[0])
|
|
|
|
}
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
for (let comp of renderedComponentsThisIteration) {
|
|
|
|
comp.unsubscribe = bind(comp.component)
|
|
|
|
renderedComponents.push(comp)
|
2020-01-28 15:14:53 +01:00
|
|
|
}
|
2020-02-03 10:24:25 +01:00
|
|
|
}
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-14 12:51:45 +01:00
|
|
|
treeNode.children = renderedComponents
|
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return renderedComponents
|
2020-01-28 15:14:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
const splitName = fullname => {
|
2020-02-03 10:24:25 +01:00
|
|
|
const componentName = $(fullname, [split("/"), last])
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
const libName = fullname.substring(
|
|
|
|
0,
|
|
|
|
fullname.length - componentName.length - 1
|
|
|
|
)
|
2020-01-28 15:14:53 +01:00
|
|
|
|
2020-02-03 10:24:25 +01:00
|
|
|
return { libName, componentName }
|
2020-01-30 00:01:14 +01:00
|
|
|
}
|