Match-id-c512ddd2eafdc01bfd6b07d73a3aead7828578e8

This commit is contained in:
* 2022-04-20 14:47:42 +08:00 committed by *
parent d45d6629aa
commit d14122a5d3
8 changed files with 54 additions and 63 deletions

View File

@ -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 上的属性相关信息

View File

@ -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);
});
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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;
}

View File

@ -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;

View File

@ -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');
});
});

View File

@ -172,6 +172,11 @@ describe('Dom Input', () => {
expect(realNode.getAttribute('value')).toBe('default');
});
it('value为0、defaultValue为1input 的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);
});
});
});
});