Match-id-40743eee5f465d3a2be6bfcf670dae3382bdd887
This commit is contained in:
commit
da571cecd3
|
@ -7,11 +7,11 @@ import {
|
|||
getNearestVNode,
|
||||
getNonDelegatedListenerMap,
|
||||
} from '../dom/DOMInternalKeys';
|
||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
||||
import {runDiscreteUpdates} from '../renderer/TreeBuilder';
|
||||
import {isMounted} from '../renderer/vnode/VNodeUtils';
|
||||
import {SuspenseComponent} from '../renderer/vnode/VNodeTags';
|
||||
import {handleEventMain} from './HorizonEventMain';
|
||||
import {decorateNativeEvent} from './customEvents/EventFactory';
|
||||
|
||||
const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
|
||||
|
||||
|
@ -98,7 +98,7 @@ function isCaptureEvent(horizonEventName) {
|
|||
// 封装监听函数
|
||||
function getWrapperListener(horizonEventName, nativeEvtName, targetElement, listener) {
|
||||
return event => {
|
||||
const customEvent = new CustomBaseEvent(horizonEventName, nativeEvtName, event, null, targetElement);
|
||||
const customEvent = decorateNativeEvent(horizonEventName, nativeEvtName, event);
|
||||
listener(customEvent);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -8,13 +8,12 @@ import {
|
|||
EVENT_TYPE_CAPTURE,
|
||||
} from './const';
|
||||
import { getListeners as getBeforeInputListeners } from './simulatedEvtHandler/BeforeInputEventHandler';
|
||||
import { getListeners as getCompositionListeners } from './simulatedEvtHandler/CompositionEventHandler';
|
||||
import { getListeners as getChangeListeners } from './simulatedEvtHandler/ChangeEventHandler';
|
||||
import { getListeners as getSelectionListeners } from './simulatedEvtHandler/SelectionEventHandler';
|
||||
import {
|
||||
addOnPrefix,
|
||||
addOnPrefix, setPropertyWritable,
|
||||
} from './utils';
|
||||
import { createCustomEvent } from './customEvents/EventFactory';
|
||||
import { decorateNativeEvent } from './customEvents/EventFactory';
|
||||
import { getListenersFromTree } from './ListenerGetter';
|
||||
import { shouldUpdateValue, updateControlledValue } from './ControlledValueUpdater';
|
||||
import { asyncUpdates, runDiscreteUpdates } from '../renderer/Renderer';
|
||||
|
@ -47,7 +46,7 @@ function getCommonListeners(
|
|||
nativeEvtName = 'blur';
|
||||
}
|
||||
|
||||
const horizonEvent = createCustomEvent(horizonEvtName, nativeEvtName, nativeEvent, target);
|
||||
const horizonEvent = decorateNativeEvent(horizonEvtName, nativeEvtName, nativeEvent);
|
||||
return getListenersFromTree(
|
||||
vNode,
|
||||
horizonEvtName,
|
||||
|
@ -63,6 +62,8 @@ function processListeners(listenerList: ListenerUnitList): void {
|
|||
if (event.isPropagationStopped()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setPropertyWritable(event, 'currentTarget');
|
||||
event.currentTarget = currentTarget;
|
||||
listener(event);
|
||||
event.currentTarget = null;
|
||||
|
@ -105,17 +106,6 @@ function getProcessListeners(
|
|||
));
|
||||
}
|
||||
|
||||
if (nativeEvtName === 'compositionend' ||
|
||||
nativeEvtName === 'compositionstart' ||
|
||||
nativeEvtName === 'compositionupdate') {
|
||||
listenerList = listenerList.concat(getCompositionListeners(
|
||||
nativeEvtName,
|
||||
nativeEvent,
|
||||
vNode,
|
||||
target,
|
||||
));
|
||||
}
|
||||
|
||||
if (horizonEventToNativeMap.get('onBeforeInput').includes(nativeEvtName)) {
|
||||
listenerList = listenerList.concat(getBeforeInputListeners(
|
||||
nativeEvtName,
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import {VNode} from '../renderer/Types';
|
||||
import {DomComponent} from '../renderer/vnode/VNodeTags';
|
||||
import {EVENT_TYPE_ALL, EVENT_TYPE_CAPTURE, EVENT_TYPE_BUBBLE} from './const';
|
||||
import {ListenerUnitList} from './Types';
|
||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
||||
import {AnyNativeEvent, ListenerUnitList} from './Types';
|
||||
|
||||
// 获取监听事件
|
||||
export function getListenersFromTree(
|
||||
targetVNode: VNode | null,
|
||||
horizonEvtName: string | null,
|
||||
horizonEvent: CustomBaseEvent,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
eventType: string,
|
||||
): ListenerUnitList {
|
||||
if (!horizonEvtName) {
|
||||
|
@ -31,7 +30,7 @@ export function getListenersFromTree(
|
|||
vNode,
|
||||
listener: captureListener,
|
||||
currentTarget: realNode,
|
||||
event: horizonEvent,
|
||||
event: nativeEvent,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +42,7 @@ export function getListenersFromTree(
|
|||
vNode,
|
||||
listener: bubbleListener,
|
||||
currentTarget: realNode,
|
||||
event: horizonEvent,
|
||||
event: nativeEvent,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
|
||||
import type {VNode} from '../renderer/Types';
|
||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
||||
|
||||
export type AnyNativeEvent = KeyboardEvent | MouseEvent | TouchEvent | UIEvent | Event;
|
||||
|
||||
|
@ -8,7 +7,7 @@ export type ListenerUnit = {
|
|||
vNode: null | VNode;
|
||||
listener: Function;
|
||||
currentTarget: EventTarget;
|
||||
event: CustomBaseEvent;
|
||||
event: AnyNativeEvent;
|
||||
};
|
||||
|
||||
export type ListenerUnitList = Array<ListenerUnit>;
|
||||
|
|
|
@ -66,6 +66,9 @@ export const CommonEventToHorizonMap = {
|
|||
animationiteration: 'animationIteration',
|
||||
animationstart: 'animationStart',
|
||||
transitionend: 'transitionEnd',
|
||||
compositionstart: 'compositionStart',
|
||||
compositionend: 'compositionEnd',
|
||||
compositionupdate: 'compositionUpdate',
|
||||
};
|
||||
|
||||
export const CHAR_CODE_ENTER = 13;
|
||||
|
|
|
@ -1,70 +0,0 @@
|
|||
/**
|
||||
* 自定义的基本事件类型
|
||||
*/
|
||||
|
||||
// 兼容IE的event key
|
||||
const uniqueKeyMap = new Map([
|
||||
['Esc', 'Escape'],
|
||||
['Spacebar', ' '],
|
||||
['Left', 'ArrowLeft'],
|
||||
['Up', 'ArrowUp'],
|
||||
['Right', 'ArrowRight'],
|
||||
['Down', 'ArrowDown'],
|
||||
['Del', 'Delete'],
|
||||
]);
|
||||
|
||||
// 从原生事件中复制属性到自定义事件中
|
||||
function extendAttribute(target, source) {
|
||||
let val;
|
||||
let attr;
|
||||
for (attr in source) {
|
||||
val = source[attr];
|
||||
if (val !== undefined) {
|
||||
if (typeof val === 'function') {
|
||||
let fun = source[attr];
|
||||
target[attr] = function() {
|
||||
return fun.apply(source, arguments);
|
||||
};
|
||||
} else {
|
||||
target[attr] = val;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class CustomBaseEvent {
|
||||
|
||||
isDefaultPrevented: () => boolean;
|
||||
isPropagationStopped: () => boolean;
|
||||
target: EventTarget | null;
|
||||
|
||||
// 键盘事件属性
|
||||
key: string;
|
||||
|
||||
// custom事件自定义属性
|
||||
customEventName: string;
|
||||
type: string;
|
||||
nativeEvent: any;
|
||||
|
||||
constructor(
|
||||
customEvtName: string,
|
||||
nativeEvtName: string,
|
||||
nativeEvt: { [propName: string]: any },
|
||||
target: EventTarget | null
|
||||
) {
|
||||
// 复制原生属性到自定义事件
|
||||
extendAttribute(this, nativeEvt);
|
||||
|
||||
this.isDefaultPrevented = () => nativeEvt.defaultPrevented;
|
||||
this.isPropagationStopped = () => nativeEvt.cancelBubble;
|
||||
this.target = target;
|
||||
|
||||
// 键盘事件属性
|
||||
this.key = uniqueKeyMap.get(nativeEvt.key) || nativeEvt.key;
|
||||
|
||||
// custom事件自定义属性
|
||||
this.customEventName = customEvtName;
|
||||
this.type = nativeEvtName;
|
||||
this.nativeEvent = nativeEvt;
|
||||
}
|
||||
}
|
|
@ -1,11 +1,33 @@
|
|||
import {CustomBaseEvent} from './CustomBaseEvent';
|
||||
|
||||
// 兼容IE的event key
|
||||
const uniqueKeyMap = new Map([
|
||||
['Esc', 'Escape'],
|
||||
['Spacebar', ' '],
|
||||
['Left', 'ArrowLeft'],
|
||||
['Up', 'ArrowUp'],
|
||||
['Right', 'ArrowRight'],
|
||||
['Down', 'ArrowDown'],
|
||||
['Del', 'Delete'],
|
||||
]);
|
||||
|
||||
// 创建普通自定义事件对象实例,和原生事件对应
|
||||
export function createCustomEvent(customEventName, nativeEvtName, nativeEvent, currentTarget) {
|
||||
return new CustomBaseEvent(
|
||||
customEventName,
|
||||
nativeEvtName,
|
||||
nativeEvent,
|
||||
currentTarget,
|
||||
);
|
||||
export function decorateNativeEvent(customEventName, nativeEvtName, nativeEvent) {
|
||||
|
||||
nativeEvent.isDefaultPrevented = () => nativeEvent.defaultPrevented;
|
||||
nativeEvent.isPropagationStopped = () => nativeEvent.cancelBubble;
|
||||
|
||||
// custom事件自定义属性
|
||||
nativeEvent.customEventName = customEventName;
|
||||
nativeEvent.nativeEvent = nativeEvent;
|
||||
// 保存原生的事件类型,因为下面会修改
|
||||
nativeEvent.nativeEventType = nativeEvent.type;
|
||||
|
||||
Object.defineProperty(nativeEvent, 'type', { writable: true });
|
||||
nativeEvent.type = nativeEvtName;
|
||||
|
||||
const orgKey = nativeEvent.key;
|
||||
Object.defineProperty(nativeEvent, 'key', { writable: true });
|
||||
nativeEvent.key = uniqueKeyMap.get(orgKey) || orgKey;
|
||||
|
||||
return nativeEvent;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import type {VNode} from '../../renderer/Types';
|
||||
import type {AnyNativeEvent} from '../Types';
|
||||
import {getListenersFromTree} from '../ListenerGetter';
|
||||
import {createCustomEvent} from '../customEvents/EventFactory';
|
||||
import {decorateNativeEvent} 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);
|
||||
|
||||
|
@ -36,11 +35,10 @@ export function getListeners(
|
|||
return [];
|
||||
}
|
||||
|
||||
const event: CustomBaseEvent = createCustomEvent(
|
||||
const event: AnyNativeEvent = decorateNativeEvent(
|
||||
'onBeforeInput',
|
||||
'beforeinput',
|
||||
nativeEvent,
|
||||
target,
|
||||
);
|
||||
event.data = chars;
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import {createCustomEvent} from '../customEvents/EventFactory';
|
||||
import {decorateNativeEvent} from '../customEvents/EventFactory';
|
||||
import {getDom} from '../../dom/DOMInternalKeys';
|
||||
import {isInputValueChanged} from '../../dom/valueHandler/ValueChangeHandler';
|
||||
import {addValueUpdateList} from '../ControlledValueUpdater';
|
||||
|
@ -48,11 +48,10 @@ export function getListeners(
|
|||
// 判断是否需要触发change事件
|
||||
if (shouldTriggerChangeEvent(targetDom, nativeEvtName)) {
|
||||
addValueUpdateList(target);
|
||||
const event = createCustomEvent(
|
||||
const event = decorateNativeEvent(
|
||||
'onChange',
|
||||
'change',
|
||||
nativeEvt,
|
||||
target,
|
||||
);
|
||||
return getListenersFromTree(vNode, 'onChange', event, EVENT_TYPE_ALL);
|
||||
}
|
||||
|
|
|
@ -1,30 +0,0 @@
|
|||
import type {VNode} from '../../renderer/Types';
|
||||
import type {AnyNativeEvent} from '../Types';
|
||||
import {getListenersFromTree} from '../ListenerGetter';
|
||||
import {createCustomEvent} from '../customEvents/EventFactory';
|
||||
import {EVENT_TYPE_ALL} from '../const';
|
||||
import {ListenerUnitList} from '../Types';
|
||||
|
||||
const compositionEventObj = {
|
||||
compositionstart: 'onCompositionStart',
|
||||
compositionend: 'onCompositionEnd',
|
||||
compositionupdate: 'onCompositionUpdate',
|
||||
};
|
||||
|
||||
// compoisition事件主要处理中文输入法输入时的触发事件
|
||||
export function getListeners(
|
||||
nativeEvtName: string,
|
||||
nativeEvt: AnyNativeEvent,
|
||||
vNode: null | VNode,
|
||||
target: null | EventTarget,
|
||||
): ListenerUnitList {
|
||||
const evtType = compositionEventObj[nativeEvtName];
|
||||
|
||||
const event = createCustomEvent(
|
||||
evtType,
|
||||
nativeEvtName,
|
||||
nativeEvt,
|
||||
target,
|
||||
);
|
||||
return getListenersFromTree(vNode, evtType, event, EVENT_TYPE_ALL);
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
import {createCustomEvent} from '../customEvents/EventFactory';
|
||||
import {decorateNativeEvent} from '../customEvents/EventFactory';
|
||||
import {shallowCompare} from '../../renderer/utils/compare';
|
||||
import {getFocusedDom} from '../../dom/utils/Common';
|
||||
import {getDom} from '../../dom/DOMInternalKeys';
|
||||
import {isDocument} from '../../dom/utils/Common';
|
||||
import {isInputElement} from '../utils';
|
||||
import {isInputElement, setPropertyWritable} from '../utils';
|
||||
import type {AnyNativeEvent} from '../Types';
|
||||
import {getListenersFromTree} from '../ListenerGetter';
|
||||
import type {VNode} from '../../renderer/Types';
|
||||
|
@ -54,12 +54,12 @@ function getSelectEvent(nativeEvent, target) {
|
|||
if (!shallowCompare(lastSelection, currentSelection)) {
|
||||
lastSelection = currentSelection;
|
||||
|
||||
const event = createCustomEvent(
|
||||
const event = decorateNativeEvent(
|
||||
horizonEventName,
|
||||
'select',
|
||||
nativeEvent,
|
||||
target,
|
||||
);
|
||||
setPropertyWritable(nativeEvent, 'target');
|
||||
event.target = currentElement;
|
||||
|
||||
return getListenersFromTree(
|
||||
|
|
|
@ -14,3 +14,10 @@ export function addOnPrefix(name) {
|
|||
}
|
||||
return 'on' + name[0].toUpperCase() + name.slice(1);
|
||||
}
|
||||
|
||||
export function setPropertyWritable(obj, propName) {
|
||||
const desc = Object.getOwnPropertyDescriptor(obj, propName);
|
||||
if (!desc || !desc.writable) {
|
||||
Object.defineProperty(obj, propName, { writable : true });
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue