diff --git a/libs/horizon/src/dom/utils/Common.ts b/libs/horizon/src/dom/utils/Common.ts index 30c172cf..dde99489 100644 --- a/libs/horizon/src/dom/utils/Common.ts +++ b/libs/horizon/src/dom/utils/Common.ts @@ -84,3 +84,7 @@ const types = ['button', 'input', 'select', 'textarea']; export function shouldAutoFocus(tagName: string, props: Props): boolean { return types.includes(tagName) ? Boolean(props.autoFocus) : false; } + +export function isNotNull(object: any): boolean { + return object !== null && object !== undefined; +} diff --git a/libs/horizon/src/dom/validators/ValidateProps.ts b/libs/horizon/src/dom/validators/ValidateProps.ts index f025ce63..ed1f0132 100644 --- a/libs/horizon/src/dom/validators/ValidateProps.ts +++ b/libs/horizon/src/dom/validators/ValidateProps.ts @@ -73,7 +73,7 @@ export function isInvalidValue( propDetails: PropDetails | null, isNativeTag: boolean ): boolean { - if (value == null) { + if (value === null || value === undefined) { return true; } @@ -104,7 +104,7 @@ export function validateProps(type, props) { } // style属性必须是对象 - if (props.style != null && typeof props.style !== 'object') { + if (props.style !== null && props.style !== undefined && typeof props.style !== 'object') { throw new Error('style should be a object.'); } diff --git a/libs/horizon/src/dom/valueHandler/InputValueHandler.ts b/libs/horizon/src/dom/valueHandler/InputValueHandler.ts index 824d57dd..16908947 100644 --- a/libs/horizon/src/dom/valueHandler/InputValueHandler.ts +++ b/libs/horizon/src/dom/valueHandler/InputValueHandler.ts @@ -29,7 +29,7 @@ function getInitValue(dom: HTMLInputElement, props: Props) { export function getInputPropsWithoutValue(dom: HTMLInputElement, props: Props) { // checked属于必填属性,无法置 let { checked } = props; - if (checked == null) { + if (checked === undefined) { checked = getInitValue(dom, props).initChecked; } @@ -45,12 +45,12 @@ export function getInputPropsWithoutValue(dom: HTMLInputElement, props: Props) { export function updateInputValue(dom: HTMLInputElement, props: Props) { const { value, checked } = props; - if (value != null) { + if (value !== undefined) { // 处理 dom.value 逻辑 if (dom.value !== String(value)) { dom.value = String(value); } - } else if (checked != null) { + } else if (checked !== undefined) { updateCommonProp(dom, 'checked', checked, true); } } @@ -60,7 +60,7 @@ export function setInitInputValue(dom: HTMLInputElement, props: Props) { const { value, defaultValue } = props; const { initValue, initChecked } = getInitValue(dom, props); - if (value != null || defaultValue != null) { + if (value !== undefined || defaultValue !== undefined) { // value 的使用优先级 value 属性 > defaultValue 属性 > 空字符串 const initValueStr = String(initValue); diff --git a/libs/horizon/src/dom/valueHandler/SelectValueHandler.ts b/libs/horizon/src/dom/valueHandler/SelectValueHandler.ts index fb9f859e..9ba9273f 100644 --- a/libs/horizon/src/dom/valueHandler/SelectValueHandler.ts +++ b/libs/horizon/src/dom/valueHandler/SelectValueHandler.ts @@ -69,18 +69,18 @@ export function updateSelectValue(dom: HorizonSelect, props: Props, isInit = fal dom._multiple = newMultiple; // 设置了 value 属性 - if (value != null) { + if (value !== null && value !== undefined) { updateValue(dom.options, value, newMultiple); } else if (oldMultiple !== newMultiple) { // 修改了 multiple 属性 // 切换 multiple 之后,如果设置了 defaultValue 需要重新应用 - if (defaultValue != null) { + if (defaultValue !== null && defaultValue !== undefined) { updateValue(dom.options, defaultValue, newMultiple); } else { // 恢复到未选定状态 updateValue(dom.options, newMultiple ? [] : '', newMultiple); } - } else if (isInit && defaultValue != null) { + } else if (isInit && defaultValue !== null && defaultValue !== undefined) { // 设置了 defaultValue 属性 updateValue(dom.options, defaultValue, newMultiple); } diff --git a/libs/horizon/src/dom/valueHandler/TextareaValueHandler.ts b/libs/horizon/src/dom/valueHandler/TextareaValueHandler.ts index 82b2203e..cf91b9c0 100644 --- a/libs/horizon/src/dom/valueHandler/TextareaValueHandler.ts +++ b/libs/horizon/src/dom/valueHandler/TextareaValueHandler.ts @@ -19,7 +19,7 @@ import { Props } from '../utils/Interface'; function getInitValue(props: Props) { const { value } = props; - if (value == null) { + if (value === undefined) { const { defaultValue, children } = props; let initValue = defaultValue; @@ -30,7 +30,7 @@ function getInitValue(props: Props) { } // defaultValue 属性未配置,置为空字符串 - initValue = initValue != null ? initValue : ''; + initValue = initValue ?? ''; return initValue; } else { return value; diff --git a/libs/horizon/src/event/EventBinding.ts b/libs/horizon/src/event/EventBinding.ts index e4e0f59d..baf965dd 100644 --- a/libs/horizon/src/event/EventBinding.ts +++ b/libs/horizon/src/event/EventBinding.ts @@ -62,13 +62,6 @@ function isCaptureEvent(horizonEventName) { return horizonEventName.slice(-7) === 'Capture'; } -// 利用冒泡事件模拟不冒泡事件,需要直接在根节点绑定 -export function listenSimulatedDelegatedEvents(root: VNode) { - for (let i = 0; i < simulatedDelegatedEvents.length; i++) { - lazyDelegateOnRoot(root, simulatedDelegatedEvents[i]); - } -} - // 事件懒委托,当用户定义事件后,再进行委托到根节点 export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) { currentRoot.delegatedEvents.add(eventName); @@ -80,11 +73,8 @@ export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) { const nativeFullName = isCapture ? nativeEvent + 'capture' : nativeEvent; // 事件存储在DOM节点属性,避免多个VNode(root和portal)对应同一个DOM, 造成事件重复监听 - let events = currentRoot.realNode.$EV; - - if (!events) { - events = (currentRoot.realNode as any).$EV = {}; - } + currentRoot.realNode.$EV = currentRoot.realNode.$EV ?? {}; + const events = currentRoot.realNode.$EV; if (!events[nativeFullName]) { events[nativeFullName] = listenToNativeEvent(nativeEvent, currentRoot.realNode, isCapture); @@ -92,6 +82,13 @@ export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) { }); } +// 利用冒泡事件模拟不冒泡事件,需要直接在根节点绑定 +export function listenSimulatedDelegatedEvents(root: VNode) { + for (let i = 0; i < simulatedDelegatedEvents.length; i++) { + lazyDelegateOnRoot(root, simulatedDelegatedEvents[i]); + } +} + // 通过horizon事件名获取到native事件名 function getNativeEvtName(horizonEventName, capture) { let nativeName; diff --git a/libs/horizon/src/event/FormValueController.ts b/libs/horizon/src/event/FormValueController.ts index 3c63a299..1b1649d0 100644 --- a/libs/horizon/src/event/FormValueController.ts +++ b/libs/horizon/src/event/FormValueController.ts @@ -14,7 +14,7 @@ */ import { getVNodeProps } from '../dom/DOMInternalKeys'; -import { getDomTag } from '../dom/utils/Common'; +import { getDomTag, isNotNull } from '../dom/utils/Common'; import { Props } from '../dom/utils/Interface'; import { updateTextareaValue } from '../dom/valueHandler/TextareaValueHandler'; import { updateInputHandlerIfChanged } from '../dom/valueHandler/ValueChangeHandler'; @@ -41,14 +41,14 @@ function controlInputValue(inputDom: HTMLInputElement, props: Props) { const { name, type } = props; // 如果是 radio,找出同一form内,name相同的Radio,更新它们Handler的Value - if (type === 'radio' && name != null) { + if (type === 'radio' && isNotNull(name)) { const radioList = document.querySelectorAll(`input[type="radio"][name="${name}"]`); for (let i = 0; i < radioList.length; i++) { const radio = radioList[i]; if (radio === inputDom) { continue; } - if (radio.form != null && inputDom.form != null && radio.form !== inputDom.form) { + if (isNotNull(radio.form) && isNotNull(inputDom.form) && radio.form !== inputDom.form) { continue; } diff --git a/libs/horizon/src/event/ListenerGetter.ts b/libs/horizon/src/event/ListenerGetter.ts index 3b19cf2a..02feee6f 100644 --- a/libs/horizon/src/event/ListenerGetter.ts +++ b/libs/horizon/src/event/ListenerGetter.ts @@ -87,34 +87,30 @@ export function getListenersFromTree( return listeners; } -// 获取enter和leave事件队列 -export function collectMouseListeners( - leaveEvent: null | WrappedEvent, - enterEvent: null | WrappedEvent, - from: VNode | null, - to: VNode | null, -): ListenerUnitList { - // 确定公共父节点,作为在树上遍历的终点 - const commonParent = from && to ? getCommonAncestor(from, to) : null; - let leaveEventList: ListenerUnitList = []; - if (from && leaveEvent) { - // 遍历树,获取绑定的leave事件 - leaveEventList = getMouseListenersFromTree( - leaveEvent, - from, - commonParent, - ); + +// 获取父节点 +function getParent(inst: VNode | null): VNode | null { + if (inst === null) { + return null; } - let enterEventList: ListenerUnitList = []; - if (to && enterEvent) { - // 先触发父节点enter事件,所以需要逆序 - enterEventList = getMouseListenersFromTree( - enterEvent, - to, - commonParent, - ).reverse(); + do { + inst = inst.parent; + } while (inst && inst.tag !== DomComponent); + return inst || null; +} + +// 寻找两个节点的共同最近祖先,如果没有则返回null +function getCommonAncestor(instA: VNode, instB: VNode): VNode | null { + const parentsSet = new Set(); + for (let tempA: VNode | null = instA; tempA; tempA = getParent(tempA)) { + parentsSet.add(tempA); } - return [...leaveEventList, ...enterEventList]; + for (let tempB: VNode | null = instB; tempB; tempB = getParent(tempB)) { + if (parentsSet.has(tempB)) { + return tempB; + } + } + return null; } function getMouseListenersFromTree( @@ -149,27 +145,32 @@ function getMouseListenersFromTree( return listeners; } -// 寻找两个节点的共同最近祖先,如果没有则返回null -function getCommonAncestor(instA: VNode, instB: VNode): VNode | null { - const parentsSet = new Set(); - for (let tempA: VNode | null = instA; tempA; tempA = getParent(tempA)) { - parentsSet.add(tempA); +// 获取enter和leave事件队列 +export function collectMouseListeners( + leaveEvent: null | WrappedEvent, + enterEvent: null | WrappedEvent, + from: VNode | null, + to: VNode | null, +): ListenerUnitList { + // 确定公共父节点,作为在树上遍历的终点 + const commonParent = from && to ? getCommonAncestor(from, to) : null; + let leaveEventList: ListenerUnitList = []; + if (from && leaveEvent) { + // 遍历树,获取绑定的leave事件 + leaveEventList = getMouseListenersFromTree( + leaveEvent, + from, + commonParent, + ); } - for (let tempB: VNode | null = instB; tempB; tempB = getParent(tempB)) { - if (parentsSet.has(tempB)) { - return tempB; - } + let enterEventList: ListenerUnitList = []; + if (to && enterEvent) { + // 先触发父节点enter事件,所以需要逆序 + enterEventList = getMouseListenersFromTree( + enterEvent, + to, + commonParent, + ).reverse(); } - return null; -} - -// 获取父节点 -function getParent(inst: VNode | null): VNode | null { - if (inst === null) { - return null; - } - do { - inst = inst.parent; - } while (inst && inst.tag !== DomComponent); - return inst || null; + return [...leaveEventList, ...enterEventList]; } diff --git a/libs/horizon/src/renderer/TreeBuilder.ts b/libs/horizon/src/renderer/TreeBuilder.ts index 9798bb8a..ad27609c 100644 --- a/libs/horizon/src/renderer/TreeBuilder.ts +++ b/libs/horizon/src/renderer/TreeBuilder.ts @@ -139,7 +139,7 @@ function bubbleVNode(vNode: VNode): void { node = parent; // 更新processing,抛出异常时可以使用 processing = node; - } while (node !== null); + } while (node); // 修改结果 if (getBuildResult() === BuildInComplete) { @@ -180,7 +180,7 @@ function getChildByIndex(vNode: VNode, idx: number) { let node = vNode.child; for (let i = 0; i < idx; i++) { // 场景:当组件被销毁,业务若异步(定时器)调用setState修改状态,可能出现路径错误,此处进行保护。 - if (node == null) { + if (node === null || node === undefined) { return null; } @@ -225,7 +225,7 @@ export function calcStartUpdateVNode(treeRoot: VNode) { const pathIndex = Number(startNodePath[i]); node = getChildByIndex(node, pathIndex)!; // 路径错误时,回退到从根更新 - if (node == null) { + if (node === null) { return treeRoot; } } diff --git a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts index 42f30b53..83798c68 100644 --- a/libs/horizon/src/renderer/diff/nodeDiffComparator.ts +++ b/libs/horizon/src/renderer/diff/nodeDiffComparator.ts @@ -182,6 +182,10 @@ function getNewNode(parentNode: VNode, newChild: any, oldNode: VNode | null) { } break; } + break; + } + default: { + break; } } @@ -374,7 +378,7 @@ function diffArrayNodesHandler(parentNode: VNode, firstChild: VNode | null, newC // 4. 新节点还有一部分,但是老节点已经没有了 if (oldNode === null) { let isDirectAdd = false; - // TODO: 是否可以扩大至非dom类型节点 + // 是否可以扩大至非dom类型节点待确认 // 如果dom节点在上次添加前没有节点,说明本次添加时,可以直接添加到最后,不需要通过 getSiblingDom 函数找到 before 节点 if ( parentNode.tag === DomComponent && @@ -513,7 +517,7 @@ function diffIteratorNodesHandler( } // 新节点是字符串类型 -function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode, isComparing: boolean) { +function diffStringNodeHandler(parentNode: VNode, newChild: any, firstChildVNode: VNode | null, isComparing: boolean) { let newTextNode: VNode | null = null; // 第一个vNode是Text,则复用 @@ -560,7 +564,7 @@ function diffObjectNodeHandler( } let resultNode: VNode | null = null; - let startDelVNode = firstChildVNode; + let startDelVNode: VNode | null = firstChildVNode; if (newChild.vtype === TYPE_COMMON_ELEMENT) { if (canReuseNode) { // 可以复用 diff --git a/libs/horizon/src/renderer/hooks/BaseHook.ts b/libs/horizon/src/renderer/hooks/BaseHook.ts index 3ffcaf62..0109bf62 100644 --- a/libs/horizon/src/renderer/hooks/BaseHook.ts +++ b/libs/horizon/src/renderer/hooks/BaseHook.ts @@ -52,7 +52,7 @@ export function createHook(state: any = null): Hook { return currentHook; } -export function getNextHook(hook: Hook, hooks: Array>) { +export function getNextHook(hook: Hook, hooks: Array>): Hook | null { return hooks[hook.hIndex + 1] || null; } diff --git a/libs/horizon/src/renderer/hooks/UseImperativeHook.ts b/libs/horizon/src/renderer/hooks/UseImperativeHook.ts index 3ae2feef..9a39a69b 100644 --- a/libs/horizon/src/renderer/hooks/UseImperativeHook.ts +++ b/libs/horizon/src/renderer/hooks/UseImperativeHook.ts @@ -17,12 +17,9 @@ import { useLayoutEffectImpl } from './UseEffectHook'; import { getHookStage } from './HookStage'; import { throwNotInFuncError } from './BaseHook'; import type { Ref } from './HookType'; +import { isNotNull } from '../../dom/utils/Common'; -function isNotNull(object: any): boolean { - return object !== null && object !== undefined; -} - -function effectFunc(func: () => R, ref: Ref | ((any) => any) | null): (() => void) | void { +function effectFunc(func: () => R, ref: Ref | ((any) => any) | null): (() => void) | null { if (typeof ref === 'function') { const value = func(); ref(value); @@ -37,6 +34,7 @@ function effectFunc(func: () => R, ref: Ref | ((any) => any) | null): (() ref.current = null; }; } + return null; } export function useImperativeHandleImpl( diff --git a/libs/horizon/src/renderer/render/ContextProvider.ts b/libs/horizon/src/renderer/render/ContextProvider.ts index 1eadd6cc..6a8f7810 100644 --- a/libs/horizon/src/renderer/render/ContextProvider.ts +++ b/libs/horizon/src/renderer/render/ContextProvider.ts @@ -64,7 +64,7 @@ function handleContextChange(processing: VNode, context: ContextType): void node => { const depContexts = node.depContexts; if (depContexts && depContexts.length) { - isMatch = matchDependencies(depContexts, context, node) ?? isMatch; + isMatch = matchDependencies(depContexts, context, node) || isMatch; } }, node => diff --git a/libs/horizon/src/renderer/render/DomComponent.ts b/libs/horizon/src/renderer/render/DomComponent.ts index 2eaef98b..77273d96 100644 --- a/libs/horizon/src/renderer/render/DomComponent.ts +++ b/libs/horizon/src/renderer/render/DomComponent.ts @@ -54,7 +54,7 @@ export function bubbleRender(processing: VNode) { const type = processing.type; const newProps = processing.props; - if (!processing.isCreated && processing.realNode != null) { + if (!processing.isCreated && processing.realNode !== null) { // 更新dom属性 updateDom(processing, type, newProps); diff --git a/libs/horizon/src/renderer/render/DomText.ts b/libs/horizon/src/renderer/render/DomText.ts index 6f46901c..663f15f6 100644 --- a/libs/horizon/src/renderer/render/DomText.ts +++ b/libs/horizon/src/renderer/render/DomText.ts @@ -18,6 +18,7 @@ import type { VNode } from '../Types'; import { throwIfTrue } from '../utils/throwIfTrue'; import { newTextDom } from '../../dom/DOMOperator'; import { FlagUtils } from '../vnode/VNodeFlags'; +import { isNull } from '../../dom/utils/Common'; export function captureRender(): VNode | null { return null; @@ -26,7 +27,7 @@ export function captureRender(): VNode | null { export function bubbleRender(processing: VNode) { const newText = processing.props; - if (!processing.isCreated && processing.realNode != null) { + if (!processing.isCreated && processing.realNode !== null) { // 更新 const oldText = processing.oldProps; // 如果文本不同,将其标记为更新 diff --git a/libs/horizon/src/renderer/render/SuspenseComponent.ts b/libs/horizon/src/renderer/render/SuspenseComponent.ts index 82c04dee..4bc1a3b6 100644 --- a/libs/horizon/src/renderer/render/SuspenseComponent.ts +++ b/libs/horizon/src/renderer/render/SuspenseComponent.ts @@ -165,7 +165,7 @@ function canCapturePromise(vNode: VNode | null): boolean { // 处理Suspense子组件抛出的promise export function handleSuspenseChildThrowError(parent: VNode, processing: VNode, promise: PromiseType): boolean { - let vNode = parent; + let vNode: VNode | null = parent; // 向上找到最近的不在fallback状态的Suspense,并触发重新渲染 do { diff --git a/libs/horizon/src/renderer/render/class/ClassLifeCycleProcessor.ts b/libs/horizon/src/renderer/render/class/ClassLifeCycleProcessor.ts index f1fe2d1d..bf3c9c14 100644 --- a/libs/horizon/src/renderer/render/class/ClassLifeCycleProcessor.ts +++ b/libs/horizon/src/renderer/render/class/ClassLifeCycleProcessor.ts @@ -35,7 +35,7 @@ export function callDerivedStateFromProps( const newState = getDerivedStateFromProps(nextProps, oldState); // 组件未返回state,需要返回旧的preState - processing.state = newState === null || newState === undefined ? oldState : { ...oldState, ...newState }; + processing.state = newState ? { ...oldState, ...newState } : oldState; } } diff --git a/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts b/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts index 729dfbc8..bec90454 100644 --- a/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts +++ b/libs/horizon/src/renderer/taskExecutor/RenderQueue.ts @@ -35,7 +35,7 @@ function callRenderQueue() { try { let callback; - while ((callback = renderQueue.shift())) { + while (callback = renderQueue.shift()) { callback(); } diff --git a/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts b/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts index 3c0bfcfe..84fa08bd 100644 --- a/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts +++ b/libs/horizon/src/renderer/taskExecutor/TaskQueue.ts @@ -63,12 +63,12 @@ export function add(node: Node): void { export function first(): Node | null { const val: Node | null | undefined = taskQueue[0]; - return val !== undefined ? val : null; + return val ?? null; } export function shift(): Node | null { const val = taskQueue.shift(); - return val !== undefined ? val : null; + return val ?? null; } export function remove(node: Node) { diff --git a/libs/horizon/src/renderer/vnode/VNodeCreator.ts b/libs/horizon/src/renderer/vnode/VNodeCreator.ts index 73944854..65b777c8 100644 --- a/libs/horizon/src/renderer/vnode/VNodeCreator.ts +++ b/libs/horizon/src/renderer/vnode/VNodeCreator.ts @@ -136,7 +136,7 @@ export function createUndeterminedVNode(type, key, props, source: Source | null) vNodeTag = typeMap[type.vtype]; isLazy = type.vtype === TYPE_LAZY; } else { - throw Error(`Component type is invalid, got: ${type == null ? type : componentType}`); + throw Error(`Component type is invalid, got: ${type === null || type === undefined ? type : componentType}`); } const vNode = newVirtualNode(vNodeTag, key, props); @@ -183,7 +183,7 @@ export function createTreeRootVNode(container) { return vNode; } -// TODO: 暂时保留给测试用例使用,后续修改测试用例 +// 暂时保留给测试用例使用,后续修改测试用例 export function createVNode(tag: VNodeTag | string, ...secondArg) { let vNode = null; switch (tag) { diff --git a/libs/horizon/src/renderer/vnode/VNodeFlags.ts b/libs/horizon/src/renderer/vnode/VNodeFlags.ts index 31e40aa7..7ca52c55 100644 --- a/libs/horizon/src/renderer/vnode/VNodeFlags.ts +++ b/libs/horizon/src/renderer/vnode/VNodeFlags.ts @@ -36,71 +36,71 @@ export const ForceUpdate = /** */ 1 << 12; // For suspense export const Clear = /** */ 1 << 13; const LifecycleEffectArr = Update | Callback | Ref | Snapshot; -export class FlagUtils { - static removeFlag(node: VNode, flag: number) { +export const FlagUtils = { + removeFlag(node: VNode, flag: number) { node.flags &= ~flag; - } + }, - static removeLifecycleEffectFlags(node) { + removeLifecycleEffectFlags(node) { node.flags &= ~LifecycleEffectArr; - } + }, - static hasAnyFlag(node: VNode) { + hasAnyFlag(node: VNode) { // 有标志位 return node.flags !== InitFlag; - } + }, - static hasFlag(node: VNode, flag) { + hasFlag(node: VNode, flag) { return (node.flags & flag) !== 0; - } + }, - static setNoFlags(node: VNode) { + setNoFlags(node: VNode) { node.flags = InitFlag; - } + }, - static markAddition(node: VNode) { + markAddition(node: VNode) { node.flags |= Addition; - } + }, - static setAddition(node: VNode) { + setAddition(node: VNode) { node.flags = Addition; - } + }, - static markDirectAddition(node: VNode) { + markDirectAddition(node: VNode) { node.flags |= DirectAddition; - } - static markUpdate(node: VNode) { + }, + markUpdate(node: VNode) { node.flags |= Update; - } - static setDeletion(node: VNode) { + }, + setDeletion(node: VNode) { node.flags = Deletion; - } - static markContentReset(node: VNode) { + }, + markContentReset(node: VNode) { node.flags |= ResetText; - } - static markCallback(node: VNode) { + }, + markCallback(node: VNode) { node.flags |= Callback; - } - static markDidCapture(node: VNode) { + }, + markDidCapture(node: VNode) { node.flags |= DidCapture; - } - static markShouldCapture(node: VNode) { + }, + markShouldCapture(node: VNode) { node.flags |= ShouldCapture; - } - static markRef(node: VNode) { + }, + markRef(node: VNode) { node.flags |= Ref; - } - static markSnapshot(node: VNode) { + }, + markSnapshot(node: VNode) { node.flags |= Snapshot; - } - static markInterrupted(node: VNode) { + }, + markInterrupted(node: VNode) { node.flags |= Interrupted; - } - static markForceUpdate(node: VNode) { + }, + markForceUpdate(node: VNode) { node.flags |= ForceUpdate; - } + }, - static markClear(node: VNode) { + markClear(node: VNode) { node.flags |= Clear; } }