From 65f6f3c41471a0381e8f2a15fd614bfe75801d1d Mon Sep 17 00:00:00 2001 From: pupiltong <12288479+PupilTong@users.noreply.github.com> Date: Thu, 23 Apr 2026 17:01:23 +0800 Subject: [PATCH] fix: ensure __AddClass triggers style updates when enableCSSSelector is disabled --- .changeset/fix-addclass-style.md | 9 ++++ .../web-core.disable-css-selector.json | 54 +++++++++++++++++++ .../web-core-e2e/tests/web-core.test.ts | 49 +++++++++++++++++ .../elementAPIs/createElementAPI.ts | 9 +++- .../ts/server/elementAPIs/createElementAPI.ts | 11 +++- 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 .changeset/fix-addclass-style.md create mode 100644 packages/web-platform/web-core-e2e/resources/web-core.disable-css-selector.json diff --git a/.changeset/fix-addclass-style.md b/.changeset/fix-addclass-style.md new file mode 100644 index 0000000000..4af6a35dc8 --- /dev/null +++ b/.changeset/fix-addclass-style.md @@ -0,0 +1,9 @@ +--- +"@lynx-js/web-core": patch +--- + +fix: `__AddClass` triggers style updates when `enableCSSSelector` is `false` + +`__AddClass` was missing the expected call to `update_css_og_style` when CSS selectors are disabled (`enableCSSSelector: false`). With this fix, dynamically adding a class correctly delegates style population from the template AST into the DOM, mirroring the behavior of `__SetClasses`. + +Added behavioral unit test and end-to-end playwright validations using dynamically generated JSON AST `styleInfo` mocks. diff --git a/packages/web-platform/web-core-e2e/resources/web-core.disable-css-selector.json b/packages/web-platform/web-core-e2e/resources/web-core.disable-css-selector.json new file mode 100644 index 0000000000..180432d18e --- /dev/null +++ b/packages/web-platform/web-core-e2e/resources/web-core.disable-css-selector.json @@ -0,0 +1,54 @@ +{ + "styleInfo": { + "0": { + "content": [], + "rules": [ + { + "sel": [ + [ + [ + ".my-class" + ], + [], + [], + [] + ] + ], + "decl": [ + [ + "color", + "blue" + ], + [ + "font-size", + "16px" + ] + ] + } + ] + } + }, + "lepusCode": { + "root": "const self = globalThis.parent??globalThis;self.runtime = globalThis;self.__lynx_worker_type = 'main'; globalThis.registerDataProcessor='pass'; self.registerDataProcessor = registerDataProcessor;" + }, + "manifest": { + "/app-service.js": "globalThis.runtime = lynxCoreInject.tt; globalThis.__lynx_worker_type = 'background'" + }, + "customSections": {}, + "cardType": "react", + "appType": "card", + "pageConfig": { + "enableFiberArch": true, + "useLepusNG": true, + "enableReuseContext": true, + "bundleModuleMode": "ReturnByFunction", + "templateDebugUrl": "", + "debugInfoOutside": true, + "defaultDisplayLinear": true, + "enableCSSInvalidation": true, + "enableCSSSelector": false, + "enableLepusDebug": false, + "enableRemoveCSSScope": true, + "targetSdkVersion": "2.10" + } +} diff --git a/packages/web-platform/web-core-e2e/tests/web-core.test.ts b/packages/web-platform/web-core-e2e/tests/web-core.test.ts index a7ccc40a66..cc4c4636c5 100644 --- a/packages/web-platform/web-core-e2e/tests/web-core.test.ts +++ b/packages/web-platform/web-core-e2e/tests/web-core.test.ts @@ -87,6 +87,55 @@ test.describe('web core tests', () => { await wait(1000); expect(isSuccess).toBeTruthy(); }); + test('__AddClass when enableCSSSelector is false calls update_css_og_style', async ({ page, browserName }) => { + // firefox not support + test.skip(browserName === 'firefox'); + + page.on('console', msg => console.log('PAGE LOG:', msg.text())); + page.on('pageerror', err => console.log('PAGE ERROR:', err.message)); + + await goto(page, 'web-core.disable-css-selector.json'); + + const result = await page.evaluate(() => { + const root = globalThis.runtime.__CreatePage('0', '0', {}); + const element = globalThis.runtime.__CreateElement('view', '0', {}); + globalThis.runtime.__AppendElement(root, element); + + const component = globalThis.runtime.__CreateComponent( + 0, + '0-1234', + 0, + '__Card__', + '', + '', + {}, + {}, + ); + globalThis.runtime.__AppendElement(element, component); + + const node = globalThis.runtime.__CreateView( + globalThis.runtime.__GetElementUniqueID(component), + ); + globalThis.runtime.__AppendElement(component, node); + + globalThis.runtime.__FlushElementTree(); + + globalThis.runtime.__AddClass(node, 'my-class'); + globalThis.runtime.__FlushElementTree(); + + return { + color: window.getComputedStyle(node).color, + fontSize: window.getComputedStyle(node).fontSize, + classes: globalThis.runtime.__GetClasses(node), + }; + }); + + console.log('RESULT::', result); + expect(result.classes).toContain('my-class'); + expect(result.color).toBe('rgb(0, 0, 255)'); // 'blue' + expect(result.fontSize).toBe('16px'); + }); + test('lynx.requireModuleAsync', async ({ page, browserName }) => { test.skip( browserName === 'firefox', diff --git a/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts b/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts index 7f03e3812d..466f89e968 100644 --- a/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts +++ b/packages/web-platform/web-core/ts/client/mainthread/elementAPIs/createElementAPI.ts @@ -514,7 +514,14 @@ export function createElementAPI( __GetID, __SetID, __GetTag, - __AddClass, + __AddClass: config_enable_css_selector + ? __AddClass + : ((element, className) => { + __AddClass(element, className); + const uniqueId = __GetElementUniqueID(element); + const entryName = element.getAttribute(lynxEntryNameAttribute); + wasmContext.update_css_og_style(uniqueId, entryName); + }), __GetClasses, __MarkTemplateElement, __MarkPartElement, diff --git a/packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts b/packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts index 9c2a2ff3f4..4ab3057ac1 100644 --- a/packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts +++ b/packages/web-platform/web-core/ts/server/elementAPIs/createElementAPI.ts @@ -234,7 +234,16 @@ export function createElementAPI( getAttribute(el, lynxEntryNameAttribute), ); }), - __AddClass, + __AddClass: config.enableCSSSelector + ? __AddClass + : ((element, className) => { + __AddClass(element, className); + const el = element as ServerElement; + wasmContext.update_css_og_style( + el[uniqueIdSymbol], + getAttribute(el, lynxEntryNameAttribute), + ); + }), __AddConfig, __UpdateComponentInfo,