render function, with code blocks - tested simple cases
This commit is contained in:
parent
80514d07bc
commit
9a857dcd77
|
@ -6,8 +6,7 @@ import { trimSlash } from "./common/trimSlash";
|
|||
import { isBound } from "./state/isState";
|
||||
import { _initialiseChildren } from "./render/initialiseChildren";
|
||||
|
||||
export const createApp = (componentLibraries, appDefinition, user) => {
|
||||
|
||||
export const createApp = (componentLibraries, appDefinition, user, uiFunctions) => {
|
||||
|
||||
const coreApi = createCoreApi(appDefinition, user);
|
||||
appDefinition.hierarchy = coreApi.templateApi.constructHierarchy(appDefinition.hierarchy);
|
||||
|
@ -40,7 +39,7 @@ export const createApp = (componentLibraries, appDefinition, user) => {
|
|||
post: apiCall("POST"),
|
||||
get: apiCall("GET"),
|
||||
patch: apiCall("PATCH"),
|
||||
delete:apiCall("DELETE")
|
||||
delete: apiCall("DELETE")
|
||||
};
|
||||
|
||||
const safeCallEvent = (event, context) => {
|
||||
|
@ -54,7 +53,7 @@ export const createApp = (componentLibraries, appDefinition, user) => {
|
|||
const initialiseChildrenParams = (parentContext, hydrate) => ({
|
||||
bb, coreApi, store,
|
||||
componentLibraries, appDefinition,
|
||||
parentContext, hydrate
|
||||
parentContext, hydrate, uiFunctions
|
||||
});
|
||||
|
||||
const bb = (context, props) => ({
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import { createApp } from "./createApp";
|
||||
import { trimSlash } from "./common/trimSlash";
|
||||
|
||||
export const loadBudibase = async ({componentLibraries, props, window, localStorage}) => {
|
||||
export const loadBudibase = async ({
|
||||
componentLibraries, props,
|
||||
window, localStorage, uiFunctions }) => {
|
||||
|
||||
const appDefinition = window["##BUDIBASE_APPDEFINITION##"];
|
||||
|
||||
|
@ -33,7 +35,7 @@ export const loadBudibase = async ({componentLibraries, props, window, localStor
|
|||
props = appDefinition.props;
|
||||
}
|
||||
|
||||
const _app = createApp(componentLibraries, appDefinition, user);
|
||||
const _app = createApp(componentLibraries, appDefinition, user, uiFunctions);
|
||||
_app.hydrateChildren(
|
||||
[props],
|
||||
window.document.body);
|
||||
|
|
|
@ -6,10 +6,15 @@ import {
|
|||
last
|
||||
} from "lodash/fp";
|
||||
import { $ } from "../core/common";
|
||||
import { renderComponent } from "./renderComponent";
|
||||
|
||||
export const _initialiseChildren = ({ bb, coreApi, store, componentLibraries, appDefinition, parentContext, hydrate }) =>
|
||||
export const _initialiseChildren = (initialiseOpts) =>
|
||||
(childrenProps, htmlElement, context, anchor=null) => {
|
||||
|
||||
const { uiFunctions, bb, coreApi,
|
||||
store, componentLibraries,
|
||||
appDefinition, parentContext, hydrate } = initialiseOpts;
|
||||
|
||||
const childComponents = [];
|
||||
|
||||
if(hydrate) {
|
||||
|
@ -19,6 +24,7 @@ export const _initialiseChildren = ({ bb, coreApi, store, componentLibraries, ap
|
|||
}
|
||||
|
||||
for(let childProps of childrenProps) {
|
||||
|
||||
const {componentName, libName} = splitName(childProps._component);
|
||||
|
||||
if(!componentName || !libName) return;
|
||||
|
@ -27,18 +33,19 @@ export const _initialiseChildren = ({ bb, coreApi, store, componentLibraries, ap
|
|||
store, childProps, coreApi,
|
||||
context || parentContext, appDefinition.appRootPath);
|
||||
|
||||
|
||||
/// here needs to go inside renderComponent ???
|
||||
const componentProps = {
|
||||
...initialProps,
|
||||
_bb:bb(context || parentContext, childProps)
|
||||
};
|
||||
|
||||
const component = new (componentLibraries[libName][componentName])({
|
||||
target: htmlElement,
|
||||
props: componentProps,
|
||||
hydrate:false,
|
||||
anchor
|
||||
});
|
||||
const componentConstructor = componentLibraries[libName][componentName];
|
||||
|
||||
const {component} = renderComponent({
|
||||
componentConstructor,uiFunctions,
|
||||
htmlElement, anchor,
|
||||
parentContext, componentProps});
|
||||
|
||||
|
||||
bind(component);
|
||||
childComponents.push(component);
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
export const renderComponent = ({
|
||||
componentConstructor, uiFunctions,
|
||||
htmlElement, anchor, parentContext,
|
||||
componentProps}) => {
|
||||
|
||||
const func = uiFunctions[componentProps._id];
|
||||
let component;
|
||||
let componentContext;
|
||||
const render = (context) => {
|
||||
|
||||
if(context) {
|
||||
componentContext = {...componentContext};
|
||||
componentContext.$parent = parentContext;
|
||||
} else {
|
||||
componentContext = parentContext;
|
||||
}
|
||||
|
||||
component = new componentConstructor({
|
||||
target: htmlElement,
|
||||
props: componentProps,
|
||||
hydrate:false,
|
||||
anchor
|
||||
});
|
||||
}
|
||||
|
||||
if(func) {
|
||||
func(render, parentContext);
|
||||
} else {
|
||||
render();
|
||||
}
|
||||
|
||||
return ({
|
||||
context: componentContext,
|
||||
component
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
import { load } from "./testAppDef";
|
||||
|
||||
describe("controlFlow", () => {
|
||||
|
||||
it("should display simple div, with always true render function", async () => {
|
||||
|
||||
const {dom} = await load({
|
||||
_component: "testlib/div",
|
||||
className: "my-test-class",
|
||||
_id: "always_render"
|
||||
});
|
||||
|
||||
expect(dom.window.document.body.children.length).toBe(1);
|
||||
const child = dom.window.document.body.children[0];
|
||||
expect(child.className).toBe("my-test-class");
|
||||
|
||||
})
|
||||
|
||||
it("should not display div, with always false render function", async () => {
|
||||
|
||||
const {dom} = await load({
|
||||
_component: "testlib/div",
|
||||
className: "my-test-class",
|
||||
_id: "never_render"
|
||||
});
|
||||
|
||||
expect(dom.window.document.body.children.length).toBe(0);
|
||||
|
||||
})
|
||||
|
||||
it("should display 3 divs in a looped render function", async () => {
|
||||
|
||||
const {dom} = await load({
|
||||
_component: "testlib/div",
|
||||
className: "my-test-class",
|
||||
_id: "three_clones"
|
||||
});
|
||||
|
||||
expect(dom.window.document.body.children.length).toBe(3);
|
||||
|
||||
const child0 = dom.window.document.body.children[0];
|
||||
expect(child0.className).toBe("my-test-class");
|
||||
|
||||
const child1 = dom.window.document.body.children[1];
|
||||
expect(child1.className).toBe("my-test-class");
|
||||
|
||||
const child2 = dom.window.document.body.children[2];
|
||||
expect(child2.className).toBe("my-test-class");
|
||||
|
||||
})
|
||||
|
||||
});
|
|
@ -3,16 +3,32 @@ import { loadBudibase } from "../src/index";
|
|||
|
||||
export const load = async (props) => {
|
||||
const dom = new JSDOM(`<!DOCTYPE html><html><body></body><html>`);
|
||||
autoAssignIds(props);
|
||||
setAppDef(dom.window, props);
|
||||
const app = await loadBudibase({
|
||||
componentLibraries: allLibs(dom.window),
|
||||
window: dom.window,
|
||||
localStorage: createLocalStorage(),
|
||||
props
|
||||
props,
|
||||
uiFunctions
|
||||
});
|
||||
return {dom, app};
|
||||
}
|
||||
|
||||
// this happens for real by the builder...
|
||||
// ..this only assigns _ids when missing
|
||||
const autoAssignIds = (props, count=0) => {
|
||||
if(!props._id) {
|
||||
props._id = `auto_id_${count}`;
|
||||
}
|
||||
if(props._children) {
|
||||
for(let child of props._children) {
|
||||
count += 1;
|
||||
autoAssignIds(child, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const setAppDef = (window, props) => {
|
||||
window["##BUDIBASE_APPDEFINITION##"] = ({
|
||||
componentLibraries: [],
|
||||
|
@ -87,5 +103,18 @@ const maketestlib = (window) => ({
|
|||
}
|
||||
});
|
||||
|
||||
const uiFunctions = ({
|
||||
|
||||
never_render : (render, parentContext) => {},
|
||||
|
||||
always_render : (render, parentContext) => {
|
||||
render();
|
||||
},
|
||||
|
||||
three_clones : (render, parentContext) => {
|
||||
for(let i = 0; i<3; i++) {
|
||||
render();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue