diff --git a/.changeset/clone-touch-events.md b/.changeset/clone-touch-events.md new file mode 100644 index 0000000000..51002f780e --- /dev/null +++ b/.changeset/clone-touch-events.md @@ -0,0 +1,5 @@ +--- +"@lynx-js/web-core": patch +--- + +Always clone touch event lists when creating cross-thread events so synthetic touch events only carry structured-clone-safe primitive fields. diff --git a/packages/web-platform/web-core/tests/element-apis.spec.ts b/packages/web-platform/web-core/tests/element-apis.spec.ts index fba5310a44..8c63b94822 100644 --- a/packages/web-platform/web-core/tests/element-apis.spec.ts +++ b/packages/web-platform/web-core/tests/element-apis.spec.ts @@ -135,6 +135,25 @@ describe('Element APIs', () => { expect(lynxEvent.detail).toEqual({ x: 100, y: 200 }); }); + test('createCrossThreadEvent clone touches for untrusted events', async () => { + const { createCrossThreadEvent } = await import( + '../ts/client/mainthread/elementAPIs/createCrossThreadEvent.js' + ); + const touchEvent = new Event('touchstart') as any; + touchEvent.touches = [{ + clientX: 100, + clientY: 200, + nested: { ignored: true }, + }]; + touchEvent.targetTouches = [{ identifier: 1, target: {} }]; + touchEvent.changedTouches = [{ pageX: 10, preventDefault: () => {} }]; + + const lynxEvent = createCrossThreadEvent(touchEvent); + expect(lynxEvent.touches).toEqual([{ clientX: 100, clientY: 200 }]); + expect(lynxEvent.targetTouches).toEqual([{ identifier: 1 }]); + expect(lynxEvent.changedTouches).toEqual([{ pageX: 10 }]); + }); + test('createCrossThreadEvent sets empty detail if no touches', async () => { const { createCrossThreadEvent } = await import( '../ts/client/mainthread/elementAPIs/createCrossThreadEvent.js' diff --git a/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createCrossThreadEvent.ts b/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createCrossThreadEvent.ts index 4f869d1e89..10613df9fd 100644 --- a/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createCrossThreadEvent.ts +++ b/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createCrossThreadEvent.ts @@ -28,7 +28,6 @@ export function createCrossThreadEvent( ): LynxCrossThreadEvent { const type = domEvent.type; const params: Cloneable = {}; - const isTrusted = domEvent.isTrusted; const otherProperties: CloneableObject = {}; let detail = domEvent.detail ?? {}; if (type.match(/^transition/)) { @@ -49,17 +48,9 @@ export function createCrossThreadEvent( const targetTouches = [...touchEvent.targetTouches as unknown as Touch[]]; const changedTouches = [...touchEvent.changedTouches as unknown as Touch[]]; Object.assign(otherProperties, { - touches: isTrusted ? touch.map(toCloneableObject) : touch, - targetTouches: isTrusted - ? targetTouches.map( - toCloneableObject, - ) - : targetTouches, - changedTouches: isTrusted - ? changedTouches.map( - toCloneableObject, - ) - : changedTouches, + touches: touch.map(toCloneableObject), + targetTouches: targetTouches.map(toCloneableObject), + changedTouches: changedTouches.map(toCloneableObject), }); if (touch[0]) { detail = {