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)

144 lines (143 loc) 4.77 kB
import { detectIsComponent, getComponentKey, hasComponentFlag } from '../component'; import { detectIsArray, detectIsFunction, detectIsEmpty } from '../utils'; import { REPLACER, KEY_ATTR } from '../constants'; import { $$scope } from '../scope'; const $$vNode = Symbol('vNode'); const ATTR_TYPE = 'type'; 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; } } function 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[ATTR_TYPE] = options.as; factory[KEY_ATTR] = options.key; return factory; } const Text = source => new TextVirtualNode(source); Text.from = source => (detectIsTextVirtualNode(source) ? source.value : String(source)); const Comment = text => new CommentVirtualNode(text); const detectIsVirtualNode = vNode => vNode instanceof VirtualNode; const detectIsTagVirtualNode = vNode => vNode instanceof TagVirtualNode; const detectIsCommentVirtualNode = vNode => vNode instanceof CommentVirtualNode; const detectIsTextVirtualNode = vNode => vNode instanceof TextVirtualNode; const detectIsVirtualNodeFactory = factory => detectIsFunction(factory) && factory[$$vNode] === true; const getTagVirtualNodeKey = vNode => (vNode.attrs ? vNode.attrs[KEY_ATTR] ?? null : null); const hasTagVirtualNodeFlag = (vNode, flag) => Boolean(vNode.attrs[flag]); const getVirtualNodeFactoryKey = factory => factory[KEY_ATTR] ?? null; const hasVirtualNodeFactoryFlag = (factory, flag) => Boolean(factory[flag]); const detectIsPlainVirtualNode = vNode => detectIsTextVirtualNode(vNode) || detectIsCommentVirtualNode(vNode); const createReplacer = () => new CommentVirtualNode(REPLACER); const detectIsReplacer = vNode => detectIsCommentVirtualNode(vNode) && vNode.value === REPLACER; function getElementKey(inst) { return detectIsComponent(inst) ? getComponentKey(inst) : detectIsVirtualNodeFactory(inst) ? getVirtualNodeFactoryKey(inst) : detectIsTagVirtualNode(inst) ? getTagVirtualNodeKey(inst) : null; } function hasElementFlag(inst, flag) { return detectIsComponent(inst) ? hasComponentFlag(inst, flag) : detectIsVirtualNodeFactory(inst) ? hasVirtualNodeFactoryFlag(inst, flag) : detectIsTagVirtualNode(inst) ? hasTagVirtualNodeFlag(inst, flag) : false; } function getElementType(inst) { return detectIsComponent(inst) ? inst.type : detectIsVirtualNodeFactory(inst) ? inst[ATTR_TYPE] : detectIsTagVirtualNode(inst) ? inst.name : detectIsVirtualNode(inst) ? inst.type : null; } function hasChildrenProp(inst) { return detectIsTagVirtualNode(inst) || detectIsComponent(inst); } function detectAreSameInstanceTypes(prevInst, nextInst, isComponentFactories = false) { 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 isComponentFactories ? prevInst.type === nextInst.type : getElementType(prevInst) === getElementType(nextInst); } function detectAreSameComponentTypesWithSameKeys(prevInst, nextInst) { return ( detectIsComponent(prevInst) && detectIsComponent(nextInst) && detectAreSameInstanceTypes(prevInst, nextInst, true) && 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, detectIsReplacer, getElementKey, hasElementFlag, getElementType, hasChildrenProp, detectIsVirtualNode, detectIsTagVirtualNode, detectIsCommentVirtualNode, detectIsTextVirtualNode, detectIsPlainVirtualNode, detectIsVirtualNodeFactory, detectAreSameInstanceTypes, detectAreSameComponentTypesWithSameKeys, }; //# sourceMappingURL=view.js.map