-
Bug
-
Resolution: Fixed
-
P3
-
jfx21
When a style refers to a value via a lookup variable, they will be resolved to find the final value. During this resolution, the style origin priority is modified to the highest priority encountered during the resolution process. If a lookup variable is defined in an AUTHOR stylesheet, then a Style defined in a USER_AGENT stylesheet will be increased to AUTHOR level priority.
This is undesirable as it means that changing a variable like "-fx-base" means many Styles (defined in Modena for example) will be treated as AUTHOR level styles. AUTHOR level styles are allowed to override values set by setters (which are considered USER level styles).
This behavior was previously hidden because in most cases, properties which were set manually by the user were not fully calculated if they were of a lower priority (ie. from a USER_AGENT stylesheet). However, this calculation is now always being completed as the calculated value may be shared with other sibling nodes with the same styles, and not completing it could mean that these sibling nodes were not styled correctly. See https://bugs.openjdk.org/browse/JDK-8245919
The completion of the calculation however now will also resolve the lookups, potentially raising the final style origin priority from USER_AGENT to AUTHOR if a lookup variable was encountered that was defined in an AUTHOR stylesheet. As the priority can now be raised above USER level, properties set manually now more aggressively get overridden, even though the developer never specified such property in their own AUTHOR stylesheet.
Solution
-----------
Resolving of lookups should not raise the priority of the originating style. This happens to coincide with how CSS variables are implemented and seems to be a more sensible default.
It looks like no special action needs to be taken to ensure such resolved values do not poison the cache if such a variable was specified as part of an INLINE style. Nodes with INLINE styles get their own separate cache already to avoid sharing their calculated values with other nodes with no or different INLINE styles.
Example Code
-----------
package app;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class TestApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new MyLabel());
// See the difference with/without -fx-base in the stylesheet
scene.getStylesheets().add(TestApp.class.getResource("/style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
}
class MyLabel extends Label {
public MyLabel() {
setTextFill(Color.YELLOW);
setText("Hello world");
}
}
Example Stylesheet
-------------------------
.root {
-fx-base: #ff0000;
}
This is undesirable as it means that changing a variable like "-fx-base" means many Styles (defined in Modena for example) will be treated as AUTHOR level styles. AUTHOR level styles are allowed to override values set by setters (which are considered USER level styles).
This behavior was previously hidden because in most cases, properties which were set manually by the user were not fully calculated if they were of a lower priority (ie. from a USER_AGENT stylesheet). However, this calculation is now always being completed as the calculated value may be shared with other sibling nodes with the same styles, and not completing it could mean that these sibling nodes were not styled correctly. See https://bugs.openjdk.org/browse/JDK-8245919
The completion of the calculation however now will also resolve the lookups, potentially raising the final style origin priority from USER_AGENT to AUTHOR if a lookup variable was encountered that was defined in an AUTHOR stylesheet. As the priority can now be raised above USER level, properties set manually now more aggressively get overridden, even though the developer never specified such property in their own AUTHOR stylesheet.
Solution
-----------
Resolving of lookups should not raise the priority of the originating style. This happens to coincide with how CSS variables are implemented and seems to be a more sensible default.
It looks like no special action needs to be taken to ensure such resolved values do not poison the cache if such a variable was specified as part of an INLINE style. Nodes with INLINE styles get their own separate cache already to avoid sharing their calculated values with other nodes with no or different INLINE styles.
Example Code
-----------
package app;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class TestApp extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
Scene scene = new Scene(new MyLabel());
// See the difference with/without -fx-base in the stylesheet
scene.getStylesheets().add(TestApp.class.getResource("/style.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
}
}
class MyLabel extends Label {
public MyLabel() {
setTextFill(Color.YELLOW);
setText("Hello world");
}
}
Example Stylesheet
-------------------------
.root {
-fx-base: #ff0000;
}
- duplicates
-
JDK-8317434 Regression rendering Label with setTextFill color
-
- Closed
-
- links to
-
Commit(master) openjdk/jfx/ffbd12dc
-
Review(master) openjdk/jfx/1503