-
-
Notifications
You must be signed in to change notification settings - Fork 145
fix: css important semantics #792
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
base: main
Are you sure you want to change the base?
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughConsolidates inline-style handling to legacy declarations, adds !important tracking and propagation across native and Dart layers, splits sheet vs inline UI commands, and refactors style cascade/engine to stage and emit sheet/inline/pseudo styles via the bridge. Changes
Sequence Diagram(s)sequenceDiagram
participant JS as JS/Client
participant Bridge as Native Bridge
participant StyleEngine as Native StyleEngine
participant UI as UICommandBuffer/SharedUICommand
participant Dart as Dart/View
JS->>Bridge: setInlineStyle(elementId, property, value, important?)
Bridge->>StyleEngine: enqueue inline/sheet update or forward to Dart
StyleEngine-->>UI: Add (kSetInlineStyle | kSetSheetStyle) with value/href/important
UI->>Dart: deliver command (setInlineStyle/setSheetStyle / setSheetStyleById)
Dart->>Dart: view.applyStyle(elementId, property, value, important)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (10)
webf/test/src/css/inset_shorthand_test.dart (1)
56-65: Inconsistent type usage needs clarification or standardization.The "removes to initial longhands" test uses
ElementCSSStyleDeclarationwhile all other tests in this file useCSSStyleDeclaration. Based on the commit context ("treat kLocalStyleChange as element-only"), this type change appears intentional. However, since both types are functionally equivalent for this test (both usePropertyType.inlineby default and share the sameremovePropertyimplementation), the inconsistency lacks explanation.Either add a comment explaining why this specific test requires
ElementCSSStyleDeclaration, or standardize all tests to use the same type for consistency and clarity.bridge/core/css/resolver/style_resolver.cc (1)
287-308: Verify no native-side style consumers still rely on inline styles being applied here.With inline declarations removed from
MatchAllRules()(Line 306-308), any native computation that expectsComputedStyleto already reflectstyle=""/ CSSOM changes will be wrong unless the Dart-side merge is guaranteed to run before those code paths (and with correct !important/origin precedence).Please double-check:
- native layout/paint/style-recalc paths only consume styles after Dart merge, and
- precedence is correct across origins (UA/user/author/inline) for both normal and
!importantdeclarations.webf/example/lib/main.dart (1)
49-57: AddenableBlink: trueto the fallback controller creation for consistency.The preloaded controller (line 49-57) explicitly sets
enableBlink: true, but the fallback controller created in thecreateControllercallback (line 377-411) does not. While the preloaded controller will typically be reused, if it's ever disposed and needs to be recreated (due tomaxAliveInstanceslimits), the new instance would lack this setting, causing inconsistent behavior.Add enableBlink to the fallback controller
createController: () => WebFController( + enableBlink: true, routeObserver: routeObserver, initialRoute: widget.initialRoute, onControllerInit: (controller) async {},webf/lib/src/widget/widget_element.dart (1)
118-128: Check rebuild gating logic whenimportantpriority changes—the fix requires a different API approach.
shouldElementRebuild()currently compares only values, missing priority changes. If a property value stays the same butimportantflips, the cascade can change without triggering a widget rebuild. However, the codebase does not exposestyle.getPropertyPriority(); instead, access the inline style entry directly before callingsuper.setInlineStyle():Corrected fix
void setInlineStyle(String property, String value, {String? baseHref, bool fromNative = false, bool important = false}) { - bool shouldRebuild = shouldElementRebuild(property, style.getPropertyValue(property), value); + final previousEntry = inlineStyle[property]; + final previousPriority = previousEntry?.important ?? false; + final shouldRebuild = + shouldElementRebuild(property, style.getPropertyValue(property), value) || + previousPriority != important; super.setInlineStyle(property, value, baseHref: baseHref, fromNative: fromNative, important: important); if (state != null && shouldRebuild) { state!.requestUpdateState(); } styleDidUpdate(property, value); }webf/lib/src/css/computed_style_declaration.dart (1)
102-111: Add missing@overrideannotation to setProperty method.The parent class
CSSStyleDeclaration.setPropertyhas an identical signature with thePropertyType? propertyTypeparameter. SinceComputedStyleDeclaration.setPropertyoverrides this method, the@overrideannotation must be present to comply with Dart code style guidelines.@override void setProperty( String propertyName, String? value, { bool? isImportant, PropertyType? propertyType, String? baseHref, bool validate = true, }) { throw UnimplementedError('No Modification Allowed'); }webf/lib/src/bridge/ui_command.dart (2)
137-265: Dartswitchhas duplicatecaselabels (won’t compile).
In the command-logswitch(command.type),setPseudoStyle,removePseudoStyle, andclearPseudoStyleappear twice (Line 217-254 and again Line 245-254). This is a hard compile-time error in Dart.Proposed fix (remove duplicate cases and keep the richer payload logger)
case UICommandType.setPseudoStyle: if (command.nativePtr2 != nullptr) { try { final Pointer<NativePseudoStyleWithHref> payload = command.nativePtr2.cast<NativePseudoStyleWithHref>(); @@ break; - case UICommandType.removePseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} remove: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.clearPseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args}'; - break; - case UICommandType.setPseudoStyle: - printMsg = - 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} cssText: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.removePseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} remove: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.clearPseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args}'; - break; case UICommandType.setAttribute: printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} key: ${nativeStringToString(command.nativePtr2.cast<NativeString>())} value: ${command.args}'; break;
284-292: FFI leak:toNativeUtf8()result is never freed on RAF error path.
('Error: $e\n$stack').toNativeUtf8()allocates native memory that is passed torafCallback()but never freed. Wrap the callback invocation in a try-finally block to ensure cleanup withmalloc.free().Proposed fix
} catch (e, stack) { Pointer<Utf8> nativeErrorMessage = ('Error: $e\n$stack').toNativeUtf8(); - rafCallback(command.nativePtr.cast<Void>(), view.contextId, highResTimeStamp, nativeErrorMessage); + try { + rafCallback(command.nativePtr.cast<Void>(), view.contextId, highResTimeStamp, nativeErrorMessage); + } finally { + malloc.free(nativeErrorMessage); + } }bridge/core/css/legacy/legacy_inline_css_style_declaration.cc (1)
66-87: Fix potential UB: ctype calls must useunsigned char.
std::isupper(c)/std::tolower(c)(Line 77-80) are undefined for negativecharvalues.Proposed fix
for (char c : propertyName) { - if (std::isupper(c)) { + const unsigned char uc = static_cast<unsigned char>(c); + if (std::isupper(uc)) { result += '-'; - result += std::tolower(c); + result += static_cast<char>(std::tolower(uc)); } else { result += c; } }bridge/core/dom/element.cc (1)
438-508: Avoid reintroducingelement_data_->InlineStyle()snapshots in Blink mode during clone.
CloneNonAttributePropertiesFromclones legacy inline style (good), but then also clonesother.element_data_->InlineStyle()intounique_data->inline_style_unconditionally (Line 501-507). In Blink mode, you’re explicitly clearinginline_style_elsewhere to keep inline style “legacy-only”; cloning can undermine that.Proposed fix (gate snapshot clone to non-Blink mode)
// Also clone the inline style from element_data_ if it exists - if (other.element_data_ && other.element_data_->InlineStyle()) { + if (!GetExecutingContext()->isBlinkEnabled() && + other.element_data_ && other.element_data_->InlineStyle()) { if (element_data_ && element_data_->IsUnique()) { auto* unique_data = static_cast<UniqueElementData*>(element_data_.get()); unique_data->inline_style_ = other.element_data_->InlineStyle()->MutableCopy(); } }webf/lib/src/css/style_declaration.dart (1)
1310-1390: Pseudo rule recomputation can keep stale properties (missing reset beforeunion()).
handlePseudoRules()reuses existingpseudo*Styleand only unions new rules, so properties that disappear from matched rules won’t be removed unless the entire pseudo rule set becomes empty. This can leave incorrect pseudo computed styles.Proposed fix (rebuild pseudo declarations each time)
if (beforeRules.isNotEmpty) { - pseudoBeforeStyle ??= CSSStyleDeclaration.sheet(); - // Merge all the rules - for (CSSStyleRule rule in beforeRules) { - pseudoBeforeStyle!.union(rule.declaration); - } + final CSSStyleDeclaration next = CSSStyleDeclaration.sheet(); + for (CSSStyleRule rule in beforeRules) { + next.union(rule.declaration); + } + pseudoBeforeStyle = next; parentElement.markBeforePseudoElementNeedsUpdate(); } else if (beforeRules.isEmpty && pseudoBeforeStyle != null) { pseudoBeforeStyle = null; } @@ if (afterRules.isNotEmpty) { - pseudoAfterStyle ??= CSSStyleDeclaration.sheet(); - for (CSSStyleRule rule in afterRules) { - pseudoAfterStyle!.union(rule.declaration); - } + final CSSStyleDeclaration next = CSSStyleDeclaration.sheet(); + for (CSSStyleRule rule in afterRules) { + next.union(rule.declaration); + } + pseudoAfterStyle = next; parentElement.markAfterPseudoElementNeedsUpdate(); } else if (afterRules.isEmpty && pseudoAfterStyle != null) { pseudoAfterStyle = null; } @@ if (firstLetterRules.isNotEmpty) { - pseudoFirstLetterStyle ??= CSSStyleDeclaration.sheet(); - for (CSSStyleRule rule in firstLetterRules) { - pseudoFirstLetterStyle!.union(rule.declaration); - } + final CSSStyleDeclaration next = CSSStyleDeclaration.sheet(); + for (CSSStyleRule rule in firstLetterRules) { + next.union(rule.declaration); + } + pseudoFirstLetterStyle = next; parentElement.markFirstLetterPseudoNeedsUpdate(); } else if (firstLetterRules.isEmpty && pseudoFirstLetterStyle != null) { pseudoFirstLetterStyle = null; } @@ if (firstLineRules.isNotEmpty) { - pseudoFirstLineStyle ??= CSSStyleDeclaration.sheet(); - for (CSSStyleRule rule in firstLineRules) { - pseudoFirstLineStyle!.union(rule.declaration); - } + final CSSStyleDeclaration next = CSSStyleDeclaration.sheet(); + for (CSSStyleRule rule in firstLineRules) { + next.union(rule.declaration); + } + pseudoFirstLineStyle = next; parentElement.markFirstLinePseudoNeedsUpdate(); } else if (firstLineRules.isEmpty && pseudoFirstLineStyle != null) { pseudoFirstLineStyle = null; }
🤖 Fix all issues with AI agents
In @bridge/core/api/element.cc:
- Around line 17-28: Check ptr for null before using it and check
element->GetExecutingContext() before constructing MemberMutationScope: if ptr
is null return WebFValue<LegacyCssStyleDeclaration,
LegacyCssStyleDeclarationPublicMethods>::Null(); then static_cast to
webf::Element*, call element->GetExecutingContext() into a local (e.g., context)
and if context is null also return Null(); only then construct
MemberMutationScope{context} and proceed as before (retrieve style_declaration,
check it, call KeepAlive(), and return the WebFValue).
In @webf/lib/src/css/css_animation.dart:
- Around line 98-100: The cleanup in _revertOriginProperty() currently skips
removing inline styles when no origin was cached, leaving animation-introduced
properties behind; update _revertOriginProperty() to call
target.setInlineStyle(property, '') whenever origin == null (instead of doing
nothing) so properties applied by beforeRunningAnimation() are removed when the
animation ends or is cancelled; ensure this logic uses the
_cacheOriginProperties lookup and covers both normal revert and cancel paths so
animations with fill: backwards/both don't leave stale inline styles.
In @webf/lib/src/css/style_declaration.dart:
- Around line 770-779: operator== currently compares only hashCode which is
unsafe; change CSSStyleDeclaration.operator== to perform structural equality by
first checking identical(this, other) or runtimeType equality and then comparing
the actual significant fields (at minimum cssText) for equality (e.g., other is
CSSStyleDeclaration and other.cssText == cssText); keep hashCode derived from
the same fields so it remains consistent with equality.
🧹 Nitpick comments (17)
webf/test/src/rendering/css_sizing_test.dart (3)
59-63: MakeenqueueInlineProperty()application explicit (flush) for future un-skippingIf
enqueueInlineProperty()only queues changes, this test may start failing onceskip: trueis removed unless you flush before pumping (like you do later in the file).Proposed change
// Change width dynamically div.style.enqueueInlineProperty('width', '200px'); + div.style.flushPendingProperties(); await tester.pump();
236-240: Same: flush queued inline updates before pumpingKeeps test semantics consistent with the later “dynamic style updates” test.
Proposed change
// Change height dynamically div.style.enqueueInlineProperty('height', '250px'); + div.style.flushPendingProperties(); await tester.pump();
776-786: Reduce repeatedpump()calls to a small loop (same behavior, less noise)Proposed change
box.style.flushPendingProperties(); - await tester.pump(); - await tester.pump(); - await tester.pump(); - await tester.pump(); - await tester.pump(); - await tester.pump(); + for (var i = 0; i < 6; i++) { + await tester.pump(); + }webf/test/local_http_server.dart (2)
44-49: Consider adding Windows error code for completeness.The helper correctly detects EADDRINUSE on macOS (48) and Linux (98). The message fallback should handle Windows, but explicitly checking error code
10048(Windows WSAEADDRINUSE) would improve reliability.🔧 Optional enhancement for Windows compatibility
static bool _isAddressInUse(SocketException error) { final int? code = error.osError?.errorCode; - if (code == 48 || code == 98) return true; // macOS/Linux EADDRINUSE + if (code == 48 || code == 98 || code == 10048) return true; // macOS/Linux/Windows EADDRINUSE final String message = error.message.toLowerCase(); return message.contains('address already in use'); }
51-119: LGTM: Retry mechanism is well-implemented.The retry logic correctly:
- Detects address-in-use errors via
_isAddressInUse- Retries up to 20 times with a new random port
- Delegates exhausted retries to
Zone.current.handleUncaughtError(appropriate for test code)- Exits early on line 116 after scheduling retry
One optional improvement: consider logging retry attempts to aid debugging when port conflicts occur frequently in test environments.
📝 Optional: Add logging for retry attempts
}).catchError((Object error, StackTrace stackTrace) { if (error is SocketException && _isAddressInUse(error) && attempt < 20) { + print('Port $port in use, retrying with new port (attempt ${attempt + 1}/20)'); port = _randomPort(); _startServer(attempt + 1); return; } Zone.current.handleUncaughtError(error, stackTrace); });webf/lib/src/devtools/cdp_service/modules/css.dart (1)
559-582: BatchrecalculateStyle()to avoid O(n) full style recalcs during inline-style edits.
Right now_applyInlineStyleText()recalculates after every property set; this is noticeable when DevTools edits multiple declarations.Proposed change
for (String decl in decls) { @@ - element.setInlineStyle(camelize(name), value, important: important); - element.recalculateStyle(); + element.setInlineStyle(camelize(name), value, important: important); } + element.recalculateStyle();webf/lib/src/css/rule_set.dart (1)
38-41: Consider makinghasPseudoElementSelectorsprivate with a getter for defensive programming.The field is currently public and mutable, but empirical verification shows all external access is read-only (in
grouping_content.dart:160andelement.dart:2250). All writes occur only withinRuleSetitself (inreset()andfindBestRuleSetAndAdd()). While no external writes currently exist, using a private backing field with a public getter prevents future accidental mutations that could silently break pseudo-element matching behavior.Suggested refactor
class RuleSet { - bool hasPseudoElementSelectors = false; + bool _hasPseudoElementSelectors = false; + bool get hasPseudoElementSelectors => _hasPseudoElementSelectors;bridge/core/css/rule_feature_set.h (2)
136-140: Consider updatingToString()docs/legend to reflect new pseudo flags.
You addedUsesFirstLetterRules/UsesBeforeRules/UsesAfterRules, but the “META flags” comment block still only documentsF/W/R/P/..., which can make debugging confusing ifToString()starts surfacing these.
271-275: New FeatureMetadata flags look correct; consider packing if size matters.
IfFeatureMetadatais copied frequently, these additionalbools may add padding; a bitfield/bitmask could keep it compact (optional).bridge/core/css/blink_inline_style_validation_test.cc (1)
29-34: Make thevalue_ptrcast const-correct to matchSharedNativeStringToUTF8.
Right nowSharedNativeStringToUTF8takesconst webf::SharedNativeString*, butvalue_ptris cast as non-const.Proposed diff
- auto* value_ptr = reinterpret_cast<webf::SharedNativeString*>(static_cast<uintptr_t>(item.string_01)); + const auto* value_ptr = + reinterpret_cast<const webf::SharedNativeString*>(static_cast<uintptr_t>(item.string_01)); value_text = SharedNativeStringToUTF8(value_ptr);Also applies to: 78-84
webf/lib/src/css/parser/parser.dart (1)
96-145: Inline!importantparsing/validation looks correct; considercamelize()on reset path for consistent keys.
In theresetPropertybranch you setpropertyIdent = identifier().name;which can differ from the normalcamelize(...)format.bridge/foundation/shared_ui_command.h (1)
49-56: Defaultimportantvalue would make this API harder to misuse.Since this is a “fast-path” helper similar to
AddStyleByIdCommand, consider defaultingimportanttofalseto reduce call-site friction and avoid accidental uninitialized/placeholder values.Proposed tweak
void AddSheetStyleByIdCommand(void* native_binding_object, int32_t property_id, int64_t value_slot, SharedNativeString* base_href, - bool important, + bool important = false, bool request_ui_update = true);bridge/core/dom/legacy/element_attributes.cc (1)
134-142: Style attribute serialization: potential allocation/side-effect viaelement_->style()in ToString().
element_->style()appears to “ensure”/allocate the legacy inline declaration for styled elements; calling it fromToString()can create state during serialization. If that’s intended (to serialize normalized parsed style), fine—otherwise consider a non-allocating accessor if one exists.webf/lib/src/html/grouping_content.dart (1)
152-156: Inline styles propagate importance flag correctly.The use of
enqueueInlinePropertywithisImportant: entry.important ? true : nullproperly propagates the per-entry importance flag. However, the ternaryentry.important ? true : nullcould be simplified.♻️ Optional simplification
- style.enqueueInlineProperty(propertyName, entry.value, isImportant: entry.important ? true : null); + style.enqueueInlineProperty(propertyName, entry.value, isImportant: entry.important);If
isImportantacceptsbool?andentry.importantis already abool, you can pass it directly unless the API specifically requiresnullforfalsevalues.webf/lib/src/bridge/ui_command.dart (1)
121-123: Use aSet<int>forpendingStylePropertiesTargets(it’s a set, not a map).
You only care about unique addresses;Set<int>reduces noise and intent is clearer.[detail optional]
- Replace
Map<int, bool>withfinal pendingStylePropertiesTargets = <int>{};- Replace assignments with
pendingStylePropertiesTargets.add(nativePtr.address);Also applies to: 356-467, 576-585
webf/lib/src/dom/element.dart (2)
2009-2091:setInlineStyle()correctness looks OK; consider de-duplicating legacy!importantdecoding.
You now have near-identical!importantsuffix decoding insetInlineStyle()andsetSheetStyle(), plus_normalizeInlineStyleEntryFromNative(). A shared helper would reduce drift risk.
2319-2370: InlineStyleEntry-based removal + native normalization helper look OK; ensure normalization is used consistently.
If_normalizeInlineStyleEntryFromNative()is meant to be the canonical legacy!importantdetector (quote/paren-safe), consider using it in both inline/sheet paths rather than maintaining two decoders.
| WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods> ElementPublicMethods::Style(Element* ptr) { | ||
| auto* element = static_cast<webf::Element*>(ptr); | ||
| MemberMutationScope member_mutation_scope{element->GetExecutingContext()}; | ||
| auto style = element->style(); | ||
| auto* style_declaration = element->style(); | ||
| if (!style_declaration) { | ||
| return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>::Null(); | ||
| } | ||
|
|
||
| return std::visit( | ||
| MakeVisitor( | ||
| [&](legacy::LegacyInlineCssStyleDeclaration* styleDeclaration) { | ||
| WebFValueStatus* status_block = styleDeclaration->KeepAlive(); | ||
| return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>( | ||
| styleDeclaration, styleDeclaration->legacyCssStyleDeclarationPublicMethods(), status_block); | ||
| }, | ||
| [](auto&&) { return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>::Null(); }), | ||
| style); | ||
| WebFValueStatus* status_block = style_declaration->KeepAlive(); | ||
| return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>( | ||
| style_declaration, style_declaration->legacyCssStyleDeclarationPublicMethods(), status_block); | ||
| } |
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.
🧩 Analysis chain
🏁 Script executed:
# First, find the Element class definition and understand GetExecutingContext()
fd -t f -e h -e hpp "element\." bridge/ | head -20Repository: openwebf/webf
Length of output: 866
🏁 Script executed:
# Search for Element class definition
rg "class Element" bridge/ -t cpp -t h -A 3Repository: openwebf/webf
Length of output: 27727
🏁 Script executed:
# Find GetExecutingContext() method
rg "GetExecutingContext" bridge/ -t cpp -t h -B 2 -A 3Repository: openwebf/webf
Length of output: 50370
🏁 Script executed:
# Check MemberMutationScope constructor
rg "MemberMutationScope" bridge/ -t cpp -t h -B 2 -A 5Repository: openwebf/webf
Length of output: 50369
🏁 Script executed:
# Check KeepAlive() method signature
rg "KeepAlive\(\)" bridge/ -t cpp -t h -B 2 -A 3Repository: openwebf/webf
Length of output: 17213
🏁 Script executed:
# Find MemberMutationScope class definition and constructor
rg "class MemberMutationScope" bridge/ -t cpp -t h -A 10Repository: openwebf/webf
Length of output: 1450
🏁 Script executed:
# Check how ptr is used - is it a valid opaque pointer from FFI?
rg "ElementPublicMethods::Style" bridge/ -t cpp -t h -B 3 -A 3Repository: openwebf/webf
Length of output: 560
🏁 Script executed:
# Look for callers of ElementPublicMethods::Style to see if they guard ptr
rg "Style\(" bridge/core/api/ -t cpp -A 2 -B 2 | head -50Repository: openwebf/webf
Length of output: 459
🏁 Script executed:
# Find MemberMutationScope constructor implementation
rg "MemberMutationScope::MemberMutationScope" bridge/ -t cpp -A 10Repository: openwebf/webf
Length of output: 894
🏁 Script executed:
# Check if Element::GetExecutingContext() is defined and look at its return type
rg "GetExecutingContext()" bridge/core/dom/element.h -A 2 -B 2Repository: openwebf/webf
Length of output: 39
🏁 Script executed:
# Check the actual implementation to see how it can be null in execution
rg -A 5 "MemberMutationScope\(ExecutingContext" bridge/bindings/qjs/cppgc/mutation_scope.ccRepository: openwebf/webf
Length of output: 283
Add defensive null checks for ptr and GetExecutingContext().
The current code directly dereferences ptr without checking and passes element->GetExecutingContext() to MemberMutationScope without verifying it's non-null. The MemberMutationScope constructor immediately dereferences the context pointer (calling context->GetScriptState() and context->SetMutationScope()), which will crash if null. Since GetExecutingContext() can legitimately return null (as seen in similar code paths), this needs defensive checks. Also note the asymmetry: style_declaration is checked for null (lines 21–23) but GetExecutingContext() is not.
Proposed patch
WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods> ElementPublicMethods::Style(Element* ptr) {
+ if (!ptr) {
+ return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>::Null();
+ }
auto* element = static_cast<webf::Element*>(ptr);
- MemberMutationScope member_mutation_scope{element->GetExecutingContext()};
+ auto* context = element->GetExecutingContext();
+ if (!context) {
+ return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>::Null();
+ }
+ MemberMutationScope member_mutation_scope{context};
auto* style_declaration = element->style();
if (!style_declaration) {
return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>::Null();
}
WebFValueStatus* status_block = style_declaration->KeepAlive();
return WebFValue<LegacyCssStyleDeclaration, LegacyCssStyleDeclarationPublicMethods>(
style_declaration, style_declaration->legacyCssStyleDeclarationPublicMethods(), status_block);
}🤖 Prompt for AI Agents
In @bridge/core/api/element.cc around lines 17 - 28, Check ptr for null before
using it and check element->GetExecutingContext() before constructing
MemberMutationScope: if ptr is null return WebFValue<LegacyCssStyleDeclaration,
LegacyCssStyleDeclarationPublicMethods>::Null(); then static_cast to
webf::Element*, call element->GetExecutingContext() into a local (e.g., context)
and if context is null also return Null(); only then construct
MemberMutationScope{context} and proceed as before (retrieve style_declaration,
check it, call KeepAlive(), and return the WebFValue).
| final Map<String, Animation> _runningAnimation = {}; | ||
| final Map<String, String> _cacheOriginProperties = {}; | ||
| final Map<String, InlineStyleEntry> _cacheOriginProperties = {}; | ||
|
|
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.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for removal/clear APIs for inline styles
rg -n --hidden -S 'removeInlineStyle\s*\(|clearInlineStyle\s*\(|removeProperty\s*\(' webf/lib/src/dom webf/lib/src/css 2>/dev/null || echo "No exact matches found"
# Search more broadly for removal methods
rg -n 'def.*remove.*[Ss]tyle|def.*clear.*[Ss]tyle' webf/lib/src --type=dart 2>/dev/null || trueRepository: openwebf/webf
Length of output: 17827
🏁 Script executed:
#!/bin/bash
# Find InlineStyleEntry definition
rg -n 'class\s+InlineStyleEntry\b' webf/lib/srcRepository: openwebf/webf
Length of output: 125
🏁 Script executed:
#!/bin/bash
# Also examine the css_animation.dart file to see the implementation at the specified lines
wc -l webf/lib/src/css/css_animation.dartRepository: openwebf/webf
Length of output: 96
🏁 Script executed:
#!/bin/bash
# Inspect InlineStyleEntry definition and implementation
sed -n '106,150p' webf/lib/src/css/style_declaration.dartRepository: openwebf/webf
Length of output: 1829
🏁 Script executed:
#!/bin/bash
# Read the css_animation.dart file to see the full context at specified lines
sed -n '95,110p' webf/lib/src/css/css_animation.dart
sed -n '140,155p' webf/lib/src/css/css_animation.dart
sed -n '260,280p' webf/lib/src/css/css_animation.dartRepository: openwebf/webf
Length of output: 1722
🏁 Script executed:
#!/bin/bash
# Verify if setInlineStyle can be called with null to remove a property
rg -n 'void setInlineStyle' webf/lib/src/dom/element.dart -A 10Repository: openwebf/webf
Length of output: 732
🏁 Script executed:
#!/bin/bash
# Check the context of line 348 in element.dart to see how _removeInlineStyle works
sed -n '2315,2335p' webf/lib/src/dom/element.dartRepository: openwebf/webf
Length of output: 629
🏁 Script executed:
#!/bin/bash
# Check if there's a way to remove an inline style property (null case for setInlineStyle)
sed -n '2009,2100p' webf/lib/src/dom/element.dart | head -60Repository: openwebf/webf
Length of output: 2630
🏁 Script executed:
#!/bin/bash
# Verify the full context of how _revertOriginProperty is called and whether it handles the "no origin" case
sed -n '250,310p' webf/lib/src/css/css_animation.dartRepository: openwebf/webf
Length of output: 1974
Remove animation-introduced inline styles when no origin property existed.
When beforeRunningAnimation() applies animation values as inline styles and no origin existed, _revertOriginProperty() skips cleanup (since there's nothing cached to restore). Those styles remain as inline declarations after the animation finishes or is cancelled.
Use target.setInlineStyle(property, '') in _revertOriginProperty() when origin == null to properly remove the property, ensuring animations with fill: backwards or fill: both don't leave behind stale inline styles.
Affects lines 142–148 and 264–273.
🤖 Prompt for AI Agents
In @webf/lib/src/css/css_animation.dart around lines 98 - 100, The cleanup in
_revertOriginProperty() currently skips removing inline styles when no origin
was cached, leaving animation-introduced properties behind; update
_revertOriginProperty() to call target.setInlineStyle(property, '') whenever
origin == null (instead of doing nothing) so properties applied by
beforeRunningAnimation() are removed when the animation ends or is cancelled;
ensure this logic uses the _cacheOriginProperties lookup and covers both normal
revert and cancel paths so animations with fill: backwards/both don't leave
stale inline styles.
| /// An empty style declaration. | ||
| static CSSStyleDeclaration empty = CSSStyleDeclaration(); | ||
|
|
||
| final Map<String, CSSPropertyValue> _properties = {}; | ||
|
|
||
| CSSPropertyValue? _getEffectivePropertyValueEntry(String propertyName) => _properties[propertyName]; | ||
|
|
||
| void _setStagedPropertyValue(String propertyName, CSSPropertyValue value) { | ||
| _properties[propertyName] = value; | ||
| } | ||
|
|
||
| // ::first-letter pseudo style (applies to the first typographic letter) | ||
| CSSStyleDeclaration? _pseudoFirstLetterStyle; | ||
| CSSStyleDeclaration? get pseudoFirstLetterStyle => _pseudoFirstLetterStyle; | ||
| set pseudoFirstLetterStyle(CSSStyleDeclaration? newStyle) { | ||
| _pseudoFirstLetterStyle = newStyle; | ||
| // Trigger a layout rebuild so IFC can re-shape text for first-letter styling | ||
| target?.markFirstLetterPseudoNeedsUpdate(); | ||
| List<String> _effectivePropertyNamesSnapshot() => _properties.keys.toList(growable: false); | ||
|
|
||
| static bool _samePropertyValue(CSSPropertyValue? a, CSSPropertyValue? b) { | ||
| if (identical(a, b)) return true; | ||
| if (a == null && b == null) return true; | ||
| if (a == null || b == null) return false; | ||
| return a.value == b.value && | ||
| a.baseHref == b.baseHref && | ||
| a.important == b.important && | ||
| a.propertyType == b.propertyType; | ||
| } |
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.
CSSStyleDeclaration.empty should not be mutable shared state.
static CSSStyleDeclaration empty = CSSStyleDeclaration(); is globally shared and can be mutated by accident, polluting “empty” everywhere.
Proposed fix (at least make it non-reassignable + document)
- static CSSStyleDeclaration empty = CSSStyleDeclaration();
+ /// Shared empty declaration. Treat as read-only; do not mutate.
+ static final CSSStyleDeclaration empty = CSSStyleDeclaration();📝 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.
| /// An empty style declaration. | |
| static CSSStyleDeclaration empty = CSSStyleDeclaration(); | |
| final Map<String, CSSPropertyValue> _properties = {}; | |
| CSSPropertyValue? _getEffectivePropertyValueEntry(String propertyName) => _properties[propertyName]; | |
| void _setStagedPropertyValue(String propertyName, CSSPropertyValue value) { | |
| _properties[propertyName] = value; | |
| } | |
| // ::first-letter pseudo style (applies to the first typographic letter) | |
| CSSStyleDeclaration? _pseudoFirstLetterStyle; | |
| CSSStyleDeclaration? get pseudoFirstLetterStyle => _pseudoFirstLetterStyle; | |
| set pseudoFirstLetterStyle(CSSStyleDeclaration? newStyle) { | |
| _pseudoFirstLetterStyle = newStyle; | |
| // Trigger a layout rebuild so IFC can re-shape text for first-letter styling | |
| target?.markFirstLetterPseudoNeedsUpdate(); | |
| List<String> _effectivePropertyNamesSnapshot() => _properties.keys.toList(growable: false); | |
| static bool _samePropertyValue(CSSPropertyValue? a, CSSPropertyValue? b) { | |
| if (identical(a, b)) return true; | |
| if (a == null && b == null) return true; | |
| if (a == null || b == null) return false; | |
| return a.value == b.value && | |
| a.baseHref == b.baseHref && | |
| a.important == b.important && | |
| a.propertyType == b.propertyType; | |
| } | |
| /// Shared empty declaration. Treat as read-only; do not mutate. | |
| static final CSSStyleDeclaration empty = CSSStyleDeclaration(); | |
| final Map<String, CSSPropertyValue> _properties = {}; | |
| CSSPropertyValue? _getEffectivePropertyValueEntry(String propertyName) => _properties[propertyName]; | |
| void _setStagedPropertyValue(String propertyName, CSSPropertyValue value) { | |
| _properties[propertyName] = value; | |
| } | |
| List<String> _effectivePropertyNamesSnapshot() => _properties.keys.toList(growable: false); | |
| static bool _samePropertyValue(CSSPropertyValue? a, CSSPropertyValue? b) { | |
| if (identical(a, b)) return true; | |
| if (a == null && b == null) return true; | |
| if (a == null || b == null) return false; | |
| return a.value == b.value && | |
| a.baseHref == b.baseHref && | |
| a.important == b.important && | |
| a.propertyType == b.propertyType; | |
| } |
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.
it is named constructor
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.
@CGQAQ, I understand the confusion, but this is actually a static field, not a named constructor. Let me clarify:
Named constructors in your class look like this:
CSSStyleDeclaration([super.context]) : _defaultPropertyType = PropertyType.inline;
CSSStyleDeclaration.sheet([super.context]) : _defaultPropertyType = PropertyType.sheet;The line CodeRabbit is flagging is a static field declaration:
static CSSStyleDeclaration empty = CSSStyleDeclaration();CodeRabbit's concern is valid:
-
Without
final, this field can be reassigned anywhere in the code:CSSStyleDeclaration.empty = someOtherInstance; // Currently allowed
-
Even with
final, the instance itself can still be mutated (properties added/changed), but at least the reference can't be reassigned:static final CSSStyleDeclaration empty = CSSStyleDeclaration(); // Now: CSSStyleDeclaration.empty = x; // ❌ Won't compile // But: CSSStyleDeclaration.empty.setProperty(...) // ✅ Still possible
Recommendation: Add final to prevent accidental reassignment. If you want true immutability, you'd need additional patterns (like freezing the instance or using an unmodifiable wrapper), but final is a good first step.
🧠 Learnings used
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
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
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: CSS property implementations are located in lib/src/css/
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/
- Track origin (inline vs sheet) and priority during merges - Propagate inline style importance through UICommand payloads and legacy parsing - Add integration/unit tests for important precedence
RuleFeatureSet now tracks usage of ::before/::after/::first-letter alongside ::first-line. StyleEngine consults the global RuleFeatureSet to avoid emitting/sending pseudo style payloads for pseudos that cannot match, and stops descending into display:none subtrees during subtree style recalculation.
StyleEngine::RecalcStyleForSubtree/RecalcStyleForElementOnly now: - Guard against missing ExecutingContext. - Cache StyleResolver/UICommandBuffer for the whole operation. - Switch subtree traversal to an explicit stack and drop unused inherited-state plumbing. - Detect display:none via CSSValueID when possible (fallback to string compare). - Reuse pseudo selector atoms and avoid redundant UTF-8 conversions for href payloads. integration_tests: wait a frame before asserting scrollWidth/clientWidth in translate transform spec. Tests: not run (not requested)
StyleEngine::RecalcStyle previously handled any dirty element that wasn't\nkInlineIndependentStyleChange by calling RecalcStyleForSubtree(*element).\nThis made self-only invalidations (InvalidatesSelf), style="" mutations,\nand animation marks using kLocalStyleChange trigger expensive subtree rule\nmatching and UI style export.\n\nHandle kLocalStyleChange via RecalcStyleForElementOnly and clear the dirty\nbit. Subtree recalcs are now reserved for kSubtreeStyleChange and the\nexplicit ForceRecalcDescendants path.\n\nThis keeps semantics while avoiding unnecessary DOM subtree traversal.
978c974 to
4e53ae7
Compare
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: 0
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
webf/example/lib/main.dart (1)
49-61: KeepenableBlink: trueconsistent across both controller instances.The pre-registered 'demo' controller (line 51) uses
enableBlink: true, but the fallback controller created at line 378 defaults toenableBlink: false. Since both serve the samedemoControllerName, ensure the fallback also explicitly setsenableBlink: trueto maintain consistency.Suggested fix
WebFController( + enableBlink: true, routeObserver: routeObserver, initialRoute: widget.initialRoute, onControllerInit: (controller) async {},Note:
enableBlinkcontrols the CSS engine (native Blink vs Dart-side parsing) and is not debug-only, so gating it behindkDebugModewould be inappropriate.webf/lib/src/bridge/ui_command.dart (2)
217-254: Duplicate case statements for pseudo-style logging.There are duplicate case handlers in the logging switch statement:
setPseudoStyleappears at lines 217 and 245removePseudoStyleappears at lines 239 and 249clearPseudoStyleappears at lines 242 and 252Only the first matching case will execute. This appears to be dead code from incomplete refactoring.
🔧 Suggested fix: remove duplicate cases
printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} property: <null>'; } break; - case UICommandType.removePseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} remove: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.clearPseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args}'; - break; - case UICommandType.setPseudoStyle: - printMsg = - 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} cssText: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.removePseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args} remove: ${command.nativePtr2 != nullptr ? nativeStringToString(command.nativePtr2.cast<NativeString>()) : null}'; - break; - case UICommandType.clearPseudoStyle: - printMsg = 'nativePtr: ${command.nativePtr} type: ${command.type} pseudo: ${command.args}'; - break; case UICommandType.setAttribute:
441-513: Duplicate execution case statements for pseudo-style.Similar to the logging switch, there are duplicate case handlers in the execution switch:
setPseudoStyleat lines 441 and 468removePseudoStyleat lines 449 and 503clearPseudoStyleat lines 457 and 511The first
setPseudoStyle(lines 441-448) usesnativePairToPairRecord, while the second (lines 468-502) usesNativePseudoStyleWithHrefwith baseHref support. The second implementation appears more complete. The duplicates should be consolidated.🔧 Suggested fix: remove older duplicate cases
pendingStylePropertiesTargets[nativePtr.address] = true; break; - case UICommandType.setPseudoStyle: - if (command.nativePtr2 != nullptr) { - final keyValue = nativePairToPairRecord(command.nativePtr2.cast()); - if (keyValue.key.isNotEmpty) { - view.setPseudoStyle(nativePtr, command.args, keyValue.key, keyValue.value); - } - } - break; - case UICommandType.removePseudoStyle: - if (command.nativePtr2 != nullptr) { - Pointer<NativeString> nativeKey = command.nativePtr2.cast<NativeString>(); - String key = nativeStringToString(nativeKey); - freeNativeString(nativeKey); - view.removePseudoStyle(nativePtr, command.args, key); - } - break; - case UICommandType.clearPseudoStyle: - view.clearPseudoStyle(nativePtr, command.args); - break; case UICommandType.clearStyle:
🧹 Nitpick comments (5)
webf/lib/src/css/style_declaration.dart (1)
1393-1423: Consider refining pseudo-style update detection in merge().The
merge()method setspseudoUpdated = truewheneverotherhas a pseudo-style, even when the subsequentmerge()call might not produce any actual changes (lines 1404, 1409, 1414, 1419). This could trigger unnecessary pseudo-element updates.♻️ Optional refinement to track actual changes
bool merge(CSSStyleDeclaration other) { final bool updateStatus = super.merge(other); if (other is! ElementCSSStyleDeclaration) return updateStatus; bool pseudoUpdated = false; // Merge pseudo-element styles. Ensure target side is initialized so rules from // 'other' are not dropped when this side is null. if (other.pseudoBeforeStyle != null) { pseudoBeforeStyle ??= CSSStyleDeclaration.sheet(); - pseudoBeforeStyle!.merge(other.pseudoBeforeStyle!); - pseudoUpdated = true; + if (pseudoBeforeStyle!.merge(other.pseudoBeforeStyle!)) { + pseudoUpdated = true; + } } if (other.pseudoAfterStyle != null) { pseudoAfterStyle ??= CSSStyleDeclaration.sheet(); - pseudoAfterStyle!.merge(other.pseudoAfterStyle!); - pseudoUpdated = true; + if (pseudoAfterStyle!.merge(other.pseudoAfterStyle!)) { + pseudoUpdated = true; + } } if (other.pseudoFirstLetterStyle != null) { pseudoFirstLetterStyle ??= CSSStyleDeclaration.sheet(); - pseudoFirstLetterStyle!.merge(other.pseudoFirstLetterStyle!); - pseudoUpdated = true; + if (pseudoFirstLetterStyle!.merge(other.pseudoFirstLetterStyle!)) { + pseudoUpdated = true; + } } if (other.pseudoFirstLineStyle != null) { pseudoFirstLineStyle ??= CSSStyleDeclaration.sheet(); - pseudoFirstLineStyle!.merge(other.pseudoFirstLineStyle!); - pseudoUpdated = true; + if (pseudoFirstLineStyle!.merge(other.pseudoFirstLineStyle!)) { + pseudoUpdated = true; + } } return updateStatus || pseudoUpdated; }bridge/core/css/legacy/legacy_inline_css_style_declaration_test.cc (1)
14-16: Consider removing or utilizing unusedlogCalledvariables.Multiple tests declare
static bool logCalled = falseand set up a console handler, but never assert onlogCalled. If console output verification is needed, add assertions; otherwise, consider removing these unused variables to reduce noise.Also applies to: 30-32, 44-46, 70-72, 97-99, 114-116, 133-135
bridge/core/css/style_engine.cc (2)
1156-1166: Consider consolidating display:none detection.The detection logic first attempts
GetPropertyCSSValuewith identifier check, then falls back to string comparison. This is reasonable but could be extracted to a helper function since it's duplicated inRecalcStyleForElementOnly(lines 1546-1557).
1505-1869: Consider extracting shared logic between RecalcStyleForSubtree and RecalcStyleForElementOnly.The
apply_for_elementlogic inRecalcStyleForSubtree(lines 1138-1480) is nearly identical to the body ofRecalcStyleForElementOnly(lines 1529-1866). This significant duplication increases maintenance burden and risk of divergence.Consider extracting the per-element styling logic into a shared helper method.
♻️ Suggested approach
// Private helper that applies sheet/pseudo styles for a single element. // Returns true if element has display:none (indicating subtree skip). bool StyleEngine::ApplyStylesForElement(Element* element, StyleResolver& resolver, UICommandBuffer* command_buffer, bool emit_before, bool emit_after, bool emit_first_letter, bool emit_first_line);Then both
RecalcStyleForSubtreeandRecalcStyleForElementOnlycan call this helper, reducing ~700 lines of duplication.webf/lib/src/dom/element.dart (1)
2331-2370: Robust parsing but potential duplication with inline logic.The
_normalizeInlineStyleEntryFromNativemethod correctly handles:
- Quoted strings and nested function calls (lines 2338-2363)
- Trailing
!importantdetection with depth tracking- Proper extraction and trimming
However, similar (simpler) parsing logic exists in
setInlineStyle(lines 2027-2047) andsetSheetStyle(lines 2104-2124). Consider whether these inline blocks should delegate to this helper for consistency.♻️ Potential consolidation
Both
setInlineStyleandsetSheetStylecontain inline!importantparsing. Consider refactoring to use_normalizeInlineStyleEntryFromNativein those locations for consistency, as this method is more robust (handles quotes and nested calls).For example, in
setInlineStylearound line 2027:- if (fromNative && !derivedImportant) { - int end = derivedValue.length; - while (end > 0 && derivedValue.codeUnitAt(end - 1) <= 0x20) { - end--; - } - - const String keyword = 'important'; - if (end >= keyword.length) { - final int keywordStart = end - keyword.length; - if (derivedValue.substring(keywordStart, end).toLowerCase() == keyword) { - int i = keywordStart; - while (i > 0 && derivedValue.codeUnitAt(i - 1) <= 0x20) { - i--; - } - if (i > 0 && derivedValue.codeUnitAt(i - 1) == 0x21) { - derivedImportant = true; - derivedValue = derivedValue.substring(0, i - 1).trimRight(); - } - } - } - } - InlineStyleEntry entry = InlineStyleEntry(derivedValue, important: derivedImportant); - if (fromNative && !derivedImportant) { + if (fromNative) { entry = _normalizeInlineStyleEntryFromNative(entry); + derivedImportant = entry.important; + derivedValue = entry.value; }Similarly for
setSheetStyle.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
integration_tests/snapshots/css/css-flexbox/relayout-align-to-stretch.ts.f379be341.pngis excluded by!**/*.png
📒 Files selected for processing (63)
bridge/bindings/qjs/converter_impl.hbridge/core/api/element.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/core/css/css_properties.json5bridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/core/css/resolver/cascade_map.ccbridge/core/css/resolver/cascade_map.hbridge/core/css/resolver/style_cascade.ccbridge/core/css/resolver/style_resolver.ccbridge/core/css/resolver/style_resolver.hbridge/core/css/rule_feature_set.ccbridge/core/css/rule_feature_set.hbridge/core/css/style_engine.ccbridge/core/css/style_engine.hbridge/core/dom/element.ccbridge/core/dom/element.d.tsbridge/core/dom/element.hbridge/core/dom/legacy/element_attributes.ccbridge/core/frame/window.ccbridge/foundation/native_type.hbridge/foundation/shared_ui_command.ccbridge/foundation/shared_ui_command.hbridge/foundation/shared_ui_command_test.ccbridge/foundation/ui_command_buffer.ccbridge/foundation/ui_command_buffer.hbridge/foundation/ui_command_ring_buffer_test.ccbridge/foundation/ui_command_strategy.ccbridge/foundation/ui_command_strategy_test.ccbridge/test/css_unittests.cmakebridge/test/webf_test_context.ccintegration_tests/specs/css/css-inline/important-semantics.tsintegration_tests/specs/css/css-transforms/translate.tswebf/example/lib/main.dartwebf/lib/src/bridge/native_types.dartwebf/lib/src/bridge/to_native.dartwebf/lib/src/bridge/ui_command.dartwebf/lib/src/css/animation.dartwebf/lib/src/css/computed_style_declaration.dartwebf/lib/src/css/css_animation.dartwebf/lib/src/css/element_rule_collector.dartwebf/lib/src/css/parser/parser.dartwebf/lib/src/css/rule_set.dartwebf/lib/src/css/style_declaration.dartwebf/lib/src/devtools/cdp_service/modules/css.dartwebf/lib/src/dom/element.dartwebf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.dartwebf/lib/src/html/svg.dartwebf/lib/src/launcher/view_controller.dartwebf/lib/src/widget/widget_element.dartwebf/test/local_http_server.dartwebf/test/src/css/background_shorthand_clip_text_test.dartwebf/test/src/css/css_wide_keywords_inherit_test.dartwebf/test/src/css/inline_style_important_from_native_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inset_shorthand_test.dartwebf/test/src/css/style_declaration_merge_union_test.dartwebf/test/src/css/style_inline_parser.dartwebf/test/src/rendering/css_sizing_test.dart
💤 Files with no reviewable changes (2)
- webf/test/src/css/background_shorthand_clip_text_test.dart
- webf/test/src/css/css_wide_keywords_inherit_test.dart
✅ Files skipped from review due to trivial changes (1)
- bridge/core/css/resolver/cascade_map.cc
🚧 Files skipped from review as they are similar to previous changes (23)
- bridge/core/css/css_properties.json5
- bridge/foundation/native_type.h
- webf/lib/src/css/css_animation.dart
- webf/test/src/rendering/css_sizing_test.dart
- bridge/core/css/resolver/cascade_map.h
- webf/lib/src/css/computed_style_declaration.dart
- webf/lib/src/html/svg.dart
- webf/lib/src/devtools/cdp_service/modules/css.dart
- bridge/core/dom/legacy/element_attributes.cc
- webf/test/src/css/style_declaration_merge_union_test.dart
- bridge/foundation/shared_ui_command.h
- integration_tests/specs/css/css-inline/important-semantics.ts
- webf/lib/src/widget/widget_element.dart
- webf/test/src/css/inline_style_important_from_native_test.dart
- bridge/core/api/element.cc
- bridge/core/css/rule_feature_set.h
- bridge/foundation/ui_command_strategy.cc
- integration_tests/specs/css/css-transforms/translate.ts
- bridge/foundation/ui_command_buffer.cc
- webf/lib/src/bridge/native_types.dart
- bridge/core/frame/window.cc
- webf/lib/src/css/element_rule_collector.dart
- webf/lib/src/css/rule_set.dart
🧰 Additional context used
📓 Path-based instructions (12)
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/css/animation.dartwebf/example/lib/main.dartwebf/lib/src/bridge/to_native.dartwebf/test/src/css/style_inline_parser.dartwebf/lib/src/html/form/base_input.dartwebf/test/local_http_server.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/lib/src/launcher/view_controller.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/lib/src/css/parser/parser.dartwebf/lib/src/dom/element.dartwebf/lib/src/bridge/ui_command.dartwebf/test/src/css/inset_shorthand_test.dartwebf/lib/src/css/style_declaration.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/animation.dartwebf/lib/src/css/parser/parser.dartwebf/lib/src/css/style_declaration.dart
{bridge/**/*.{cc,h},webf/**/*.dart}
📄 CodeRabbit inference engine (CLAUDE.md)
Document memory ownership clearly in FFI implementations
Files:
webf/lib/src/css/animation.dartbridge/core/dom/element.hbridge/foundation/ui_command_ring_buffer_test.ccbridge/foundation/shared_ui_command_test.ccwebf/example/lib/main.dartbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/rule_feature_set.ccwebf/lib/src/bridge/to_native.dartbridge/test/webf_test_context.ccbridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/style_engine.ccwebf/test/src/css/style_inline_parser.dartbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccbridge/foundation/ui_command_strategy_test.ccbridge/core/css/style_engine.hwebf/lib/src/html/form/base_input.dartwebf/test/local_http_server.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/lib/src/launcher/view_controller.dartbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/foundation/shared_ui_command.ccwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartbridge/bindings/qjs/converter_impl.hwebf/lib/src/css/parser/parser.dartbridge/foundation/ui_command_buffer.hwebf/lib/src/dom/element.dartbridge/core/css/resolver/style_cascade.ccwebf/lib/src/bridge/ui_command.dartbridge/core/css/blink_inline_style_validation_test.ccwebf/test/src/css/inset_shorthand_test.dartbridge/core/css/resolver/style_resolver.hwebf/lib/src/css/style_declaration.dart
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/element.hbridge/foundation/ui_command_ring_buffer_test.ccbridge/foundation/shared_ui_command_test.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/rule_feature_set.ccbridge/test/webf_test_context.ccbridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/style_engine.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccbridge/foundation/ui_command_strategy_test.ccbridge/core/css/style_engine.hbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/foundation/shared_ui_command.ccbridge/bindings/qjs/converter_impl.hbridge/foundation/ui_command_buffer.hbridge/core/css/resolver/style_cascade.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/core/css/resolver/style_resolver.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/element.hbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/style_engine.hbridge/bindings/qjs/converter_impl.hbridge/foundation/ui_command_buffer.hbridge/core/css/resolver/style_resolver.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 possibleC++ bridge code must use 2-space indent, 120 column line limit, and follow Chromium style via
.clang-format
Files:
bridge/core/dom/element.hbridge/foundation/ui_command_ring_buffer_test.ccbridge/foundation/shared_ui_command_test.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/rule_feature_set.ccbridge/test/webf_test_context.ccbridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/style_engine.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccbridge/foundation/ui_command_strategy_test.ccbridge/core/css/style_engine.hbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/foundation/shared_ui_command.ccbridge/bindings/qjs/converter_impl.hbridge/foundation/ui_command_buffer.hbridge/core/css/resolver/style_cascade.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/core/css/resolver/style_resolver.h
bridge/core/**
📄 CodeRabbit inference engine (bridge/AGENTS.md)
Core bridge code should be located in
bridge/core/directory
Files:
bridge/core/dom/element.hbridge/core/dom/element.d.tsbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/rule_feature_set.ccbridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/style_engine.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.hbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccbridge/core/css/style_engine.hbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/core/css/resolver/style_cascade.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/core/css/resolver/style_resolver.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/foundation/ui_command_ring_buffer_test.ccbridge/foundation/shared_ui_command_test.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.ccbridge/core/css/rule_feature_set.ccbridge/test/webf_test_context.ccbridge/core/css/inline_css_style_declaration_test.ccbridge/core/css/style_engine.ccbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccbridge/foundation/ui_command_strategy_test.ccbridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/foundation/shared_ui_command.ccbridge/core/css/resolver/style_cascade.ccbridge/core/css/blink_inline_style_validation_test.cc
bridge/test/**/*.{cc,cpp}
📄 CodeRabbit inference engine (bridge/CLAUDE.md)
Add bridge unit test files to
bridge/test/directory and use Google Test macros:TEST(),EXPECT_EQ(), etc. Tests are automatically discovered by CMake
Files:
bridge/test/webf_test_context.cc
bridge/test/**/*.{cc,h}
📄 CodeRabbit inference engine (AGENTS.md)
Bridge unit tests must be added under
bridge/test/and use Google Test frameworkBridge unit tests must use GoogleTest framework, keep tests small and behavior-focused, and mirror source paths under
bridge/test/
Files:
bridge/test/webf_test_context.cc
webf/test/**/*.dart
📄 CodeRabbit inference engine (AGENTS.md)
Dart/Flutter widget and unit tests must be placed in
webf/test/and useWebFWidgetTestUtilsandpumpAndSettle()where needed
Files:
webf/test/src/css/style_inline_parser.dartwebf/test/local_http_server.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/test/src/css/inset_shorthand_test.dart
webf/test/**/*_test.dart
📄 CodeRabbit inference engine (webf/CLAUDE.md)
webf/test/**/*_test.dart: Use WebFWidgetTestUtils.prepareWidgetTest() to test HTML/CSS rendering in widget unit tests
Access render objects in tests to verify layout calculations
Call setupTest() in setUpAll() method for one-time setup in unit tests
When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future
Use mock bundles from test/src/foundation/mock_bundle.dart for testing in unit tests
Files:
webf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/test/src/css/inset_shorthand_test.dart
🧠 Learnings (55)
📓 Common learnings
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
Learnt from: CR
Repo: openwebf/webf PR: 0
File: webf/CLAUDE.md:0-0
Timestamp: 2025-12-08T23:28:00.818Z
Learning: CSS property implementations are located in lib/src/css/
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`
📚 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/css/animation.dartbridge/core/dom/element.d.tswebf/lib/src/bridge/to_native.dartbridge/core/css/style_engine.ccwebf/test/src/css/style_inline_parser.dartbridge/core/css/resolver/style_resolver.ccbridge/core/dom/element.ccwebf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/lib/src/launcher/view_controller.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartbridge/bindings/qjs/converter_impl.hwebf/lib/src/css/parser/parser.dartwebf/lib/src/dom/element.dartbridge/core/css/resolver/style_cascade.ccwebf/lib/src/bridge/ui_command.dartbridge/core/css/blink_inline_style_validation_test.ccwebf/test/src/css/inset_shorthand_test.dartwebf/lib/src/css/style_declaration.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/css/animation.dartwebf/example/lib/main.dartwebf/test/src/css/style_inline_parser.dartwebf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/lib/src/launcher/view_controller.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/lib/src/css/parser/parser.dartwebf/lib/src/dom/element.dartwebf/lib/src/css/style_declaration.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: No build needed for Dart-only changes in webf/
Applied to files:
webf/lib/src/css/animation.dartwebf/example/lib/main.dartwebf/lib/src/html/form/base_input.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/lib/src/launcher/view_controller.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/lib/src/css/style_declaration.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/css/animation.dartwebf/example/lib/main.dartwebf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/lib/src/dom/element.dartwebf/lib/src/css/style_declaration.dart
📚 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/core/dom/element.hbridge/foundation/shared_ui_command_test.ccbridge/core/dom/element.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/test/css_unittests.cmake
📚 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} : C++ code should follow Chromium style (.clang-format) with C++17 standard, 120 character column limit, and 2-space indentation
Applied to files:
bridge/core/dom/element.hbridge/foundation/shared_ui_command_test.ccbridge/core/css/style_engine.ccbridge/core/dom/element.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/test/css_unittests.cmake
📚 Learning: 2025-12-21T14:42:52.637Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/AGENTS.md:0-0
Timestamp: 2025-12-21T14:42:52.637Z
Learning: Applies to bridge/**/*.{cc,h} : C++ bridge code must use 2-space indent, 120 column line limit, and follow Chromium style via `.clang-format`
Applied to files:
bridge/core/dom/element.hbridge/foundation/shared_ui_command_test.ccbridge/core/dom/element.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/test/css_unittests.cmake
📚 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:
bridge/core/dom/element.hbridge/core/dom/element.d.tswebf/example/lib/main.dartwebf/lib/src/html/grouping_content.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/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/**/*.{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:
bridge/foundation/ui_command_ring_buffer_test.ccbridge/foundation/shared_ui_command_test.ccbridge/foundation/ui_command_strategy_test.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} : Implement ring buffer overflow handling with metrics and alerts to monitor command buffer capacity
Applied to files:
bridge/foundation/ui_command_ring_buffer_test.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/**/*.{cpp,h,hpp} : Use RAII patterns in C++ where possible for memory management
Applied to files:
bridge/foundation/ui_command_ring_buffer_test.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/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/foundation/shared_ui_command_test.ccbridge/test/css_unittests.cmake
📚 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:
bridge/core/dom/element.d.tswebf/lib/src/bridge/to_native.dartwebf/lib/src/bridge/ui_command.dartbridge/core/css/blink_inline_style_validation_test.cc
📚 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/element.d.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: Applies to webf/**/*.dart : Prefer final fields when applicable in Dart code
Applied to files:
webf/example/lib/main.dartwebf/lib/src/html/form/base_input.dartwebf/lib/src/dom/element.dartwebf/lib/src/css/style_declaration.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/example/lib/main.dartwebf/test/local_http_server.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 : When testing with WebFController, wait for initialization with: await controller.controlledInitCompleter.future
Applied to files:
webf/example/lib/main.dartwebf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.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/example/lib/main.dartwebf/test/local_http_server.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/example/lib/main.dartwebf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.dartwebf/lib/src/launcher/view_controller.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/lib/src/dom/element.dartwebf/test/src/css/inset_shorthand_test.dartwebf/lib/src/css/style_declaration.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 : Variables and functions must use camelCase in Dart
Applied to files:
webf/example/lib/main.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 docs/**/*.md : Include WebFControllerManager setup in code examples within documentation
Applied to files:
webf/example/lib/main.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/bridge.dart : lib/bridge.dart contains FFI bindings to C++ bridge
Applied to files:
webf/lib/src/bridge/to_native.dartwebf/test/local_http_server.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} : Avoid `PostToJsSync` when threads may interdepend to prevent synchronous deadlocks in FFI communication
Applied to files:
bridge/test/webf_test_context.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.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} : Avoid `PostToJsSync` synchronous execution when possible
Applied to files:
bridge/test/webf_test_context.ccbridge/core/css/legacy/legacy_inline_css_style_declaration.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/css/legacy/legacy_inline_css_style_declaration.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 ARIA attributes in WidgetElement when applicable for accessibility
Applied to files:
webf/lib/src/html/form/base_input.dartwebf/lib/src/html/grouping_content.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/html/form/base_input.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/html/form/base_input.dartwebf/lib/src/dom/element.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:
webf/test/local_http_server.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 : Use `malloc.free()` for `toNativeUtf8()` allocations in Dart FFI
Applied to files:
webf/test/local_http_server.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 : Always free allocated memory in Dart FFI
Applied to files:
webf/test/local_http_server.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} : 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:
webf/test/local_http_server.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 : Track ownership of allocated pointers in FFI callbacks
Applied to files:
webf/test/local_http_server.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 : Always free allocated memory in Dart FFI using malloc.free() for toNativeUtf8() allocations
Applied to files:
webf/test/local_http_server.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 : Free FFI allocated memory in finally blocks to ensure cleanup on exceptions
Applied to files:
webf/test/local_http_server.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/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/test/src/css/inset_shorthand_test.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/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartwebf/test/src/css/inset_shorthand_test.dart
📚 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 webf/test/**/*.dart : Dart/Flutter widget and unit tests must be placed in `webf/test/` and use `WebFWidgetTestUtils` and `pumpAndSettle()` where needed
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dart
📚 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 webf/integration_test/**/*.dart : Dart/Flutter integration tests must be placed in `webf/integration_test/` directory
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.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: Run widget unit tests with: cd webf && flutter test test/src/rendering/
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.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 : Access render objects in tests to verify layout calculations
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.dartwebf/test/src/css/inline_style_important_upgrade_same_value_test.dartbridge/core/css/blink_inline_style_validation_test.ccwebf/test/src/css/inset_shorthand_test.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/integration_tests/specs/**/*.dart : Use snapshot tests in integration_tests/specs/ for visual regression testing with await snapshot()
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.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: Run Flutter dart tests with: cd webf && flutter test
Applied to files:
webf/test/src/css/inline_style_remove_fallback_test.dart
📚 Learning: 2025-12-21T14:42:52.637Z
Learnt from: CR
Repo: openwebf/webf PR: 0
File: bridge/AGENTS.md:0-0
Timestamp: 2025-12-21T14:42:52.637Z
Learning: Applies to bridge/test/**/*.{cc,h} : Bridge unit tests must use GoogleTest framework, keep tests small and behavior-focused, and mirror source paths under `bridge/test/`
Applied to files:
bridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/core/css/blink_inline_style_validation_test.ccbridge/test/css_unittests.cmake
📚 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/test/**/*.{cc,h} : Bridge unit tests must be added under `bridge/test/` and use Google Test framework
Applied to files:
bridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccbridge/test/css_unittests.cmake
📚 Learning: 2025-12-26T09:18:25.075Z
Learnt from: CGQAQ
Repo: openwebf/webf PR: 777
File: integration_tests/specs/css/css-text-mixin/text_comprehensive_test.ts:389-391
Timestamp: 2025-12-26T09:18:25.075Z
Learning: In WebF integration tests, the background shorthand property syntax `background: <gradient> text` is valid CSS per MDN spec, where "text" is a valid background-clip value. The explicit backgroundClip assignment that follows is a workaround for WebF's current CSS parser limitation, not because the syntax is invalid.
Applied to files:
bridge/core/css/legacy/legacy_inline_css_style_declaration_test.ccwebf/test/src/css/inset_shorthand_test.dartwebf/lib/src/css/style_declaration.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 : Override buildWidget(BuildContext context) method in WidgetElement to build the Flutter widget
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/**/*.{cc,cpp,h,hpp} : Use `WEBF_EXPORT_C` macro for exporting C functions to Dart FFI
Applied to files:
webf/lib/src/bridge/ui_command.dartbridge/core/css/blink_inline_style_validation_test.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 string handling in FFI, copy strings that might be freed using `std::string(const_char_ptr)`, and use `toNativeUtf8()` with proper memory deallocation
Applied to files:
bridge/core/css/blink_inline_style_validation_test.cc
📚 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/css/blink_inline_style_validation_test.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,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/css/blink_inline_style_validation_test.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/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/test/css_unittests.cmake
📚 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: CSS property implementations are located in lib/src/css/
Applied to files:
webf/lib/src/css/style_declaration.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/css/style_declaration.dart
🧬 Code graph analysis (9)
bridge/core/dom/element.h (3)
bridge/core/css/css_property_value_set.cc (3)
MutableCSSPropertyValueSet(352-353)MutableCSSPropertyValueSet(355-362)MutableCSSPropertyValueSet(364-377)bridge/core/css/legacy/legacy_inline_css_style_declaration.cc (1)
LegacyInlineCssStyleDeclaration(158-159)bridge/core/dom/element.cc (2)
style(438-444)style(438-438)
bridge/core/dom/element.d.ts (2)
bridge/core/dom/element.h (8)
Element(48-462)Element(401-403)Element(406-412)Element(418-421)Element(425-438)Element(448-452)Element(454-456)Element(458-460)bridge/core/css/legacy/legacy_inline_css_style_declaration.cc (1)
LegacyInlineCssStyleDeclaration(158-159)
bridge/core/css/style_engine.cc (4)
bridge/core/executing_context.cc (2)
ctx(509-512)ctx(509-509)bridge/core/css/invalidation/pending_invalidations_test.cc (1)
collector(218-218)bridge/core/css/element_rule_collector.h (1)
PseudoElementStyleRequest(58-112)bridge/core/css/properties/css_parsing_utils.cc (14)
value(268-307)value(334-369)value(424-516)value(527-547)value(586-624)value(638-659)value(662-673)value(676-699)value(724-745)value(752-775)value(873-891)value(894-937)value(945-949)value(957-1036)
bridge/core/css/legacy/legacy_inline_css_style_declaration.h (3)
bridge/core/css/legacy/legacy_inline_css_style_declaration.cc (6)
InternalSetProperty(409-460)InternalSetProperty(409-411)InternalRemoveProperty(462-478)InternalRemoveProperty(462-462)InternalClearProperty(480-487)InternalClearProperty(480-480)bridge/core/css/legacy/legacy_css_style_declaration.h (3)
std(73-73)std(74-75)AtomicString(42-42)bridge/core/css/css_style_declaration.h (1)
AtomicString(42-87)
bridge/core/css/resolver/style_resolver.cc (2)
bridge/core/css/element_rule_collector.cc (1)
context(224-224)bridge/core/css/style_engine.cc (3)
evaluator(2133-2133)collector(1144-1144)collector(1535-1535)
bridge/foundation/ui_command_strategy_test.cc (1)
bridge/foundation/shared_ui_command_test.cc (1)
shared_command_(50-53)
bridge/foundation/shared_ui_command.cc (5)
bridge/foundation/ui_command_buffer.cc (2)
AddSheetStyleByIdCommand(102-118)AddSheetStyleByIdCommand(102-107)bridge/foundation/native_type.h (2)
property_id(98-98)important(89-89)bridge/foundation/ui_command_ring_buffer_test.cc (1)
item(106-106)bridge/foundation/ui_command_strategy.h (1)
item(68-68)bridge/foundation/ui_command_ring_buffer.cc (1)
item(254-254)
bridge/foundation/ui_command_buffer.h (3)
bridge/foundation/shared_ui_command.cc (2)
AddSheetStyleByIdCommand(94-116)AddSheetStyleByIdCommand(94-99)bridge/foundation/ui_command_buffer.cc (2)
AddSheetStyleByIdCommand(102-118)AddSheetStyleByIdCommand(102-107)bridge/foundation/native_type.h (2)
property_id(98-98)important(89-89)
bridge/core/css/blink_inline_style_validation_test.cc (5)
bridge/core/css/legacy/legacy_inline_css_style_declaration.cc (2)
item(161-200)item(161-161)bridge/foundation/ui_command_ring_buffer_test.cc (1)
item(106-106)bridge/foundation/ui_command_strategy.h (1)
item(68-68)bridge/foundation/ui_command_ring_buffer.cc (1)
item(254-254)bridge/test/webf_test_env.cc (2)
TEST_runLoop(331-337)TEST_runLoop(331-331)
⏰ 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_windows_bridge (Debug)
- GitHub Check: Analyze (c-cpp)
- GitHub Check: Analyze (javascript-typescript)
- GitHub Check: Analyze (rust)
- GitHub Check: build_windows_bridge (Debug)
4e53ae7 to
a6098af
Compare
Summary by CodeRabbit
New Features
Bug Fixes
Chores
Tests
✏️ Tip: You can customize this high-level summary in your review settings.