UNPKG

neweb

Version:

[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url] [![Coverage percentage][coveralls-image]][coveralls-url] [![experimental](http://badges.github.io/stability-badges/dist/ex

69 lines (68 loc) 2.81 kB
import { JSDOM } from "jsdom"; import { Component, Document } from "neweb-components"; import { IPage } from "neweb-core"; import { BehaviorSubject, Observable, of } from "rxjs"; export interface IPageRendererConfig { app: { getFrameViewClass: (frameName: string) => any; }; } class PageRenderer { constructor(protected config: IPageRendererConfig) { } public async render(page: IPage) { const views = await this.resolveViewClasses(page); const dom = new JSDOM(`<!doctype><html><body><div id="root"></div></body></html>`, { runScripts: "dangerously", }); const window = dom.window; const document = new Document({ window, }); Component.setDocument(document); const rootComponent = this.renderFrame(page.rootFrame, page, views); rootComponent.mount(); const root = window.document.querySelector("#root") as HTMLElement; root.appendChild(rootComponent.getRootElement()); const html = root.innerHTML; // window.close(); return html; } protected renderFrame( frameId: string, page: IPage, views: { [index: string]: any }, ): Component<any> { const pageFrame = page.frames.filter((f) => f.frameId === frameId)[0]; const FrameView = views[pageFrame.frameId]; if (!FrameView) { throw new Error("Not found frame " + pageFrame.frameName); } const children: { [index: string]: Component<any> } = {}; Object.keys(pageFrame.frames).map(async (placeName) => { const childFrameId = pageFrame.frames[placeName]; // const childFrame = page.frames.filter((f) => f.frameId === childFrameId)[0]; children[placeName] = this.renderFrame(childFrameId, page, views); }); const data: { [index: string]: Observable<any> } = {}; Object.keys(pageFrame.data).map((dataName) => { data[dataName] = new BehaviorSubject(pageFrame.data[dataName]); }); const component = new FrameView({ data, children: new BehaviorSubject(children), params: new BehaviorSubject(pageFrame.params), seance: { networkStatus: of("disconnected"), navigateStatus: of("ready"), }, }); return component; } protected async resolveViewClasses(page: IPage) { const views: { [index: string]: any } = {}; await Promise.all(page.frames.map(async (pageFrame) => { views[pageFrame.frameId] = await this.config.app.getFrameViewClass(pageFrame.frameName); })); return views; } } export default PageRenderer;