UNPKG

lupine.web

Version:

lupine.web is a extremely fast, small size and lightweight frontend framework, using React TSX syntax.

117 lines (103 loc) 4.25 kB
import { Logger } from '../lib/logger'; import { generateAllGlobalStyles } from './bind-styles'; import { defaultThemeName, getCurrentTheme, updateTheme } from './bind-theme'; import { mountInnerComponent } from './mount-component'; // import { callPageResetEvent } from './page-reset-events'; import { PageRouter } from './page-router'; import { callPageLoadedEvent } from './page-loaded-events'; import { initServerCookies } from './server-cookie'; import { IToClientDelivery } from '../models'; import { getMetaDataObject, getMetaDataTags, getPageTitle } from './bind-meta'; import { initWebEnv } from '../lib/web-env'; import { _lupineJs, PageProps, PageResultType, setRenderPageProps } from './export-lupine'; import { isFrontEnd } from '../lib/is-frontend'; import { WebConfig } from '../lib/web-config'; const logger = new Logger('initialize'); const renderTargetPage = async (props: PageProps, renderPartPage: boolean) => { if (_lupineJs.router instanceof PageRouter) { return _lupineJs.router.handleRoute(props.url, props, renderPartPage); } return await _lupineJs.router(props); }; // this is called by server side for SSR (server-side-rendering) const generatePage = async (props: PageProps, toClientDelivery: IToClientDelivery): Promise<PageResultType> => { setRenderPageProps(props); initWebEnv(toClientDelivery.getWebEnv()); WebConfig.initFromData(toClientDelivery.getWebSetting()); // initWebSetting(toClientDelivery.getWebSetting()); initServerCookies(toClientDelivery.getServerCookie()); // callPageResetEvent(); callPageLoadedEvent(); const jsxNodes = await renderTargetPage(props, false); if (!jsxNodes || !jsxNodes.props) { return { content: `Unexpected url: ${props.url}`, title: '', metaData: '', globalCss: '', themeName: defaultThemeName, }; } await mountInnerComponent(null, jsxNodes); const currentTheme = getCurrentTheme(); const cssText = generateAllGlobalStyles(); const content = jsxNodes.props._html.join(''); return { content, title: getPageTitle(), metaData: getMetaDataTags(), globalCss: cssText, themeName: currentTheme.themeName, }; }; _lupineJs.generatePage = generatePage; const _initSaved = { pageInitialized: false, }; // this is called in the FE when the document is loaded // to avoid circular reference, bindLinks can't call initializePage directly export const initializePage = async (newUrl?: string) => { const currentPageInitialized = _initSaved.pageInitialized; _initSaved.pageInitialized = true; logger.log('initializePage: ', newUrl); if (newUrl) { window.history.pushState({ urlPath: newUrl }, '', newUrl); // prevents browser from storing history with each change: // window.history.replaceState({ html: '', pageTitle: newUrl }, '', newUrl); } const splitUrl = newUrl ? newUrl.split('?') : []; const url = splitUrl[0] || document.location.pathname; const queryString = splitUrl[1] || document.location.search; const props: PageProps = { url, // urlSections: url.split('/').filter((i) => !!i), query: Object.fromEntries(new URLSearchParams(queryString)), // new URLSearchParams(queryString), urlParameters: {}, renderPageFunctions: _lupineJs.renderPageFunctions, }; setRenderPageProps(props); // !currentPageInitialized && callPageResetEvent(); !currentPageInitialized && callPageLoadedEvent(); const jsxNodes = await renderTargetPage(props, currentPageInitialized); if (jsxNodes === null) return; if (!jsxNodes || !jsxNodes.props) { document.querySelector('.lupine-root')!.innerHTML = `Unexpected url: ${url}`; return; } // generateAllGlobalStyles will be updated directly in Browser await mountInnerComponent('.lupine-root', jsxNodes); updateTheme(getCurrentTheme().themeName); // title document.title = getPageTitle(); const metaData = getMetaDataObject(); // meta data? }; if (isFrontEnd()) { addEventListener('popstate', (event) => { initializePage(); }); addEventListener('load', (event) => { initializePage(); }); } _lupineJs.initializePage = initializePage;