Match-id-042ae92de82f9b93439ee7428abed25c46f90559

This commit is contained in:
* 2022-05-13 15:56:46 +08:00 committed by *
commit 062e0065b8
5 changed files with 17630 additions and 50 deletions

View File

@ -1,14 +1,32 @@
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 {AnyNativeEvent, ListenerUnitList} from './Types'; import { AnyNativeEvent, ListenerUnitList } from './Types';
// 从vnode属性中获取事件listener
function getListenerFromVNode(vNode: VNode, eventName: string): Function | null {
const props = vNode.props;
const mouseEvents = ['onClick', 'onDoubleClick', 'onMouseDown', 'onMouseMove', 'onMouseUp', 'onMouseEnter'];
const formElements = ['button', 'input', 'select', 'textarea'];
// 是否应该阻止禁用的表单元素触发鼠标事件
const shouldPreventMouseEvent =
mouseEvents.includes(eventName) && props.disabled && formElements.includes(vNode.type);
const listener = props[eventName];
if (shouldPreventMouseEvent) {
return null;
} else {
return listener;
}
}
// 获取监听事件 // 获取监听事件
export function getListenersFromTree( export function getListenersFromTree(
targetVNode: VNode | null, targetVNode: VNode | null,
horizonEvtName: string | null, horizonEvtName: string | null,
nativeEvent: AnyNativeEvent, nativeEvent: AnyNativeEvent,
eventType: string, eventType: string
): ListenerUnitList { ): ListenerUnitList {
if (!horizonEvtName) { if (!horizonEvtName) {
return []; return [];
@ -20,11 +38,11 @@ export function getListenersFromTree(
// 从目标节点到根节点遍历获取listener // 从目标节点到根节点遍历获取listener
while (vNode !== null) { while (vNode !== null) {
const {realNode, tag} = vNode; const { realNode, tag } = vNode;
if (tag === DomComponent && realNode !== null) { if (tag === DomComponent && realNode !== null) {
if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_CAPTURE) { if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_CAPTURE) {
const captureName = horizonEvtName + EVENT_TYPE_CAPTURE; const captureName = horizonEvtName + EVENT_TYPE_CAPTURE;
const captureListener = vNode.props[captureName]; const captureListener = getListenerFromVNode(vNode, captureName);
if (captureListener) { if (captureListener) {
listeners.unshift({ listeners.unshift({
vNode, vNode,
@ -36,7 +54,7 @@ export function getListenersFromTree(
} }
if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_BUBBLE) { if (eventType === EVENT_TYPE_ALL || eventType === EVENT_TYPE_BUBBLE) {
const bubbleListener = vNode.props[horizonEvtName]; const bubbleListener = getListenerFromVNode(vNode, horizonEvtName);
if (bubbleListener) { if (bubbleListener) {
listeners.push({ listeners.push({
vNode, vNode,
@ -52,6 +70,3 @@ export function getListenersFromTree(
return listeners; return listeners;
} }

View File

@ -8,6 +8,7 @@
"build": " webpack --config ./scripts/webpack/webpack.config.js", "build": " webpack --config ./scripts/webpack/webpack.config.js",
"build-3rdLib": "node ./scripts/gen3rdLib.js", "build-3rdLib": "node ./scripts/gen3rdLib.js",
"build-3rdLib-dev": "npm run build & node ./scripts/gen3rdLib.js --dev", "build-3rdLib-dev": "npm run build & node ./scripts/gen3rdLib.js --dev",
"build-horizon3rdLib-dev": "npm run build & node ./scripts/gen3rdLib.js --dev --type horizon",
"debug-test": "yarn test --debug", "debug-test": "yarn test --debug",
"test": "jest --config=jest.config.js", "test": "jest --config=jest.config.js",
"watch-test": "yarn test --watch --dev" "watch-test": "yarn test --watch --dev"

View File

@ -2,8 +2,8 @@ import * as Horizon from '@cloudsop/horizon/index.ts';
import { getLogUtils } from '../jest/testUtils'; import { getLogUtils } from '../jest/testUtils';
describe('MouseEvent Test', () => { describe('MouseEvent Test', () => {
const LogUtils =getLogUtils(); const LogUtils = getLogUtils();
describe('onClick Test', () => { describe('onClick Test', () => {
it('绑定this', () => { it('绑定this', () => {
class App extends Horizon.Component { class App extends Horizon.Component {
@ -11,7 +11,7 @@ describe('MouseEvent Test', () => {
super(props); super(props);
this.state = { this.state = {
num: this.props.num, num: this.props.num,
price: this.props.price price: this.props.price,
}; };
} }
@ -19,21 +19,24 @@ describe('MouseEvent Test', () => {
this.setState({ num: this.state.num + 1 }); this.setState({ num: this.state.num + 1 });
} }
setPrice = (e) => { setPrice = e => {
this.setState({ num: this.state.price + 1 }); this.setState({ num: this.state.price + 1 });
} };
render() { render() {
return ( return (
<> <>
<p>{this.state.num}</p> <p>{this.state.num}</p>
<p id="p">{this.state.price}</p> <p id="p">{this.state.price}</p>
<button onClick={this.setNum.bind(this)} >button</button> <button onClick={this.setNum.bind(this)}>button</button>
<button id="btn" onClick={() => this.setPrice()} >button</button> <button id="btn" onClick={() => this.setPrice()}>
button
</button>
</> </>
); );
} }
} }
Horizon.render(<App num={0} price={100} />, container); Horizon.render(<App num={0} price={100} />, container);
expect(container.querySelector('p').innerHTML).toBe('0'); expect(container.querySelector('p').innerHTML).toBe('0');
expect(container.querySelector('#p').innerHTML).toBe('100'); expect(container.querySelector('#p').innerHTML).toBe('100');
@ -55,6 +58,20 @@ describe('MouseEvent Test', () => {
} }
expect(handleClick).toHaveBeenCalledTimes(6); expect(handleClick).toHaveBeenCalledTimes(6);
}); });
it('disable不触发click', () => {
const handleClick = jest.fn();
const spanRef = Horizon.createRef();
Horizon.render(
<button onClick={handleClick} disabled={true}>
<span ref={spanRef}>Click Me</span>
</button>,
container
);
spanRef.current.click();
expect(handleClick).toHaveBeenCalledTimes(0);
});
}); });
const test = (name, config) => { const test = (name, config) => {
@ -62,27 +79,21 @@ describe('MouseEvent Test', () => {
let event = new MouseEvent(name, { let event = new MouseEvent(name, {
relatedTarget: null, relatedTarget: null,
bubbles: true, bubbles: true,
screenX: 1 screenX: 1,
}); });
node.dispatchEvent(event); node.dispatchEvent(event);
expect(LogUtils.getAndClear()).toEqual([ expect(LogUtils.getAndClear()).toEqual([`${name} capture`, `${name} bubble`]);
`${name} capture`,
`${name} bubble`
]);
event = new MouseEvent(name, { event = new MouseEvent(name, {
relatedTarget: null, relatedTarget: null,
bubbles: true, bubbles: true,
screenX: 2 screenX: 2,
}); });
node.dispatchEvent(event); node.dispatchEvent(event);
// 再次触发新事件 // 再次触发新事件
expect(LogUtils.getAndClear()).toEqual([ expect(LogUtils.getAndClear()).toEqual([`${name} capture`, `${name} bubble`]);
`${name} capture`,
`${name} bubble`
]);
}; };
describe('合成鼠标事件', () => { describe('合成鼠标事件', () => {
@ -93,10 +104,7 @@ describe('MouseEvent Test', () => {
const onMouseMoveCapture = () => { const onMouseMoveCapture = () => {
LogUtils.log('mousemove capture'); LogUtils.log('mousemove capture');
}; };
test('mousemove', <div test('mousemove', <div onMouseMove={onMouseMove} onMouseMoveCapture={onMouseMoveCapture} />);
onMouseMove={onMouseMove}
onMouseMoveCapture={onMouseMoveCapture}
/>);
}); });
it('onMouseDown', () => { it('onMouseDown', () => {
@ -106,10 +114,7 @@ describe('MouseEvent Test', () => {
const onMousedownCapture = () => { const onMousedownCapture = () => {
LogUtils.log('mousedown capture'); LogUtils.log('mousedown capture');
}; };
test('mousedown', <div test('mousedown', <div onMousedown={onMousedown} onMousedownCapture={onMousedownCapture} />);
onMousedown={onMousedown}
onMousedownCapture={onMousedownCapture}
/>);
}); });
it('onMouseUp', () => { it('onMouseUp', () => {
@ -119,10 +124,7 @@ describe('MouseEvent Test', () => {
const onMouseUpCapture = () => { const onMouseUpCapture = () => {
LogUtils.log('mouseup capture'); LogUtils.log('mouseup capture');
}; };
test('mouseup', <div test('mouseup', <div onMouseUp={onMouseUp} onMouseUpCapture={onMouseUpCapture} />);
onMouseUp={onMouseUp}
onMouseUpCapture={onMouseUpCapture}
/>);
}); });
it('onMouseOut', () => { it('onMouseOut', () => {
@ -132,10 +134,7 @@ describe('MouseEvent Test', () => {
const onMouseOutCapture = () => { const onMouseOutCapture = () => {
LogUtils.log('mouseout capture'); LogUtils.log('mouseout capture');
}; };
test('mouseout', <div test('mouseout', <div onMouseOut={onMouseOut} onMouseOutCapture={onMouseOutCapture} />);
onMouseOut={onMouseOut}
onMouseOutCapture={onMouseOutCapture}
/>);
}); });
it('onMouseOver', () => { it('onMouseOver', () => {
@ -145,10 +144,7 @@ describe('MouseEvent Test', () => {
const onMouseOverCapture = () => { const onMouseOverCapture = () => {
LogUtils.log('mouseover capture'); LogUtils.log('mouseover capture');
}; };
test('mouseover', <div test('mouseover', <div onMouseOver={onMouseOver} onMouseOverCapture={onMouseOverCapture} />);
onMouseOver={onMouseOver}
onMouseOverCapture={onMouseOverCapture}
/>);
}); });
}); });
}); });

View File

@ -9,7 +9,7 @@ const argv = require('minimist')(process.argv.slice(2));
const libPathPrefix = '../build'; const libPathPrefix = '../build';
const suffix = argv.dev ? 'development.js' : 'production.js'; const suffix = argv.dev ? 'development.js' : 'production.js';
const template = argv.type === 'horizon' ? 'horizon3rdTemplate.ejs' : 'template.ejs';
const readLib = (lib) => { const readLib = (lib) => {
const libName = lib.split('.')[0]; const libName = lib.split('.')[0];
const libPath = path.resolve(__dirname, `${libPathPrefix}/${libName}/umd/${lib}`); const libPath = path.resolve(__dirname, `${libPathPrefix}/${libName}/umd/${lib}`);
@ -20,7 +20,7 @@ const readLib = (lib) => {
} }
}; };
ejs.renderFile(path.resolve(__dirname, './template.ejs'), { ejs.renderFile(path.resolve(__dirname, `./${template}`), {
Horizon: readLib(`horizon.${suffix}`), Horizon: readLib(`horizon.${suffix}`),
}, null, function(err, result) { }, null, function(err, result) {
const common3rdLibPath = path.resolve(__dirname, `${libPathPrefix}/horizonCommon3rdlib.min.js`) const common3rdLibPath = path.resolve(__dirname, `${libPathPrefix}/horizonCommon3rdlib.min.js`)

17568
scripts/horizon3rdTemplate.ejs Normal file

File diff suppressed because it is too large Load Diff