client: providing access to component root elements
This commit is contained in:
parent
54202e6344
commit
7823be0592
|
@ -5,8 +5,9 @@ import { setState, setStateFromBinding } from "./state/setState";
|
||||||
import { trimSlash } from "./common/trimSlash";
|
import { trimSlash } from "./common/trimSlash";
|
||||||
import { isBound } from "./state/isState";
|
import { isBound } from "./state/isState";
|
||||||
import { _initialiseChildren } from "./render/initialiseChildren";
|
import { _initialiseChildren } from "./render/initialiseChildren";
|
||||||
|
import { createTreeNode } from "./render/renderComponent";
|
||||||
|
|
||||||
export const createApp = (componentLibraries, appDefinition, user, uiFunctions) => {
|
export const createApp = (document, componentLibraries, appDefinition, user, uiFunctions) => {
|
||||||
|
|
||||||
const coreApi = createCoreApi(appDefinition, user);
|
const coreApi = createCoreApi(appDefinition, user);
|
||||||
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
|
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
|
||||||
|
@ -50,19 +51,19 @@ export const createApp = (componentLibraries, appDefinition, user, uiFunctions)
|
||||||
if(isFunction(event)) event(context);
|
if(isFunction(event)) event(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialiseChildrenParams = (hydrate, parentContext, childIndex) => ({
|
const initialiseChildrenParams = (hydrate, treeNode) => ({
|
||||||
bb, coreApi, store, parentContext,
|
bb, coreApi, store, document,
|
||||||
componentLibraries, appDefinition,
|
componentLibraries, appDefinition,
|
||||||
hydrate, uiFunctions, childIndex
|
hydrate, uiFunctions, treeNode
|
||||||
});
|
});
|
||||||
|
|
||||||
const bb = (componentProps, componentContext, childIndex) => ({
|
const bb = (treeNode, componentProps) => ({
|
||||||
hydrateChildren: _initialiseChildren(initialiseChildrenParams(true, componentContext, childIndex)),
|
hydrateChildren: _initialiseChildren(initialiseChildrenParams(true, treeNode)),
|
||||||
appendChildren: _initialiseChildren(initialiseChildrenParams(false, componentContext, childIndex)),
|
appendChildren: _initialiseChildren(initialiseChildrenParams(false, treeNode)),
|
||||||
insertChildren: (props, htmlElement, anchor) =>
|
insertChildren: (props, htmlElement, anchor) =>
|
||||||
_initialiseChildren(initialiseChildrenParams(false, componentContext, childIndex))
|
_initialiseChildren(initialiseChildrenParams(false, treeNode))
|
||||||
(props, htmlElement, anchor),
|
(props, htmlElement, anchor),
|
||||||
context: componentContext,
|
context: treeNode.context,
|
||||||
props: componentProps,
|
props: componentProps,
|
||||||
call:safeCallEvent,
|
call:safeCallEvent,
|
||||||
setStateFromBinding: (binding, value) => setStateFromBinding(store, binding, value),
|
setStateFromBinding: (binding, value) => setStateFromBinding(store, binding, value),
|
||||||
|
@ -76,6 +77,6 @@ export const createApp = (componentLibraries, appDefinition, user, uiFunctions)
|
||||||
parent
|
parent
|
||||||
});
|
});
|
||||||
|
|
||||||
return bb();
|
return bb(createTreeNode());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ export const loadBudibase = async ({
|
||||||
}
|
}
|
||||||
|
|
||||||
const app = createApp(
|
const app = createApp(
|
||||||
|
window.document,
|
||||||
componentLibraries,
|
componentLibraries,
|
||||||
appDefinition,
|
appDefinition,
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -12,10 +12,15 @@ export const _initialiseChildren = (initialiseOpts) =>
|
||||||
(childrenProps, htmlElement, anchor=null) => {
|
(childrenProps, htmlElement, anchor=null) => {
|
||||||
|
|
||||||
const { uiFunctions, bb, coreApi,
|
const { uiFunctions, bb, coreApi,
|
||||||
store, componentLibraries, childIndex,
|
store, componentLibraries, treeNode,
|
||||||
appDefinition, parentContext, hydrate } = initialiseOpts;
|
appDefinition, document, hydrate } = initialiseOpts;
|
||||||
|
|
||||||
const childComponents = [];
|
for(let childNode of treeNode.children) {
|
||||||
|
if(childNode.unsubscribe)
|
||||||
|
childNode.unsubscribe();
|
||||||
|
if(childNode.component)
|
||||||
|
childNode.component.$destroy();
|
||||||
|
}
|
||||||
|
|
||||||
if(hydrate) {
|
if(hydrate) {
|
||||||
while (htmlElement.firstChild) {
|
while (htmlElement.firstChild) {
|
||||||
|
@ -23,7 +28,7 @@ export const _initialiseChildren = (initialiseOpts) =>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let childIndex = 0;
|
const renderedComponents = [];
|
||||||
for(let childProps of childrenProps) {
|
for(let childProps of childrenProps) {
|
||||||
|
|
||||||
const {componentName, libName} = splitName(childProps._component);
|
const {componentName, libName} = splitName(childProps._component);
|
||||||
|
@ -34,25 +39,22 @@ export const _initialiseChildren = (initialiseOpts) =>
|
||||||
store, childProps, coreApi,
|
store, childProps, coreApi,
|
||||||
appDefinition.appRootPath);
|
appDefinition.appRootPath);
|
||||||
|
|
||||||
|
|
||||||
const componentConstructor = componentLibraries[libName][componentName];
|
const componentConstructor = componentLibraries[libName][componentName];
|
||||||
|
|
||||||
const {component, context, lastChildIndex} = renderComponent({
|
const renderedComponentsThisIteration = renderComponent({
|
||||||
|
props: childProps,
|
||||||
|
parentNode: treeNode,
|
||||||
componentConstructor,uiFunctions,
|
componentConstructor,uiFunctions,
|
||||||
htmlElement, anchor, childIndex,
|
htmlElement, anchor, initialProps,
|
||||||
parentContext, initialProps, bb});
|
bb, document});
|
||||||
|
|
||||||
childIndex = lastChildIndex;
|
for(let comp of renderedComponentsThisIteration) {
|
||||||
|
comp.unsubscribe = bind(comp.component);
|
||||||
const unsubscribe = bind(component);
|
renderedComponents.push(comp);
|
||||||
childComponents.push({
|
}
|
||||||
component,
|
|
||||||
context,
|
|
||||||
unsubscribe
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return childComponents;
|
return renderedComponents;
|
||||||
}
|
}
|
||||||
|
|
||||||
const splitName = fullname => {
|
const splitName = fullname => {
|
||||||
|
|
|
@ -1,34 +1,43 @@
|
||||||
|
|
||||||
export const renderComponent = ({
|
export const renderComponent = ({
|
||||||
componentConstructor, uiFunctions,
|
componentConstructor, uiFunctions,
|
||||||
htmlElement, anchor, parentContext,
|
htmlElement, anchor, props,
|
||||||
initialProps, bb, childIndex}) => {
|
initialProps, bb, document,
|
||||||
|
parentNode}) => {
|
||||||
|
|
||||||
const func = initialProps._id
|
const func = initialProps._id
|
||||||
? uiFunctions[componentProps._id]
|
? uiFunctions[initialProps._id]
|
||||||
: undefined;
|
: undefined;
|
||||||
|
|
||||||
let component;
|
const parentContext = (parentNode && parentNode.context) || {};
|
||||||
let componentContext;
|
|
||||||
|
let renderedNodes = [];
|
||||||
const render = (context) => {
|
const render = (context) => {
|
||||||
|
|
||||||
|
let componentContext = parentContext;
|
||||||
if(context) {
|
if(context) {
|
||||||
componentContext = {...componentContext};
|
componentContext = {...componentContext};
|
||||||
componentContext.$parent = parentContext;
|
componentContext.$parent = parentContext;
|
||||||
} else {
|
|
||||||
componentContext = parentContext;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
initialProps._bb = bb(initialProps, componentContext);
|
const thisNode = createTreeNode();
|
||||||
|
thisNode.context = componentContext;
|
||||||
|
thisNode.parentNode = parentNode;
|
||||||
|
|
||||||
component = new componentConstructor({
|
parentNode.children.push(thisNode);
|
||||||
|
renderedNodes.push(thisNode);
|
||||||
|
|
||||||
|
initialProps._bb = bb(thisNode, props);
|
||||||
|
|
||||||
|
thisNode.component = new componentConstructor({
|
||||||
target: htmlElement,
|
target: htmlElement,
|
||||||
props: initialProps,
|
props: initialProps,
|
||||||
hydrate:false,
|
hydrate:false,
|
||||||
anchor
|
anchor
|
||||||
});
|
});
|
||||||
|
|
||||||
childIndex += 1;
|
thisNode.rootElement = htmlElement.children[
|
||||||
|
htmlElement.children.length - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(func) {
|
if(func) {
|
||||||
|
@ -37,10 +46,15 @@ export const renderComponent = ({
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
return ({
|
return renderedNodes;
|
||||||
context: componentContext,
|
|
||||||
lastChildIndex: childIndex,
|
|
||||||
component
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const createTreeNode = () => ({
|
||||||
|
context: {},
|
||||||
|
rootElement: null,
|
||||||
|
parentNode: null,
|
||||||
|
children: [],
|
||||||
|
component: null,
|
||||||
|
unsubscribe: () => {}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ const maketestlib = (window) => ({
|
||||||
node.removeChild(c);
|
node.removeChild(c);
|
||||||
}
|
}
|
||||||
const components = currentProps._bb.appendChildren(currentProps._children, node);
|
const components = currentProps._bb.appendChildren(currentProps._children, node);
|
||||||
childNodes = components.map(c => c._element);
|
childNodes = components.map(c => c.component._element);
|
||||||
} else {
|
} else {
|
||||||
currentProps._bb.hydrateChildren(currentProps._children, node);
|
currentProps._bb.hydrateChildren(currentProps._children, node);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue