Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/social-deer-brush.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/web-mainthread-apis": patch
---

fix: mts && bts events can be binded both
Comment thread
Sherry-hue marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -210,48 +210,59 @@ export function createMainThreadGlobalThis(
currentTarget as any as HTMLElement,
);
if (runtimeInfo) {
const hname = isCapture
const handlerInfos = (isCapture
? runtimeInfo.eventHandlerMap[lynxEventName]?.capture
?.handler
: runtimeInfo.eventHandlerMap[lynxEventName]?.bind
?.handler;
const crossThreadEvent = createCrossThreadEvent(
event as MinimalRawEventObject,
lynxEventName,
);
if (typeof hname === 'string') {
const parentComponentUniqueId = Number(
currentTarget.getAttribute(parentComponentUniqueIdAttribute)!,
);
const parentComponent = lynxUniqueIdToElement[parentComponentUniqueId]!
.deref()!;
const componentId =
parentComponent?.getAttribute(lynxTagAttribute) !== 'page'
? parentComponent?.getAttribute(componentIdAttribute) ?? undefined
: undefined;
if (componentId) {
callbacks.publicComponentEvent(
componentId,
hname,
crossThreadEvent,
);
} else {
callbacks.publishEvent(
hname,
crossThreadEvent,
: runtimeInfo.eventHandlerMap[lynxEventName]?.bind) as unknown as {
handler: string | { type: 'worklet'; value: unknown };
}[];
let stopPropagation = false;
if (handlerInfos) {
for (const handlerInfo of handlerInfos) {
const hname = handlerInfo.handler;
const crossThreadEvent = createCrossThreadEvent(
event as MinimalRawEventObject,
lynxEventName,
);
if (typeof hname === 'string') {
const parentComponentUniqueId = Number(
currentTarget.getAttribute(parentComponentUniqueIdAttribute)!,
);
const parentComponent =
lynxUniqueIdToElement[parentComponentUniqueId]!
.deref()!;
const componentId =
parentComponent?.getAttribute(lynxTagAttribute) !== 'page'
? parentComponent?.getAttribute(componentIdAttribute)
?? undefined
: undefined;
if (componentId) {
callbacks.publicComponentEvent(
componentId,
hname,
crossThreadEvent,
);
} else {
callbacks.publishEvent(
hname,
crossThreadEvent,
);
}
if (handlerInfos.length === 1) {
stopPropagation = true;
}
} else if (hname) {
(crossThreadEvent as MainThreadScriptEvent).target.elementRefptr =
event.target;
if (crossThreadEvent.currentTarget) {
(crossThreadEvent as MainThreadScriptEvent).currentTarget!
.elementRefptr = event.currentTarget;
}
(mtsRealm.globalWindow as typeof globalThis & MainThreadGlobalThis)
.runWorklet?.(hname.value, [crossThreadEvent]);
}
}
return true;
} else if (hname) {
(crossThreadEvent as MainThreadScriptEvent).target.elementRefptr =
event.target;
if (crossThreadEvent.currentTarget) {
(crossThreadEvent as MainThreadScriptEvent).currentTarget!
.elementRefptr = event.currentTarget;
}
(mtsRealm.globalWindow as typeof globalThis & MainThreadGlobalThis)
.runWorklet?.(hname.value, [crossThreadEvent]);
}
return stopPropagation;
}
return false;
};
Expand Down Expand Up @@ -285,9 +296,10 @@ export function createMainThreadGlobalThis(
componentAtIndex: undefined,
enqueueComponent: undefined,
};
const currentHandler = isCapture
const handlerList = (isCapture
? runtimeInfo.eventHandlerMap[eventName]?.capture
: runtimeInfo.eventHandlerMap[eventName]?.bind;
: runtimeInfo.eventHandlerMap[eventName]?.bind) as unknown as any[];
const currentHandler = handlerList && handlerList.length > 0;
const currentRegisteredHandler = isCatch
? (isCapture ? catchCaptureHandler : defaultCatchHandler)
: (isCapture ? captureHandler : defaultHandler);
Expand All @@ -305,6 +317,13 @@ export function createMainThreadGlobalThis(
if (isExposure && element.getAttribute('exposure-id') === '-1') {
mtsGlobalThis.__SetAttribute(element, 'exposure-id', null);
}
if (runtimeInfo.eventHandlerMap[eventName]) {
if (isCapture) {
runtimeInfo.eventHandlerMap[eventName]!.capture = undefined;
} else {
runtimeInfo.eventHandlerMap[eventName]!.bind = undefined;
}
}
}
} else {
/**
Expand Down Expand Up @@ -336,10 +355,28 @@ export function createMainThreadGlobalThis(
bind: undefined,
};
}
let targetList = (isCapture
? runtimeInfo.eventHandlerMap[eventName]!.capture
: runtimeInfo.eventHandlerMap[eventName]!.bind) as unknown as any[];

if (!Array.isArray(targetList)) {
targetList = targetList ? [targetList] : [];
}

const typeOfNew = typeof newEventHandler;
const index = targetList.findIndex((h: any) =>
typeof h.handler === typeOfNew
);
if (index !== -1) {
targetList[index] = info;
} else {
targetList.push(info);
}

if (isCapture) {
runtimeInfo.eventHandlerMap[eventName]!.capture = info;
runtimeInfo.eventHandlerMap[eventName]!.capture = targetList as any;
} else {
runtimeInfo.eventHandlerMap[eventName]!.bind = info;
runtimeInfo.eventHandlerMap[eventName]!.bind = targetList as any;
}
}
elementToRuntimeInfoMap.set(element, runtimeInfo);
Expand All @@ -354,10 +391,13 @@ export function createMainThreadGlobalThis(
if (runtimeInfo) {
eventName = eventName.toLowerCase();
const isCapture = eventType.startsWith('capture');
const handler = isCapture
const handler = (isCapture
? runtimeInfo.eventHandlerMap[eventName]?.capture
: runtimeInfo.eventHandlerMap[eventName]?.bind;
return handler?.handler;
: runtimeInfo.eventHandlerMap[eventName]?.bind) as unknown as any[];
if (Array.isArray(handler)) {
return handler[0]?.handler;
}
return (handler as any)?.handler;
} else {
return undefined;
}
Expand All @@ -374,13 +414,18 @@ export function createMainThreadGlobalThis(
for (const [lynxEventName, info] of Object.entries(eventHandlerMap)) {
for (const atomInfo of [info.bind, info.capture]) {
if (atomInfo) {
const { type, handler } = atomInfo;
if (handler) {
eventInfos.push({
type: type as LynxEventType,
name: lynxEventName,
function: handler,
});
const handlerList = (Array.isArray(atomInfo)
? atomInfo
: [atomInfo]) as any[];
for (const item of handlerList) {
const { type, handler } = item;
if (handler) {
eventInfos.push({
type: type as LynxEventType,
name: lynxEventName,
function: handler,
});
}
}
}
}
Expand Down
10 changes: 10 additions & 0 deletions packages/web-platform/web-tests/tests/react.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
if (testname2) {
url += `&casename2=${testname2}`;
}
await page.goto(url, {

Check failure on line 59 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[webkit] › tests/react.spec.ts:4667:7 › reactlynx3 tests › elements › list › basic-element-list-estimated-main-axis-size-px

1) [webkit] › tests/react.spec.ts:4667:7 › reactlynx3 tests › elements › list › basic-element-list-estimated-main-axis-size-px Error: page.goto: Test timeout of 30000ms exceeded. Call log: - navigating to "http://localhost:3080/?casename=basic-element-list-estimated-main-axis-size-px", waiting until "load" 57 | url += `&casename2=${testname2}`; 58 | } > 59 | await page.goto(url, { | ^ 60 | waitUntil: 'load', 61 | }); 62 | await page.evaluate(() => document.fonts.ready); at goto (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:59:14) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:4670:17

Check failure on line 59 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (1/3) / check

[webkit] › tests/react.spec.ts:2544:7 › reactlynx3 tests › elements › svg › basic-element-svg-hex-color

1) [webkit] › tests/react.spec.ts:2544:7 › reactlynx3 tests › elements › svg › basic-element-svg-hex-color Error: page.goto: Test timeout of 30000ms exceeded. Call log: - navigating to "http://localhost:3080/?casename=basic-element-svg-hex-color", waiting until "load" 57 | url += `&casename2=${testname2}`; 58 | } > 59 | await page.goto(url, { | ^ 60 | waitUntil: 'load', 61 | }); 62 | await page.evaluate(() => document.fonts.ready); at goto (/__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:59:14) at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:2545:15
waitUntil: 'load',
});
await page.evaluate(() => document.fonts.ready);
Expand Down Expand Up @@ -116,6 +116,16 @@
await wait(100);
await expect(await target.getAttribute('style')).toContain('pink');
});
test('basic-bindtap-simultaneous', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
const target = page.locator('#target');
await target.click();
await wait(100);
await expect(await target.getAttribute('style')).toContain('green'); // BTS check
await expect(await target.getAttribute('data-mts-clicked')).toBe('true'); // MTS check
await expect(page.locator('#bts-status')).toHaveText('BTS Clicked');
});
test('basic-bindtap-detail', async ({ page }, { title }) => {
await goto(page, title);
await wait(100);
Expand Down Expand Up @@ -882,7 +892,7 @@
'background-color',
'rgb(0, 128, 0)',
); // green
expect(page.locator('#target2'), 'mouse up event captured').toHaveCSS(

Check failure on line 895 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-CSR (2/3) / check

[chromium] › tests/react.spec.ts:882:5 › reactlynx3 tests › basic › basic-bindmouse

2) [chromium] › tests/react.spec.ts:882:5 › reactlynx3 tests › basic › basic-bindmouse ─────────── Error: mouse up event captured expect(locator).toHaveCSS(expected) failed Locator: locator('#target2') Expected: "rgb(0, 128, 0)" Received: "rgb(255, 192, 203)" Call log: - mouse up event captured with timeout 5000ms - waiting for locator('#target2') 2 × locator resolved to <x-view l-uid="5" id="target2" lynx-tag="view" l-p-comp-uid="1"></x-view> - unexpected value "rgb(255, 192, 203)" 893 | 'rgb(0, 128, 0)', 894 | ); // green > 895 | expect(page.locator('#target2'), 'mouse up event captured').toHaveCSS( | ^ 896 | 'background-color', 897 | 'rgb(0, 128, 0)', 898 | ); // green at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:895:69
'background-color',
'rgb(0, 128, 0)',
); // green
Expand Down Expand Up @@ -2461,7 +2471,7 @@
await page.locator('#img').first().click();
await wait(100);
expect(await page.locator('#result').getAttribute('class'))
.toStrictEqual(

Check failure on line 2474 in packages/web-platform/web-tests/tests/react.spec.ts

View workflow job for this annotation

GitHub Actions / Playwright ALL_ON_UI-SSR (3/3) / check

[chromium] › tests/react.spec.ts:2467:7 › reactlynx3 tests › elements › image › basic-element-image-support-tap-event

3) [chromium] › tests/react.spec.ts:2467:7 › reactlynx3 tests › elements › image › basic-element-image-support-tap-event Error: expect(received).toStrictEqual(expected) // deep equality Expected: "success" Received: "fail" 2472 | await wait(100); 2473 | expect(await page.locator('#result').getAttribute('class')) > 2474 | .toStrictEqual( | ^ 2475 | 'success', 2476 | ); 2477 | }, at /__w/lynx-stack/lynx-stack/packages/web-platform/web-tests/tests/react.spec.ts:2474:14
'success',
);
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { useState, root } from '@lynx-js/react';

function App() {
const [btsClicked, setBtsClicked] = useState(false);

const handleBtsTap = () => {
setBtsClicked(true);
console.log('BTS Clicked');
};

const handleMtsTap = (event) => {
'main thread';
event.currentTarget.setAttribute('data-mts-clicked', 'true');
console.log('MTS Clicked');
};

return (
<view>
<view
id='target'
bindtap={handleBtsTap}
main-thread:bindtap={handleMtsTap}
style={{
height: '100px',
width: '100px',
background: btsClicked ? 'green' : 'red',
}}
data-mts-clicked='false'
/>
<text id='bts-status'>
{btsClicked ? 'BTS Clicked' : 'BTS Not Clicked'}
</text>
</view>
);
}

root.render(<App />);
Loading