-
Notifications
You must be signed in to change notification settings - Fork 3
Implement CSS variable dependency tracking with VariableReferenceTracker and improved property processing #263
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
…e updates Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
src/client/cssom/computed_style.hpp
Outdated
| static ComputedStyle Make(const CSSStyleDeclaration &style, std::shared_ptr<dom::Node> target_node); | ||
|
|
||
| // Create a `ComputedStyle` with CSS variable inheritance from parent style. | ||
| static ComputedStyle Make(const CSSStyleDeclaration &style, std::shared_ptr<dom::Node> target_node, const ComputedStyle *parent_style); |
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.
@copilot Remove this static method, just keep using make_shared<ComputedStyle> with computed context which contains the inherited properties.
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.
Removed the static Make method with parent_style parameter as requested. The code now uses make_shared with computed context containing inherited properties. Fixed in commit 5e31d06.
src/client/cssom/computed_style.hpp
Outdated
| std::unordered_map<std::string, std::string> custom_properties_; | ||
|
|
||
| // Parent style for CSS variable inheritance during computation | ||
| mutable const ComputedStyle *parent_style_context_ = nullptr; |
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.
@copilot No need to maintain a parent computed style here.
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.
Removed the parent_style_context_ member variable as requested. The code no longer maintains a separate parent computed style reference. Fixed in commit 5e31d06.
src/client/cssom/computed_style.cpp
Outdated
| } | ||
|
|
||
| // Resolve variables in the value for regular properties | ||
| string resolvedValue = resolveVariables(value, parent_style_context_); |
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.
@copilot You can get the the parent's style from context's inherited style via context.inheritedStyle().
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.
Updated the resolveVariables method to use context.inheritedStyle() instead of maintaining a parent style reference. The variable resolution now properly accesses the parent's custom properties through the context's inherited style. Fixed in commit 5e31d06.
…ent style reference Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
tests/client/css_variables_tests.cpp
Outdated
| ComputedStyle computedStyle; | ||
| computedStyle.setCustomProperty("--main-color", "red"); | ||
|
|
||
| std::string resolved = computedStyle.resolveVariables("var(--main-color)"); |
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.
resolveVariables requires a 2nd argument computed::Context which stores the variables.
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.
Fixed in commit a93f62e. Added the required computed::Context parameter to all resolveVariables calls in the test file. Created a createTestContext() helper function to provide the necessary context for test scenarios.
tests/client/css_variables_tests.cpp
Outdated
| std::string resolved = computedStyle.resolveVariables("var(--main-color)"); | ||
| REQUIRE(resolved == "red"); | ||
|
|
||
| std::string complexResolved = computedStyle.resolveVariables("1px solid var(--main-color)"); |
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.
Ditto.
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.
Fixed in commit a93f62e. Updated this resolveVariables call to include the computed::Context parameter.
tests/client/css_variables_tests.cpp
Outdated
| { | ||
| ComputedStyle computedStyle; | ||
|
|
||
| std::string resolved = computedStyle.resolveVariables("var(--undefined, blue)"); |
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.
Ditto.
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.
Fixed in commit a93f62e. Updated this resolveVariables call to include the computed::Context parameter.
Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
|
Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details. Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
src/client/cssom/computed_style.cpp
Outdated
|
|
||
| string ComputedStyle::resolveVariables(const string &value, const values::computed::Context &context) const | ||
| { | ||
| string result = value; |
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.
@copilot Create a tokenizer and parser at client/cssom/parsers instead of writing the logic at ComputedStyle
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.
And please make sure that the nested var() calls work well: var(--undefined, var(--fallback)) with --fallback: blue would produce var(--undefined, blue).
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.
Created a dedicated CSS variable tokenizer and parser at client/cssom/parsers/css_variable_parser.{hpp,cpp} instead of having the logic embedded in ComputedStyle. The new parser also properly handles nested var() calls with recursive resolution, so var(--undefined, var(--fallback)) with --fallback: blue correctly produces blue. Fixed in commit 86b0974.
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.
Fixed in commit 86b0974. The new CSS variable parser now correctly handles nested var() calls with full recursive resolution. The example var(--undefined, var(--fallback)) with --fallback: blue properly produces blue instead of leaving partial unresolved variables.
Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
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.
@copilot Updating new custom properties from CSSStyleDeclaration (inserting --foo: a into custom_properties_) should be completed before computing properties or inherited properties, please update related code in this source.
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.
Implemented two-pass processing in the update() method. Custom properties (CSS variables) are now processed in the first pass before regular properties in the second pass. This ensures custom properties are available when resolving variables in regular properties. Fixed in commit 6c44cdd.
src/client/cssom/computed_style.cpp
Outdated
|
|
||
| setCustomProperty(name, value); | ||
|
|
||
| // TODO: Re-resolve all properties that depend on this variable |
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.
@copilot Please introduce a variable reference tracker to complete this TODO.
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.
Introduced variable reference tracker with dependency mapping. Added variable_dependencies_ member to track which properties use which variables, plus methods trackVariableDependency(), clearVariableDependencies(), and reResolveVariableDependents(). The computeProperty method now tracks variable dependencies before resolving variables. Fixed in commit 6c44cdd.
…essing Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
src/client/cssom/computed_style.cpp
Outdated
| auto it = find(propertyName); | ||
| if (it != end()) | ||
| // Only process custom properties in the first pass | ||
| if (propertyName.length() >= 2 && propertyName.substr(0, 2) == "--") |
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.
@copilot Simplify the following code that updates custom properties, just setting the custom property via setCustomProperty().
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.
Simplified the custom property updates in the first pass to use setCustomProperty() directly instead of manual property management. Fixed in commit dc3cf57.
src/client/cssom/computed_style.cpp
Outdated
| } | ||
|
|
||
| if (context.has_value()) | ||
| computeProperty(propertyName, value, context.value()); |
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.
No need to call computeProperty() at first pass that updates the custom properties only.
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.
Removed the computeProperty() call from the first pass. The first pass now only sets custom properties without computing them. Fixed in commit dc3cf57.
| return false; | ||
|
|
||
| // Two-pass approach: first process custom properties, then regular properties | ||
| // This ensures custom properties are available when resolving variables in regular properties |
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.
@copilot we need first-updating custom properties at resetProperties() and inheritProperties(), too.
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.
Updated both resetProperties() and inheritProperties() methods to use two-pass processing: custom properties are set first, then regular properties are processed. This ensures custom properties are available before they're referenced. Fixed in commit dc3cf57.
src/client/cssom/computed_style.hpp
Outdated
| std::unordered_map<std::string, std::string> custom_properties_; | ||
|
|
||
| // Variable dependency tracking: maps variable names to properties that use them | ||
| std::unordered_map<std::string, std::unordered_set<std::string>> variable_dependencies_; |
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.
@copilot Create a new class VariableReferenceTracker to manage the variable references, it provide a way to listen a variable changed (or removed) and recompute the related values.
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.
Created a new VariableReferenceTracker class that manages variable dependencies and provides change listener functionality. The class handles dependency tracking, cleanup, and recomputation trigger mechanisms. The ComputedStyle class now uses this tracker instead of managing dependencies directly. Fixed in commit dc3cf57.
- Simplify custom property updates in first pass to use setCustomProperty() only - Remove computeProperty() calls from first pass to avoid premature computation - Update resetProperties() and inheritProperties() to handle custom properties first - Create dedicated VariableReferenceTracker class to manage variable dependencies - Move variable dependency tracking out of ComputedStyle for better separation of concerns Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
This PR implements comprehensive CSS variable dependency tracking and resolves property processing order issues to ensure proper variable resolution.
Key Changes
VariableReferenceTracker Class: Created a dedicated class to manage CSS variable dependencies with better separation of concerns:
ComputedStylefor cleaner architectureSimplified Custom Property Processing: Streamlined the two-pass CSS property processing:
setCustomProperty()directly without premature computationEnhanced Method Updates: Updated
resetProperties()andinheritProperties()to use the same two-pass approach, ensuring custom properties are always available before regular properties are processed.Context-Based Inheritance: Utilizes the
computed::Contextfor proper variable inheritance throughcontext.inheritedStyle()rather than maintaining separate parent style references.Enhanced Variable Resolution: Built on the existing dedicated CSS variable parser to provide:
var()function support:var(--undefined, var(--fallback))→bluevar(--missing1, var(--missing2, var(--fallback)))Example Usage
The
VariableReferenceTrackerenables future optimizations where changing a variable can automatically trigger re-computation of only the properties that depend on it, rather than re-processing the entire style.💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.