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/add-event-bubble-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/web-core": patch
---

feat(web-core): add `is_bubble` parameter to `common_event_handler` to properly handle non-bubbling events like `window.Event('click', { bubbles: false })`.
5 changes: 5 additions & 0 deletions .changeset/fix-query-component-processevalresult.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@lynx-js/web-core": patch
---

fix(web-core): fallback to the original export chunk when `processEvalResult` is absent during `queryComponent` execution
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"appType": "lazy",
"lepusCode": {
"root": "({ mockResult: 'MOCKED_EVAL_RESULT' })"
},
"pageConfig": {
"enableCSSSelector": true
}
}
68 changes: 68 additions & 0 deletions packages/web-platform/web-core-e2e/tests/web-core.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,74 @@ test.describe('web core tests', () => {
expect(fail).toBe(false);
});

test('__QueryComponent without processEvalResult', async ({ page, browserName }) => {
// firefox dose not support this.
test.skip(browserName === 'firefox');
await goto(page);

await page.evaluate(() => {
delete (globalThis as any).runtime.processEvalResult;
});

const evalResult = await page.evaluate(async () => {
return new Promise((resolve) => {
globalThis.addEventListener('unhandledrejection', (e) => {
resolve({ error: e.reason?.message ?? String(e.reason) });
});
globalThis.runtime.__QueryComponent(
'/resources/mock-component.json',
(res: any) => {
resolve(res);
},
);
});
});

expect(evalResult).toMatchObject({
code: 0,
});
expect((evalResult as any).data.url).toBe('/resources/mock-component.json');
expect((evalResult as any).data.evalResult).toEqual({
mockResult: 'MOCKED_EVAL_RESULT',
});
});

test('__QueryComponent with processEvalResult', async ({ page, browserName }) => {
// firefox dose not support this.
test.skip(browserName === 'firefox');
await goto(page);

await page.evaluate(() => {
(globalThis as any).runtime.processEvalResult = (
exports: any,
url: string,
) => {
return 'OVERRIDDEN_MOCKED_EVAL_RESULT';
};
});

const evalResult = await page.evaluate(async () => {
return new Promise((resolve) => {
globalThis.addEventListener('unhandledrejection', (e) => {
resolve({ error: e.reason?.message ?? String(e.reason) });
});
globalThis.runtime.__QueryComponent(
'/resources/mock-component.json',
(res: any) => {
resolve(res);
},
);
});
});

expect(evalResult).toMatchObject({
code: 0,
});
expect((evalResult as any).data.evalResult).toBe(
'OVERRIDDEN_MOCKED_EVAL_RESULT',
);
});

