diff --git a/packages/core/src/fiber/fiber.ts b/packages/core/src/fiber/fiber.ts index ea190e78..2ae09358 100644 --- a/packages/core/src/fiber/fiber.ts +++ b/packages/core/src/fiber/fiber.ts @@ -357,7 +357,7 @@ function mutateFiber(options: MutateFiberOptions) { } if (!fiber.nativeElement && detectIsVirtualNode(fiber.instance)) { - fiber.nativeElement = platform.createNativeElement(fiber); + fiber.nativeElement = platform.createNativeElement(fiber.instance); } } diff --git a/packages/core/src/helpers/index.ts b/packages/core/src/helpers/index.ts index 5bd09cb7..31b5ddb5 100644 --- a/packages/core/src/helpers/index.ts +++ b/packages/core/src/helpers/index.ts @@ -1,13 +1,21 @@ import type { NestedArray } from '../shared'; const detectIsFunction = (o: any): o is Function => typeof o === 'function'; -const detectIsUndefined = (o: any) => typeof o === 'undefined'; -const detectIsNumber = (o: any) => typeof o === 'number'; -const detectIsString = (o: any) => typeof o === 'string'; -const detectIsObject = (o: any) => typeof o === 'object'; -const detectIsBoolean = (o: any) => typeof o === 'boolean'; + +const detectIsUndefined = (o: any): o is undefined => typeof o === 'undefined'; + +const detectIsNumber = (o: any): o is number => typeof o === 'number'; + +const detectIsString = (o: any): o is string => typeof o === 'string'; + +const detectIsObject = (o: any): o is object => typeof o === 'object'; + +const detectIsBoolean = (o: any): o is boolean => typeof o === 'boolean'; + const detectIsArray = (o: any): o is Array => Array.isArray(o); -const detectIsNull = (o: any) => o === null; + +const detectIsNull = (o: any): o is null => o === null; + const detectIsEmpty = (o: any) => detectIsNull(o) || detectIsUndefined(o); function error(str: string) { diff --git a/packages/core/src/platform/types.ts b/packages/core/src/platform/types.ts index 8e6a6c6e..291e4541 100644 --- a/packages/core/src/platform/types.ts +++ b/packages/core/src/platform/types.ts @@ -1,11 +1,12 @@ import { type Fiber } from '../fiber'; import { type TaskPriority } from '../constants'; import { type ComponentFactory } from '../component'; +import { type VirtualNode } from '../view'; export type Platform = { scheduleCallback: (callback: () => void, options?: ScheduleCallbackOptions) => void; shouldYeildToHost: () => boolean; - createNativeElement: (fiber: Fiber) => N; + createNativeElement: (vNode: VirtualNode) => N; applyCommit: (fiber: Fiber) => void; finishCommitWork: () => void; detectIsPortal: (factory: ComponentFactory) => boolean; diff --git a/packages/core/src/view/view.ts b/packages/core/src/view/view.ts index 4bb9f334..2a571de5 100644 --- a/packages/core/src/view/view.ts +++ b/packages/core/src/view/view.ts @@ -1,5 +1,5 @@ import { EMPTY_NODE, ATTR_KEY } from '../constants'; -import { detectIsArray, detectIsEmpty, detectIsFunction } from '../helpers'; +import { detectIsArray, detectIsEmpty, detectIsFunction, detectIsString } from '../helpers'; import type { DarkElementKey } from '../shared'; import type { ComponentFactory, StandardComponentProps } from '../component'; import { NodeType, type ViewDef } from './types'; @@ -56,9 +56,13 @@ class CommentVirtualNode extends VirtualNode { } const detectIsVirtualNode = (vNode: unknown): vNode is VirtualNode => vNode instanceof VirtualNode; + const detectIsTagVirtualNode = (vNode: unknown): vNode is TagVirtualNode => vNode instanceof TagVirtualNode; + const detectIsCommentVirtualNode = (vNode: unknown): vNode is CommentVirtualNode => vNode instanceof CommentVirtualNode; + const detectIsTextVirtualNode = (vNode: unknown): vNode is TextVirtualNode => vNode instanceof TextVirtualNode; + const detectIsEmptyVirtualNode = (vNode: unknown): boolean => detectIsCommentVirtualNode(vNode) && vNode.value === EMPTY_NODE; @@ -68,20 +72,10 @@ function getVirtualNodeKey(vNode: TagVirtualNode): DarkElementKey | null { return !detectIsEmpty(key) ? key : null; } -function Text(source: string | StandardComponentProps['slot']): string | TextVirtualNode { - const text = - typeof source === 'string' ? new TextVirtualNode(source) : detectIsTextVirtualNode(source) ? source.value : ''; - - return text; -} - -function Comment(text: string): CommentVirtualNodeFactory { - const factory = () => new CommentVirtualNode(text); - - factory[$$virtualNode] = true; +const createEmptyVirtualNode = () => new CommentVirtualNode(EMPTY_NODE); - return factory; -} +const detectIsVirtualNodeFactory = (factory: unknown): factory is VirtualNodeFactory => + detectIsFunction(factory) && factory[$$virtualNode] === true; function View(def: ViewDef): TagVirtualNodeFactory { const factory = () => { @@ -101,10 +95,23 @@ function View(def: ViewDef): TagVirtualNodeFactory { return factory; } -const createEmptyVirtualNode = () => new CommentVirtualNode(EMPTY_NODE); +function Text(source: string | StandardComponentProps['slot']): string | TextVirtualNode { + const text = detectIsString(source) + ? new TextVirtualNode(source) + : detectIsTextVirtualNode(source) + ? source.value + : ''; -const detectIsVirtualNodeFactory = (factory: unknown): factory is VirtualNodeFactory => - detectIsFunction(factory) && factory[$$virtualNode] === true; + return text; +} + +function Comment(text: string): CommentVirtualNodeFactory { + const factory = () => new CommentVirtualNode(text); + + factory[$$virtualNode] = true; + + return factory; +} export { VirtualNode, @@ -117,9 +124,9 @@ export { detectIsTextVirtualNode, detectIsEmptyVirtualNode, getVirtualNodeKey, - Text, - Comment, - View, createEmptyVirtualNode, detectIsVirtualNodeFactory, + View, + Text, + Comment, }; diff --git a/packages/platform-browser/src/dom/dom.ts b/packages/platform-browser/src/dom/dom.ts index 02b92a25..dd0054b7 100644 --- a/packages/platform-browser/src/dom/dom.ts +++ b/packages/platform-browser/src/dom/dom.ts @@ -28,7 +28,7 @@ const attrBlackListMap = { let fragmentsMap: Map = new Map(); -function createElement(vNode: VirtualNode): DOMElement { +function createNativeElement(vNode: VirtualNode): DOMElement { const map = { [NodeType.TAG]: (vNode: VirtualNode) => { const tagNode = vNode as TagVirtualNode; @@ -55,7 +55,7 @@ function createElement(vNode: VirtualNode): DOMElement { return map[vNode.type](vNode); } -function detectIsSvgElement(tagName) { +function detectIsSvgElement(tagName: string) { const tagMap = { svg: true, circle: true, @@ -85,14 +85,6 @@ function detectIsSvgElement(tagName) { return Boolean(tagMap[tagName]); } -function createNativeElement(fiber: Fiber): DOMElement { - if (!detectIsVirtualNode(fiber.instance)) { - throw new Error('[Dark]: createNativeElement receives only virtual node!'); - } - - return createElement(fiber.instance); -} - function applyRef(ref: MutableRef, element: Element) { if (detectIsRef(ref)) { ref.current = element;