From 9f1e22af85ee9e6295198a4b930384d89aa61b55 Mon Sep 17 00:00:00 2001 From: * <8> Date: Mon, 7 Feb 2022 18:09:15 +0800 Subject: [PATCH] Match-id-b70289aaf481d9a953a7eb213a5be1d33c3aa6b5 --- libs/horizon/src/dom/DOMInternalKeys.ts | 1 + libs/horizon/src/dom/DOMOperator.ts | 9 --- libs/horizon/src/dom/utils/Common.ts | 2 +- libs/horizon/src/event/EventBinding.ts | 1 + libs/horizon/src/event/HorizonEventMain.ts | 60 +++++++++---------- libs/horizon/src/event/ListenerGetter.ts | 56 ++--------------- libs/horizon/src/event/Types.ts | 2 - libs/horizon/src/event/const.ts | 2 +- .../BeforeInputEventHandler.ts | 5 +- .../simulatedEvtHandler/ChangeEventHandler.ts | 4 +- .../CompositionEventHandler.ts | 5 +- .../SelectionEventHandler.ts | 7 ++- .../src/renderer/submit/HookEffectHandler.ts | 10 ++-- .../src/renderer/submit/LifeCycleHandler.ts | 33 ++++------ libs/horizon/src/renderer/submit/Submit.ts | 10 +--- libs/horizon/src/renderer/vnode/VNodeUtils.ts | 4 +- 16 files changed, 68 insertions(+), 143 deletions(-) diff --git a/libs/horizon/src/dom/DOMInternalKeys.ts b/libs/horizon/src/dom/DOMInternalKeys.ts index a71e7502..d8475d97 100644 --- a/libs/horizon/src/dom/DOMInternalKeys.ts +++ b/libs/horizon/src/dom/DOMInternalKeys.ts @@ -58,6 +58,7 @@ export function getNearestVNode(dom: Node): null | VNode { if (vNode) { // 如果是已经被框架标记过的 DOM 节点,那么直接返回其 VNode 实例 return vNode; } + // 下面处理的是为被框架标记过的 DOM 节点,向上找其父节点是否被框架标记过 let parentDom = dom.parentNode; let nearVNode = null; diff --git a/libs/horizon/src/dom/DOMOperator.ts b/libs/horizon/src/dom/DOMOperator.ts index cc023da9..969219f0 100644 --- a/libs/horizon/src/dom/DOMOperator.ts +++ b/libs/horizon/src/dom/DOMOperator.ts @@ -226,15 +226,6 @@ export function unHideDom(tag: string, dom: Element | Text, props: Props) { } } -export function clearContainer(container: Container): void { - if (isElement(container)) { - container.textContent = ''; - } - if (isDocument(container) && container.body != null) { - container.body.textContent = ''; - } -} - export function prePortal(portal: Element): void { listenDelegatedEvents(portal); } diff --git a/libs/horizon/src/dom/utils/Common.ts b/libs/horizon/src/dom/utils/Common.ts index dd836240..8de8f7c4 100644 --- a/libs/horizon/src/dom/utils/Common.ts +++ b/libs/horizon/src/dom/utils/Common.ts @@ -5,7 +5,7 @@ import {Props} from '../DOMOperator'; * 获取当前聚焦的 input 或者 textarea 元素 * @param doc 指定 document */ -export function getFocusedDom(doc?: Document): HorizonDom | void { +export function getFocusedDom(doc?: Document): HorizonDom | null { let currentDocument; if (doc) { currentDocument = doc; diff --git a/libs/horizon/src/event/EventBinding.ts b/libs/horizon/src/event/EventBinding.ts index 5fa168e6..1a630fff 100644 --- a/libs/horizon/src/event/EventBinding.ts +++ b/libs/horizon/src/event/EventBinding.ts @@ -78,6 +78,7 @@ export function listenDelegatedEvents(dom: Element) { return; } dom[listeningMarker] = true; + allDelegatedNativeEvents.forEach((nativeEvtName: string) => { // 委托冒泡事件 listenToNativeEvent(nativeEvtName, dom, false); diff --git a/libs/horizon/src/event/HorizonEventMain.ts b/libs/horizon/src/event/HorizonEventMain.ts index fa0046ab..4a669885 100644 --- a/libs/horizon/src/event/HorizonEventMain.ts +++ b/libs/horizon/src/event/HorizonEventMain.ts @@ -1,4 +1,4 @@ -import type { AnyNativeEvent, ProcessingListenerList } from './Types'; +import type { AnyNativeEvent } from './Types'; import type { VNode } from '../renderer/Types'; import { @@ -25,6 +25,7 @@ import { getListenersFromTree } from './ListenerGetter'; import { shouldUpdateValue, updateControlledValue } from './ControlledValueUpdater'; import { asyncUpdates, runDiscreteUpdates } from '../renderer/Renderer'; import { getExactNode } from '../renderer/vnode/VNodeUtils'; +import {ListenerUnitList} from './Types'; // 获取事件触发的普通事件监听方法队列 function getCommonListeners( @@ -33,7 +34,7 @@ function getCommonListeners( nativeEvent: AnyNativeEvent, target: null | EventTarget, isCapture: boolean, -): ProcessingListenerList { +): ListenerUnitList { const horizonEvtName = getCustomEventNameWithOn(CommonEventToHorizonMap[nativeEvtName]); if (!horizonEvtName) { return []; @@ -67,20 +68,17 @@ function getCommonListeners( } // 按顺序执行事件队列 -function processListeners(processingEventsList: ProcessingListenerList): void { - processingEventsList.forEach(eventUnitList => { - let lastVNode; - eventUnitList.forEach(eventUnit => { - const { vNode, currentTarget, listener, event } = eventUnit; - if (vNode !== lastVNode && event.isPropagationStopped()) { - return; - } - event.currentTarget = currentTarget; - runListenerAndCatchFirstError(listener, event); - event.currentTarget = null; - lastVNode = vNode; - }); +function processListeners(listenerList: ListenerUnitList): void { + listenerList.forEach(eventUnit => { + const { currentTarget, listener, event } = eventUnit; + if (event.isPropagationStopped()) { + return; + } + event.currentTarget = currentTarget; + runListenerAndCatchFirstError(listener, event); + event.currentTarget = null; }); + // 执行所有事件后,重新throw遇到的第一个错误 throwCaughtEventError(); } @@ -91,9 +89,9 @@ function getProcessListenersFacade( nativeEvent: AnyNativeEvent, target, isCapture: boolean -): ProcessingListenerList { +): ListenerUnitList { // 触发普通委托事件 - let processingListenerList: ProcessingListenerList = getCommonListeners( + let listenerList: ListenerUnitList = getCommonListeners( nativeEvtName, vNode, nativeEvent, @@ -104,7 +102,7 @@ function getProcessListenersFacade( // 触发特殊handler委托事件 if (!isCapture) { if (horizonEventToNativeMap.get('onChange').includes(nativeEvtName)) { - processingListenerList = processingListenerList.concat(getChangeListeners( + listenerList = listenerList.concat(getChangeListeners( nativeEvtName, nativeEvent, vNode, @@ -113,7 +111,7 @@ function getProcessListenersFacade( } if (horizonEventToNativeMap.get('onSelect').includes(nativeEvtName)) { - processingListenerList = processingListenerList.concat(getSelectionListeners( + listenerList = listenerList.concat(getSelectionListeners( nativeEvtName, nativeEvent, vNode, @@ -124,7 +122,7 @@ function getProcessListenersFacade( if (nativeEvtName === 'compositionend' || nativeEvtName === 'compositionstart' || nativeEvtName === 'compositionupdate') { - processingListenerList = processingListenerList.concat(getCompositionListeners( + listenerList = listenerList.concat(getCompositionListeners( nativeEvtName, nativeEvent, vNode, @@ -133,7 +131,7 @@ function getProcessListenersFacade( } if (horizonEventToNativeMap.get('onBeforeInput').includes(nativeEvtName)) { - processingListenerList = processingListenerList.concat(getBeforeInputListeners( + listenerList = listenerList.concat(getBeforeInputListeners( nativeEvtName, nativeEvent, vNode, @@ -141,7 +139,7 @@ function getProcessListenersFacade( )); } } - return processingListenerList; + return listenerList; } // 触发可以被执行的horizon事件监听 @@ -154,10 +152,10 @@ function triggerHorizonEvents( const nativeEventTarget = getEventTarget(nativeEvent); // 获取委托事件队列 - const processingListenerList = getProcessListenersFacade(nativeEvtName, vNode, nativeEvent, nativeEventTarget, isCapture); + const listenerList = getProcessListenersFacade(nativeEvtName, vNode, nativeEvent, nativeEventTarget, isCapture); // 处理触发的事件队列 - processListeners(processingListenerList); + processListeners(listenerList); } @@ -170,26 +168,26 @@ export function handleEventMain( isCapture: boolean, nativeEvent: AnyNativeEvent, vNode: null | VNode, - target: EventTarget, + targetContainer: EventTarget, ): void { - let rootVNode = vNode; - if (vNode !== null) { - rootVNode = getExactNode(vNode, target); - if (!rootVNode) { + let startVNode = vNode; + if (startVNode !== null) { + startVNode = getExactNode(startVNode, targetContainer); + if (!startVNode) { return; } } // 有事件正在执行,同步执行事件 if (isInEventsExecution) { - triggerHorizonEvents(nativeEvtName, isCapture, nativeEvent, rootVNode); + triggerHorizonEvents(nativeEvtName, isCapture, nativeEvent, startVNode); return; } // 没有事件在执行,经过调度再执行事件 isInEventsExecution = true; try { - asyncUpdates(() => triggerHorizonEvents(nativeEvtName, isCapture, nativeEvent, rootVNode)); + asyncUpdates(() => triggerHorizonEvents(nativeEvtName, isCapture, nativeEvent, startVNode)); } finally { isInEventsExecution = false; if (shouldUpdateValue()) { diff --git a/libs/horizon/src/event/ListenerGetter.ts b/libs/horizon/src/event/ListenerGetter.ts index 5d9c9169..9ecf42fd 100644 --- a/libs/horizon/src/event/ListenerGetter.ts +++ b/libs/horizon/src/event/ListenerGetter.ts @@ -1,62 +1,16 @@ import {VNode} from '../renderer/Types'; import {DomComponent} from '../renderer/vnode/VNodeTags'; -import {throwIfTrue} from '../renderer/utils/throwIfTrue'; -import type {Props} from '../dom/DOMOperator'; import {EVENT_TYPE_ALL, EVENT_TYPE_CAPTURE, EVENT_TYPE_BUBBLE} from './const'; -import {ProcessingListenerList, ListenerUnitList} from './Types'; +import {ListenerUnitList} from './Types'; import {CustomBaseEvent} from './customEvents/CustomBaseEvent'; -// 返回是否应该阻止事件响应标记,disabled组件不响应鼠标事件 -function shouldPrevent(eventName: string, type: string, props: Props): boolean { - const canPreventMouseEvents = [ - 'onClick', - 'onClickCapture', - 'onDoubleClick', - 'onDoubleClickCapture', - 'onMouseDown', - 'onMouseDownCapture', - 'onMouseMove', - 'onMouseMoveCapture', - 'onMouseUp', - 'onMouseUpCapture', - 'onMouseEnter', - ]; - const interActiveElements = ['button', 'input', 'select', 'textarea']; - if (canPreventMouseEvents.includes(eventName)) { - return !!(props.disabled && interActiveElements.includes(type)); - } - return false; -} - -// 从vnode属性中获取事件listener -function getListener(vNode: VNode, eventName: string): Function | null { - const realNode = vNode.realNode; - if (realNode === null) { - return null; - } - const props = vNode.props; - if (props === null) { - return null; - } - const listener = props[eventName]; - if (shouldPrevent(eventName, vNode.type, props)) { - return null; - } - throwIfTrue( - listener && typeof listener !== 'function', - '`%s` listener should be a function.', - eventName - ); - return listener; -} - // 获取监听事件 export function getListenersFromTree( targetVNode: VNode | null, horizonEvtName: string | null, horizonEvent: CustomBaseEvent, eventType: string, -): ProcessingListenerList { +): ListenerUnitList { if (!horizonEvtName) { return []; } @@ -71,7 +25,7 @@ export function getListenersFromTree( if (tag === DomComponent && realNode !== null) { if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_CAPTURE) { const captureName = horizonEvtName + EVENT_TYPE_CAPTURE; - const captureListener = getListener(vNode, captureName); + const captureListener = vNode.props[captureName]; if (captureListener) { listeners.unshift({ vNode, @@ -82,7 +36,7 @@ export function getListenersFromTree( } } if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_BUBBLE) { - const bubbleListener = getListener(vNode, horizonEvtName); + const bubbleListener = vNode.props[horizonEvtName]; if (bubbleListener) { listeners.push({ vNode, @@ -95,7 +49,7 @@ export function getListenersFromTree( } vNode = vNode.parent; } - return listeners.length > 0 ? [listeners]: []; + return listeners; } diff --git a/libs/horizon/src/event/Types.ts b/libs/horizon/src/event/Types.ts index fb67cf86..b007bb2c 100644 --- a/libs/horizon/src/event/Types.ts +++ b/libs/horizon/src/event/Types.ts @@ -12,5 +12,3 @@ export type ListenerUnit = { }; export type ListenerUnitList = Array; - -export type ProcessingListenerList = Array; diff --git a/libs/horizon/src/event/const.ts b/libs/horizon/src/event/const.ts index 20c954ae..75bea89f 100644 --- a/libs/horizon/src/event/const.ts +++ b/libs/horizon/src/event/const.ts @@ -34,7 +34,7 @@ export const horizonEventToNativeMap = new Map([ ['onCompositionStart', ['compositionstart']], ['onCompositionUpdate', ['compositionupdate']], ['onBeforeInput', ['compositionend', 'keypress', 'textInput']], - ['onChange', ['change', 'click', 'focusout', 'input',]], + ['onChange', ['change', 'click', 'focusout', 'input']], ['onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']], diff --git a/libs/horizon/src/event/simulatedEvtHandler/BeforeInputEventHandler.ts b/libs/horizon/src/event/simulatedEvtHandler/BeforeInputEventHandler.ts index ccbe450a..cd96a2e9 100644 --- a/libs/horizon/src/event/simulatedEvtHandler/BeforeInputEventHandler.ts +++ b/libs/horizon/src/event/simulatedEvtHandler/BeforeInputEventHandler.ts @@ -1,9 +1,10 @@ import type {VNode} from '../../renderer/Types'; -import type {AnyNativeEvent, ProcessingListenerList} from '../Types'; +import type {AnyNativeEvent} from '../Types'; import {getListenersFromTree} from '../ListenerGetter'; import {createHandlerCustomEvent} from '../customEvents/EventFactory'; import {CHAR_CODE_SPACE, EVENT_TYPE_ALL} from '../const'; import {CustomBaseEvent} from '../customEvents/CustomBaseEvent'; +import {ListenerUnitList} from '../Types'; const SPACE_CHAR = String.fromCharCode(CHAR_CODE_SPACE); function getInputCharsByNative( @@ -28,7 +29,7 @@ export function getListeners( nativeEvent: AnyNativeEvent, vNode: null | VNode, target: null | EventTarget, -): ProcessingListenerList { +): ListenerUnitList { const chars = getInputCharsByNative(nativeEvtName, nativeEvent); // 无字符将要输入,无需处理 if (!chars) { diff --git a/libs/horizon/src/event/simulatedEvtHandler/ChangeEventHandler.ts b/libs/horizon/src/event/simulatedEvtHandler/ChangeEventHandler.ts index 781ea607..7a32a5c8 100644 --- a/libs/horizon/src/event/simulatedEvtHandler/ChangeEventHandler.ts +++ b/libs/horizon/src/event/simulatedEvtHandler/ChangeEventHandler.ts @@ -4,7 +4,7 @@ import {isInputValueChanged} from '../../dom/valueHandler/ValueChangeHandler'; import {addValueUpdateList} from '../ControlledValueUpdater'; import {isTextInputElement} from '../utils'; import {EVENT_TYPE_ALL} from '../const'; -import {AnyNativeEvent, ProcessingListenerList} from '../Types'; +import {AnyNativeEvent, ListenerUnitList} from '../Types'; import { getListenersFromTree, } from '../ListenerGetter'; @@ -39,7 +39,7 @@ export function getListeners( nativeEvt: AnyNativeEvent, vNode: null | VNode, target: null | EventTarget, -): ProcessingListenerList { +): ListenerUnitList { if (!vNode) { return []; } diff --git a/libs/horizon/src/event/simulatedEvtHandler/CompositionEventHandler.ts b/libs/horizon/src/event/simulatedEvtHandler/CompositionEventHandler.ts index a3914893..c02dc78e 100644 --- a/libs/horizon/src/event/simulatedEvtHandler/CompositionEventHandler.ts +++ b/libs/horizon/src/event/simulatedEvtHandler/CompositionEventHandler.ts @@ -1,8 +1,9 @@ import type {VNode} from '../../renderer/Types'; -import type {AnyNativeEvent, ProcessingListenerList} from '../Types'; +import type {AnyNativeEvent} from '../Types'; import {getListenersFromTree} from '../ListenerGetter'; import {createHandlerCustomEvent} from '../customEvents/EventFactory'; import {EVENT_TYPE_ALL} from '../const'; +import {ListenerUnitList} from '../Types'; const compositionEventObj = { compositionstart: 'onCompositionStart', @@ -16,7 +17,7 @@ export function getListeners( nativeEvt: AnyNativeEvent, vNode: null | VNode, target: null | EventTarget, -): ProcessingListenerList { +): ListenerUnitList { const evtType = compositionEventObj[evtName]; const event = createHandlerCustomEvent( diff --git a/libs/horizon/src/event/simulatedEvtHandler/SelectionEventHandler.ts b/libs/horizon/src/event/simulatedEvtHandler/SelectionEventHandler.ts index 87724137..ac7cbe43 100644 --- a/libs/horizon/src/event/simulatedEvtHandler/SelectionEventHandler.ts +++ b/libs/horizon/src/event/simulatedEvtHandler/SelectionEventHandler.ts @@ -4,10 +4,11 @@ import {getFocusedDom} from '../../dom/utils/Common'; import {getDom} from '../../dom/DOMInternalKeys'; import {isDocument} from '../../dom/utils/Common'; import {isTextInputElement} from '../utils'; -import type {AnyNativeEvent, ProcessingListenerList} from '../Types'; +import type {AnyNativeEvent} from '../Types'; import {getListenersFromTree} from '../ListenerGetter'; import type {VNode} from '../../renderer/Types'; import {EVENT_TYPE_ALL} from '../const'; +import {ListenerUnitList} from '../Types'; const horizonEventName = 'onSelect' @@ -83,9 +84,9 @@ export function getListeners( nativeEvt: AnyNativeEvent, vNode: null | VNode, target: null | EventTarget, -): ProcessingListenerList { +): ListenerUnitList { const targetNode = vNode ? getDom(vNode) : window; - let eventUnitList: ProcessingListenerList = []; + let eventUnitList: ListenerUnitList = []; switch (name) { case 'focusin': initTargetCache(targetNode, vNode); diff --git a/libs/horizon/src/renderer/submit/HookEffectHandler.ts b/libs/horizon/src/renderer/submit/HookEffectHandler.ts index 31e93db0..b6706389 100644 --- a/libs/horizon/src/renderer/submit/HookEffectHandler.ts +++ b/libs/horizon/src/renderer/submit/HookEffectHandler.ts @@ -34,8 +34,8 @@ export function callUseEffects(vNode: VNode) { (effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect && (effectConstant & EffectConstant.DepsChange) !== EffectConstant.NoEffect ) { - hookEffects.push({effect, vNode}); - hookRemoveEffects.push({effect, vNode}); + hookEffects.push(effect); + hookRemoveEffects.push(effect); // 异步调用 if (!isScheduling) { @@ -53,7 +53,7 @@ export function runAsyncEffects() { // 调用effect destroy const removeEffects = hookRemoveEffects; hookRemoveEffects = []; - removeEffects.forEach(({effect}) => { + removeEffects.forEach((effect) => { const destroy = effect.removeEffect; effect.removeEffect = undefined; @@ -69,7 +69,7 @@ export function runAsyncEffects() { // 调用effect create const createEffects = hookEffects; hookEffects = []; - createEffects.forEach(({effect}) => { + createEffects.forEach((effect) => { try { const create = effect.effect; @@ -91,7 +91,7 @@ export function callEffectRemove(vNode: VNode) { if (removeEffect !== undefined) { if ((effectConstant & EffectConstant.Effect) !== EffectConstant.NoEffect) { // 如果是useEffect,就异步调用 - hookRemoveEffects.push({effect, vNode}); + hookRemoveEffects.push(effect); if (!isScheduling) { isScheduling = true; diff --git a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts index ecaa6298..a6ae1835 100644 --- a/libs/horizon/src/renderer/submit/LifeCycleHandler.ts +++ b/libs/horizon/src/renderer/submit/LifeCycleHandler.ts @@ -27,7 +27,6 @@ import { removeChildDom, hideDom, unHideDom, - clearContainer, } from '../../dom/DOMOperator'; import { callEffectRemove, @@ -56,28 +55,17 @@ function callComponentWillUnmount(vNode: VNode, instance: any) { function callBeforeSubmitLifeCycles( vNode: VNode, ): void { - switch (vNode.tag) { - case ClassComponent: { // 调用instance.getSnapshotBeforeUpdate - if (!vNode.isCreated) { - const prevProps = vNode.isLazyComponent - ? mergeDefaultProps(vNode.type, vNode.oldProps) - : vNode.oldProps; - const prevState = vNode.oldState; - const instance = vNode.realNode; + if (vNode.tag === ClassComponent && !vNode.isCreated) { // 调用instance.getSnapshotBeforeUpdate + const prevProps = vNode.isLazyComponent + ? mergeDefaultProps(vNode.type, vNode.oldProps) + : vNode.oldProps; + const prevState = vNode.oldState; + const instance = vNode.realNode; - const snapshot = instance.getSnapshotBeforeUpdate(prevProps, prevState); + const snapshot = instance.getSnapshotBeforeUpdate(prevProps, prevState); - // __snapshotResult会在调用componentDidUpdate的时候作为第三个参数 - instance.__snapshotResult = snapshot; - } - return; - } - case TreeRoot: { - const root = vNode.realNode; - clearContainer(root.outerDom); - } - - // No Default + // __snapshotResult会在调用componentDidUpdate的时候作为第三个参数 + instance.__snapshotResult = snapshot; } } @@ -138,7 +126,6 @@ function callAfterSubmitLifeCycles( if (vNode.isCreated && vNode.flags.Update) { // button、input、select、textarea、如果有 autoFocus 属性需要focus if (shouldAutoFocus(vNode.type, vNode.props)) { - // button、input、select、textarea、如果有 autoFocus 属性需要focus vNode.realNode.focus(); } } @@ -333,7 +320,7 @@ function submitClear(vNode: VNode): void { clearVNode(clearChild); clearChild = clearChild.next as VNode; } - + // 在所有子项都卸载后,删除dom树中的节点 removeChildDom(currentParent, vNode.realNode); currentParent.append(cloneDom); diff --git a/libs/horizon/src/renderer/submit/Submit.ts b/libs/horizon/src/renderer/submit/Submit.ts index 5b3f852c..5d359a90 100644 --- a/libs/horizon/src/renderer/submit/Submit.ts +++ b/libs/horizon/src/renderer/submit/Submit.ts @@ -11,7 +11,7 @@ import { callBeforeSubmitLifeCycles, submitDeletion, submitAddition, submitResetTextContent, submitUpdate, detachRef, submitClear, } from './LifeCycleHandler'; -import {tryRenderFromRoot, setProcessing} from '../TreeBuilder'; +import {tryRenderFromRoot} from '../TreeBuilder'; import { BySync, InRender, @@ -81,11 +81,6 @@ export function submitToRender(treeRoot) { throw error; } - // 非批量:即同步执行的,没有必要去执行RenderQueue,RenderQueue放的是异步的 - if (!checkMode(BySync)) { // 非批量 - callRenderQueueImmediate(); - } - return null; } @@ -96,7 +91,6 @@ function beforeSubmit(dirtyNodes: Array) { callBeforeSubmitLifeCycles(node); } } catch (error) { - throwIfTrue(node === null, 'Should be working on an effect.'); handleSubmitError(node, error); } }); @@ -138,7 +132,6 @@ function submit(dirtyNodes: Array) { } } } catch (error) { - throwIfTrue(node === null, 'Should be working on an effect.'); handleSubmitError(node, error); } }); @@ -155,7 +148,6 @@ function afterSubmit(dirtyNodes: Array) { attachRef(node); } } catch (error) { - throwIfTrue(node === null, 'Should be working on an effect.'); handleSubmitError(node, error); } }); diff --git a/libs/horizon/src/renderer/vnode/VNodeUtils.ts b/libs/horizon/src/renderer/vnode/VNodeUtils.ts index 92407f1b..dc38b93e 100644 --- a/libs/horizon/src/renderer/vnode/VNodeUtils.ts +++ b/libs/horizon/src/renderer/vnode/VNodeUtils.ts @@ -261,14 +261,14 @@ export function getExactNode(targetVNode, targetContainer) { if (isPortalRoot(vNode, targetContainer)) { return null; } + while (container !== null) { const parentNode = getNearestVNode(container); if (parentNode === null) { return null; } if (parentNode.tag === DomComponent || parentNode.tag === DomText) { - vNode = parentNode; - return getExactNode(vNode, targetContainer); + return getExactNode(parentNode, targetContainer); } container = container.parentNode; }