test('api-enableJSDataProcessor disables processData', async ({ page, browserName }) => {
test.skip(browserName === 'firefox');
await goto(page, 'web-core.enable-js-data-processor.json');
Expand Down
4 changes: 2 additions & 2 deletions packages/web-platform/web-core/binary/client/client.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class MainThreadWasmContext {
add_cross_thread_event(unique_id: number, event_type: string, event_name: string, event_handler_identifier?: string | null): void;
add_dataset(unique_id: number, key: any, value: any): void;
add_run_worklet_event(unique_id: number, event_type: string, event_name: string, event_handler_identifier?: any | null): void;
common_event_handler(event: any, bubble_unique_id_path: Uint32Array, event_name: string): void;
common_event_handler(event: any, bubble_unique_id_path: Uint32Array, event_name: string, is_bubble: boolean): void;
create_element_common(parent_component_unique_id: number, dom: HTMLElement, css_id?: number | null, component_id?: string | null): number;
dispatch_event_by_path(bubble_unique_id_path: Uint32Array, event_name: string, is_capture: boolean, serialized_event: any): boolean;
get_component_id(unique_id: number): string | undefined;
Expand Down Expand Up @@ -199,7 +199,7 @@ export interface InitOutput {
readonly mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
readonly mainthreadwasmcontext_add_dataset: (a: number, b: number, c: any, d: any) => [number, number];
readonly mainthreadwasmcontext_add_run_worklet_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly mainthreadwasmcontext_common_event_handler: (a: number, b: any, c: number, d: number, e: number, f: number) => void;
readonly mainthreadwasmcontext_common_event_handler: (a: number, b: any, c: number, d: number, e: number, f: number, g: number) => void;
readonly mainthreadwasmcontext_create_element_common: (a: number, b: number, c: any, d: number, e: number, f: number) => number;
readonly mainthreadwasmcontext_dispatch_event_by_path: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => number;
readonly mainthreadwasmcontext_get_component_id: (a: number, b: number) => [number, number, number, number];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const get_style_content: (a: any) => [number, number, number, number];
export const mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
export const mainthreadwasmcontext_add_dataset: (a: number, b: number, c: any, d: any) => [number, number];
export const mainthreadwasmcontext_add_run_worklet_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
export const mainthreadwasmcontext_common_event_handler: (a: number, b: any, c: number, d: number, e: number, f: number) => void;
export const mainthreadwasmcontext_common_event_handler: (a: number, b: any, c: number, d: number, e: number, f: number, g: number) => void;
export const mainthreadwasmcontext_create_element_common: (a: number, b: number, c: any, d: number, e: number, f: number) => number;
export const mainthreadwasmcontext_dispatch_event_by_path: (a: number, b: number, c: number, d: number, e: number, f: number, g: any) => number;
export const mainthreadwasmcontext_get_component_id: (a: number, b: number) => [number, number, number, number];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class MainThreadWasmContext {
add_cross_thread_event(unique_id: number, event_type: string, event_name: string, event_handler_identifier?: string | null): void;
add_dataset(unique_id: number, key: any, value: any): void;
add_run_worklet_event(unique_id: number, event_type: string, event_name: string, event_handler_identifier?: any | null): void;
common_event_handler(event: any, bubble_unique_id_path: Uint32Array, event_name: string): void;
common_event_handler(event: any, bubble_unique_id_path: Uint32Array, event_name: string, is_bubble: boolean): void;
create_element_common(parent_component_unique_id: number, dom: HTMLElement, css_id?: number | null, component_id?: string | null): number;
dispatch_event_by_path(bubble_unique_id_path: Uint32Array, event_name: string, is_capture: boolean, serialized_event: any): boolean;
get_component_id(unique_id: number): string | undefined;
Expand Down Expand Up @@ -199,7 +199,7 @@ export interface InitOutput {
readonly mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
readonly mainthreadwasmcontext_add_dataset: (a: number, b: number, c: number, d: number, e: number) => void;
readonly mainthreadwasmcontext_add_run_worklet_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly mainthreadwasmcontext_common_event_handler: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
readonly mainthreadwasmcontext_common_event_handler: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
readonly mainthreadwasmcontext_create_element_common: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
readonly mainthreadwasmcontext_dispatch_event_by_path: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
readonly mainthreadwasmcontext_get_component_id: (a: number, b: number, c: number) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const get_style_content: (a: number, b: number) => void;
export const mainthreadwasmcontext_add_cross_thread_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
export const mainthreadwasmcontext_add_dataset: (a: number, b: number, c: number, d: number, e: number) => void;
export const mainthreadwasmcontext_add_run_worklet_event: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
export const mainthreadwasmcontext_common_event_handler: (a: number, b: number, c: number, d: number, e: number, f: number) => void;
export const mainthreadwasmcontext_common_event_handler: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
export const mainthreadwasmcontext_create_element_common: (a: number, b: number, c: number, d: number, e: number, f: number) => number;
export const mainthreadwasmcontext_dispatch_event_by_path: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => number;
export const mainthreadwasmcontext_get_component_id: (a: number, b: number, c: number) => void;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,15 @@ impl MainThreadWasmContext {
event: JsValue,
bubble_unique_id_path: Vec<usize>,
event_name: &str,
is_bubble: bool,
) {
let caught = self.dispatch_event_by_path(&bubble_unique_id_path, event_name, true, &event);
if !caught {
self.dispatch_event_by_path(&bubble_unique_id_path, event_name, false, &event);
if is_bubble {
self.dispatch_event_by_path(&bubble_unique_id_path, event_name, false, &event);
} else if let Some(target_id) = bubble_unique_id_path.first() {
self.dispatch_event_by_path(&[*target_id], event_name, false, &event);
}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions packages/web-platform/web-core/tests/element-apis.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,44 @@ describe('Element APIs', () => {
);
});

test('event with bubbles: false should not bubble to parent', () => {
vi.spyOn(mtsBinding, 'addEventListener');
vi.spyOn(mtsBinding, 'publishEvent');
let page = mtsGlobalThis.__CreatePage('0', 0);
let parent = mtsGlobalThis.__CreateComponent(
0,
'id1',
0,
'test_entry',
'name',
'path',
{},
{},
);
let parentUid = mtsGlobalThis.__GetElementUniqueID(parent);
let child = mtsGlobalThis.__CreateView(parentUid);
mtsGlobalThis.__AppendElement(page, parent);
mtsGlobalThis.__AppendElement(parent, child);
mtsGlobalThis.__SetID(parent, 'parent_id');
mtsGlobalThis.__SetID(child, 'child_id');
mtsGlobalThis.__AddEvent(parent, 'bindEvent', 'tap', 'parent_hname');
mtsGlobalThis.__AddEvent(child, 'bindEvent', 'tap', 'child_hname');
mtsGlobalThis.__FlushElementTree();
const event = new window.Event('click', { bubbles: false });
rootDom.querySelector('#child_id')?.dispatchEvent(event);
expect(mtsBinding.addEventListener).toBeCalledWith('tap');
expect(mtsBinding.publishEvent).toBeCalledTimes(1);
expect(mtsBinding.publishEvent).toBeCalledWith(
'child_hname',
'id1',
expect.any(Object),
expect.any(Number),
undefined,
expect.any(Number),
undefined,
);
});

test('__UpdateComponentInfo', () => {
let ele = mtsGlobalThis.__CreateComponent(
0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ export class LynxViewInstance implements AsyncDisposable {
lepusRootChunkExport = this.mainThreadGlobalThis.processEvalResult?.(
lepusRootChunkExport,
url,
);
) ?? lepusRootChunkExport;
Comment thread
PupilTong marked this conversation as resolved.
return lepusRootChunkExport;
});
this.#queryComponentCache.set(url, promise);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ export class WASMJSBinding implements RustMainthreadContextBinding {
eventObject,
bubblePath.slice(0, bubblePathLength),
eventObject.type,
event.bubbles,
);
};

Expand Down
Loading