Match-id-c512ddd2eafdc01bfd6b07d73a3aead7828578e8
This commit is contained in:
parent
d45d6629aa
commit
d14122a5d3
|
@ -49,23 +49,17 @@ export function getVNode(dom: Node|Container): VNode | null {
|
|||
|
||||
// 用 DOM 对象,来寻找其对应或者说是最近父级的 vNode
|
||||
export function getNearestVNode(dom: Node): null | VNode {
|
||||
let vNode = dom[INTERNAL_VNODE];
|
||||
if (vNode) { // 如果是已经被框架标记过的 DOM 节点,那么直接返回其 VNode 实例
|
||||
return vNode;
|
||||
let domNode: Node | null = dom;
|
||||
// 寻找当前节点及其所有祖先节点是否有标记VNODE
|
||||
while (domNode) {
|
||||
const vNode = domNode[INTERNAL_VNODE];
|
||||
if (vNode) {
|
||||
return vNode;
|
||||
}
|
||||
domNode = domNode.parentNode;
|
||||
}
|
||||
|
||||
// 下面处理的是为被框架标记过的 DOM 节点,向上找其父节点是否被框架标记过
|
||||
let parentDom = dom.parentNode;
|
||||
let nearVNode = null;
|
||||
while (parentDom) {
|
||||
vNode = parentDom[INTERNAL_VNODE];
|
||||
if (vNode) {
|
||||
nearVNode = vNode;
|
||||
break;
|
||||
}
|
||||
parentDom = parentDom.parentNode;
|
||||
}
|
||||
return nearVNode;
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取 vNode 上的属性相关信息
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
function isNeedUnitCSS(propName: string) {
|
||||
return !(noUnitCSS.includes(propName)
|
||||
|| propName.startsWith('borderImage')
|
||||
|| propName.startsWith('flex')
|
||||
|| propName.startsWith('gridRow')
|
||||
|| propName.startsWith('gridColumn')
|
||||
|| propName.startsWith('stroke')
|
||||
|| propName.startsWith('box')
|
||||
|| propName.endsWith('Opacity'));
|
||||
function isNeedUnitCSS(styleName: string) {
|
||||
return !(noUnitCSS.includes(styleName)
|
||||
|| styleName.startsWith('borderImage')
|
||||
|| styleName.startsWith('flex')
|
||||
|| styleName.startsWith('gridRow')
|
||||
|| styleName.startsWith('gridColumn')
|
||||
|| styleName.startsWith('stroke')
|
||||
|| styleName.startsWith('box')
|
||||
|| styleName.endsWith('Opacity'));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,9 +38,7 @@ export function setStyles(dom, styles) {
|
|||
Object.keys(styles).forEach((name) => {
|
||||
const styleVal = styles[name];
|
||||
|
||||
const validStyleValue = adjustStyleValue(name, styleVal);
|
||||
|
||||
style[name] = validStyleValue;
|
||||
style[name] = adjustStyleValue(name, styleVal);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
|||
|
||||
|
||||
// 是内置元素
|
||||
export function isNativeElement(tagName: string, props: Object) {
|
||||
export function isNativeElement(tagName: string, props: Record<string, any>) {
|
||||
return !tagName.includes('-') && props.is === undefined;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import {
|
|||
getTextareaPropsWithoutValue,
|
||||
updateTextareaValue,
|
||||
} from './TextareaValueHandler';
|
||||
import {getDomTag} from "../utils/Common";
|
||||
import {getDomTag} from '../utils/Common';
|
||||
|
||||
// 获取元素除了被代理的值以外的属性
|
||||
function getPropsWithoutValue(type: string, dom: HorizonDom, properties: IProperty) {
|
||||
|
|
|
@ -16,8 +16,11 @@ import { decorateNativeEvent } from './customEvents/EventFactory';
|
|||
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';
|
||||
import { findRoot } from '../renderer/vnode/VNodeUtils';
|
||||
import { ListenerUnitList } from './Types';
|
||||
|
||||
// web规范,鼠标右键key值
|
||||
const RIGHT_MOUSE_BUTTON = 2;
|
||||
|
||||
// 获取事件触发的普通事件监听方法队列
|
||||
function getCommonListeners(
|
||||
|
@ -29,13 +32,13 @@ function getCommonListeners(
|
|||
): ListenerUnitList {
|
||||
const name = CommonEventToHorizonMap[nativeEvtName];
|
||||
const horizonEvtName = !name ? '' : `on${name[0].toUpperCase()}${name.slice(1)}`; // 例:dragEnd -> onDragEnd
|
||||
|
||||
|
||||
if (!horizonEvtName) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// 鼠标点击右键
|
||||
if (nativeEvent instanceof MouseEvent && nativeEvtName === 'click' && nativeEvent.button === 2) {
|
||||
if (nativeEvent instanceof MouseEvent && nativeEvtName === 'click' && nativeEvent.button === RIGHT_MOUSE_BUTTON) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -76,7 +79,7 @@ function getProcessListeners(
|
|||
vNode: VNode | null,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
target,
|
||||
isCapture: boolean
|
||||
isCapture: boolean,
|
||||
): ListenerUnitList {
|
||||
// 触发普通委托事件
|
||||
let listenerList: ListenerUnitList = getCommonListeners(
|
||||
|
@ -136,11 +139,11 @@ export function handleEventMain(
|
|||
isCapture: boolean,
|
||||
nativeEvent: AnyNativeEvent,
|
||||
vNode: null | VNode,
|
||||
targetContainer: EventTarget,
|
||||
targetDom: EventTarget,
|
||||
): void {
|
||||
let startVNode = vNode;
|
||||
if (startVNode !== null) {
|
||||
startVNode = getExactNode(startVNode, targetContainer);
|
||||
startVNode = findRoot(startVNode, targetDom);
|
||||
if (!startVNode) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ export function travelVNodeTree(
|
|||
finishVNode: VNode, // 结束遍历节点,有时候和beginVNode不相同
|
||||
handleWhenToParent: Function | null
|
||||
): VNode | null {
|
||||
const filter = childFilter === null;
|
||||
let node = beginVNode;
|
||||
|
||||
while (true) {
|
||||
|
@ -43,7 +42,7 @@ export function travelVNodeTree(
|
|||
|
||||
// 找子节点
|
||||
const childVNode = node.child;
|
||||
if (childVNode !== null && (filter || !childFilter(node))) {
|
||||
if (childVNode !== null && (childFilter === null || !childFilter(node))) {
|
||||
childVNode.parent = node;
|
||||
node = childVNode;
|
||||
continue;
|
||||
|
@ -194,20 +193,6 @@ export function getSiblingDom(vNode: VNode): Element | null {
|
|||
}
|
||||
}
|
||||
|
||||
function isSameContainer(
|
||||
container: Element,
|
||||
targetContainer: EventTarget,
|
||||
): boolean {
|
||||
if (container === targetContainer) {
|
||||
return true;
|
||||
}
|
||||
// 注释类型的节点
|
||||
if (isComment(container) && container.parentNode === targetContainer) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function isPortalRoot(vNode, targetContainer) {
|
||||
if (vNode.tag === DomPortal) {
|
||||
let topVNode = vNode.parent;
|
||||
|
@ -216,7 +201,7 @@ function isPortalRoot(vNode, targetContainer) {
|
|||
if (grandTag === TreeRoot || grandTag === DomPortal) {
|
||||
const topContainer = topVNode.realNode;
|
||||
// 如果topContainer是targetContainer,不需要在这里处理
|
||||
if (isSameContainer(topContainer, targetContainer)) {
|
||||
if (topContainer === targetContainer) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -228,28 +213,28 @@ function isPortalRoot(vNode, targetContainer) {
|
|||
}
|
||||
|
||||
// 获取根vNode节点
|
||||
export function getExactNode(targetVNode, targetContainer) {
|
||||
export function findRoot(targetVNode, targetDom) {
|
||||
// 确认vNode节点是否准确,portal场景下可能祖先节点不准确
|
||||
let vNode = targetVNode;
|
||||
while (vNode !== null) {
|
||||
if (vNode.tag === TreeRoot || vNode.tag === DomPortal) {
|
||||
let container = vNode.realNode;
|
||||
if (isSameContainer(container, targetContainer)) {
|
||||
let dom = vNode.realNode;
|
||||
if (dom === targetDom) {
|
||||
break;
|
||||
}
|
||||
if (isPortalRoot(vNode, targetContainer)) {
|
||||
if (isPortalRoot(vNode, targetDom)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
while (container !== null) {
|
||||
const parentNode = getNearestVNode(container);
|
||||
while (dom !== null) {
|
||||
const parentNode = getNearestVNode(dom);
|
||||
if (parentNode === null) {
|
||||
return null;
|
||||
}
|
||||
if (parentNode.tag === DomComponent || parentNode.tag === DomText) {
|
||||
return getExactNode(parentNode, targetContainer);
|
||||
return findRoot(parentNode, targetDom);
|
||||
}
|
||||
container = container.parentNode;
|
||||
dom = dom.parentNode;
|
||||
}
|
||||
}
|
||||
vNode = vNode.parent;
|
||||
|
|
|
@ -61,4 +61,10 @@ describe('Dom Attribute', () => {
|
|||
container.querySelector('div').setAttribute('data-first-name', 'Tom');
|
||||
expect(container.querySelector('div').dataset.firstName).toBe('Tom');
|
||||
});
|
||||
});
|
||||
|
||||
it('style 自动加px', () => {
|
||||
const div = Horizon.render(<div style={{width: 10, height: 20}}/>, container);
|
||||
expect(window.getComputedStyle(div).getPropertyValue('width')).toBe('10px');
|
||||
expect(window.getComputedStyle(div).getPropertyValue('height')).toBe('20px');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -172,6 +172,11 @@ describe('Dom Input', () => {
|
|||
expect(realNode.getAttribute('value')).toBe('default');
|
||||
});
|
||||
|
||||
it('value为0、defaultValue为1,input 的value应该为0', () => {
|
||||
const input = Horizon.render(<input defaultValue={1} value={0} />, container);
|
||||
expect(input.getAttribute('value')).toBe('0');
|
||||
});
|
||||
|
||||
it('name属性', () => {
|
||||
let realNode = Horizon.render(<input type='text' name={'name'} />, container);
|
||||
expect(realNode.name).toBe('name');
|
||||
|
@ -426,4 +431,4 @@ describe('Dom Input', () => {
|
|||
expect(container.querySelector('input').hasAttribute('value')).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue