Match-id-c74211ebd4670fd9c8b20892189f91fb10bce812
This commit is contained in:
parent
52537bdf93
commit
91dc5656ab
|
@ -7,11 +7,11 @@ import {
|
||||||
getNearestVNode,
|
getNearestVNode,
|
||||||
getNonDelegatedListenerMap,
|
getNonDelegatedListenerMap,
|
||||||
} from '../dom/DOMInternalKeys';
|
} from '../dom/DOMInternalKeys';
|
||||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
|
||||||
import {runDiscreteUpdates} from '../renderer/TreeBuilder';
|
import {runDiscreteUpdates} from '../renderer/TreeBuilder';
|
||||||
import {isMounted} from '../renderer/vnode/VNodeUtils';
|
import {isMounted} from '../renderer/vnode/VNodeUtils';
|
||||||
import {SuspenseComponent} from '../renderer/vnode/VNodeTags';
|
import {SuspenseComponent} from '../renderer/vnode/VNodeTags';
|
||||||
import {handleEventMain} from './HorizonEventMain';
|
import {handleEventMain} from './HorizonEventMain';
|
||||||
|
import {decorateNativeEvent} from './customEvents/EventFactory';
|
||||||
|
|
||||||
const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
|
const listeningMarker = '_horizonListening' + Math.random().toString(36).slice(4);
|
||||||
|
|
||||||
|
@ -98,7 +98,7 @@ function isCaptureEvent(horizonEventName) {
|
||||||
// 封装监听函数
|
// 封装监听函数
|
||||||
function getWrapperListener(horizonEventName, nativeEvtName, targetElement, listener) {
|
function getWrapperListener(horizonEventName, nativeEvtName, targetElement, listener) {
|
||||||
return event => {
|
return event => {
|
||||||
const customEvent = new CustomBaseEvent(horizonEventName, nativeEvtName, event, null, targetElement);
|
const customEvent = decorateNativeEvent(horizonEventName, nativeEvtName, event);
|
||||||
listener(customEvent);
|
listener(customEvent);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,13 +8,12 @@ import {
|
||||||
EVENT_TYPE_CAPTURE,
|
EVENT_TYPE_CAPTURE,
|
||||||
} from './const';
|
} from './const';
|
||||||
import { getListeners as getBeforeInputListeners } from './simulatedEvtHandler/BeforeInputEventHandler';
|
import { getListeners as getBeforeInputListeners } from './simulatedEvtHandler/BeforeInputEventHandler';
|
||||||
import { getListeners as getCompositionListeners } from './simulatedEvtHandler/CompositionEventHandler';
|
|
||||||
import { getListeners as getChangeListeners } from './simulatedEvtHandler/ChangeEventHandler';
|
import { getListeners as getChangeListeners } from './simulatedEvtHandler/ChangeEventHandler';
|
||||||
import { getListeners as getSelectionListeners } from './simulatedEvtHandler/SelectionEventHandler';
|
import { getListeners as getSelectionListeners } from './simulatedEvtHandler/SelectionEventHandler';
|
||||||
import {
|
import {
|
||||||
addOnPrefix,
|
addOnPrefix, setPropertyWritable,
|
||||||
} from './utils';
|
} from './utils';
|
||||||
import { createCustomEvent } from './customEvents/EventFactory';
|
import { decorateNativeEvent } from './customEvents/EventFactory';
|
||||||
import { getListenersFromTree } from './ListenerGetter';
|
import { getListenersFromTree } from './ListenerGetter';
|
||||||
import { shouldUpdateValue, updateControlledValue } from './ControlledValueUpdater';
|
import { shouldUpdateValue, updateControlledValue } from './ControlledValueUpdater';
|
||||||
import { asyncUpdates, runDiscreteUpdates } from '../renderer/Renderer';
|
import { asyncUpdates, runDiscreteUpdates } from '../renderer/Renderer';
|
||||||
|
@ -47,7 +46,7 @@ function getCommonListeners(
|
||||||
nativeEvtName = 'blur';
|
nativeEvtName = 'blur';
|
||||||
}
|
}
|
||||||
|
|
||||||
const horizonEvent = createCustomEvent(horizonEvtName, nativeEvtName, nativeEvent, target);
|
const horizonEvent = decorateNativeEvent(horizonEvtName, nativeEvtName, nativeEvent);
|
||||||
return getListenersFromTree(
|
return getListenersFromTree(
|
||||||
vNode,
|
vNode,
|
||||||
horizonEvtName,
|
horizonEvtName,
|
||||||
|
@ -63,6 +62,8 @@ function processListeners(listenerList: ListenerUnitList): void {
|
||||||
if (event.isPropagationStopped()) {
|
if (event.isPropagationStopped()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setPropertyWritable(event, 'currentTarget');
|
||||||
event.currentTarget = currentTarget;
|
event.currentTarget = currentTarget;
|
||||||
listener(event);
|
listener(event);
|
||||||
event.currentTarget = null;
|
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)) {
|
if (horizonEventToNativeMap.get('onBeforeInput').includes(nativeEvtName)) {
|
||||||
listenerList = listenerList.concat(getBeforeInputListeners(
|
listenerList = listenerList.concat(getBeforeInputListeners(
|
||||||
nativeEvtName,
|
nativeEvtName,
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import {VNode} from '../renderer/Types';
|
import {VNode} from '../renderer/Types';
|
||||||
import {DomComponent} from '../renderer/vnode/VNodeTags';
|
import {DomComponent} from '../renderer/vnode/VNodeTags';
|
||||||
import {EVENT_TYPE_ALL, EVENT_TYPE_CAPTURE, EVENT_TYPE_BUBBLE} from './const';
|
import {EVENT_TYPE_ALL, EVENT_TYPE_CAPTURE, EVENT_TYPE_BUBBLE} from './const';
|
||||||
import {ListenerUnitList} from './Types';
|
import {AnyNativeEvent, ListenerUnitList} from './Types';
|
||||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
|
||||||
|
|
||||||
// 获取监听事件
|
// 获取监听事件
|
||||||
export function getListenersFromTree(
|
export function getListenersFromTree(
|
||||||
targetVNode: VNode | null,
|
targetVNode: VNode | null,
|
||||||
horizonEvtName: string | null,
|
horizonEvtName: string | null,
|
||||||
horizonEvent: CustomBaseEvent,
|
nativeEvent: AnyNativeEvent,
|
||||||
eventType: string,
|
eventType: string,
|
||||||
): ListenerUnitList {
|
): ListenerUnitList {
|
||||||
if (!horizonEvtName) {
|
if (!horizonEvtName) {
|
||||||
|
@ -31,7 +30,7 @@ export function getListenersFromTree(
|
||||||
vNode,
|
vNode,
|
||||||
listener: captureListener,
|
listener: captureListener,
|
||||||
currentTarget: realNode,
|
currentTarget: realNode,
|
||||||
event: horizonEvent,
|
event: nativeEvent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +42,7 @@ export function getListenersFromTree(
|
||||||
vNode,
|
vNode,
|
||||||
listener: bubbleListener,
|
listener: bubbleListener,
|
||||||
currentTarget: realNode,
|
currentTarget: realNode,
|
||||||
event: horizonEvent,
|
event: nativeEvent,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
import type {VNode} from '../renderer/Types';
|
import type {VNode} from '../renderer/Types';
|
||||||
import {CustomBaseEvent} from './customEvents/CustomBaseEvent';
|
|
||||||
|
|
||||||
export type AnyNativeEvent = KeyboardEvent | MouseEvent | TouchEvent | UIEvent | Event;
|
export type AnyNativeEvent = KeyboardEvent | MouseEvent | TouchEvent | UIEvent | Event;
|
||||||
|
|
||||||
|
@ -8,7 +7,7 @@ export type ListenerUnit = {
|
||||||
vNode: null | VNode;
|
vNode: null | VNode;
|
||||||
listener: Function;
|
listener: Function;
|
||||||
currentTarget: EventTarget;
|
currentTarget: EventTarget;
|
||||||
event: CustomBaseEvent;
|
event: AnyNativeEvent;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ListenerUnitList = Array<ListenerUnit>;
|
export type ListenerUnitList = Array<ListenerUnit>;
|
||||||
|
|
|
@ -66,6 +66,9 @@ export const CommonEventToHorizonMap = {
|
||||||
animationiteration: 'animationIteration',
|
animationiteration: 'animationIteration',
|
||||||
animationstart: 'animationStart',
|
animationstart: 'animationStart',
|
||||||
transitionend: 'transitionEnd',
|
transitionend: 'transitionEnd',
|
||||||
|
compositionstart: 'compositionStart',
|
||||||
|
compositionend: 'compositionEnd',
|
||||||
|
compositionupdate: 'compositionUpdate',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CHAR_CODE_ENTER = 13;
|
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) {
|
export function decorateNativeEvent(customEventName, nativeEvtName, nativeEvent) {
|
||||||
return new CustomBaseEvent(
|
|
||||||
customEventName,
|
nativeEvent.isDefaultPrevented = () => nativeEvent.defaultPrevented;
|
||||||
nativeEvtName,
|
nativeEvent.isPropagationStopped = () => nativeEvent.cancelBubble;
|
||||||
nativeEvent,
|
|
||||||
currentTarget,
|
// 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 {VNode} from '../../renderer/Types';
|
||||||
import type {AnyNativeEvent} from '../Types';
|
import type {AnyNativeEvent} from '../Types';
|
||||||
import {getListenersFromTree} from '../ListenerGetter';
|
import {getListenersFromTree} from '../ListenerGetter';
|
||||||
import {createCustomEvent} from '../customEvents/EventFactory';
|
import {decorateNativeEvent} from '../customEvents/EventFactory';
|
||||||
import {CHAR_CODE_SPACE, EVENT_TYPE_ALL} from '../const';
|
import {CHAR_CODE_SPACE, EVENT_TYPE_ALL} from '../const';
|
||||||
import {CustomBaseEvent} from '../customEvents/CustomBaseEvent';
|
|
||||||
import {ListenerUnitList} from '../Types';
|
import {ListenerUnitList} from '../Types';
|
||||||
const SPACE_CHAR = String.fromCharCode(CHAR_CODE_SPACE);
|
const SPACE_CHAR = String.fromCharCode(CHAR_CODE_SPACE);
|
||||||
|
|
||||||
|
@ -36,11 +35,10 @@ export function getListeners(
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
const event: CustomBaseEvent = createCustomEvent(
|
const event: AnyNativeEvent = decorateNativeEvent(
|
||||||
'onBeforeInput',
|
'onBeforeInput',
|
||||||
'beforeinput',
|
'beforeinput',
|
||||||
nativeEvent,
|
nativeEvent,
|
||||||
target,
|
|
||||||
);
|
);
|
||||||
event.data = chars;
|
event.data = chars;
|
||||||
|
|
||||||
|
|
|
@ -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 {shallowCompare} from '../../renderer/utils/compare';
|
||||||
import {getFocusedDom} from '../../dom/utils/Common';
|
import {getFocusedDom} from '../../dom/utils/Common';
|
||||||
import {getDom} from '../../dom/DOMInternalKeys';
|
import {getDom} from '../../dom/DOMInternalKeys';
|
||||||
import {isDocument} from '../../dom/utils/Common';
|
import {isDocument} from '../../dom/utils/Common';
|
||||||
import {isInputElement} from '../utils';
|
import {isInputElement, setPropertyWritable} from '../utils';
|
||||||
import type {AnyNativeEvent} from '../Types';
|
import type {AnyNativeEvent} from '../Types';
|
||||||
import {getListenersFromTree} from '../ListenerGetter';
|
import {getListenersFromTree} from '../ListenerGetter';
|
||||||
import type {VNode} from '../../renderer/Types';
|
import type {VNode} from '../../renderer/Types';
|
||||||
|
@ -54,12 +54,12 @@ function getSelectEvent(nativeEvent, target) {
|
||||||
if (!shallowCompare(lastSelection, currentSelection)) {
|
if (!shallowCompare(lastSelection, currentSelection)) {
|
||||||
lastSelection = currentSelection;
|
lastSelection = currentSelection;
|
||||||
|
|
||||||
const event = createCustomEvent(
|
const event = decorateNativeEvent(
|
||||||
horizonEventName,
|
horizonEventName,
|
||||||
'select',
|
'select',
|
||||||
nativeEvent,
|
nativeEvent,
|
||||||
target,
|
|
||||||
);
|
);
|
||||||
|
setPropertyWritable(nativeEvent, 'target');
|
||||||
event.target = currentElement;
|
event.target = currentElement;
|
||||||
|
|
||||||
return getListenersFromTree(
|
return getListenersFromTree(
|
||||||
|
|
|
@ -14,3 +14,10 @@ export function addOnPrefix(name) {
|
||||||
}
|
}
|
||||||
return 'on' + name[0].toUpperCase() + name.slice(1);
|
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