-
- Notifications
You must be signed in to change notification settings - Fork 145
feat(dom): complete IntersectionObserver API #765
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughAdds full IntersectionObserver support across native C++ bridge, QuickJS bindings, Dart bindings/FFI, rendering/event plumbing, UI command wiring, TypeScript declarations, and integration tests to enable observing element visibility and delivering entries to JS. Changes
Sequence DiagramsequenceDiagram participant JS as JS participant QJS as QuickJS bridge participant Native as Native C++ participant Dart as Dart binding participant Doc as Document participant Elem as Element participant Render as RenderBoxModel JS->>QJS: new IntersectionObserver(callback, options) QJS->>Native: Create(context, function, init) Native->>Doc: RegisterIntersectionObserver(observer) Doc->>Doc: store observer JS->>QJS: observer.observe(element) QJS->>Native: observe(element) Native->>Dart: notify observation start Dart->>Elem: addIntersectionObserver(observer, thresholds) Elem->>Render: addIntersectionChangeListener(callback, thresholds) Note over Render: during layout/scroll Render->>Render: compute intersectionRatio Render->>Elem: _handleIntersectionObserver(entry) Elem->>Dart: addEntry(entry) Note over Dart: per-frame delivery Dart->>Dart: deliverIntersectionObserver() Dart->>Native: FFI call with native entry array Native->>Native: create IntersectionObserverEntry array Native->>QJS: convert to JS objects QJS->>JS: invoke callback(entries) Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 15
🧹 Nitpick comments (11)
scripts/tasks.js (1)
111-111: Apply the same defensive CPU counting pattern here for consistency.Line 111 uses
os.cpus().lengthdirectly without guards, which could fail in the same scenarios that line 171 addresses. Line 570 in theconfigureAndBuildIOSTargetfunction has the same issue.Apply this diff at line 111:
- let cpus = os.cpus(); - execSync(`cmake --build ${paths.bridge}/cmake-build-macos-${currentArch} --target ${webfTargets.join(' ')} -- -j ${cpus.length}`, { + const cpuCount = Math.max(1, (os.cpus() || []).length || 1); + execSync(`cmake --build ${paths.bridge}/cmake-build-macos-${currentArch} --target ${webfTargets.join(' ')} -- -j ${cpuCount}`, {Apply this diff at line 570 in the
configureAndBuildIOSTargetfunction:- const cpuCount = os.cpus().length; + const cpuCount = Math.max(1, (os.cpus() || []).length || 1);webf/lib/src/rendering/intersection_observer.dart (1)
202-214: IntersectionObserverLayer timer and callback throttling: minor cleanup opportunities
_timeris static and never cancelled; it continues firing even when_updatedis empty. While_processCallbacksexits quickly in that case, this still keeps a periodic timer alive for the lifetime of the process. Consider cancelling the timer when there are no more active layers and reinstating it on demand._handleUpdateTimer()is now unused since_scheduleIntersectionObservationUpdate()creates its ownTimer.periodicwith an inline callback. This dead code can be removed for clarity.These are non‑blocking but would simplify the lifecycle and reduce background work slightly.
Also applies to: 269-281, 303-326, 371-381, 389-424
bridge/core/binding_object.h (1)
75-81: EnsureCreateBindingObjectTypestays in sync across C++ and DartAdding
kCreateIntersectionObserver = 4is fine here, but all call‑sites (e.g., the Dart FFI side and any C++ switch statements) must be updated to use this new enum value consistently to avoid mis‑dispatch.Please double‑check that every switch/dispatch over
CreateBindingObjectType(including the Dart bridge enum) has a correspondingkCreateIntersectionObserver/createIntersectionObservercase wired up.integration_tests/specs/dom/intersection-observer.ts (1)
31-435: Comprehensive test coverage, but missing cleanup.The test suite covers the IntersectionObserver API surface thoroughly, including v2 features. However, tests don't clean up created DOM elements after execution, which could cause test pollution. Per coding guidelines, created elements should be removed after tests.
Consider adding an
afterEachblock to clean up:afterEach(() => { // Reset scroll position window.scrollTo(0, 0); // Remove test elements (spacers and observed elements) document.body.innerHTML = ''; });Alternatively, wrap test-specific cleanup in each test or use a shared cleanup utility.
bridge/core/dom/intersection_observer.d.ts (1)
14-15: Consider the static analysis warning aboutnewin interface.Biome flags
new(callback: Function, options?: IntersectionObserverInit): IntersectionObserveras misleading since interfaces aren't directly instantiable. However, reviewingIntersectionObserverEntry.d.tsshows this is a project convention for WebF bridge bindings code generation.If this pattern is intentional for the code generator, consider adding a Biome ignore directive or documenting this convention. Otherwise, a class declaration with a constructor might be more semantically accurate.
webf/lib/src/dom/element.dart (1)
1157-1158: Consider clearing_intersectionObserverListin dispose for completeness.While observers should ideally disconnect before element disposal, explicitly clearing the observer set in
dispose()would ensure no stale references remain and provide defense-in-depth cleanup.renderStyle.removeIntersectionChangeListener(_handleIntersectionObserver); + _intersectionObserverList.clear(); super.dispose();webf/lib/src/dom/intersection_observer.dart (2)
117-126: Unnecessary null assertion operator onelement.At line 123,
element!uses a null assertion, but_elementListis declared asList<Element>(line 219), notList<Element?>. The null assertion is unnecessary and could mask type errors if the list type changes.for (var element in _elementList) { - element!.removeIntersectionObserver(this); + element.removeIntersectionObserver(this); }
128-130: Method naming violates Dart conventions.
HasObservations()uses PascalCase, but Dart conventions (and the coding guidelines) require camelCase for methods and functions.- bool HasObservations() { + bool hasObservations() { return _elementList.isNotEmpty; }As per coding guidelines: "Variables and functions must use camelCase in Dart".
bridge/core/dom/intersection_observer_entry.h (1)
7-8: Header guard path doesn't match actual file location.The header guard suggests a path of
core/intersection_observer/intersection_observer_entry.hbut the file is actually atcore/dom/intersection_observer_entry.h. While this doesn't affect functionality, it could cause confusion.-#ifndef WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_ENTRY_H_ -#define WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_ENTRY_H_ +#ifndef WEBF_CORE_DOM_INTERSECTION_OBSERVER_ENTRY_H_ +#define WEBF_CORE_DOM_INTERSECTION_OBSERVER_ENTRY_H_ ... -#endif // WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_ENTRY_H_ +#endif // WEBF_CORE_DOM_INTERSECTION_OBSERVER_ENTRY_H_bridge/core/dom/intersection_observer.h (1)
7-8: Header guard path doesn't match actual file location.Same issue as the entry header - the guard suggests
core/intersection_observer/but the file is incore/dom/.-#ifndef WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_H_ -#define WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_H_ +#ifndef WEBF_CORE_DOM_INTERSECTION_OBSERVER_H_ +#define WEBF_CORE_DOM_INTERSECTION_OBSERVER_H_ ... -#endif // WEBF_CORE_INTERSECTION_OBSERVER_INTERSECTION_OBSERVER_H_ +#endif // WEBF_CORE_DOM_INTERSECTION_OBSERVER_H_bridge/core/dom/intersection_observer.cc (1)
48-94: Consider simplifying repeated null checks.The constructor has many repeated
observer_init &&checks. While functionally correct, this could be simplified for better readability.Consider this refactoring:
IntersectionObserver::IntersectionObserver(ExecutingContext* context, const std::shared_ptr<QJSFunction>& function, const std::shared_ptr<IntersectionObserverInit>& observer_init) : BindingObject(context->ctx()), function_(function) { - if (observer_init && observer_init->hasRoot()) { - root_ = observer_init->root(); - } - if (observer_init && observer_init->hasRootMargin()) { - root_margin_ = observer_init->rootMargin(); - } - if (observer_init && observer_init->hasScrollMargin()) { - scroll_margin_ = observer_init->scrollMargin(); - } - if (observer_init && observer_init->hasDelay()) { - delay_ = std::max(0.0, observer_init->delay()); - } - if (observer_init && observer_init->hasTrackVisibility()) { - track_visibility_ = observer_init->trackVisibility(); + if (observer_init) { + if (observer_init->hasRoot()) { + root_ = observer_init->root(); + } + if (observer_init->hasRootMargin()) { + root_margin_ = observer_init->rootMargin(); + } + if (observer_init->hasScrollMargin()) { + scroll_margin_ = observer_init->scrollMargin(); + } + if (observer_init->hasDelay()) { + delay_ = std::max(0.0, observer_init->delay()); + } + if (observer_init->hasTrackVisibility()) { + track_visibility_ = observer_init->trackVisibility(); + } }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (38)
bridge/CMakeLists.txt(2 hunks)bridge/bindings/qjs/binding_initializer.cc(2 hunks)bridge/bindings/qjs/generated_code_helper.h(1 hunks)bridge/bindings/qjs/wrapper_type_info.h(1 hunks)bridge/bridge_sources.json5(2 hunks)bridge/core/binding_object.cc(1 hunks)bridge/core/binding_object.h(1 hunks)bridge/core/dom/document.cc(2 hunks)bridge/core/dom/document.h(4 hunks)bridge/core/dom/intersection_observer.cc(1 hunks)bridge/core/dom/intersection_observer.d.ts(1 hunks)bridge/core/dom/intersection_observer.h(1 hunks)bridge/core/dom/intersection_observer_entry.cc(1 hunks)bridge/core/dom/intersection_observer_entry.d.ts(1 hunks)bridge/core/dom/intersection_observer_entry.h(1 hunks)bridge/core/dom/intersection_observer_init.d.ts(1 hunks)bridge/core/executing_context.cc(1 hunks)bridge/foundation/ui_command_buffer.cc(1 hunks)bridge/foundation/ui_command_buffer.h(2 hunks)bridge/foundation/ui_command_strategy.cc(1 hunks)bridge/scripts/code_generator/templates/idl_templates/base.cc.tpl(1 hunks)bridge/scripts/code_generator/templates/idl_templates/dictionary.h.tpl(1 hunks)integration_tests/lib/main.dart(0 hunks)integration_tests/specs/dom/intersection-observer.ts(1 hunks)scripts/tasks.js(1 hunks)webf/lib/src/bridge/binding_bridge.dart(3 hunks)webf/lib/src/bridge/to_native.dart(1 hunks)webf/lib/src/bridge/ui_command.dart(1 hunks)webf/lib/src/css/render_style.dart(1 hunks)webf/lib/src/dom/document.dart(4 hunks)webf/lib/src/dom/element.dart(5 hunks)webf/lib/src/dom/event.dart(1 hunks)webf/lib/src/dom/intersection_observer.dart(1 hunks)webf/lib/src/dom/intersection_observer_entry.dart(1 hunks)webf/lib/src/html/img.dart(2 hunks)webf/lib/src/launcher/controller.dart(1 hunks)webf/lib/src/launcher/view_controller.dart(3 hunks)webf/lib/src/rendering/intersection_observer.dart(11 hunks)
💤 Files with no reviewable changes (1)
- integration_tests/lib/main.dart
🧰 Additional context used
📓 Path-based instructions (11)
scripts/**/tasks.js
📄 CodeRabbit inference engine (scripts/CLAUDE.md)
scripts/**/tasks.js: Add global declarations fordocumentandwindowin themerge-bridge-typingstask defined intasks.js
Display task-level errors in type generation with specific error messages, build tool output, and parsing errors including file paths and line numbers
Files:
scripts/tasks.js
scripts/**/*.{js,json}
📄 CodeRabbit inference engine (CLAUDE.md)
scripts/**/*.{js,json}: Bundle QuickJS into the WebF library for Android builds by default using static STL
Use separate QuickJS library only in advanced scenarios when sharing QuickJS with other libraries
SetANDROID_STL=c++_staticas the default C++ standard library for Android builds
Files:
scripts/tasks.js
bridge/**/*.{cc,cpp,h,hpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
bridge/**/*.{cc,cpp,h,hpp}: C++ code should follow Chromium style (.clang-format) with C++17 standard, 120 character column limit, and 2-space indentation
UseWEBF_EXPORT_Cmacro for exporting C functions to Dart FFI
In FFI contexts, useDart_Handleinstead ofHandlefor type compatibility
For C++ FFI function naming: useGetObjectPropertiesFromDartfor C++ exports,NativeGetObjectPropertiesFuncfor Dart typedefs, andGetObjectPropertiesFuncfor Dart functions
Lambda signatures in C++ must match expected function signatures to avoid FFI type mismatches
Choose power-of-2 buffer sizes (512, 1024, 2048) for ring buffer implementation, with smaller sizes for DEBUG_BUILD, MOBILE constraints, and larger sizes for DESKTOP performance
Files:
bridge/core/binding_object.ccbridge/core/executing_context.ccbridge/bindings/qjs/generated_code_helper.hbridge/core/dom/document.hbridge/bindings/qjs/wrapper_type_info.hbridge/core/dom/intersection_observer_entry.ccbridge/bindings/qjs/binding_initializer.ccbridge/foundation/ui_command_strategy.ccbridge/foundation/ui_command_buffer.ccbridge/core/binding_object.hbridge/foundation/ui_command_buffer.hbridge/core/dom/intersection_observer.ccbridge/core/dom/document.ccbridge/core/dom/intersection_observer_entry.hbridge/core/dom/intersection_observer.h
bridge/**/*.{cc,cpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
bridge/**/*.{cc,cpp}: For async FFI operations, useDart_NewPersistentHandle_DLto keep Dart objects alive, convert back withDart_HandleFromPersistent_DLbefore use, and always callDart_DeletePersistentHandle_DLafter the async operation completes
For string handling in FFI, copy strings that might be freed usingstd::string(const_char_ptr), and usetoNativeUtf8()with proper memory deallocation
For async callbacks with potential errors, always provide error path in callbacks (e.g.,callback(object, nullptr)), handle cancellation cases in async operations, and propagate errors through callback parameters rather than exceptions
For thread-safe error reporting in FFI, copy error messages before crossing thread boundaries usingstd::stringto ensure string lifetime, and consider error callbacks separate from result callbacks
AvoidPostToJsSyncwhen threads may interdepend to prevent synchronous deadlocks in FFI communication
Ensure callback functions aren't invoked after context destruction to prevent use-after-free errors in FFI async operations
Implement ring buffer overflow handling with metrics and alerts to monitor command buffer capacity
Process multiple UI commands per frame in a loop with a MAX_COMMANDS_PER_FRAME limit to balance responsiveness and performance
Pin threads to cores for optimal cache usage in ring buffer operations by setting CPU affinity for UI threads
Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks
Files:
bridge/core/binding_object.ccbridge/core/executing_context.ccbridge/core/dom/intersection_observer_entry.ccbridge/bindings/qjs/binding_initializer.ccbridge/foundation/ui_command_strategy.ccbridge/foundation/ui_command_buffer.ccbridge/core/dom/intersection_observer.ccbridge/core/dom/document.cc
bridge/**/*.{cc,h}
📄 CodeRabbit inference engine (AGENTS.md)
C++ code in bridge module must use C++17 standard with 2-space indentation, 120 column limit, and follow Chromium style guide as defined in
.clang-format
bridge/**/*.{cc,h}: Use RAII patterns in C++ where possible for resource management
UsePostToJsfor executing operations on the JS thread in FFI
UsePostToDartfor returning results to Dart isolate
AvoidPostToJsSyncsynchronous execution when possible
Files:
bridge/core/binding_object.ccbridge/core/executing_context.ccbridge/bindings/qjs/generated_code_helper.hbridge/core/dom/document.hbridge/bindings/qjs/wrapper_type_info.hbridge/core/dom/intersection_observer_entry.ccbridge/bindings/qjs/binding_initializer.ccbridge/foundation/ui_command_strategy.ccbridge/foundation/ui_command_buffer.ccbridge/core/binding_object.hbridge/foundation/ui_command_buffer.hbridge/core/dom/intersection_observer.ccbridge/core/dom/document.ccbridge/core/dom/intersection_observer_entry.hbridge/core/dom/intersection_observer.h
{bridge/**/*.{cc,h},webf/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
Document memory ownership clearly in FFI implementations
Files:
bridge/core/binding_object.ccbridge/core/executing_context.ccbridge/bindings/qjs/generated_code_helper.hwebf/lib/src/launcher/controller.dartbridge/core/dom/document.hbridge/bindings/qjs/wrapper_type_info.hwebf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartbridge/core/dom/intersection_observer_entry.ccbridge/bindings/qjs/binding_initializer.ccbridge/foundation/ui_command_strategy.ccwebf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartbridge/foundation/ui_command_buffer.ccwebf/lib/src/html/img.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/element.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartwebf/lib/src/css/render_style.dartbridge/core/binding_object.hbridge/foundation/ui_command_buffer.hbridge/core/dom/intersection_observer.ccbridge/core/dom/document.ccwebf/lib/src/rendering/intersection_observer.dartbridge/core/dom/intersection_observer_entry.hbridge/core/dom/intersection_observer.h
bridge/**/*.{h,hpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
bridge/**/*.{h,hpp}: Ring buffer command structure should useenum Type : uint8_tfor command types with union for type-specific data to ensure type-safe and cache-friendly command handling
Ring buffer implementation should usealignas(64)for atomic head and tail pointers,std::atomic<size_t>for thread-safe synchronization, and power-of-2 buffer sizes enforced withstatic_assert
Files:
bridge/bindings/qjs/generated_code_helper.hbridge/core/dom/document.hbridge/bindings/qjs/wrapper_type_info.hbridge/core/binding_object.hbridge/foundation/ui_command_buffer.hbridge/core/dom/intersection_observer_entry.hbridge/core/dom/intersection_observer.h
integration_tests/specs/**/*.ts
📄 CodeRabbit inference engine (integration_tests/CLAUDE.md)
integration_tests/specs/**/*.ts: Place tests in appropriate directories underspecs/(css/, dom/, or window/)
Use TypeScript (.ts extension) for test files
Usedone()callback for async tests
Usesnapshot()for visual regression tests to capture current rendering
UsesimulateClickwith coordinates for hit testing tests
Test assets should reference files inassets/directory
Usefdescribe()instead ofdescribe()to run only specific test specs (Jasmine feature)
Usefit()instead ofit()to run only specific test cases
Snapshots are stored as images for comparison and failed snapshots generate diff images
The max width of testing window is 340px
Test specs will always pass if there are no existing snapshots
Group related tests in describe blocks
Each test should be independent
Remove created elements after tests (test cleanup)
Use clear, descriptive test names
Test behavior, not implementation
Include edge cases and error conditions in tests
Batch DOM operations to minimize reflows
Use async/await and proper async patterns for asynchronous operations in tests
Measure operations usingperformance.now()for timing in performance-critical tests
Files:
integration_tests/specs/dom/intersection-observer.ts
webf/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
webf/**/*.dart: Follow rules in webf/analysis_options.yaml for Dart code style
Use single quotes for strings in Dart code
File names must use snake_case in Dart
Class names must use PascalCase in Dart
Variables and functions must use camelCase in Dart
Prefer final fields when applicable in Dart code
Lines should be max 120 characters in Dart code
Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Track ownership of allocated pointers in FFI callbacks
Free NativeValue pointers after converting with fromNativeValue in FFI code
Document memory ownership clearly in FFI async callbacks
Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree
Register custom WidgetElements using WidgetElementRegistry.register(tagName, builder)
Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
Call updateWidget() when attributes change in WidgetElement implementations
Dispose controllers and subscriptions in WidgetElement for memory management
Follow W3C event standards when dispatching events from WidgetElement
Minimize widget rebuilds in WidgetElement for performance optimization
Implement ARIA attributes in WidgetElement when applicable for accessibilityDart code in webf module must follow naming conventions: snake_case for file names, PascalCase for classes, and camelCase for class members
webf/**/*.dart: Always free allocated memory in Dart FFI
Usemalloc.free()fortoNativeUtf8()allocations in Dart FFI
Track pointer ownership in callbacks within Dart FFI
Files:
webf/lib/src/launcher/controller.dartwebf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/html/img.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/element.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartwebf/lib/src/css/render_style.dartwebf/lib/src/rendering/intersection_observer.dart
webf/lib/src/css/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use CSSRenderStyle for style computation and storage in Dart CSS code
Files:
webf/lib/src/css/render_style.dart
webf/lib/src/rendering/**/*.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
Use RenderBoxModel as base class for layout in Dart rendering code
Files:
webf/lib/src/rendering/intersection_observer.dart
🧠 Learnings (60)
📓 Common learnings
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks 📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/**/tasks.js : Display task-level errors in type generation with specific error messages, build tool output, and parsing errors including file paths and line numbers Applied to files:
scripts/tasks.js
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/**/tasks.js : Add global declarations for `document` and `window` in the `merge-bridge-typings` task defined in `tasks.js` Applied to files:
scripts/tasks.js
📚 Learning: 2025-11-26T10:24:13.090Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: cli/CLAUDE.md:0-0 Timestamp: 2025-11-26T10:24:13.090Z Learning: Applies to cli/**/*.ts : Process files in batches using processFilesInBatch for optimal parallelism Applied to files:
scripts/tasks.js
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Build for macOS using `npm run build:bridge:macos` (debug) or `npm run build:bridge:macos:release` (release); for iOS use `npm run build:bridge:ios` (debug) or `npm run build:bridge:ios:release` (release); for Android use `npm run build:bridge:android` (debug) or `npm run build:bridge:android:release` (release) Applied to files:
scripts/tasks.js
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : For C++ FFI function naming: use `GetObjectPropertiesFromDart` for C++ exports, `NativeGetObjectPropertiesFunc` for Dart typedefs, and `GetObjectPropertiesFunc` for Dart functions Applied to files:
bridge/core/binding_object.ccwebf/lib/src/bridge/binding_bridge.dartbridge/core/dom/intersection_observer.ccbridge/core/dom/intersection_observer.h
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : In FFI contexts, use `Dart_Handle` instead of `Handle` for type compatibility Applied to files:
bridge/core/binding_object.ccwebf/lib/src/bridge/binding_bridge.dartbridge/core/dom/intersection_observer.cc
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : For async FFI operations, use `Dart_NewPersistentHandle_DL` to keep Dart objects alive, convert back with `Dart_HandleFromPersistent_DL` before use, and always call `Dart_DeletePersistentHandle_DL` after the async operation completes Applied to files:
bridge/core/binding_object.ccwebf/lib/src/dom/intersection_observer.dartbridge/core/dom/intersection_observer.cc
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Free NativeValue pointers after converting with fromNativeValue in FFI code Applied to files:
bridge/core/binding_object.ccwebf/lib/src/dom/intersection_observer_entry.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to bridge/**/*.{cc,h} : Use `PostToDart` for returning results to Dart isolate Applied to files:
bridge/core/binding_object.ccwebf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.cc
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/lib/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge Applied to files:
bridge/core/binding_object.ccwebf/lib/src/launcher/controller.dartwebf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/element.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.ccwebf/lib/src/rendering/intersection_observer.dartbridge/core/dom/intersection_observer_entry.hbridge/core/dom/intersection_observer.h
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to bridge/**/*.{cc,h} : Use `PostToJs` for executing operations on the JS thread in FFI Applied to files:
bridge/core/executing_context.ccbridge/core/dom/document.hbridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : Avoid `PostToJsSync` when threads may interdepend to prevent synchronous deadlocks in FFI communication Applied to files:
bridge/core/executing_context.ccbridge/bindings/qjs/generated_code_helper.hbridge/core/dom/document.hbridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/polyfill/**/*.{ts,tsx,d.ts} : Include a reference to `webf.d.ts` in polyfill type generation for accessing core types like `EventTarget` Applied to files:
bridge/core/executing_context.ccbridge/core/dom/intersection_observer_entry.d.tsbridge/core/dom/intersection_observer.d.tsbridge/core/dom/intersection_observer_init.d.ts
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to bridge/**/*.{cc,h} : Avoid `PostToJsSync` synchronous execution when possible Applied to files:
bridge/core/executing_context.ccbridge/core/dom/document.hbridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks Applied to files:
bridge/core/executing_context.ccwebf/lib/src/bridge/ui_command.dartbridge/core/dom/intersection_observer.ccbridge/core/dom/intersection_observer.h
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp,h,hpp} : Use `WEBF_EXPORT_C` macro for exporting C functions to Dart FFI Applied to files:
bridge/core/executing_context.ccwebf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/bridge/binding_bridge.dartbridge/scripts/code_generator/templates/idl_templates/dictionary.h.tplwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.ccbridge/core/dom/intersection_observer.h
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to {bridge/**/*.{cc,h},webf/**/*.dart} : Document memory ownership clearly in FFI implementations Applied to files:
bridge/core/executing_context.ccbridge/core/dom/document.hwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.ccbridge/core/dom/document.ccbridge/core/dom/intersection_observer.h
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Batch DOM operations to minimize reflows Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Test behavior, not implementation Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Place tests in appropriate directories under `specs/` (css/, dom/, or window/) Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Use `snapshot()` for visual regression tests to capture current rendering Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Use async/await and proper async patterns for asynchronous operations in tests Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Measure operations using `performance.now()` for timing in performance-critical tests Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Include edge cases and error conditions in tests Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Remove created elements after tests (test cleanup) Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Use clear, descriptive test names Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:27:27.888Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: integration_tests/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:27.888Z Learning: Applies to integration_tests/specs/**/*.ts : Each test should be independent Applied to files:
integration_tests/specs/dom/intersection-observer.ts
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: No build needed for Dart-only changes in webf/ Applied to files:
webf/lib/src/launcher/controller.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/intersection_observer_entry.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/test/**/*_test.dart : Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests Applied to files:
webf/lib/src/launcher/controller.dartwebf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to webf/**/*.dart : Track pointer ownership in callbacks within Dart FFI Applied to files:
webf/lib/src/launcher/controller.dartwebf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/html/img.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/element.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.ccwebf/lib/src/rendering/intersection_observer.dartbridge/core/dom/intersection_observer_entry.h
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Implement WidgetElement to create custom Flutter widgets integrated into WebF's DOM tree Applied to files:
webf/lib/src/launcher/controller.dartwebf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/element.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Document memory ownership clearly in FFI async callbacks Applied to files:
webf/lib/src/launcher/controller.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/html/img.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/core/**/*.d.ts : DO NOT manually edit `bridge/typings/webf.d.ts` - it is generated from bridge/core/*.d.ts Applied to files:
bridge/core/dom/intersection_observer_entry.d.tsbridge/core/dom/intersection_observer.d.tsbridge/core/dom/intersection_observer_init.d.tsbridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/polyfill/**/*.{ts,tsx} : DO NOT manually edit `bridge/typings/polyfill.d.ts` - it is generated from polyfill TypeScript source Applied to files:
bridge/core/dom/intersection_observer_entry.d.tsbridge/core/dom/intersection_observer_init.d.tsbridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/typings/index.d.ts : Configure `bridge/typings/index.d.ts` to reference both `webf.d.ts` and `polyfill.d.ts` and re-export polyfill module exports for a unified interface Applied to files:
bridge/core/dom/intersection_observer_entry.d.tsbridge/core/dom/intersection_observer_init.d.ts
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/core/**/*.d.ts : Transform WebF-specific type annotations: `DartImpl<T>` → `T`, `StaticMember<T>` → `T`, `StaticMethod<T>` → `T`, `SupportAsync<T>` → generates both sync and async variants, `DependentsOnLayout<T>` → `T` Applied to files:
webf/lib/src/bridge/ui_command.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : Process multiple UI commands per frame in a loop with a MAX_COMMANDS_PER_FRAME limit to balance responsiveness and performance Applied to files:
webf/lib/src/bridge/ui_command.dartbridge/foundation/ui_command_strategy.ccbridge/foundation/ui_command_buffer.ccbridge/foundation/ui_command_buffer.h
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/test/**/*_test.dart : Access render objects in tests to verify layout calculations Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/lib/src/rendering/**/*.dart : Use RenderBoxModel as base class for layout in Dart rendering code Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/element.dartwebf/lib/src/css/render_style.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Minimize widget rebuilds in WidgetElement for performance optimization Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/element.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/lib/src/css/**/*.dart : Use CSSRenderStyle for style computation and storage in Dart CSS code Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/dom/element.dartwebf/lib/src/css/render_style.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/test/**/*_test.dart : Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Use widget unit tests to verify rendering changes with: cd webf && flutter test test/src/rendering/ Applied to files:
webf/lib/src/dom/document.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Follow W3C event standards when dispatching events from WidgetElement Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/bridge/binding_bridge.dartwebf/lib/src/dom/event.dartwebf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Dispose controllers and subscriptions in WidgetElement for memory management Applied to files:
webf/lib/src/dom/document.dartwebf/lib/src/launcher/view_controller.dart
📚 Learning: 2025-12-08T23:27:41.357Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: scripts/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:41.357Z Learning: Applies to scripts/bridge/core/**/*.d.ts : Create a `webf` namespace containing all type exports from merged bridge core types Applied to files:
bridge/scripts/code_generator/templates/idl_templates/base.cc.tpl
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Track ownership of allocated pointers in FFI callbacks Applied to files:
webf/lib/src/bridge/binding_bridge.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/dom/intersection_observer.dartwebf/lib/src/dom/intersection_observer_entry.dartbridge/core/dom/intersection_observer.ccwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Implement ARIA attributes in WidgetElement when applicable for accessibility Applied to files:
webf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Call updateWidget() when attributes change in WidgetElement implementations Applied to files:
webf/lib/src/dom/element.dartwebf/lib/src/css/render_style.dartwebf/lib/src/rendering/intersection_observer.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Follow rules in webf/analysis_options.yaml for Dart code style Applied to files:
webf/lib/src/dom/element.dartwebf/lib/src/css/render_style.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Class names must use PascalCase in Dart Applied to files:
webf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Use single quotes for strings in Dart code Applied to files:
webf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/**/*.dart : Prefer final fields when applicable in Dart code Applied to files:
webf/lib/src/dom/element.dart
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/ios/webf_ios.podspec : Ensure all source files, particularly `member_installer.cc`, are included in the `source_files` pattern in `ios/webf_ios.podspec` Applied to files:
bridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/ios/webf_ios.podspec : Include all necessary C++ bridge source files with pattern `bridge/**/*.{h,cc,cpp}` and bindings with `bridge/bindings/**/*.{h,cc}` in the iOS podspec source_files Applied to files:
bridge/bridge_sources.json5
📚 Learning: 2025-12-08T23:28:11.651Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: AGENTS.md:0-0 Timestamp: 2025-12-08T23:28:11.651Z Learning: Applies to bridge/**/*.{cc,h} : C++ code in bridge module must use C++17 standard with 2-space indentation, 120 column limit, and follow Chromium style guide as defined in `.clang-format` Applied to files:
bridge/bridge_sources.json5bridge/CMakeLists.txt
📚 Learning: 2025-12-08T23:27:15.946Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/test/**/*.{cc,cpp} : Add bridge unit test files to `bridge/test/` directory and use Google Test macros: `TEST()`, `EXPECT_EQ()`, etc. Tests are automatically discovered by CMake Applied to files:
bridge/CMakeLists.txt
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to scripts/**/*.{js,json} : Set `ANDROID_STL=c++_static` as the default C++ standard library for Android builds Applied to files:
bridge/CMakeLists.txt
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to scripts/**/*.{js,json} : Bundle QuickJS into the WebF library for Android builds by default using static STL Applied to files:
bridge/CMakeLists.txt
🧬 Code graph analysis (8)
scripts/tasks.js (1)
integration_tests/scripts/core_integration_starter.js (1)
os(6-6)
integration_tests/specs/dom/intersection-observer.ts (3)
bridge/core/dom/intersection_observer.cc (2)
IntersectionObserver(41-46)IntersectionObserver(48-94)bridge/core/dom/intersection_observer_entry.cc (1)
IntersectionObserverEntry(30-46)bridge/core/dom/intersection_observer_entry.d.ts (1)
IntersectionObserverEntry(11-25)
bridge/core/dom/document.h (1)
bridge/core/dom/document.cc (4)
RegisterIntersectionObserver(560-564)RegisterIntersectionObserver(560-560)UnregisterIntersectionObserver(566-575)UnregisterIntersectionObserver(566-566)
bridge/core/dom/intersection_observer_entry.d.ts (1)
bridge/core/dom/intersection_observer_entry.cc (1)
IntersectionObserverEntry(30-46)
bridge/core/dom/intersection_observer.d.ts (3)
bridge/core/dom/intersection_observer_entry.h (1)
target(64-64)bridge/core/dom/intersection_observer_entry.cc (1)
IntersectionObserverEntry(30-46)bridge/core/dom/intersection_observer_entry.d.ts (1)
IntersectionObserverEntry(11-25)
bridge/core/dom/intersection_observer_entry.cc (4)
bridge/core/dom/intersection_observer_entry.d.ts (1)
IntersectionObserverEntry(11-25)bridge/core/dom/intersection_observer_entry.h (1)
target(64-64)bridge/core/dom/intersection_observer.cc (2)
Trace(282-286)Trace(282-282)bridge/core/binding_object.cc (2)
Trace(403-407)Trace(403-403)
bridge/core/dom/document.cc (1)
bridge/core/dom/intersection_observer.cc (2)
Trace(282-286)Trace(282-282)
bridge/core/dom/intersection_observer_entry.h (3)
bridge/core/dom/intersection_observer_entry.cc (3)
IntersectionObserverEntry(30-46)Trace(48-53)Trace(48-48)bridge/core/dom/intersection_observer_entry.d.ts (1)
IntersectionObserverEntry(11-25)bridge/core/binding_object.cc (2)
Trace(403-407)Trace(403-403)
🪛 Biome (2.1.2)
bridge/core/dom/intersection_observer.d.ts
[error] 15-15: Don't use the new method in interfaces.
new in an interface suggests it's instantiable, which is incorrect. The returned type should different from the constructor's type.
(lint/suspicious/noMisleadingInstantiator)
bridge/core/dom/intersection_observer_init.d.ts
[error] 11-12: Decorators are not valid here.
Decorators are only valid on class declarations, class expressions, and class methods.
(parse)
🪛 GitHub Actions: Run Code Linter
bridge/CMakeLists.txt
[error] 334-334: Cannot find source file: code_gen/qjs_css_style_declaration.cc (add_library webf_core)
[error] 334-334: No SOURCES given to target: webf_core
[error] 1-1: CMake Generate step failed. Build files cannot be regenerated correctly.
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
- GitHub Check: build_bridge
- GitHub Check: build_windows_bridge (Debug)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (c-cpp)
- GitHub Check: Analyze (rust)
| void IntersectionObserver::observe(Element* target, ExceptionState& exception_state) { | ||
| if (!RootIsValid() || !target) { | ||
| WEBF_LOG(ERROR) << "[IntersectionObserver]: observe valid:" << std::endl; | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error message clarity.
The error log message on line 102 is incomplete and doesn't provide actionable information. It should clearly state what is invalid.
Apply this diff:
if (!RootIsValid() || !target) { - WEBF_LOG(ERROR) << "[IntersectionObserver]: observe valid:" << std::endl; + WEBF_LOG(ERROR) << "[IntersectionObserver]: observe() called with invalid root or null target" << std::endl; return; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void IntersectionObserver::observe(Element* target, ExceptionState& exception_state) { | |
| if (!RootIsValid() || !target) { | |
| WEBF_LOG(ERROR) << "[IntersectionObserver]: observe valid:" << std::endl; | |
| return; | |
| } | |
| void IntersectionObserver::observe(Element* target, ExceptionState& exception_state) { | |
| if (!RootIsValid() || !target) { | |
| WEBF_LOG(ERROR) << "[IntersectionObserver]: observe() called with invalid root or null target" << std::endl; | |
| return; | |
| } |
🤖 Prompt for AI Agents
In bridge/core/dom/intersection_observer.cc around lines 100–104, the WEBF_LOG error message is vague; update it to explicitly state which condition failed (RootIsValid() false or null target) and include identifying info (e.g., target pointer or tag/name) so the log is actionable — change the log call to check the two conditions and emit a clear message like "observe failed: invalid root" or "observe failed: null target (target=<value>)" depending on which check fails. | #if ENABLE_LOG | ||
| WEBF_LOG(DEBUG) << "[IntersectionObserver]: observe target=" << target << ",tagName=" << target->nodeName() | ||
| << std::endl; | ||
| #endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replace Chinese punctuation with English comma.
The log message on line 107 contains a Chinese comma (,) instead of an English comma.
Apply this diff:
#if ENABLE_LOG - WEBF_LOG(DEBUG) << "[IntersectionObserver]: observe target=" << target << ",tagName=" << target->nodeName() + WEBF_LOG(DEBUG) << "[IntersectionObserver]: observe target=" << target << ", tagName=" << target->nodeName() << std::endl; #endif📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #if ENABLE_LOG | |
| WEBF_LOG(DEBUG) << "[IntersectionObserver]: observe target=" << target << ",tagName=" << target->nodeName() | |
| << std::endl; | |
| #endif | |
| #if ENABLE_LOG | |
| WEBF_LOG(DEBUG) << "[IntersectionObserver]: observe target=" << target << ", tagName=" << target->nodeName() | |
| << std::endl; | |
| #endif |
🤖 Prompt for AI Agents
In bridge/core/dom/intersection_observer.cc around lines 106 to 109, the log message uses a Chinese comma (,) between "target=" and "tagName="; replace that Chinese comma with an English comma so the log reads with a standard ASCII comma, preserving the surrounding text and spacing exactly. | void IntersectionObserver::unobserve(Element* target, ExceptionState& exception_state) { | ||
| if (!target) { | ||
| WEBF_LOG(ERROR) << "[IntersectionObserver]: unobserve valid:" << std::endl; | ||
| return; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Improve error message clarity.
The error log message on line 130 is incomplete and doesn't provide actionable information.
Apply this diff:
if (!target) { - WEBF_LOG(ERROR) << "[IntersectionObserver]: unobserve valid:" << std::endl; + WEBF_LOG(ERROR) << "[IntersectionObserver]: unobserve() called with null target" << std::endl; return; }📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| void IntersectionObserver::unobserve(Element* target, ExceptionState& exception_state) { | |
| if (!target) { | |
| WEBF_LOG(ERROR) << "[IntersectionObserver]: unobserve valid:" << std::endl; | |
| return; | |
| } | |
| void IntersectionObserver::unobserve(Element* target, ExceptionState& exception_state) { | |
| if (!target) { | |
| WEBF_LOG(ERROR) << "[IntersectionObserver]: unobserve() called with null target" << std::endl; | |
| return; | |
| } |
🤖 Prompt for AI Agents
In bridge/core/dom/intersection_observer.cc around lines 128-132, the existing log message "unobserve valid:" is incomplete; replace it with a clear, actionable message indicating that unobserve was called with a null/invalid target (for example: "[IntersectionObserver] unobserve called with null target") and include function context (e.g., function name) so logs show where the call originated; keep behavior the same (return on null) but improve the log text to explicitly state "null/invalid target" rather than the current ambiguous message. | bool addIntersectionObserver(IntersectionObserver observer, List<double> thresholds) { | ||
| if (_intersectionObserverList.contains(observer)) { | ||
| return false; | ||
| } | ||
| if (enableWebFCommandLog) { | ||
| domLogger.fine('[IntersectionObserver] attach target=$pointer observer=${observer.pointer} thresholds=$thresholds'); | ||
| } | ||
| renderStyle.addIntersectionChangeListener(_handleIntersectionObserver, thresholds); | ||
| _intersectionObserverList.add(observer); | ||
| _thresholds = thresholds; | ||
| return true; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Observer list uses Set but the contains check and _thresholds overwrite could lead to inconsistent state.
The addIntersectionObserver method returns false if the observer already exists, but _thresholds is unconditionally set at line 2518. If the same observer tries to re-observe with different thresholds (which should update them per spec), the current logic would skip the update.
Additionally, _intersectionObserverList is declared as a Set<IntersectionObserver> but the type annotation on the field (line 103) shows it stores nullable references. The _elementList in IntersectionObserver is typed List<Element> but line 123 accesses it as element! suggesting potential null elements.
🤖 Prompt for AI Agents
In webf/lib/src/dom/element.dart around lines 2509-2520, the addIntersectionObserver method sets _thresholds unconditionally and returns false early, which prevents updating thresholds when an existing observer re-observes, and the observer collection and element lists have nullable types that cause unsafe force-unwrapping. Change the logic so that if _intersectionObserverList.contains(observer) you compare the new thresholds to the stored thresholds and, if they differ, update _thresholds and re-register/update the renderStyle listener (call renderStyle.addIntersectionChangeListener with the new thresholds) before returning false; otherwise return false without changing state. Also make _intersectionObserverList a non-nullable Set<IntersectionObserver> (remove nullable element type), and either make IntersectionObserver._elementList non-nullable List<Element> or add null-safety checks where element! is accessed (ensure elements added are non-null or guard usages), so no force-unwrapping of potentially null elements remains. | List<double> _thresholds = [0.0]; | ||
| int _lastThresholdsIndex = 0; | ||
| bool _lastIsIntersecting = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix _thresholds! null‑check and ensure thresholds are applied consistently
_thresholdsis declared as non‑nullable (List<double> _thresholds = [0.0];) but used as_thresholds!in_dispatchChange, which is invalid under NNBD and will be rejected by the analyzer/compiler. This should just pass_thresholdsdirectly tofirstThresholdGreaterThan(...).copyTocopies_listenersbut not_thresholds,_lastThresholdsIndex, or_lastIsIntersecting, so a cloned render object may compute threshold crossings using the default[0.0]rather than the thresholds actually used when the observer was created. This can lead to extra / missing callbacks after layout moves.
Consider:
- List<double> _thresholds = [0.0]; + List<double> _thresholds = const [0.0]; ... - int index = firstThresholdGreaterThan(info.intersectionRatio, _thresholds!); + final thresholds = _thresholds; + final index = firstThresholdGreaterThan(info.intersectionRatio, thresholds);and extending copyTo to also copy the threshold state:
static copyTo(RenderIntersectionObserverMixin from, RenderIntersectionObserverMixin to) { to.intersectPadding = from.intersectPadding; to._listeners = from._listeners; + to._thresholds = from._thresholds; + to._lastThresholdsIndex = from._lastThresholdsIndex; + to._lastIsIntersecting = from._lastIsIntersecting; to._onIntersectionChange = to._dispatchChange;Also applies to: 70-82, 113-168
🤖 Prompt for AI Agents
In webf/lib/src/rendering/intersection_observer.dart around lines 54-56 (and also review usages in 70-82 and 113-168), remove the invalid null-check `_thresholds!` and pass `_thresholds` directly to firstThresholdGreaterThan(...) (NNBD requires no ! for a non-nullable field), and update the copyTo method to copy the threshold state from the source render object by assigning `_thresholds`, `_lastThresholdsIndex`, and `_lastIsIntersecting` in addition to `_listeners` so cloned render objects preserve the same thresholds and last-intersection state and avoid incorrect/missed callbacks after layout moves. | void clearIntersectionChangeListeners() { | ||
| _clearIntersectionListeners = true; | ||
| } | ||
| | ||
| void _clearIntersectionChangeListeners() { | ||
| _listeners?.clear(); | ||
| _listeners = null; | ||
| _onIntersectionChange = null; | ||
| _clearIntersectionListeners = false; | ||
| _lastThresholdsIndex = 0; | ||
| _lastIsIntersecting = false; | ||
| } | ||
| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Listener clearing is deferred and may never run; tighten lifecycle semantics
clearIntersectionChangeListeners() only flips _clearIntersectionListeners = true; actual clearing happens inside _dispatchChange() when it next runs. If clearIntersectionChangeListeners() is called while there are no further intersection updates (e.g., observer disconnect() on a stable target), _listeners and _onIntersectionChange may never be cleared, keeping callbacks and related objects alive longer than necessary.
You likely want:
- Immediate clear when not currently dispatching.
- Deferred clear only when invoked during a dispatch to avoid concurrent modification.
A minimal fix is to track an _inDispatch flag:
+ bool _inDispatch = false; void clearIntersectionChangeListeners() { - _clearIntersectionListeners = true; + if (_inDispatch) { + _clearIntersectionListeners = true; + } else { + _clearIntersectionChangeListeners(); + } } bool _dispatchChange(IntersectionObserverEntry info) { - bool deliverIntersectionObserver = false; + _inDispatch = true; + bool deliverIntersectionObserver = false; ... - if (_clearIntersectionListeners) { - _clearIntersectionChangeListeners(); - } + if (_clearIntersectionListeners) { + _clearIntersectionChangeListeners(); + } + _inDispatch = false; return deliverIntersectionObserver; }Also applies to: 113-137
🤖 Prompt for AI Agents
In webf/lib/src/rendering/intersection_observer.dart around lines 84-96 (and similarly update lines 113-137), clearIntersectionChangeListeners() currently just sets _clearIntersectionListeners = true and relies on _dispatchChange() to do the real clearing, which can leave listeners alive if no further dispatch occurs; add a private boolean _inDispatch that _dispatchChange() sets true while iterating and false afterwards, and change clearIntersectionChangeListeners() to immediately clear _listeners, _onIntersectionChange and reset related fields when _inDispatch is false, but if _inDispatch is true then keep setting _clearIntersectionListeners = true so the actual clearing happens after dispatch completes; update _dispatchChange() to check _clearIntersectionListeners after dispatch and perform the same clear operation, and ensure both places reset _clearIntersectionListeners and other state consistently. There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
🧹 Nitpick comments (2)
bridge/core/dom/intersection_observer_entry.h (2)
64-64: Remove or explain commented-out code.The commented-out
IntersectionGeometry geometry_;member should either be removed entirely or accompanied by a TODO/FIXME comment explaining why it's preserved.
52-52: Consider adding [[nodiscard]] to nullable accessor.The
rootBounds()accessor can returnnullptr(as indicated by the TypeScript interface showingBoundingClientRect | null). Adding[[nodiscard]]would encourage callers to check the return value.Apply this diff:
- BoundingClientRect* rootBounds() const { return root_bounds_.Get(); } + [[nodiscard]] BoundingClientRect* rootBounds() const { return root_bounds_.Get(); }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
bridge/core/dom/intersection_observer.h(1 hunks)bridge/core/dom/intersection_observer_entry.h(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- bridge/core/dom/intersection_observer.h
🧰 Additional context used
📓 Path-based instructions (4)
bridge/**/*.{cc,cpp,h,hpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
bridge/**/*.{cc,cpp,h,hpp}: C++ code should follow Chromium style (.clang-format) with C++17 standard, 120 character column limit, and 2-space indentation
UseWEBF_EXPORT_Cmacro for exporting C functions to Dart FFI
In FFI contexts, useDart_Handleinstead ofHandlefor type compatibility
For C++ FFI function naming: useGetObjectPropertiesFromDartfor C++ exports,NativeGetObjectPropertiesFuncfor Dart typedefs, andGetObjectPropertiesFuncfor Dart functions
Lambda signatures in C++ must match expected function signatures to avoid FFI type mismatches
Choose power-of-2 buffer sizes (512, 1024, 2048) for ring buffer implementation, with smaller sizes for DEBUG_BUILD, MOBILE constraints, and larger sizes for DESKTOP performance
Files:
bridge/core/dom/intersection_observer_entry.h
bridge/**/*.{h,hpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
bridge/**/*.{h,hpp}: Ring buffer command structure should useenum Type : uint8_tfor command types with union for type-specific data to ensure type-safe and cache-friendly command handling
Ring buffer implementation should usealignas(64)for atomic head and tail pointers,std::atomic<size_t>for thread-safe synchronization, and power-of-2 buffer sizes enforced withstatic_assert
Files:
bridge/core/dom/intersection_observer_entry.h
bridge/**/*.{cc,h}
📄 CodeRabbit inference engine (AGENTS.md)
C++ code in bridge module must use C++17 standard with 2-space indentation, 120 column limit, and follow Chromium style guide as defined in
.clang-format
bridge/**/*.{cc,h}: Use RAII patterns in C++ where possible for resource management
UsePostToJsfor executing operations on the JS thread in FFI
UsePostToDartfor returning results to Dart isolate
AvoidPostToJsSyncsynchronous execution when possible
Files:
bridge/core/dom/intersection_observer_entry.h
{bridge/**/*.{cc,h},webf/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
Document memory ownership clearly in FFI implementations
Files:
bridge/core/dom/intersection_observer_entry.h
🧠 Learnings (3)
📓 Common learnings
Learnt from: CR Repo: openwebf/webf PR: 0 File: bridge/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:27:15.946Z Learning: Applies to bridge/**/*.{cc,cpp} : Use PostToJs for executing operations on the JS thread from other threads, PostToDart for returning results to Dart isolate, and avoid PostToJsSync to prevent deadlocks 📚 Learning: 2025-12-08T23:28:00.818Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: webf/CLAUDE.md:0-0 Timestamp: 2025-12-08T23:28:00.818Z Learning: Applies to webf/lib/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge Applied to files:
bridge/core/dom/intersection_observer_entry.h
📚 Learning: 2025-12-13T16:32:47.644Z
Learnt from: CR Repo: openwebf/webf PR: 0 File: CLAUDE.md:0-0 Timestamp: 2025-12-13T16:32:47.644Z Learning: Applies to webf/**/*.dart : Track pointer ownership in callbacks within Dart FFI Applied to files:
bridge/core/dom/intersection_observer_entry.h
🧬 Code graph analysis (1)
bridge/core/dom/intersection_observer_entry.h (5)
bridge/core/dom/intersection_observer.h (1)
webf(18-97)bridge/core/dom/intersection_observer_entry.d.ts (1)
IntersectionObserverEntry(11-25)bridge/core/dom/intersection_observer_entry.cc (3)
IntersectionObserverEntry(30-46)Trace(48-53)Trace(48-48)bridge/core/binding_object.cc (2)
Trace(403-407)Trace(403-403)bridge/core/dom/node_rare_data.h (1)
Member(52-52)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
- GitHub Check: build_windows_bridge (Debug)
- GitHub Check: Analyze (rust)
- GitHub Check: Analyze (c-cpp)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
bridge/core/dom/intersection_observer_entry.h (1)
35-48: LGTM! Well-designed class declaration.The deleted default constructor ensures explicit initialization, and the explicit constructor signature provides all necessary parameters for proper setup. This aligns with RAII best practices recommended in the coding guidelines.
| struct NativeIntersectionObserverEntry : public DartReadable { | ||
| int8_t is_intersecting; | ||
| double intersectionRatio; | ||
| NativeBindingObject* target; | ||
| NativeBindingObject* boundingClientRect; | ||
| NativeBindingObject* rootBounds; | ||
| NativeBindingObject* intersectionRect; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing fields in FFI struct may cause data loss when marshalling to Dart.
The NativeIntersectionObserverEntry struct is missing time and is_visible fields that are present in the IntersectionObserverEntry C++ class (lines 68, 67) and exposed in the TypeScript interface. The PR description specifically mentions implementing the time field as part of this work.
Apply this diff to add the missing fields:
struct NativeIntersectionObserverEntry : public DartReadable { int8_t is_intersecting; + int8_t is_visible; double intersectionRatio; + int64_t time; NativeBindingObject* target; NativeBindingObject* boundingClientRect; NativeBindingObject* rootBounds; NativeBindingObject* intersectionRect; };As per coding guidelines, document memory ownership clearly in FFI implementations.
| struct NativeIntersectionObserverEntryList : public DartReadable { | ||
| NativeIntersectionObserverEntry* entries; | ||
| int32_t length; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
Document memory ownership for FFI array structure.
Add documentation clarifying:
- Whether the
entriesarray is owned by the caller or callee - Expected lifetime of the array and its elements
- Who is responsible for deallocation
As per coding guidelines, document memory ownership clearly in FFI implementations.
🤖 Prompt for AI Agents
In bridge/core/dom/intersection_observer_entry.h around lines 30 to 33, the NativeIntersectionObserverEntryList struct lacks FFI memory-ownership documentation; add a clear comment above the struct that states whether entries is owned by the caller or callee, the expected lifetime of the entries array and each NativeIntersectionObserverEntry element (e.g. valid until a specific API call or explicit free), and who must free the memory (e.g. caller must call freeEntries or callee will free on next tick). Keep the comment concise and concrete (ownership rule, lifetime guarantee, deallocation function or responsibility) to satisfy FFI coding guidelines.
Based on #698
Summary:
Summary by CodeRabbit
New Features
Bug Fixes
Tests
Chores
✏️ Tip: You can customize this high-level summary in your review settings.