lupine.web
Version:
lupine.web is a extremely fast, small size and lightweight frontend framework, using React TSX syntax.
69 lines (64 loc) • 3.18 kB
text/typescript
import { bindAttributes } from './bind-attributes';
import { bindLinks } from './bind-links';
import { VNode } from '../jsx';
// import { Logger } from '../lib/logger';
// import { bindPageResetEvent } from './page-reset-events';
import { callUnload, replaceInnerhtml } from './replace-innerhtml';
import { renderComponent } from './render-component';
// const logger = new Logger('mount-components');
export const mountInnerComponent = async (selector: string | null | Element, jsxNodes: VNode<any>) => {
renderComponent(jsxNodes.type, jsxNodes.props);
const el = selector && (typeof selector === 'string' ? document.querySelector(selector) : selector);
if (el) {
// call unload before releace innerHTML
await replaceInnerhtml(el, jsxNodes.props._html.join(''));
bindAttributes(el, jsxNodes.type, jsxNodes.props);
bindLinks(el);
}
};
// suggest to use HtmlVar.
export const mountOuterComponent = async (selector: string | Element, jsxNodes: VNode<any>) => {
renderComponent(jsxNodes.type, jsxNodes.props);
let el = selector && (typeof selector === 'string' ? document.querySelector(selector) : selector);
if (el) {
// Can't do outerHTML directly because it will lose attributes
const template = document.createElement('template');
// template.innerHTML = jsxNodes.props._html.join("");
// call unload before releace innerHTML
await replaceInnerhtml(template, jsxNodes.props._html.join(''));
// renderComponent should only have one element
template.content.children.length > 1 &&
console.error('renderComponent should only have one element: ', template.content.children.length);
const newEl = template.content.firstChild as Element;
// el.replaceWith(newEl);
await callUnload(el);
el.parentNode?.replaceChild(newEl, el);
bindAttributes(newEl, jsxNodes.type, jsxNodes.props);
bindLinks(newEl);
}
};
// suggest to use HtmlVar.
export const mountSiblingComponent = async (selector: string | Element, jsxNodes: VNode<any>, position: 'before' | 'after' = 'after') => {
renderComponent(jsxNodes.type, jsxNodes.props);
let el = selector && (typeof selector === 'string' ? document.querySelector(selector) : selector);
if (el) {
// Can't do outerHTML directly because it will lose attributes
const template = document.createElement('template');
// template.innerHTML = jsxNodes.props._html.join("");
// call unload before releace innerHTML
await replaceInnerhtml(template, jsxNodes.props._html.join(''));
// renderComponent should only have one element
template.content.children.length > 1 &&
console.error('renderComponent should only have one element: ', template.content.children.length);
const newEl = template.content.firstChild as Element;
// el.replaceWith(newEl);
await callUnload(el);
if (el.nextSibling || position === 'before') {
el.parentNode?.insertBefore(newEl, position === 'after' ? el.nextSibling : el);
} else {
el.parentNode?.appendChild(newEl);
}
bindAttributes(newEl, jsxNodes.type, jsxNodes.props);
bindLinks(newEl);
}
};