RFR: 8364149: Conditional stylesheet imports [v3]

Andy Goryachev angorya at openjdk.org
Wed Feb 25 22:21:27 UTC 2026


On Thu, 22 Jan 2026 16:52:10 GMT, Michael Strauß <mstrauss at openjdk.org> wrote:

>> The [`@import`](https://www.w3.org/TR/css-cascade-5/#at-import) rule is extended to support conditional stylesheet imports:
>> 
>> 
>> @import [ <url> | <string> ] <media-query-list>? ;
>> 
>> 
>> Conceptually, a conditional import takes all rules of the referenced stylesheet, literally includes them at the location of the `@import` rule, and surrounds them with a `@media` rule with the specified `<media-query-list>`.
>> 
>> The implementation of this feature extends media queries with a context-free evaluation function:
>> 
>> interface MediaQuery {
>>     TriState evaluate(); // returns TRUE / FALSE / UNKNOWN
>> }
>> 
>> 
>> This mode of evaluation uses Kleene's strong trivalent logic to determine whether the media query will always match (it's a tautology), will never match (it's a contradiction), or whether it depends on the context or we simply don't know.
>> 
>> Using this mechanism, a conditional stylesheet import that can never match will be skipped at runtime. Similarly, a conditional stylesheet import that will always match doesn't need the `<media-query-list>` at all; its rules will be pasted verbatim into the main stylesheet.
>> 
>> Note that this mechanism is _not_ meant to be a full-blown theorem solver. It won't detect that, for example, the following import conditions will always match:
>> 
>> @import url("stylesheet.css") (width > 1000) or (width <= 1000);
>> 
>> 
>> Its purpose is an optimization for "obvious" cases. For example, at the moment the built-in themes use hard-coded conditions to include user-agent stylesheets at runtime:
>> 
>>     // in PlatformImpl.java:
>>     if (isSupported(ConditionalFeature.INPUT_TOUCH)) {
>>         uaStylesheets.add("com/sun/javafx/scene/control/skin/modena/touch.css");
>>     }
>> 
>> In the future, we might have a way to test for `ConditionalFeature` flags that achieves the same thing, but with a public API available to all theme authors:
>> 
>> @import url("com/sun/javafx/scene/control/skin/modena/touch.css")
>>         (-fx-supports-conditional-feature: input-touch);
>
> Michael Strauß has updated the pull request with a new target base due to a merge or a rebase. The incremental webrev excludes the unrelated changes brought in by the merge/rebase. The pull request contains three additional commits since the last revision:
> 
>  - Merge branch 'master' into feature/conditional-import
>  - Merge branch 'master' into feature/conditional-import
>  - Conditional stylesheet imports

Initial comments.

Initial testing with 
https://github.com/andy-goryachev-oracle/Test/blob/main/src/goryachev/research/Css_Conditional_8364149.java

looks good, I'll test more tomorrow.

modules/javafx.graphics/src/main/java/com/sun/javafx/css/media/MediaQueryList.java line 45:

> 43:      * Attempts to determine the result of this media query list without a context, and returns
> 44:      * {@link TriState#TRUE} if it matches for all possible contexts, {@link TriState#FALSE} if
> 45:      * it matches for no possible context, or {@link TriState#UNKNOWN} if the result depends on

what does it mean "if it matches for no possible context"?  what's a context?  maybe provide an example or explain in simpler terms?

it's not a public class so it might be ok, just looks a bit cryptic to me.

modules/javafx.graphics/src/main/java/com/sun/javafx/css/media/MediaQueryParser.java line 90:

> 88:     public MediaQueryList parseMediaQueryList(List<Token> tokens) {
> 89:         var stream = new TokenStream(tokens);
> 90:         var expressions = new MediaQueryList();

minor complaint: we should probably limit the usage of 'var' keywords for tests.  these are easier to write, I admit, but make the code harder to read.

modules/javafx.graphics/src/main/java/javafx/css/Stylesheet.java line 315:

> 313:     private void readBinaryImports(int bssVersion, DataInputStream is, String[] strings) throws IOException {
> 314:         for (int i = 0, max = is.readInt(); i < max; i++) {
> 315:             int queryCount = is.readInt();

should we validate input here, at least make sure it's `>= 0` ?

modules/javafx.graphics/src/main/java/javafx/css/Stylesheet.java line 316:

> 314:         for (int i = 0, max = is.readInt(); i < max; i++) {
> 315:             int queryCount = is.readInt();
> 316:             var importConditions = new MediaQueryList();

minor: could explicitly specify the capacity via `MediaQueryList(int)`

-------------

PR Review: https://git.openjdk.org/jfx/pull/2031#pullrequestreview-3856789510
PR Review Comment: https://git.openjdk.org/jfx/pull/2031#discussion_r2855329471
PR Review Comment: https://git.openjdk.org/jfx/pull/2031#discussion_r2855363680
PR Review Comment: https://git.openjdk.org/jfx/pull/2031#discussion_r2855623618
PR Review Comment: https://git.openjdk.org/jfx/pull/2031#discussion_r2855627051


More information about the openjfx-dev mailing list