UNPKG

@dark-engine/core

Version:

The lightweight and powerful UI rendering engine without dependencies and written in TypeScript (Browser, Node.js, Android, iOS, Windows, Linux, macOS)

122 lines (121 loc) 3.65 kB
import { detectIsComponent } from '../component'; import { detectIsArray, detectIsEmpty } from '../utils'; import { REPLACER, KEY_ATTR } from '../constants'; import { $$scope } from '../scope'; const $$vNode = Symbol('vNode'); const PROP_PROPS = 'props'; const PROP_ATTRS = 'attrs'; const PROP_NAME = 'name'; const PROP_TYPE = 'type'; const PROP_CHILDREN = 'children'; class VirtualNode { type = null; constructor(type) { this.type = type; } } class TagVirtualNode extends VirtualNode { name; attrs; children; constructor(name, attrs, children) { super(NodeType.TAG); this.name = name; this.attrs = attrs; this.children = children; } } class TextVirtualNode extends VirtualNode { value; constructor(source) { super(NodeType.TEXT); this.value = String(source); } } class CommentVirtualNode extends VirtualNode { value = ''; constructor(text) { super(NodeType.COMMENT); this.value = text; } } const View = options => { const factory = () => { const { as: name, slot, _void = false, ...attrs } = options; const children = _void ? [] : detectIsArray(slot) ? slot : !detectIsEmpty(slot) ? [slot] : []; return new TagVirtualNode(name, attrs, children); }; factory[$$vNode] = true; factory[PROP_TYPE] = options.as; factory[KEY_ATTR] = options.key; return factory; }; const Text = source => new TextVirtualNode(source); Text.from = x => (detectIsTextVirtualNode(x) ? x.value : String(x)); const Comment = text => new CommentVirtualNode(text); const createReplacer = () => new CommentVirtualNode(REPLACER); const detectIsVirtualNode = x => x instanceof VirtualNode; const detectIsTagVirtualNode = x => x instanceof TagVirtualNode; const detectIsCommentVirtualNode = x => x instanceof CommentVirtualNode; const detectIsTextVirtualNode = x => x instanceof TextVirtualNode; const detectIsVirtualNodeFactory = x => x?.[$$vNode]; const detectIsPlainVirtualNode = x => !detectIsTagVirtualNode(x); const getElementType = inst => inst[PROP_NAME] ?? inst[PROP_TYPE] ?? null; const getElementKey = inst => { return inst ? inst[PROP_PROPS] ? inst[PROP_PROPS][KEY_ATTR] ?? null : inst[PROP_ATTRS] ? inst[PROP_ATTRS][KEY_ATTR] ?? null : inst[KEY_ATTR] ?? null : null; }; const hasChildrenProp = inst => { return inst?.[PROP_CHILDREN] !== undefined; }; const detectAreSameInstanceTypes = (prevInst, nextInst) => { if (process.env.NODE_ENV !== 'production') { if (process.env.NODE_ENV === 'development' && $$scope().getIsHot()) { if (detectIsComponent(prevInst) && detectIsComponent(nextInst)) { return prevInst.displayName === nextInst.displayName; } } } return getElementType(prevInst) === getElementType(nextInst); }; const detectAreSameComponentTypesWithSameKeys = (prevInst, nextInst) => { return ( detectIsComponent(prevInst) && detectIsComponent(nextInst) && detectAreSameInstanceTypes(prevInst, nextInst) && getElementKey(prevInst) === getElementKey(nextInst) ); }; export var NodeType; (function (NodeType) { NodeType['TAG'] = 'TAG'; NodeType['TEXT'] = 'TEXT'; NodeType['COMMENT'] = 'COMMENT'; })(NodeType || (NodeType = {})); export { View, Text, Comment, VirtualNode, TagVirtualNode, TextVirtualNode, CommentVirtualNode, createReplacer, getElementKey, getElementType, hasChildrenProp, detectIsVirtualNode, detectIsTagVirtualNode, detectIsCommentVirtualNode, detectIsTextVirtualNode, detectIsPlainVirtualNode, detectIsVirtualNodeFactory, detectAreSameInstanceTypes, detectAreSameComponentTypesWithSameKeys, }; //# sourceMappingURL=view.js.map