CSS Lookups and their origins (possible regression)
John Hendrikx
john.hendrikx at gmail.com
Tue Jul 9 15:24:59 UTC 2024
It's not that you can't use -fx-base, but that as it is currently that
all styles used in Modena that rely on -fx-base directly or indirectly
suddenly have a higher priority (above setters) even though you didn't
specifically specify them in your own stylesheet. All such styles are
being elevated from USER_AGENT to AUTHOR level (which is above USER
level which is used for setters).
--John
On 09/07/2024 17:03, Andy Goryachev wrote:
>
> I've used this feature in the past to change the colors in all the
> controls, so to me this is the expected behavior.
>
> So in your case (if I got it right), you need to set the direct style
> on the label (.setStyle("-fx-text-fill:yellow")) instead of setting
> the text fill programmatically. Right?
>
> -andy
>
> *From: *openjfx-dev <openjfx-dev-retn at openjdk.org> on behalf of John
> Hendrikx <john.hendrikx at gmail.com>
> *Date: *Monday, July 8, 2024 at 17:11
> *To: *openjfx-dev <openjfx-dev at openjdk.org>
> *Subject: *Re: CSS Lookups and their origins (possible regression)
>
> I realized I worded the TLDR poorly.
>
> Let me try again:
>
> TLDR; should styles which use references (like -fx-base used in
> Modena) become AUTHOR level styles if -fx-base is specified in an
> AUTHOR stylesheet? The act of simply specifying -fx-base in your own
> AUTHOR stylesheet elevates hundreds of styles from Modena to AUTHOR
> level, as if you specified them directly...
>
> --John
>
> On 09/07/2024 02:07, John Hendrikx wrote:
>
> Hi List,
>
> TLDR; should a CSS reference like -fx-base convert all styles that
> use this value (or derive from it) become AUTHOR level styles
> (higher priority than setters) ?
>
> Long version:
>
> In JavaFX 21, I did a fix (see #1072) to solve a problem where a
> CSS value could be reset on an unrelated control.
>
> This happened when the CSS engine encountered a stylable that is
> overridden by the user (with a setter), and decided NOT to proceed
> with the full CSS value calculation (as it could not override the
> user setting if that CSS value had lower priority). However, not
> proceeding with the calculation meant that a "SKIP" was stored in
> a shared cache which was incorrect. This is because when this
> "SKIP" is later encountered for an unrelated control (the cache
> entries are shared for controls with the same styles at the same
> level), they could get their values reset because they were
> assumed to be unstyled.
>
> However, this fix has exposed what seems to be a deeper bug or
> perhaps an unfortunate default:
>
> JavaFX has a special feature where you can refer to certain other
> styles by using a reference (which is resolved, recursively, to a
> final value). This does not seem to be a CSS standard, but is a
> feature only FX has.
>
> It works by saying something like:
>
> -fx-base: RED;
>
> And then using it like this:
>
> -fx-text-fill: -fx-base;
>
> This feature works accross stylesheets of different origins, so an
> AUTHOR stylesheet can specify -fx-base, and when a USER_AGENT
> refers to -fx-base, the value comes from the AUTHOR stylesheet.
>
> JavaFX then changes the origin of the style to the highest
> priority encountered while resolving the reference. This means
> that Modena can specify "-fx-text-fill: -fx-base", and when
> "-fx-base" is then part of the AUTHOR style sheet, that ALL Modena
> styles that use -fx-base will be considered AUTHOR level styles,
> as per this comment:
>
> // The origin of this parsed value is the greatest of
>
> // any of the resolved reference. If a resolved reference
>
> // comes from an inline style, for example, then the value
>
> // calculated from the resolved lookup should have inline
>
> // as its origin. Otherwise, an inline style could be
>
> // stored in shared cache.
>
> I feel that this is a really unfortunate choice. The style after
> all was specified by Modena, only its value came from another
> (higher priority) style sheet. I think a more logical choice
> would have been to not change the priority at all, unless a
> "-fx-text-fill" is explicitly made part of the AUTHOR stylesheet.
>
> A consequence of this (and which is much more visible after the
> fix) is that creating a Label with a setTextFill(Color.YELLOW) in
> its constructor will only result in a yellow text fill if the
> AUTHOR stylesheet did not override any of the Modena colors
> involved in calculating the Modena -fx-text-fill default.
> Overriding -fx-base in any way will result in the text fill of the
> label to be overridden (as the reference came from an AUTHOR
> stylesheet, which trumps a setter which is of a lower style origin).
>
> The comment also alludes to a potential problem. If an inline
> style would specify "-fx-base", but would be treated as if it came
> from Modena (USER_AGENT level), then this value could get stored
> in the cache as everything except INLINE styles can be cached.
> However, I feel that the changing of style origin level was then
> probably done to solve a CACHING problem, instead of what made
> logical sense for users. If we agree that a resolved reference
> should not change the style origin level, then this would need to
> be addressed, by perhaps marking such a calculated value as
> uncacheable, instead of overloading the meaning of style origin.
>
> I'd like to hear your thoughts, and also how to proceed. JavaFX
> versions before 21 seemingly allowed overriding reference without
> much consequence because if the user overrode the value manually,
> the cache entry would be set to "SKIP". Now that this is no
> longer the case, JavaFX more aggressively overrides user set
> values if they happen to use a referenced value. See code below.
>
> --John
>
> .root {
>
> -fx-base: #ff0000;
>
> }
>
> *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");
>
> }
>
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/openjfx-dev/attachments/20240709/39d5068f/attachment-0001.htm>
More information about the openjfx-dev
mailing list