Match-id-f16ed2f21668e5aa1a4548583d600093a215b9a8
This commit is contained in:
commit
fc37bd5602
|
@ -6,21 +6,9 @@ import {Props} from '../DOMOperator';
|
||||||
* @param doc 指定 document
|
* @param doc 指定 document
|
||||||
*/
|
*/
|
||||||
export function getFocusedDom(doc?: Document): HorizonDom | null {
|
export function getFocusedDom(doc?: Document): HorizonDom | null {
|
||||||
let currentDocument;
|
let currentDocument = doc ?? document;
|
||||||
if (doc) {
|
|
||||||
currentDocument = doc;
|
return currentDocument.activeElement ?? currentDocument.body;
|
||||||
} else {
|
|
||||||
if (document) {
|
|
||||||
currentDocument = document;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!currentDocument) {
|
|
||||||
return null;
|
|
||||||
} else if (currentDocument.activeElement) {
|
|
||||||
return currentDocument.activeElement;
|
|
||||||
} else {
|
|
||||||
return currentDocument.body;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果 input 或者 textarea 元素中有文字被选中时,activeElement 属性就会返回该元素
|
// 如果 input 或者 textarea 元素中有文字被选中时,activeElement 属性就会返回该元素
|
||||||
|
|
|
@ -69,7 +69,7 @@ function processListeners(listenerList: ListenerUnitList): void {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getProcessListenersFacade(
|
function getProcessListeners(
|
||||||
nativeEvtName: string,
|
nativeEvtName: string,
|
||||||
vNode: VNode | null,
|
vNode: VNode | null,
|
||||||
nativeEvent: AnyNativeEvent,
|
nativeEvent: AnyNativeEvent,
|
||||||
|
@ -138,7 +138,7 @@ function triggerHorizonEvents(
|
||||||
const nativeEventTarget = nativeEvent.target || nativeEvent.srcElement;
|
const nativeEventTarget = nativeEvent.target || nativeEvent.srcElement;
|
||||||
|
|
||||||
// 获取委托事件队列
|
// 获取委托事件队列
|
||||||
const listenerList = getProcessListenersFacade(nativeEvtName, vNode, nativeEvent, nativeEventTarget, isCapture);
|
const listenerList = getProcessListeners(nativeEvtName, vNode, nativeEvent, nativeEventTarget, isCapture);
|
||||||
|
|
||||||
// 处理触发的事件队列
|
// 处理触发的事件队列
|
||||||
processListeners(listenerList);
|
processListeners(listenerList);
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
/**
|
|
||||||
* style中的动画事件
|
|
||||||
*/
|
|
||||||
|
|
||||||
// style事件浏览器兼容前缀
|
|
||||||
const vendorPrefixes = {
|
|
||||||
animationend: {
|
|
||||||
MozAnimation: 'mozAnimationEnd',
|
|
||||||
WebkitAnimation: 'webkitAnimationEnd',
|
|
||||||
animation: 'animationend',
|
|
||||||
},
|
|
||||||
animationiteration: {
|
|
||||||
MozAnimation: 'mozAnimationIteration',
|
|
||||||
WebkitAnimation: 'webkitAnimationIteration',
|
|
||||||
animation: 'animationiteration',
|
|
||||||
},
|
|
||||||
animationstart: {
|
|
||||||
MozAnimation: 'mozAnimationStart',
|
|
||||||
WebkitAnimation: 'webkitAnimationStart',
|
|
||||||
animation: 'animationstart',
|
|
||||||
},
|
|
||||||
transitionend: {
|
|
||||||
MozTransition: 'mozTransitionEnd',
|
|
||||||
WebkitTransition: 'webkitTransitionEnd',
|
|
||||||
transition: 'transitionend',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// 获取属性中对应事件名
|
|
||||||
function getEventNameByStyle(eventName) {
|
|
||||||
const prefixMap = vendorPrefixes[eventName];
|
|
||||||
if (!prefixMap) {
|
|
||||||
return eventName;
|
|
||||||
}
|
|
||||||
const style = document.createElement('div').style
|
|
||||||
for (const styleProp in prefixMap) {
|
|
||||||
if (styleProp in style) {
|
|
||||||
return prefixMap[styleProp];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return eventName;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const STYLE_AMT_END: string = getEventNameByStyle(
|
|
||||||
'animationend',
|
|
||||||
);
|
|
||||||
export const STYLE_AMT_ITERATION: string = getEventNameByStyle(
|
|
||||||
'animationiteration',
|
|
||||||
);
|
|
||||||
export const STYLE_AMT_START: string = getEventNameByStyle(
|
|
||||||
'animationstart',
|
|
||||||
);
|
|
||||||
export const STYLE_TRANS_END: string = getEventNameByStyle(
|
|
||||||
'transitionend',
|
|
||||||
);
|
|
|
@ -1,9 +1,3 @@
|
||||||
import {
|
|
||||||
STYLE_AMT_END,
|
|
||||||
STYLE_AMT_ITERATION,
|
|
||||||
STYLE_AMT_START,
|
|
||||||
STYLE_TRANS_END
|
|
||||||
} from './StyleEventNames';
|
|
||||||
|
|
||||||
// Horizon事件和原生事件对应关系
|
// Horizon事件和原生事件对应关系
|
||||||
export const horizonEventToNativeMap = new Map([
|
export const horizonEventToNativeMap = new Map([
|
||||||
|
@ -38,10 +32,10 @@ export const horizonEventToNativeMap = new Map([
|
||||||
['onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin',
|
['onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin',
|
||||||
'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']],
|
'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']],
|
||||||
|
|
||||||
['onAnimationEnd', [STYLE_AMT_END]],
|
['onAnimationEnd', ['animationend']],
|
||||||
['onAnimationIteration', [STYLE_AMT_ITERATION]],
|
['onAnimationIteration', ['animationiteration']],
|
||||||
['onAnimationStart', [STYLE_AMT_START]],
|
['onAnimationStart', ['animationstart']],
|
||||||
['onTransitionEnd', [STYLE_TRANS_END]]
|
['onTransitionEnd', ['transitionend']]
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export const CommonEventToHorizonMap = {
|
export const CommonEventToHorizonMap = {
|
||||||
|
@ -68,10 +62,10 @@ export const CommonEventToHorizonMap = {
|
||||||
selectionchange: 'selectChange',
|
selectionchange: 'selectChange',
|
||||||
textInput: 'textInput',
|
textInput: 'textInput',
|
||||||
touchmove: 'touchMove',
|
touchmove: 'touchMove',
|
||||||
[STYLE_AMT_END]: 'animationEnd',
|
animationend: 'animationEnd',
|
||||||
[STYLE_AMT_ITERATION]: 'animationIteration',
|
animationiteration: 'animationIteration',
|
||||||
[STYLE_AMT_START]: 'animationStart',
|
animationstart: 'animationStart',
|
||||||
[STYLE_TRANS_END]: 'transitionEnd',
|
transitionend: 'transitionEnd',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const CHAR_CODE_ENTER = 13;
|
export const CHAR_CODE_ENTER = 13;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import {createCustomEvent} from '../customEvents/EventFactory';
|
||||||
import {getDom} from '../../dom/DOMInternalKeys';
|
import {getDom} from '../../dom/DOMInternalKeys';
|
||||||
import {isInputValueChanged} from '../../dom/valueHandler/ValueChangeHandler';
|
import {isInputValueChanged} from '../../dom/valueHandler/ValueChangeHandler';
|
||||||
import {addValueUpdateList} from '../ControlledValueUpdater';
|
import {addValueUpdateList} from '../ControlledValueUpdater';
|
||||||
import {isTextInputElement} from '../utils';
|
import {isInputElement} from '../utils';
|
||||||
import {EVENT_TYPE_ALL} from '../const';
|
import {EVENT_TYPE_ALL} from '../const';
|
||||||
import {AnyNativeEvent, ListenerUnitList} from '../Types';
|
import {AnyNativeEvent, ListenerUnitList} from '../Types';
|
||||||
import {
|
import {
|
||||||
|
@ -18,14 +18,14 @@ function shouldTriggerChangeEvent(targetDom, evtName) {
|
||||||
|
|
||||||
if (domTag === 'select' || (domTag === 'input' && type === 'file')) {
|
if (domTag === 'select' || (domTag === 'input' && type === 'file')) {
|
||||||
return evtName === 'change';
|
return evtName === 'change';
|
||||||
} else if (isTextInputElement(targetDom)) {
|
|
||||||
if (evtName === 'input' || evtName === 'change') {
|
|
||||||
return isInputValueChanged(targetDom);
|
|
||||||
}
|
|
||||||
} else if (domTag === 'input' && (type === 'checkbox' || type === 'radio')) {
|
} else if (domTag === 'input' && (type === 'checkbox' || type === 'radio')) {
|
||||||
if (evtName === 'click') {
|
if (evtName === 'click') {
|
||||||
return isInputValueChanged(targetDom);
|
return isInputValueChanged(targetDom);
|
||||||
}
|
}
|
||||||
|
} else if (isInputElement(targetDom)) {
|
||||||
|
if (evtName === 'input' || evtName === 'change') {
|
||||||
|
return isInputValueChanged(targetDom);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,16 +13,16 @@ const compositionEventObj = {
|
||||||
|
|
||||||
// compoisition事件主要处理中文输入法输入时的触发事件
|
// compoisition事件主要处理中文输入法输入时的触发事件
|
||||||
export function getListeners(
|
export function getListeners(
|
||||||
evtName: string,
|
nativeEvtName: string,
|
||||||
nativeEvt: AnyNativeEvent,
|
nativeEvt: AnyNativeEvent,
|
||||||
vNode: null | VNode,
|
vNode: null | VNode,
|
||||||
target: null | EventTarget,
|
target: null | EventTarget,
|
||||||
): ListenerUnitList {
|
): ListenerUnitList {
|
||||||
const evtType = compositionEventObj[evtName];
|
const evtType = compositionEventObj[nativeEvtName];
|
||||||
|
|
||||||
const event = createCustomEvent(
|
const event = createCustomEvent(
|
||||||
evtType,
|
evtType,
|
||||||
evtName,
|
nativeEvtName,
|
||||||
nativeEvt,
|
nativeEvt,
|
||||||
target,
|
target,
|
||||||
);
|
);
|
||||||
|
|
|
@ -3,21 +3,21 @@ 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 {isTextInputElement} from '../utils';
|
import {isInputElement} 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';
|
||||||
import {EVENT_TYPE_ALL} from '../const';
|
import {EVENT_TYPE_ALL} from '../const';
|
||||||
import {ListenerUnitList} from '../Types';
|
import {ListenerUnitList} from '../Types';
|
||||||
|
|
||||||
const horizonEventName = 'onSelect'
|
const horizonEventName = 'onSelect';
|
||||||
|
|
||||||
let currentElement = null;
|
let currentElement = null;
|
||||||
let currentVNode = null;
|
let currentVNode = null;
|
||||||
let lastSelection: Selection | null = null;
|
let lastSelection: Selection | null = null;
|
||||||
|
|
||||||
function initTargetCache(dom, vNode) {
|
function initTargetCache(dom, vNode) {
|
||||||
if (isTextInputElement(dom) || dom.contentEditable === 'true') {
|
if (isInputElement(dom) || dom.contentEditable === 'true') {
|
||||||
currentElement = dom;
|
currentElement = dom;
|
||||||
currentVNode = vNode;
|
currentVNode = vNode;
|
||||||
lastSelection = null;
|
lastSelection = null;
|
||||||
|
@ -79,23 +79,23 @@ function getSelectEvent(nativeEvent, target) {
|
||||||
* 触发场景:用户输入、折叠选择、文本选择
|
* 触发场景:用户输入、折叠选择、文本选择
|
||||||
*/
|
*/
|
||||||
export function getListeners(
|
export function getListeners(
|
||||||
name: string,
|
nativeEvtName: string,
|
||||||
nativeEvt: AnyNativeEvent,
|
nativeEvt: AnyNativeEvent,
|
||||||
vNode: null | VNode,
|
vNode: null | VNode,
|
||||||
target: null | EventTarget,
|
target: null | EventTarget,
|
||||||
): ListenerUnitList {
|
): ListenerUnitList {
|
||||||
const targetNode = vNode ? getDom(vNode) : window;
|
const targetNode = vNode ? getDom(vNode) : window;
|
||||||
let eventUnitList: ListenerUnitList = [];
|
let eventUnitList: ListenerUnitList = [];
|
||||||
switch (name) {
|
switch (nativeEvtName) {
|
||||||
case 'focusin':
|
case 'focusin':
|
||||||
initTargetCache(targetNode, vNode);
|
initTargetCache(targetNode, vNode);
|
||||||
return eventUnitList;
|
break;
|
||||||
case 'focusout':
|
case 'focusout':
|
||||||
clearTargetCache();
|
clearTargetCache();
|
||||||
return eventUnitList;
|
break;
|
||||||
case 'mousedown':
|
case 'mousedown':
|
||||||
isInMouseEvent = true;
|
isInMouseEvent = true;
|
||||||
return eventUnitList;
|
break;
|
||||||
case 'contextmenu':
|
case 'contextmenu':
|
||||||
case 'mouseup':
|
case 'mouseup':
|
||||||
case 'dragend':
|
case 'dragend':
|
||||||
|
@ -107,5 +107,6 @@ export function getListeners(
|
||||||
case 'keyup':
|
case 'keyup':
|
||||||
eventUnitList = getSelectEvent(nativeEvt, target);
|
eventUnitList = getSelectEvent(nativeEvt, target);
|
||||||
}
|
}
|
||||||
|
|
||||||
return eventUnitList;
|
return eventUnitList;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,9 @@
|
||||||
|
|
||||||
// 支持的输入框类型
|
export function isInputElement(dom?: HTMLElement): boolean {
|
||||||
const supportedInputTypes = ['color', 'date', 'datetime', 'datetime-local', 'email', 'month',
|
if (dom instanceof HTMLInputElement || dom instanceof HTMLTextAreaElement) {
|
||||||
'number', 'password', 'range', 'search', 'tel', 'text', 'time', 'url', 'week'];
|
return true;
|
||||||
|
|
||||||
export function isTextInputElement(dom?: HTMLElement): boolean {
|
|
||||||
if (dom instanceof HTMLInputElement) {
|
|
||||||
return supportedInputTypes.includes(dom.type);
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
const nodeName = dom && dom.nodeName && dom.nodeName.toLowerCase();
|
|
||||||
return nodeName === 'textarea';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue