3.5.2

lynx-family/lynx3.5.2Dec 26, 2025by Kingatnuaa0528

AI Summary

Patch release focused on bug fixes with some new features including global memory usage reporting, threshold-based memory reporting, and initial Markdown support for Harmony platform.

Key Highlights

  • Global memory usage reporter introduced for iOS
  • Threshold-based memory reporting added
  • Markdown support for Harmony platform (Part 1)
  • Event handling logic refactored with enableEventHandleRefactor switch
  • Embedded mode timing fixes for Android
  • Style resolution improvements with property-based simple style mode
  • Thread-safe component class registries for iOS

New Features

  • Global memory usage reporter for iOS with path formatting
  • Threshold-based memory reporting with configurable triggers
  • Markdown support on Harmony platform
  • LynxViewGroup async template fetch callbacks
  • Property-based simple style mode for better style cleanup

Full Release Notes

# Changelog

## 3.5.2

### Related Dependencies

```js
// Android:
org.lynxsdk.lynx:primjs:2.15.1

// iOS
pod 'PrimJS', '2.15.1', :subspecs => ['quickjs', 'napi']

// Harmony
@lynx/primjs: 2.15.1
```

### ✨ Features


- [Feature][iOS] add global memory usage reporter and path formatting. ([8c55613](https://github.com/lynx-family/lynx/commit/8c55613ee7a2d354d22781a4a841f3f16e555f6b))  @Tamerlx

	
	add global memory usage reporter and path formatting.
	
	- Introduce LynxMemoryUsageGlobalReporter to track and report memory usage across Lynx instances
	- Add formatPath utility to normalize URLs in memory reports
	- Include comprehensive unit tests for both new components

- [Feature][Markdown][Part1] Support markdown on harmony. ([316dde2](https://github.com/lynx-family/lynx/commit/316dde26f894810e1e75a8ff20e949a3008443cd))  @Randycn

	
	1.Modify markdown style initialization and settings in third_party/markdown to adapt to density.
	2.Supports setting style in markdown shadow node and supports layout of inline view.
	
	NoLanding:release/3.6,develop




- [Feature][Part3] add threshold-based memory reporting. ([cc70533](https://github.com/lynx-family/lynx/commit/cc70533cca33032c2655c33a7465fce08ec9f646))  @Tamerlx

	
	This MR is to add threshold-based memory reporting.
	
	Add global memory report threshold configuration and trigger reports when memory usage crosses threshold values. The threshold can be configured via LynxEnv and defaults to 30MB. Reports now include trigger mode (timer/threshold) and threshold configuration details.
	
	Also refactor report generation to be more flexible by accepting trigger mode parameter instead of timer-specific parameters. This change affects both iOS and Android implementations.
	
	


### 🐛 Bug Fixes




- [BugFix][Element] Enable conditional deep conversion for Lepus value handling in Fiber config/attributes/dataset ([2793abe](https://github.com/lynx-family/lynx/commit/2793abe5a52d046dbefc048e11bd77b39a68cb46))  @usczz

	
	Introduce conditional deep conversion when transforming Lepus values
	based on ElementManager’s parallel element flag. This ensures data
	passed to FiberElement methods is converted with the appropriate depth
	for parallel element scenarios.
	
	Changes:
	- Pass deep_convert to ToLepusValue for AddConfig, SetConfig,
	  SetAttribute, AddDataset, and SetDataset.
	- Preserve existing behavior when parallel elements are disabled.

- [BugFix] fix extensionService thread-safety. ([9eba04c](https://github.com/lynx-family/lynx/commit/9eba04c32936a4128a18137888bae9df32d258a7))  @nhsprite

	
	fix extensionService thread-safety.

- [BugFix][Android] Fix visibility issue when inserting child in UIShadowProxy ([095e6aa](https://github.com/lynx-family/lynx/commit/095e6aafdf0664da4ddeba3a1da963ed1c7a47f8))  @zhongyr

	
	Summary of change:
	- Added visibility setting for the shadow view when inserting a child
	- The shadow view now correctly inherits visibility from the child it wraps
	- This fixes an issue where the shadow would remain visible even when the child was hidden
	
	This change ensures that when a child is inserted into the UIShadowProxy, the shadow view's visibility is updated to match the child's visibility state, preventing incorrect rendering where hidden elements would still show their shadows.




- [BugFix][Event] Make exposure-id to accept the number type. ([a33b2ee](https://github.com/lynx-family/lynx/commit/a33b2ee0efef6532964b961d80d66df273f56be8))  @rAY-ooo

	
	description: For `<view exposure-id="{{index}}"/>`, `exposure-id` will be of type number, therefore, adaptation is required.

- [BugFix][SSE] Resolve ReferenceError for Event in EventSource ([d0c402d](https://github.com/lynx-family/lynx/commit/d0c402deaf5de5b07e9570443fe4530baef836d1))  @DragonDragonDDD

	
	The EventSource implementation was causing a `ReferenceError` because the standard `Event` object is not available in its execution environment.
	
	This change resolves the issue by creating a compatible `Event` object for the `onopen` and `onerror` handlers.
	
	- An `Event` type alias is created from the existing `BaseEventOrig` interface to ensure type safety without defining a new class.
	- The `_dispatchEvent` method is updated to construct plain event objects that conform to the `BaseEventOrig` interface, replacing the `new Event()` calls.
	- The `onmessage` handler continues to receive the raw `EventSourceEvent` for direct data access, while `onerror` and `onopen` receive the new, compliant `Event` object.

- [BugFix][devtool] Fixed an issue where BaseDevTool would cause a crash by continuing to process messages after it had been destroyed. ([0565c21](https://github.com/lynx-family/lynx/commit/0565c2165e56003d1c83985e8fc1548752a40f52))  @popoaichuiniu

	
		Make native_handler thread-safe with a lock and prevent message passing to BaseDevTool when the handler is invalid.

- [BugFix][iOS] Simplify logic executor initialization and add async template fetch callbacks ([3452820](https://github.com/lynx-family/lynx/commit/3452820e568d5f66154cee3e08d136cdea9c0a68))  @ykai55

	
	This refactor removes direct dependency on passing template bundles and
	runtime options into LynxDefaultLogicExecutor. The executor now derives
	its configuration from LynxViewGroup, reducing setup surface and coupling.
	
	Key changes:
	- Replace initWithTemplateBundle/initWithRuntimeOptions with
	  initWithLynxViewGroup:debuggable:
	- Executor now fetches LynxTemplateBundle and runtime options via
	  LynxViewGroup+Internal
	- Add LynxViewGroup fetchTemplate: API to support async callbacks once
	  template load completes or fails
	- Introduce internal callback queue, error propagation, and single-shot
	  result handling for template fetch
	- Rename _fetch_task to _fetchTask and encapsulate fetch logic in
	  fetchTemplateInternal/setFetchResult
	- Update LynxLogicExecutor protocol to use setLynxViewGroup: instead of
	  setTemplateBundle:
	- Provide getTemplateBundleNonBlocking accessor for immediate reads
	
	This streamlines initialization, ensures safe async coordination, and
	improves error handling during template fetching.

- [BugFix][EmbeddedMode] Fix timing not work in EmbeddedMode for Android. ([a92bce3](https://github.com/lynx-family/lynx/commit/a92bce37051afb5049a26f851674ee7ccd4a1afb))  @DragonDragonDDD

	
	Add embedded-mode timing collector and wire PerformanceController behavior
	
	Introduce EmbeddedTimingCollector to provide minimal timing tracking for
	embedded mode (loadBundleStart and paintEnd). PerformanceController now
	supports embedded mode via setEmbeddedMode, routing timing to the embedded
	collector and disabling heavy reporting/memory monitoring when embedded.
	
	Key changes:
	- Add EmbeddedTimingCollector with minimal pipeline event emission
	- Add PerformanceController.setEmbeddedMode/isEmbeddedMode and initialize
	  embedded collector lazily
	- In embedded mode, skip native actor interactions and memory monitoring;
	  markTiming/paintEnd handled by EmbeddedTimingCollector
	- Replace enableController flag with embedded-mode checks
	- LynxTemplateRender sets embedded mode on PerformanceController, passes
	  null to native when embedded, and marks LOAD_BUNDLE_START at render
	  entry points
	- Add PAINT_END constant to TimingConstants and align paint end handling
	
	
	
	
	Landed From: !58844
	
	Author: @kechenglong




- [BugFix][Event] Modify the way Events are held and passed. ([07eda8e](https://github.com/lynx-family/lynx/commit/07eda8ec88f55a39d1d32f84c881324238270892))  @rAY-ooo

	
	description: On the one hand, the front-end framework needs to implement interfaces such as CreateEvent, DispatchEvent, and StopPropagation through the C++ Event Ref; on the other hand, EventDispatcher needs to hold the Event Ref to avoid double free.

- [BugFix][Fiber]Prevent inline conversion for component children in FiberElement ([f655c0b](https://github.com/lynx-family/lynx/commit/f655c0bf2ca933c97c6c4cc8fa0f158b1f928e00))  @DragonDragonDDD

	
	Ensure children are only converted to inline elements when the parent is
	inline and not a component. Previously, component parents that were
	inline could force their children into inline mode, causing unexpected
	layout behavior. The added is_component() guard avoids converting child
	nodes in component contexts.

- [BugFix][Event] Fix a crash issue caused by EventDispatcher resetting failure. ([37a8ff8](https://github.com/lynx-family/lynx/commit/37a8ff8ba368ffc8528f81542e739419b7ebc807))  @rAY-ooo

	
	description: Because the EventDispatcher is destroyed before the root node, it might cause UserData to fail to reset, leading to a dangling pointer crash when an event is triggered. This is modified to reset UserData when the root node is destroyed to ensure the effectiveness of the EventDispatcher.
	
	
	NoLanding: develop, release/3.5




- [BugFix] Considering LynxThreadStrategy configged by LynxViewBuilder. ([d3e1ee8](https://github.com/lynx-family/lynx/commit/d3e1ee8d46377b2b2fcd9d2c070cec0a2bf7a3a8))  @nhsprite

	
	It's reasonable that LynxThreadStrategy set by LynxViewBuilder is with higher priority to LynxViewGroup, fix it in this patch.
	1. add a `_hasThreadStragySet` flag that identifies the threadStrategy has been set manually.
	2. when calling `getThreadStrategyForRendering`, if `_hasThreadStragySet` is true, we should return the strategy set by lynxViewBuilder
	else return with the strategy set by lynxViewGroup

- [BugFix] support updateViewport with needLayout flag. ([35ad348](https://github.com/lynx-family/lynx/commit/35ad348acfcb874f5d427154e8ed47f86c90e2f9))  @nhsprite

	
	support updateViewport with needLayout flag, so that users may manually control
	whether needLayout needs to be triggered at all.

- [BugFix][Binding] Fix remote event precision loss ([47c95b6](https://github.com/lynx-family/lynx/commit/47c95b6c43a7252045ec15e3a7ef738fffd14cf9))  @ci_lynx

	
	The default setting of std::stringstream loses precision, and we use pointers
	as identifiers in touch events, which requires a quite high precision.

- [BugFix][Android] Add unified security verification for TemplateBundle ([0a2fc83](https://github.com/lynx-family/lynx/commit/0a2fc837189f4bdae54f474f1edfe4c613b6bcf6))  @nhsprite

	
	Introduce ByteBuffer parsing and consolidate TASM security verification
	for both byte[] and ByteBuffer inputs in TemplateBundle. Key updates:
	- Add verifyTasm helper to centralize ILynxSecurityService checks
	- Extend internalBuildTemplate to accept ByteBuffer and choose native
	  parsing path accordingly
	- Enable security verification for ByteBuffer templates (previously
	  TODO)
	- Improve null-safety and early returns; support optional option.getUrl()
	- Preserve tracing and error propagation; unify options buffer handling
	
	This change enables DirectByteBuffer inputs with consistent security
	checks and reduces duplicated code paths.

- [BugFix][Event] Fix the issue where MTS's stopPropagation was not working under the new event logic. ([7c30932](https://github.com/lynx-family/lynx/commit/7c309326f2313e7fb32fbd05c92c123208b98fd2))  @rAY-ooo

	
	description: The new event logic is compatible with stopPropagation in MTS events.

- [BugFix] Do not use `putIfAbsent` in lynx ([6014afe](https://github.com/lynx-family/lynx/commit/6014afe58b9c1c640292cfb7f52e65010e048305))  @nhsprite

	
	Do not use `putIfAbsent` in lynx as it may cause crash on lower android versions

- [BugFix][Event] The new event logic is adapted to RadonDiff. ([501d0ac](https://github.com/lynx-family/lynx/commit/501d0acfceb248b3a5c8fb3babfe628645b7bdd6))  @rAY-ooo

	
	description: In the RadonDiff architecture, the framework registers events with the AttributeHolder through RadonNode. At this point, the RadonNode is not bound to an Element, so it cannot add the corresponding EventListener to the Element. Therefore, we add the corresponding EventListener to the corresponding Element during the Diff process.

- [BugFix][Event] The new event logic is adapted to SSR. ([5fb9496](https://github.com/lynx-family/lynx/commit/5fb949657819054e0fba0b6e3083d71fab5ac225))  @rAY-ooo

	
	description: Events bound to the SSR homepage can also be responded to; therefore, the corresponding EventListener needs to be added when restoring events or diffing.

- [BugFix][fetch] Persist ReadableStream class across BaseApp singleton transfer ([24ceab7](https://github.com/lynx-family/lynx/commit/24ceab79163ad757e5091096311cbf079f03c130))  @DragonDragonDDD

	
	Ensure fetch-related ReadableStream factory and class are copied when
	transferring singleton data between BaseApp and StandaloneApp. Adds
	createReadableStreamClass and ReadableStreamClass to BaseAppSingletonData,
	and wires them in transferSingletonData and snapshotSingletonData. This
	maintains consistent fetch behavior in standalone environments after app
	rebinds or reloads.

- [BugFix] harmony longpress not initial with bindLongPress Event fail ([15e863e](https://github.com/lynx-family/lynx/commit/15e863efe3a3f6a98e4bd4105149dbaacf0f463b))  @ci_lynx

	
	done.

- [BugFix][Android] Fix the issue of not setting font features when using cached fonts. ([c1f1a77](https://github.com/lynx-family/lynx/commit/c1f1a77849320b0522a56c97452810e1ccc5bcba))  @Randycn

	
	Previously, `font-feature-settings` were part of the `FontSettingsKey` used for caching `Typeface` objects. This was incorrect because the cached `Typeface` itself does not retain these settings. As a result, when a font was retrieved from the cache, the feature settings were lost.
	
	This commit decouples font feature settings from the cache key. The `fontFeatureSettings` are now applied directly to the `TextPaint` object after the `Typeface` is retrieved, regardless of whether it came from the cache or was newly created.
	
	This ensures that font features are consistently applied in all scenarios, fixing the rendering bug for cached fonts.

- [BugFix] fix iOS sendGlobalEvent in Embedded. ([0e54fca](https://github.com/lynx-family/lynx/commit/0e54fca6a1aafe776ac683e92106b99b7f33e667))  @nhsprite

	
	fix iOS sendGlobalEvent in Embedded

- [BugFix] use id instead of function for timer api ([0bd1adf](https://github.com/lynx-family/lynx/commit/0bd1adfe146e76e7769543bab342b25269858a07))  @lybvinci

	
	Use id instead of directly storing specific JS objects to avoid occasional crashes during JSC garbage collection.

- [BugFix][Canvas] correct truncation logic in TruncateToStringView ([b3c7ac5](https://github.com/lynx-family/lynx/commit/b3c7ac5f47b0d014e4b83878fefed6677c82726c))  @GhostFlying

	
	The original implementation used std::max which would extend the string view beyond the input length when max_length was larger. Using std::min ensures proper truncation behavior.

- [BugFix][DevTool]Fix that reload method parameter missing ([0ef0b47](https://github.com/lynx-family/lynx/commit/0ef0b475bba9e3f200215e7f964778d851b2d8e6))  @RovicnowYoyi

	
	Add back reload method without param url.




- [BugFix][Renderer] Fix style resolving process when removing style objects with intersecting properties ([c95eae2](https://github.com/lynx-family/lynx/commit/c95eae2caa7bc1c0273b629784096867f983435d))  @zhongyr

	
	This patch fixes an issue in the Style resolving process when multiple
	StyleObjects define different values on the same property, and one of
	them is removed. The previous implementation could leave stale property
	values when StyleObjects were removed.
	
	The fix introduces a new property-based simple style mode that:
	1. Tracks parsed styles in a map for proper cleanup
	2. Uses incremental updates based on properties rather than StyleObjects
	3. Properly resets properties that no longer exist in the new style configuration
	4. Adds a configuration flag 'enablePropertyBasedSimpleStyle' to toggle between
	   the old StyleObject-based approach and the new property-based approach
	
	Key changes:
	- Add EnablePropertyBasedSimpleStyle() method to ElementManager
	- Implement UpdateSimpleStyles() overload for move semantics
	- Add ResolveStyleObjectsBasedOnExsitingMap() in StyleResolver
	- Update SimpleStyleNode interface to support move semantics
	- Add enablePropertyBasedSimpleStyle config to LynxConfig
	
	This ensures proper style cleanup and prevents stale property values
	when StyleObjects are dynamically added or removed.




- [BugFix][EmbeddedMode] Fix timing not work in EmbeddedMode when reuse engine. ([ac3c83a](https://github.com/lynx-family/lynx/commit/ac3c83ae73e933fa9176d32a4ea5c94c8d672b5b))  @DragonDragonDDD

	
	Ensure PerformanceController registers mClientV2 as the performance
	observer when starting a page. Previously, the observer was not set in
	this code path, causing missing performance callbacks during initial
	render.
	
	Changes:
	- Add null-checked setPerformanceObserver(mClientV2) before
	  dispatchOnPageStart in both branches of the initialization flow.

- [BugFix][Renderer] Fix style resolving process when removing style objects with intersecting properties ([117f073](https://github.com/lynx-family/lynx/commit/117f0736d430fc78f5c6473accf6a2cff18e59ba))  @zhongyr

	
	This patch fixes an issue in the Style resolving process when multiple
	StyleObjects define different values on the same property, and one of
	them is removed. The previous implementation could leave stale property
	values when StyleObjects were removed.
	
	The fix introduces a new property-based simple style mode that:
	1. Tracks parsed styles in a map for proper cleanup
	2. Uses incremental updates based on properties rather than StyleObjects
	3. Properly resets properties that no longer exist in the new style configuration
	4. Adds a configuration flag 'enablePropertyBasedSimpleStyle' to toggle between
	   the old StyleObject-based approach and the new property-based approach
	
	Key changes:
	- Add EnablePropertyBasedSimpleStyle() method to ElementManager
	- Implement UpdateSimpleStyles() overload for move semantics
	- Add ResolveStyleObjectsBasedOnExsitingMap() in StyleResolver
	- Update SimpleStyleNode interface to support move semantics
	- Add enablePropertyBasedSimpleStyle config to LynxConfig
	
	This ensures proper style cleanup and prevents stale property values
	when StyleObjects are dynamically added or removed.




- [BugFix][List] Ensure the list-item's view insertion and onNodeReady callback in the same ui operation queue. ([bc8316d](https://github.com/lynx-family/lynx/commit/bc8316dee78808c227ddca22aca8f93021bd632e))  @DwwWxx

	
	Currently when using MOST_ON_TASM/MULTI_THREAD thread strategy in list, the list-item's view is added to view tree before onNodeReady callback, but many properties are applied in onNodeReady callback. So in reusing list-item scenario, non-udpated list-item's view may be rendered in some draw frames until onNodeReady callback is invoked.
	
	In this commit, we let list-item's view insertion operation and onNodeReady callback in the same ui operation queue to make sure that the list-item is updated before drawing.
	
	
	NoLanding: release/3.5,release/3.6,develop

- [BugFix] Call LynxDevToolUtils only if lynxDebugEnabled is YES ([ce510b1](https://github.com/lynx-family/lynx/commit/ce510b172cf6cc40d5a68935c0363c3ddd5d0cd7))  @talisk

	
	summary: In LynxEnv, initLynxBase will call LynxDevToolUtils. It
	will make LynxDevToolEnv initialized.
	
	On Android platform, LynxEnv.java, there's a judge for
	isLynxDebugEnabled before LynxDevToolUtils calling. So make iOS
	and Android the same way.

- [BugFix][iOS] Fix iOS source build error ([5d0cd0e](https://github.com/lynx-family/lynx/commit/5d0cd0e3eb51156edb96503a4c8ad981b30946e4))  @ci_lynx


- [BugFix][iOS] Use LynxThreadSafeDictionary for component class registries ([190bc8a](https://github.com/lynx-family/lynx/commit/190bc8a54ddcc271704357544fc35c015c777cd5))  @usczz

	
	Replace NSMutableDictionary with LynxThreadSafeDictionary for
	uiClasses and shadowNodeClasses in LynxComponentScopeRegistry. This
	ensures thread-safe access to component and shadow node class
	registrations, reducing potential race conditions during concurrent
	initialization and lookup.

- [BugFix][Harmony] Add NapiHandleScope to ensure valid N-API handle lifetimes ([68554da](https://github.com/lynx-family/lynx/commit/68554dae31c22eee3609a4e178ff3c48ba8342ab))  @rel-q

	
	Introduce NapiHandleScope in Harmony paths to properly scope N-API
	handles and prevent leaks/crashes during JS interop.

- [BugFix][Devtool]Replace "List.of" into "Arrays.asList" to support JDK version below 9 ([743af93](https://github.com/lynx-family/lynx/commit/743af93e6152f7720c56770fde44f5614247b113))  @ci_lynx






- [BugFix][Logging] Add info log in UpdateGlobalProps for data length and this pointer ([9baa4a0](https://github.com/lynx-family/lynx/commit/9baa4a088d21b6a7c95d9060223005c9f26c120e))  @nhsprite

	
	Introduce a LOGI statement in TemplateAssembler::UpdateGlobalProps to log
	the incoming data length and the current object pointer. This aids runtime
	diagnostics and traceability when updating global properties without
	altering functional behavior.

- [BugFix][iOS] correct memory usage calculation for scaled images. ([5617bb6](https://github.com/lynx-family/lynx/commit/5617bb64c588175d117780faddec3f5ea3f653ac))  @Tamerlx

	
	This MR is to correct memory usage calculation for scaled images.
	
	The previous calculation didn't account for scale factor on both dimensions, potentially underestimating memory usage for scaled images. This fix properly includes the scale factor for both height and width in the calculation.

- [BugFix] dealloc function trigger autorelease pool in concurrent_message_loop ([094dd6e](https://github.com/lynx-family/lynx/commit/094dd6e59235ee85580af43ee7f4de57f7073922))  @ci_lynx

	
	dealloc function trigger autorelease pool in concurrent_message_loop

- [BugFix][Lepus] Ensure response listeners invoked and record promise result ([7dc8cc3](https://github.com/lynx-family/lynx/commit/7dc8cc3320004c78015386aee1f2b95f7a84979f))  @nhsprite

	
	Previously, response callbacks could be dropped or executed off the
	expected thread. This change routes response listener execution through
	TASM delegate’s InvokeResponsePromiseCallback and stores the resolved
	value in ResponsePromise to preserve result state.
	
	Key changes:
	- ResponseHandlerProxy: simplify listener callback to directly invoke
	  the provided closure with the BundleResourceInfo.
	- ResponsePromise: persist resolved result in result_ when setting
	  value, before notifying callbacks.
	- Lepus binding: accept Callable instead of Closure and schedule
	  callback via TASM delegate’s InvokeResponsePromiseCallback to ensure
	  proper execution context.
	- Testing: implement InvokeResponsePromiseCallback in mock delegate and
	  add TestFetchBundle2 to verify promise resolution and listener path.
	
	fields and values via then-listener.

- [BugFix] Fix iOS compile errors ([b3f60d7](https://github.com/lynx-family/lynx/commit/b3f60d792b4553af2c4c94b0ff88b19e8d447929))  @ci_lynx

	
	- Use an independent to control compile unit for hotreload
	- Move `enableNewGesture` props to public

- [BugFix][RadonFiber] Preserve explicit attribute override on Radon architecture in SetNativeProps ([5111616](https://github.com/lynx-family/lynx/commit/51116162ad726e8ea05e7927d897c2d65ea758a5))  @DragonDragonDDD

	
	When setting native props, attributes passed via style used the style
	path, but non-style attributes always called SetAttribute(key_str, value)
	with default override behavior. On Radon architecture, this caused the
	explicit override flag to be lost, leading to incorrect attribute
	precedence.
	
	This change routes non-style attributes through SetAttribute(key_str,
	value, false) when running on Radon, preserving the explicit override
	semantics expected by Radon while keeping existing behavior for other
	architectures.

- [BugFix][iOS] copy uiHolder before enumeration to prevent mutation. ([3f1fe97](https://github.com/lynx-family/lynx/commit/3f1fe97f180b0600ebbe5fbb3c926cb480da20d5))  @Tamerlx

	
	This MR is to copy uiHolder before enumeration to prevent mutation.
	
	Prevent potential concurrent modification issues by creating an immutable copy of the uiHolder dictionary before enumeration.

- [BugFix] Separate SimpleStyle and CSS resolution to prevent duplicate processing ([0061cf9](https://github.com/lynx-family/lynx/commit/0061cf960374d769641be79a5ae1cc22b82bbf8e))  @zhongyr

	
	Summary of change:
	This change ensures that SimpleStyle and CSS resolution happen only once and orthogonally by extracting SimpleStyle resolution into a dedicated method and making CSS and SimpleStyle resolution mutually exclusive. The bug was causing duplicate style processing when both systems were active.
	
	The fix adds a new ResolveSimpleStyles() method and modifies PrepareForCreateOrUpdate() to call either ResolveSimpleStyles() or ResolveCSSStyles() based on whether SimpleStyle is enabled, preventing duplicate processing.




- [BugFix][DevTool]Fix DevToolGlobalHandler init logic ([187e23a](https://github.com/lynx-family/lynx/commit/187e23af857cf73c5c9ed28b79e4c28fa3a37a04))  @RovicnowYoyi

	
	Using isLynxDebugEnabled() to ensure the initialization logic is correct.

- [BugFix][DevTool][Android] Move `shouldLoadDevToolJsBridge` to `LynxDevtoolEnv`. ([8beab37](https://github.com/lynx-family/lynx/commit/8beab3704923c64be1d7ecf68b7ea7f31511841b))  @Dango-2021

	
	Since `shouldLoadDevToolJsBridge` is only used in `LynxDevtoolEnv`, move it there and make it private.

- [BugFix][Android] Fix class cast exception when copying ellipsized text. ([10b9c71](https://github.com/lynx-family/lynx/commit/10b9c7120a049bcbdfe4282cb04af3efabee2caa))  @Randycn

	
	- guard Selection ops to run only when text instanceof Spannable
	- copy via internal indices (mSelectStart/mSelectEnd), not Selection.getSelectionStart/End
	- draw highlight when mOverflow != 0

- [BugFix][canvas] fix clearbuffer[ifui]v performance issue ([bc4d99f](https://github.com/lynx-family/lynx/commit/bc4d99f87a77d865abb8509eda4e5c024cfa5abb))  @ci_lynx

	
	- Fix OOM issue caused by excessive buffer size in clearBuffer value parameter.
	- Adjust the logic for updating Piper header files.

- [BugFix][Layout] Correctly handle position:fixed when under display:none nodes ([68a4377](https://github.com/lynx-family/lynx/commit/68a437723e056a7656895399e290fb5222f7e32d))  @givemefive9

	
	summary: Fix an issue where position:fixed still participated in measurement and
	painting in certain scenarios (under display:none nodes). Such nodes and their
	subtrees are now fully excluded from layout, painting.
	
	In addition, add a layout switch to avoid break change, it will display the repair
	 effect when quirksMode >= "3.5" or engineVersion >= "3.5".

- [BugFix] fix callback's id reused error ([ddde49b](https://github.com/lynx-family/lynx/commit/ddde49b62ee2553fa617ad1bb5f2b165ed5509d0))  @lybvinci

	
	callback's id should release after callback invoked.

- [BugFix][Event] Fix an issue with abnormal exposure when Lynx pages were laid out horizontally off-screen. ([30a9132](https://github.com/lynx-family/lynx/commit/30a91322e9b4d3f941586e4ab115db704ef35f9f))  @rAY-ooo

	
	description: In addition to checking the viewport intersection between the exposure node and its parent node, it is also necessary to check the viewport intersection between the Lynx page root node and the screen.

- [BugFix][Android] Should update DisplayMetrics when lynxEnv setup. ([81d5a7e](https://github.com/lynx-family/lynx/commit/81d5a7e5ec4a21768614b99c7d36a178c5458c02))  @DragonDragonDDD

	
	Should update DisplayMetrics when lynxEnv setup.
	
	
- [BugFix][RadonFiber] Validate raw inline style updates when property exists ([3d2662d](https://github.com/lynx-family/lynx/commit/3d2662d69ecac9f2c9af90e3feaa0139eb97d3f8))  @DragonDragonDDD

	
	Introduce an overload of SetRawInlineStyle that accepts CSSParserConfigs and
	applies UnitHandler::Process only when the style property already exists in
	raw_inline_styles_. This preserves previously valid values if a new value is
	invalid, while avoiding validation cost for first-time additions. Update
	SetStaticInlineStyle to use the new overload when fiber-based diffing is
	enabled.

- [BugFix] getTemplateData crash caused by Concurrency. ([11a9017](https://github.com/lynx-family/lynx/commit/11a9017ee0757a3e202d73c70fb0f91328fca539))  @nhsprite

	
	- fix_detail: fix embeddedmodule crash by deep cloning data returned by getTemplateData in LynxTemplateRender


- [BugFix][Event] Fix the registration of __RemoveEventListener. ([0bcfa67](https://github.com/lynx-family/lynx/commit/0bcfa6704e5f6731685a8aedaf4dedd7d512623b))  @rAY-ooo

	
	description: In LepusNG, the registration of RendererFunctions::FiberRemoveEventListener is corrected to __AddEventListener.


- [BugFix] Remove callback's id reused logic ([a4ba851](https://github.com/lynx-family/lynx/commit/a4ba8517fc934429f224f81e6a95d74d9112af76))  @lybvinci

	
	id is enough, so we don't need reused.

- [BugFix][Event] Correct the order in which pointer-events traverse sibling nodes. ([040c4e5](https://github.com/lynx-family/lynx/commit/040c4e5f43767dcba31ba152e8556c2f99b9fa32))  @rAY-ooo

	
	description: When the node that hits the touch test has point-events:none set, the previously saved sibling nodes that hit the touch test should be traversed in ascending order.

- [BugFix][Harmony][Overlay] Stabilize overlay show/dismiss lifecycle and gesture target restoration ([ab75ad6](https://github.com/lynx-family/lynx/commit/ab75ad654aead58609a3d31062ff3ab064f052c5))  @AdrianLCA

	
	This change fixes overlay visibility and gesture handling issues on
	Harmony:
	
	- Guard dialog show/dismiss with is_show_ and native_dialog_ to avoid
	  duplicate operations and null derefs; add informative logs when
	  skipped.
	- Track "visible" prop separately (is_visible_props_) and auto-show when
	  parent is set after a visible prop update.
	- Restore gesture targets on dismiss and during destruction by updating
	  UIOwner’s root target to the next visible overlay or root.
	- Unregister NODE_TOUCH_EVENT and set dialog content to nullptr before
	  closing to prevent event leaks and dangling references.
	- Introduce RemoveNode override for proper child removal from overlay
	  stack.
	- Minor safety/refactor: lock first_active_target_ once in
	  EventDispatcher::EventThrough to avoid redundant locking.
	
	These changes make overlay lifecycle idempotent, prevent stale event
	routing, and ensure consistent gesture interception behavior.

- [BugFix][Harmony] include lynx_actor_specialization.h where lynx_actor.h is dependent. ([a93ecd6](https://github.com/lynx-family/lynx/commit/a93ecd6354bf341343050e43cf7cf23275db1b94))  @ChrisChan0668

	
	When including lynx_actor, we didn't include shell/lynx_actor_specialization.h, as a result, harmony has lost LynxActorMixin specialization codes, so fix it.

- [BugFix] add loadSuccess field to performance entry. ([5b91c4f](https://github.com/lynx-family/lynx/commit/5b91c4f669b014b134e9051e8d4e62f429bf5a9a))  @Tamerlx

	
	This MR is to add `loadSuccess ` field to performance entry.
	
	Track whether lazy bundle loading was successful by adding a boolean field to the performance entry. This helps in monitoring and debugging bundle loading issues.

- [BugFix][Event] Correct the filtering logic of EventListener. ([dae4a5b](https://github.com/lynx-family/lynx/commit/dae4a5b138dd3777011b01b43c7dbd796472b71f))  @rAY-ooo

	
	description: For events that can be captured or bubbled, the EventListener of the EventTarget needs to be filtered at different stages to ensure that the event callback is triggered correctly.

- [BugFix][Event] shouldHitTest adapts to the case where parent is JSUIBase. ([bcf525f](https://github.com/lynx-family/lynx/commit/bcf525f6ef20b51f529aa57301baa22a096d1d20))  @rAY-ooo

	
	description: When the parent node is JSUIBase, in the case of Custom Layout, the parent of FrameNode is nullptr, which will cause the child node to fail to respond to HitTest. Therefore, this needs to be avoided.

- [BugFix][LayoutInElement] fix layout tree not dirty issue ([1aa3d09](https://github.com/lynx-family/lynx/commit/1aa3d09011efc96f34e6ab97314236d402cb868d))  @linxs0211

	
	when insert/remove node,we should mark layout tree dirty!

- [BugFix] add handle for top function ([5ce08e0](https://github.com/lynx-family/lynx/commit/5ce08e0a4aac3892c59f067fc64eae958e3a254a))  @zys777


- [BugFix] Perfer PendingJs By ViewBuilder than LynxViewGroup ([80d0376](https://github.com/lynx-family/lynx/commit/80d0376337e90e929bfc38732f5703411209cbd8))  @nhsprite

	
	LynxViewBuilder is more specific than LynxViewGroup. It's reasonable that
	PendingJs configged by LynxViewBuilder is perfered to LynxViewGroup
	
	isseu: f-972365
	
	summary: Longer description of change addressing as appropriate: why the change
	is made, context if it is part of many changes, description of previous
	behavior and newly introduced differences, etc.
	
	Long lines should be wrapped to 72 columns for easier log message
	viewing in terminals.

- [BugFix][LayoutInElement] fix layoutinelement bug ([6bfd20b](https://github.com/lynx-family/lynx/commit/6bfd20b019475d7f28d01763321cd4c3fd43fea9))  @linxs0211

	
	fix the issue when inline element is wrapper element

- [BugFix][Android][List] Clamp scrollTo offsets to valid range ([fa8c72a](https://github.com/lynx-family/lynx/commit/fa8c72ab314b8034dde7ea1ce1faa1e965fdf915))  @DwwWxx

	
	Ensure scroll offsets are validated before calling super.scrollTo() to avoid overscroll when updateContentSizeAndOffset callbacks are delayed under MOST_ON_TASM or MULTI_THREAD strategies.

- [BugFix][Reland] It's not allowed for platform_data to be modified. ([49e8202](https://github.com/lynx-family/lynx/commit/49e8202069386b7079c764b3d77c83e50de6bfa9))  @nhsprite

	
	1. there may be case that value_converted_from_platform_data_ is already exist before post to js, make a shallowCopy to make it safe.
	2. when `GenerateTemplateDataPostedToJs` to generate a templateData to be consumed by js thread, we just need to copy the updateActions but now the raw lepus::Value is taken to js thread either, it may
	causing the lepus::Value freed on the js thread
	
	this relands mr: !58616

- [BugFix][Android][List] Fix error scroll state when invoking stop autoScroll ([e899962](https://github.com/lynx-family/lynx/commit/e8999629375dd59532c5cb454c9ed26b5a3725e2))  @DwwWxx

	
	Move setScrollState(SCROLL_STATE_SCROLL_ANIMATION) to UIListAutoScroller#onAutoScrollStart callback to avoid error scroll sta
	te when developer invoke stop autoScroll method.

- [BugFix] fix response handler callback lifetimes ([8837bac](https://github.com/lynx-family/lynx/commit/8837bac15c7e1bdc9567d4cff61582ecf2066aff))  @nhsprite

	
	Ensure the response handler listener will be triggered correctly even if there is
	no reference to the handler object in javascript. Making it work the same way as `Promise`
	object.
	
	Introduce unit tests for response handler behavior in both JSI and Lepus
	runtimes. Tests verify that listener callbacks fire even after the handler
	object is released, and that delegate invocation occurs as expected.
	
	Key changes:
	- Add BUILD targets and test groups for JS and Lepus response handler tests.
	- Implement response_handler_in_js_unittest.cc and
	  response_handler_in_lepus_unittest.cc.
	- Refactor JS handler to avoid weak_from_this usage:
	  - Capture native_app weak_ptr directly and guard against destruction.
	  - Use ApiCallBack and delegate-driven invocation for JS callbacks.
	  - Make ConvertBundleInfoToPiperValue static and require app pointer.
	- Refactor Lepus handler closure capture to use delegate pointer safely,
	  relying on LazyBundleLoader guarantees.
	- Fix renderer_functions to copy closure arg to ensure safe asynchronous use.

- [BugFix] Abort renderer only when DevTool is enabled in debug without LogBox ([8683aa6](https://github.com/lynx-family/lynx/commit/8683aa699af2d9c4c37075486c13e1ee9ee7c963))  @ShouruiSong

	
	RenderFatal previously aborted the renderer whenever debug was enabled
	and LogBox was disabled. This caused unintended aborts in environments
	without DevTool. The condition is updated to require DevTool to be
	enabled in addition to debug mode, ensuring aborts only occur in the
	intended developer setup.
	
	Change:
	- Add IsDevToolEnabled() to should_abort condition alongside
	  IsLynxDebugEnabled() and !IsLogBoxEnabled().


### 🚜 Refactor

- [Refactor][DevTool] Split JS engine related logic. ([d0d5cb4](https://github.com/lynx-family/lynx/commit/d0d5cb448dbd0dcf5e564fb62a62846163035f22))  @Dango-2021

	
	1. Added `JSDebugProxy` to create all objects dependent on the JS engine.
	2. Added a singleton `JSDebugHelper` to manage the pointer to `JSDebugProxy`.
	
	(Android only)
	3. Extracted `JSDebugProxy` and JS engine related logic from lynxdevtool.so into a separate lynxdevtool_js_bridge.so,
	   so that lynxdevtool.so no longer depends directly on the JS engines.
	4. Load lynxdevtool_js_bridge.so only when `ILynxDevToolService.getLoadJsBridge()` returns true.
	

### 🚀 Optimization


- [Optimize][Frame] Add usage counter for FrameElement and spec entry ([3bda9f3](https://github.com/lynx-family/lynx/commit/3bda9f31706a1414befa517bb4341e267f620667))  @pilipala195

	
	Add GlobalFeatureCounter hook when FrameElement src is set to track
	CPP_USE_FRAME_ELEMENT with instance ID. Update feature_count
	specification to include cpp.use_frame_element key for aggregation.
	
	- Increment counter on successful frame bundle load path
	- Wire in global_feature_counter header
	- Extend specification.yaml with cpp.use_frame_element for reporting




- [Optimize] Remove temporary string constructions ([ccb8dba](https://github.com/lynx-family/lynx/commit/ccb8dba44b9ff544dcbc55d6540a85cf461ea9f4))  @lybvinci

	
	Remove tmp field create to avoid redudant string creation.

- [Optimize][Harmony] Support delegate gesture ([e017516](https://github.com/lynx-family/lynx/commit/e017516dbbc3730f6e554efc34e5d9f8f6d627f9))  @ci_lynx


- [Optimize][List] Report list batch render strategy ([6b4173e](https://github.com/lynx-family/lynx/commit/6b4173ecc6bcc44a854ebf5ce7f20b8e7b1e8f02))  @DwwWxx

	
	Report lynxsdk_list_batch_render_statistic event for the ListElement when first resolving batch render strategy.

- [Optimize][Binding] Handle generic objects in remote binding ([42d500a](https://github.com/lynx-family/lynx/commit/42d500a4016d8d161b1fa7b371e9f4145228c191))  @ci_lynx

	
	We have only one occurence of generic object argument: video creation
	options, where users can pass any object to pass to their player
	service. Here I take only strings into account so the solution can be
	very much simplified: serialize everything into a 'k1:v1;k2:v2:...'
	string, assuming there are no ':' and ',' in keys/values.

- [Optimize] Use RunNowOrPostTask to ensure UI thread execution for callbacks ([4be30bf](https://github.com/lynx-family/lynx/commit/4be30bf8bfc5592e957736c0132175fa7c5bed34))  @nhsprite

	
	Replace direct PostTask usage with fml::TaskRunner::RunNowOrPostTask when
	dispatching UI-thread work in LynxResourceLoaderHarmony. This ensures tasks
	execute immediately if already on the UI thread, reducing latency and
	avoiding unnecessary queuing. Previous behavior always posted asynchronously;
	new behavior runs inline when possible, otherwise posts to the runner.
	

### 🛠️ Infra


- [Infra] Optimize CI gradle cache ([feff032](https://github.com/lynx-family/lynx/commit/feff0322a8f9ef1ca328b7951cd36447156ab926))  @jianliang00

	
	Gradle 8.7 is cached for android-integration-test, and gradle 6.7 is
	managed by habitat.
	
	Cache ~/.gradle/caches/modules-2 to optimize the stability of pulling
	dependencies.

- [Infra][Harmony] support multiple sdk version ([afbd9f6](https://github.com/lynx-family/lynx/commit/afbd9f61cf75713c67df29d96684249ef322cddd))  @GhostFlying

	
	This patch supports using the differenet sdk version in differenet task or branch.

- [Infra] Disable flaky e2e case temporarily ([ea80783](https://github.com/lynx-family/lynx/commit/ea80783a02db4f3cfe01814a25fe736ee4ad6dd3))  @Kingatnuaa0528

	
	Disable ListBase case in e2e, which is a flaky case.

- [Infra] Move dev dependency from DEPS to DEPS.dev ([faaa74b](https://github.com/lynx-family/lynx/commit/faaa74b8107476274eeb6110c9ccf823a1b638b7))  @gongfeng98

	
	Move android_sdk_manager dependency from file DEPS to DEPS.dev.
	Ensuring that publish release workflow will not throw errors due to redundant dependency.


- [Infra] Batch synchronize code from the upstream branch. ([dbfb4bc](https://github.com/lynx-family/lynx/commit/dbfb4bca3c577b286956e145348ac82d2cc32367))  @ci_lynx


- [Infra] use macos-14 runner in ios publish job ([8b2b5ae](https://github.com/lynx-family/lynx/commit/8b2b5ae2af3aa1ad08ade1232ceb3400e61dd848))  @Kingatnuaa0528

	
	Upgrade the iOS release runner from macOS 13 to macOS 14.