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