Match-id-4c5a3a22ce4ffd2686921714db97c18b77f16288

This commit is contained in:
* 2022-05-13 11:00:00 +08:00 committed by *
parent d14122a5d3
commit c34df0d5f4
11 changed files with 59 additions and 36 deletions

View File

@ -23,7 +23,7 @@ function createRoot(children: any, container: Container, callback?: Callback) {
container._treeRoot = treeRoot;
// 根节点挂接全量事件
listenDelegatedEvents(container as Element);
// listenDelegatedEvents(container as Element);
// 执行回调
if (typeof callback === 'function') {

View File

@ -4,9 +4,11 @@ import {
import { updateCommonProp } from './UpdateCommonProp';
import { setStyles } from './StyleHandler';
import {
listenNonDelegatedEvent
lazyDelegateOnRoot,
listenNonDelegatedEvent,
} from '../../event/EventBinding';
import { isEventProp } from '../validators/ValidateProps';
import { getCurrentRoot } from '../../renderer/TreeBuilder';
// 初始化DOM属性和更新 DOM 属性
export function setDomProps(
@ -27,8 +29,12 @@ export function setDomProps(
setStyles(dom, propVal);
} else if (isEventProp(propName)) {
// 事件监听属性处理
// TODO
const currentRoot = getCurrentRoot();
if (!allDelegatedHorizonEvents.has(propName)) {
listenNonDelegatedEvent(propName, dom, propVal);
} else if (currentRoot && !currentRoot.delegatedEvents.has(propName)) {
lazyDelegateOnRoot(currentRoot, propName);
}
} else if (propName === 'children') { // 只处理纯文本子节点其他children在VNode树中处理
const type = typeof propVal;
@ -147,6 +153,7 @@ export function compareProps(
if (!allDelegatedHorizonEvents.has(propName)) {
toUpdateProps[propName] = newPropValue;
}
// TODO
} else {
toUpdateProps[propName] = newPropValue;
}

View File

@ -43,7 +43,7 @@ export function getSelectPropsWithoutValue(dom: HorizonSelect, properties: Objec
return {
...properties,
value: undefined,
}
};
}
export function updateSelectValue(dom: HorizonSelect, properties: IProperty, isInit: boolean = false) {

View File

@ -1,7 +1,7 @@
/**
*
*/
import {allDelegatedNativeEvents} from './EventCollection';
import { allDelegatedHorizonEvents, allDelegatedNativeEvents } from './EventCollection';
import {isDocument} from '../dom/utils/Common';
import {
getNearestVNode,
@ -12,6 +12,7 @@ import {isMounted} from '../renderer/vnode/VNodeUtils';
import {SuspenseComponent} from '../renderer/vnode/VNodeTags';
import {handleEventMain} from './HorizonEventMain';
import {decorateNativeEvent} from './customEvents/EventFactory';
import { VNode } from '../renderer/vnode/VNode';
const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
@ -26,18 +27,20 @@ function triggerDelegatedEvent(
runDiscreteUpdates();
const nativeEventTarget = nativeEvent.target || nativeEvent.srcElement;
let targetVNode = getNearestVNode(nativeEventTarget);
const targetVNode = getNearestVNode(nativeEventTarget);
if (targetVNode !== null) {
if (isMounted(targetVNode)) {
if (targetVNode.tag === SuspenseComponent) {
targetVNode = null;
}
} else {
// vNode已销毁
targetVNode = null;
}
}
// if (targetVNode !== null) {
// if (isMounted(targetVNode)) {
// if (targetVNode.tag === SuspenseComponent) {
// debugger
// targetVNode = null;
// }
// } else {
// debugger
// // vNode已销毁
// targetVNode = null;
// }
// }
handleEventMain(nativeEvtName, isCapture, nativeEvent, targetVNode, targetDom);
}
@ -73,6 +76,16 @@ export function listenDelegatedEvents(dom: Element) {
});
}
// 事件懒委托,当用户定义事件后,再进行委托到根节点
export function lazyDelegateOnRoot(currentRoot: VNode, eventName: string) {
currentRoot.delegatedEvents.add(eventName);
const isCapture = isCaptureEvent(eventName);
const nativeEvents = allDelegatedHorizonEvents.get(eventName);
nativeEvents.forEach(nativeEvents => {
listenToNativeEvent(nativeEvents, currentRoot.realNode, isCapture);
});
}
// 通过horizon事件名获取到native事件名
function getNativeEvtName(horizonEventName, capture) {
let nativeName;

View File

@ -8,7 +8,6 @@ import {
EVENT_TYPE_CAPTURE,
} from './const';
import { getListeners as getChangeListeners } from './simulatedEvtHandler/ChangeEventHandler';
import { getListeners as getSelectionListeners } from './simulatedEvtHandler/SelectionEventHandler';
import {
setPropertyWritable,
} from './utils';
@ -81,6 +80,7 @@ function getProcessListeners(
target,
isCapture: boolean,
): ListenerUnitList {
// TODO 重复从树中获取监听器
// 触发普通委托事件
let listenerList: ListenerUnitList = getCommonListeners(
nativeEvtName,
@ -100,15 +100,6 @@ function getProcessListeners(
target,
));
}
if (horizonEventToNativeMap.get('onSelect').includes(nativeEvtName)) {
listenerList = listenerList.concat(getSelectionListeners(
nativeEvtName,
nativeEvent,
vNode,
target,
));
}
}
return listenerList;
}

View File

@ -28,8 +28,7 @@ export const horizonEventToNativeMap = new Map([
['onCompositionStart', ['compositionstart']],
['onCompositionUpdate', ['compositionupdate']],
['onChange', ['change', 'click', 'focusout', 'input']],
['onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin',
'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']],
['onSelect', ['select']],
['onAnimationEnd', ['animationend']],
['onAnimationIteration', ['animationiteration']],

View File

@ -12,6 +12,11 @@ import {VNode} from '../../renderer/Types';
import {getDomTag} from '../../dom/utils/Common';
// 返回是否需要触发change事件标记
// | 元素 | 事件 | 需要值变更 |
// | --- | --- | --------------- |
// | <select/> / <input type="file/> | change | NO |
// | <input type="checkbox" /> <input type="radio" /> | click | YES |
// | <input type="input /> / <input type="text" /> | input / change | YES |
function shouldTriggerChangeEvent(targetDom, evtName) {
const { type } = targetDom;
const domTag = getDomTag(targetDom);

View File

@ -1,9 +1,7 @@
export function isInputElement(dom?: HTMLElement): boolean {
if (dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement) {
return true;
}
return false;
return dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement;
}
export function setPropertyWritable(obj, propName) {

View File

@ -43,6 +43,11 @@ let unrecoverableErrorDuringBuild: any = null;
// 当前运行的vNode节点
let processing: VNode | null = null;
let currentRoot: VNode | null = null;
export function getCurrentRoot() {
return currentRoot;
}
export function setProcessing(vNode: VNode | null) {
processing = vNode;
}
@ -267,7 +272,7 @@ function buildVNodeTree(treeRoot: VNode) {
// 总体任务入口
function renderFromRoot(treeRoot) {
runAsyncEffects();
currentRoot = treeRoot;
// 1. 构建vNode树
buildVNodeTree(treeRoot);
@ -278,6 +283,7 @@ function renderFromRoot(treeRoot) {
// 2. 提交变更
submitToRender(treeRoot);
currentRoot = null;
if (window.__HORIZON_DEV_HOOK__) {
const hook = window.__HORIZON_DEV_HOOK__;

View File

@ -114,21 +114,21 @@ function submit(dirtyNodes: Array<VNode>) {
if ((node.flags & ResetText) === ResetText) {
submitResetTextContent(node);
}
if ((node.flags & Ref) === Ref) {
if (!node.isCreated) {
// 需要执行
detachRef(node, true);
}
}
isAdd = (node.flags & Addition) === Addition;
isUpdate = (node.flags & Update) === Update;
if (isAdd && isUpdate) {
// Addition
submitAddition(node);
FlagUtils.removeFlag(node, Addition);
// Update
submitUpdate(node);
} else {
@ -161,7 +161,7 @@ function afterSubmit(dirtyNodes: Array<VNode>) {
if ((node.flags & Update) === Update || (node.flags & Callback) === Callback) {
callAfterSubmitLifeCycles(node);
}
if ((node.flags & Ref) === Ref) {
attachRef(node);
}

View File

@ -74,7 +74,10 @@ export class VNode {
suspenseState: SuspenseState;
path = ''; // 保存从根到本节点的路径
// 根节点数据
toUpdateNodes: Set<VNode> | null; // 保存要更新的节点
delegatedEvents: Set<string>
belongClassVNode: VNode | null = null; // 记录JSXElement所属class vNode处理ref的时候使用
@ -94,6 +97,7 @@ export class VNode {
this.realNode = realNode;
this.task = null;
this.toUpdateNodes = new Set<VNode>();
this.delegatedEvents = new Set<string>();
this.updates = null;
this.stateCallbacks = null;
this.state = null;