@dark-engine/platform-server
Version:
Dark renderer for server
95 lines (94 loc) • 3.19 kB
JavaScript
import {
Text,
ROOT,
REF_ATTR,
ATTR_BLACK_LIST,
detectIsFunction,
detectIsUndefined,
NodeType,
detectIsTagVirtualNode,
dummyFn,
detectIsPlainVirtualNode,
detectIsTextVirtualNode,
createReplacer,
detectIsTextBased,
} from '@dark-engine/core';
import { VALUE_ATTR, TEXTAREA_TAG, PREVENT } from '@dark-engine/platform-browser';
import { TagNativeElement, TextNativeElement, CommentNativeElement } from '../native-element';
let chunkIds = {};
function createNativeElement(vNode) {
switch (vNode.type) {
case NodeType.TAG:
return new TagNativeElement(vNode.name);
case NodeType.TEXT:
return new TextNativeElement(vNode.value);
case NodeType.COMMENT:
return new CommentNativeElement(vNode.value);
}
}
function addAttributes(element, vNode) {
const tagElement = element;
for (const attrName in vNode.attrs) {
const attrValue = vNode.attrs[attrName];
if (attrName === REF_ATTR || attrName === PREVENT || detectIsFunction(attrValue)) {
continue;
} else if (!detectIsUndefined(attrValue) && !ATTR_BLACK_LIST[attrName]) {
!patchAttributes(tagElement, attrName, attrValue) && tagElement.setAttribute(attrName, attrValue);
}
}
}
function patchAttributes(element, attrName, attrValue) {
const fn = specialCasesMap[element.name];
const stop = fn ? fn(element, attrName, attrValue) : false;
return stop;
}
const specialCasesMap = {
[TEXTAREA_TAG]: (element, attrName, attrValue) => {
if (attrName === VALUE_ATTR && attrValue) {
const textElement = new TextNativeElement(String(attrValue));
element.children = [textElement];
textElement.parentElement = element;
return true;
}
return false;
},
};
const commit = dummyFn;
const finishCommit = () => (chunkIds = {});
function createChunk(fiber) {
let chunk = '';
const tagNode = fiber?.inst;
const tagElement = fiber?.el;
if (!fiber || !fiber.el || tagNode.name === ROOT) return chunk;
if (!chunkIds[fiber.id]) {
if (detectIsTagVirtualNode(fiber.inst)) {
addAttributes(tagElement, fiber.inst);
chunk = tagElement.render(true);
} else if (detectIsPlainVirtualNode(fiber.inst)) {
chunk = fiber.el.render();
}
} else if (detectIsTagVirtualNode(fiber.inst)) {
chunk = tagElement.render(false);
}
chunkIds[fiber.id] = true;
return chunk;
}
function createNativeChildrenNodes(children, parent) {
const elements = [];
for (const child of children) {
const isTag = detectIsTagVirtualNode(child);
const isText = detectIsTextVirtualNode(child);
const content = isTag || isText ? child : detectIsTextBased(child) ? Text(child) : createReplacer();
const element = createNativeElement(content);
isTag && addAttributes(element, child);
parent && appendNativeElement(element, parent);
if (isTag && child.children.length > 0) {
createNativeChildrenNodes(child.children, element);
}
elements.push(element);
}
return elements;
}
const appendNativeElement = (element, parent) => parent.appendChild(element);
export { createNativeElement, commit, finishCommit, createChunk, createNativeChildrenNodes };
//# sourceMappingURL=dom.js.map