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)

94 lines (93 loc) 2.61 kB
import { CLEANUP_HOST_MASK, DELETE_EFFECT_TAG, EFFECT_HOST_MASK, HOOK_DELIMETER } from '../constants'; function walk(fiber, onWalk) { let shouldDeep = true; let shouldStop = false; const skip = () => (shouldDeep = false); const stop = () => (shouldStop = true); const stack = [fiber]; while (stack.length !== 0) { const unit = stack.pop(); onWalk(unit, skip, stop); if (shouldStop) break; unit !== fiber && unit.next && stack.push(unit.next); shouldDeep && unit.child && stack.push(unit.child); shouldDeep = true; } } function collectElements(fiber, transform) { const elements = []; walk(fiber, onWalkInCollectElements(elements, transform)); return elements; } function onWalkInCollectElements(elements, transform) { return (fiber, skip) => { if (fiber.el) { !fiber.hook?.getIsPortal() && elements.push(transform(fiber)); return skip(); } }; } function getFiberWithElement(fiber) { let $fiber = fiber; while ($fiber) { if ($fiber.el) return $fiber; $fiber = $fiber.parent; } return $fiber; } function detectIsFiberAlive(fiber) { let $fiber = fiber; while ($fiber) { if ($fiber.tag === DELETE_EFFECT_TAG) return false; $fiber = $fiber.parent; } return Boolean(fiber); } function getSuspense(fiber, isPending) { let suspense = fiber; while (suspense) { if (suspense.hook?.getIsSuspense() && (isPending ? suspense.hook.getIsPending() : true)) return suspense; suspense = suspense.parent; } return null; } function resolveSuspense(fiber) { return getSuspense(fiber, true) || getSuspense(fiber, false) || null; } function resolveBoundary(fiber) { let boundary = fiber; while (boundary) { if (boundary.hook?.getIsBoundary()) return boundary; boundary = boundary.parent; } return null; } function createHookLoc(rootId, idx, hook) { const fiber = hook.owner; let $fiber = fiber; let loc = `${fiber.idx}${HOOK_DELIMETER}${idx}`; while ($fiber) { $fiber = $fiber.parent; $fiber && (loc = `${$fiber.idx}.${loc}`); } loc = `[${rootId}]${loc}`; return loc; } const createLoc = (rootId, idx, hook) => () => createHookLoc(rootId, idx, hook); function notifyParents(fiber, alt = fiber) { fiber.increment(alt.el ? 1 : alt.cec); alt.mask & EFFECT_HOST_MASK && fiber.markHost(EFFECT_HOST_MASK); alt.mask & CLEANUP_HOST_MASK && fiber.markHost(CLEANUP_HOST_MASK); } export { walk, collectElements, getFiberWithElement, detectIsFiberAlive, resolveSuspense, resolveBoundary, createHookLoc, createLoc, notifyParents, }; //# sourceMappingURL=walk.js.map