Skip to content

Commit 0aa3d40

Browse files
authored
[css-navigation-1] Move parameter resolution into <<route-location>> instead of :active-navigation (#14119)
* wip * Refactor param matchers * nit * Resolve missing navigation-relation and if()/navigation() issue * nits
1 parent 1df9846 commit 0aa3d40

1 file changed

Lines changed: 103 additions & 141 deletions

File tree

css-navigation-1/Overview.bs

Lines changed: 103 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -45,43 +45,80 @@ url: https://drafts.csswg.org/css-view-transitions-1/#capture-the-image
4545
<h3 id="route-value-type">The <<route-location>> value type</h3>
4646

4747
<pre class="prod def" dfn-type="type" nohighlight>
48-
<dfn><<route-location>></dfn> = <<route-name>> | <<url-pattern()>> | <<url>>
48+
<dfn><<route-location>></dfn> = <<url>> | [ [ <<route-name>> | <<url-pattern()>> ] <<url-pattern-param-matcher>>? ]
4949
<dfn><<route-name>></dfn> = <<dashed-ident>>
50+
<dfn><<url-pattern-param-matcher>></dfn> = with (<<url-pattern-param>># | [ all from <<url>> ])
51+
<dfn><<url-pattern-param>></dfn> = <<ident>>: <<any-value>>
5052
</pre>
5153

5254
A <<route-location>> is defined to
53-
<dfn for="route-location">match</dfn> a [=/URL=]-or-null <var>input</var> if <var>input</var> is non-null, and:
55+
<dfn for="route-location">match</dfn> a [=/URL=]-or-null <var>input</var> if <var>input</var> is non-null,
56+
and the corresponding statement:
5457

5558
<dl class=switch>
5659

5760
: the <<route-location>> is a <<route-name>>
58-
:: [=URL pattern/match|match a URL pattern=] is non-null given
59-
<var>urlPattern</var> as
60-
the [=URL pattern=] represented by the ''@route'' rule referenced by the name and
61-
<var>input</var> as <var>input</var>.
61+
:: The [=URL pattern=] represented by the ''@route'' rule referenced by the name [=match URL pattern with params|matches=] <var>input</var> given the provided <<url-pattern-param-matcher>> (if exists).
6262

6363
: the <<route-location>> is a <<url-pattern()>>
64-
:: [=URL pattern/match|match a URL pattern=] is non-null given
65-
<var>urlPattern</var> as
66-
the [=URL pattern=] represented by the function (see
67-
[=create a URL pattern for url-pattern()=]) and
68-
<var>input</var> as <var>input</var>.
64+
:: The provided [=URL pattern=] [=match URL pattern with params|matches=] <var>input</var> given the provided <<url-pattern-param-matcher>> (if exists).
6965

7066
: the <<route-location>> is a <<url>>
71-
:: The given [=/URL=] [=url/equals=] <var>input</var>.
67+
:: The provided [=/URL=] [=url/equals=] <var>input</var>.
7268

7369
</dl>
7470

71+
<div algorithm>
72+
To <dfn>match URL pattern with params</dfn>
73+
given a [=URL pattern=] <var>urlPattern</var>,
74+
a [=/URL=] <var>input</var>,
75+
and an optional <<url-pattern-param-matcher>> <var>paramMatcher</var> (default null):
76+
77+
1. Let <var>result</var> be the result of [=URL pattern/match|matching=] <var>urlPattern</var> against <var>input</var>.
78+
1. If <var>result</var> is null, return false.
79+
1. If <var>paramMatcher</var> is null, return true.
80+
1. Let <var>paramMap</var> be null.
81+
1. If <var>paramMatcher</var> is `all from ` <<url>>, then:
82+
1. Let <var>urlMatchResult</var> be the result of [=URL pattern/match|matching=] <var>urlPattern</var> against the URL represented by the <<url>> in <var>paramMatcher</var>.
83+
1. If <var>urlMatchResult</var> is null, return false.
84+
1. Set <var>paramMap</var> to <var>urlMatchResult</var>'s [=combined URL pattern result groups=].
85+
1. Otherwise, set <var>paramMap</var> to an [=ordered map=] that reflects the <<url-pattern-param>> entries in <var>paramMatcher</var>.
86+
1. Let <var>combinedResult</var> be the [=combined URL pattern result groups=] of <var>result</var>.
87+
1. [=list/iterate|For each=] (<var>groupName</var>, <var>groupValue</var>) in <var>paramMap</var>:
88+
1. If <var>combinedResult</var>[<var>groupName</var>] does not [=map/exists=] or is not <var>groupValue</var>, return false.
89+
1. Return true.
90+
91+
</div>
92+
93+
<div algorithm>
94+
To get the <dfn>combined URL pattern result groups</dfn> of a {{URLPatternResult}} <var>result</var>:
95+
96+
1. Let <var>combinedResult</var> be a new [=ordered map=].
97+
1. [=list/iterate|For each=] <var>key</var> in {{URLPatternResult/protocol}}, {{URLPatternResult/hostname}}, {{URLPatternResult/port}}, {{URLPatternResult/pathname}}, {{URLPatternResult/search}}, and {{URLPatternResult/hash}}:
98+
1. Let <var>component</var> be <var>result</var>[<var>key</var>].
99+
1. [=list/iterate|For each=] (<var>name</var>, <var>value</var>) in <var>component</var>[{{URLPatternComponentResult/groups}}]:
100+
1. [=map/set=] <var>combinedResult</var>[<var>name</var>] = <var>value</var>.
101+
1. Return <var>combinedResult</var>.
102+
103+
</div>
104+
105+
The <css>navigation-source-url</css> represents the [=current navigation URL=] given ''from''.
106+
The <css>navigation-destination-url</css> represents the [=current navigation URL=] given ''to''.
107+
The <css>navigation-current-url</css> represents the [=current navigation URL=] given ''at''.
108+
The <css>navigation-peer-url</css> represents the [=current navigation URL=] given ''with''.
109+
110+
ISSUE: bikeshed on naming these keywords.
111+
75112
<h3 id="at-route">Declaring named URL patterns: the ''@route'' rule</h3>
76113

77114
The <dfn at-rule id="at-ruledef-route">@route</dfn> rule
78115
is an at-rule that associates an author-defined name with a [=URL pattern=].
79116
This name can be referenced in ''@navigation'' rules
80-
and in '':active-navigation()'' pseudo-classes.
117+
and in '':link-to()'' pseudo-classes.
81118

82119
The syntax of the ''@route'' rule is described by the <<route-rule>> production in:
83120

84-
<pre class="prod def" nohighlight>
121+
<pre class="prod def" dfn-type="type" nohighlight>
85122
<dfn><<route-rule>></dfn> = @route <<dashed-ident>> { <<declaration-list>> }
86123
</pre>
87124

@@ -91,7 +128,7 @@ However, in valid style sheets the only descriptors must match
91128
the <<route-descriptor>> production below.
92129
Any other descriptors are ignored.
93130

94-
<pre class="prod def" nohighlight>
131+
<pre class="prod def" dfn-type="type" nohighlight>
95132
<dfn><<route-descriptor>></dfn> = <<pattern-descriptor>> |
96133
<<init-descriptor>> |
97134
<<base-descriptor>>
@@ -389,117 +426,43 @@ or <<route-location>> variants, or use the following alternative:
389426
The '':link-to()'' pseudo-class takes a single argument, a <<route-location>>,
390427
and the pseudo-class matches any element where both:
391428
* the element matches '':any-link''
392-
* the <<route-location>> [=route-location/matches=] the target of the link
393-
394-
<h3 id="active-navigation-pseudo-class">The '':active-navigation()'' pseudo-class</h3>
395-
396-
This specification defines a new
397-
<dfn id="active-navigation-pseudo" selector>'':active-navigation()''</dfn>
398-
functional pseudo-class
399-
that matches link elements that link to a certain URL
400-
that is related to a navigation that is currently active.
401-
402-
The '':active-navigation()'' pseudo-class takes a single argument, a <<active-navigation-condition>>,
403-
and the pseudo-class matches any element where:
404-
* the element matches '':any-link''
405-
* the target of the link matches the <<active-navigation-condition>>, as defined below.
406-
407-
<pre class="prod def" dfn-type="type" nohighlight>
408-
<dfn><<active-navigation-condition>></dfn> =
409-
<<navigation-relation>>? [ <<route-location>> | link-href ]?
410-
<dfn><<navigation-relation>></dfn> = at | with | from | to
411-
</pre>
412-
413-
ISSUE: Should we use ''at''/''with''/''from''/''to'' or
414-
''current''/''other''/''from''/''to''?
415-
416-
An <<active-navigation-condition>> matches the target <var>linkTarget</var> of the link when
417-
the following steps return true:
418-
1. Let <var>navigationURL</var> be
419-
the [=current navigation URL=] of the document given the <<navigation-relation>> in <<active-navigation-condition>> (default ''with'').
420-
421-
1. If <var>navigationURL</var> is null, return false.
422-
1. If ''link-href'' is present, or a <<route-location>> is not provided:
423-
1. Return true if <var>linkTarget</var> [=url/equals=] <var>navigationURL</var>; Otherwise false.
424-
425-
1. If a <<route-location>> is present:
426-
1. Let <var>targetMatchResult</var> be the result of
427-
[=URL pattern/match|matching a URL pattern=]
428-
given <var>urlPattern</var> and <var>linkTarget</var>.
429-
430-
1. Let <var>navigationMatchResult</var> be the result of
431-
[=URL pattern/match|matching a URL pattern=] given
432-
<var>urlPattern</var> and <var>navigationURL</var>.
433-
434-
1. If <var>navigationMatchResult</var> or <var>targetMatchResult</var> is null, return false.
435-
436-
1. For each property <var>prop</var> of {{URLPatternResult}} that is a
437-
{{URLPatternComponentResult}}:
438-
439-
1. If {{URLPatternComponentResult/groups}} of <var>prop</var> of
440-
<var>targetMatchResult</var> is not equal to
441-
{{URLPatternComponentResult/groups}} of <var>prop</var> of
442-
<var>navigationMatchResult</var>,
443-
then return false.
444-
445-
ISSUE: Need to formally define equality of ordered maps.
446-
447-
1. Return true.
429+
* the <<route-location>> [=route-location/matches=] the link's [^a/href^].
448430

449431
<div class="example">
450432

451-
The difference between '':link-to()'' and '':active-navigation()''
452-
is that the latter is only active while a navigation is in progress.
433+
'':link-to()'' can be used in conjunction with navigation URLs and the <css>with</css> keyword,
434+
to select links that match the current navigation using URL pattern params, without having to match the exact URL.
453435

454-
Consider this example:
436+
In the following examples, all links that link to the <code>--movie-detail</code> route,
437+
get a <code>lime</code> color when a navigation is in progress.
455438

456439
<pre highlight=css>
457-
@route --homepage {
458-
pattern: url-pattern("/");
440+
@route --movie-detail {
441+
pattern: url-pattern("/movies/:id");
459442
}
460443

461-
:link-to(--homepage) {
444+
:link-to(--movie-detail with (all from navigation-peer-url)) {
462445
color: lime;
463446
}
464-
465-
:active-navigation(--homepage) {
466-
color: hotpink;
467-
}
468447
</pre>
469448

470-
Links that link to the <code>--homepage</code> get a <code>lime</code> color.
471-
When navigating to or from the <code>--homepage</code>,
472-
their color changes to <code>hotpink</code> for as long as the animation is active.
473-
474-
Once the navigation has completed, the '':active-navigation()''
475-
selector no longer applies, and those links revert back to <code>lime</code>.
476-
477-
</div>
478-
479-
<div class="example">
480-
481-
In the following examples, all links that link to the <code>--movie-detail</code> route,
482-
get a <code>lime</code> color when a navigation is in progress.
449+
We can use specific parameters to make a URL pattern more specific, not necessarily comparing with an ongoing navigation:
483450

484451
<pre highlight=css>
485-
@route --movie-detail {
486-
pattern: url-pattern("/movies/:id");
487-
}
488-
489-
:active-navigation(--movie-detail) {
490-
color: lime;
452+
:link-to(--movie-detail with (id: 123)) {
453+
color: var(--color-for-movie-of-the-week);
491454
}
492455
</pre>
493456

494457
By adding the following selectors that use a <<navigation-relation>>,
495458
the behavior changes a bit.
496459

497460
<pre highlight=css>
498-
:active-navigation(from --movie-detail) {
461+
:link-to (--movie-detail with (all from navigation-source-url)) {
499462
color: hotpink;
500463
}
501464

502-
:active-navigation(to --movie-detail) {
465+
:link-to(--movie-detail with (all from navigation-destination-url)) {
503466
color: yellow;
504467
}
505468
</pre>
@@ -508,68 +471,68 @@ When navigating from <code>/movies/1</code> to <code>/movies/2</code>:
508471

509472
<ul>
510473
<li>
511-
Links that link to the <code>--movie-detail</code> route
512-
with any <code>:id</code>
513-
get a <code>lime</code> color
514-
during the navigation.
474+
Links that link to the <code>--movie-detail</code> route
475+
with any <code>:id</code>
476+
get a <code>lime</code> color
477+
during the navigation.
515478
</li>
516479
<li>
517-
Links that link to the <code>--movie-detail</code> route
518-
whose target is <code>/movies/1</code>
519-
<em>(the “from” page)</em>
520-
get a <code>hotpink</code> color
521-
during the navigation.
480+
Links that link to the <code>--movie-detail</code> route
481+
whose target is <code>/movies/1</code>
482+
<em>(the “from” page)</em>
483+
get a <code>hotpink</code> color
484+
during the navigation.
522485
</li>
523486
<li>
524-
Links that link to the <code>--movie-detail</code> route
525-
whose target is <code>/movies/2</code>
526-
<em>(the “to” page)</em>
527-
get a <code>yellow</code> color
528-
during the navigation.
487+
Links that link to the <code>--movie-detail</code> route
488+
whose target is <code>/movies/2</code>
489+
<em>(the “to” page)</em>
490+
get a <code>yellow</code> color
491+
during the navigation.
529492
</li>
530493
</ul>
531494

532495
When navigating from <code>/movies/2</code> to <code>/</code>:
533496

534497
<ul>
535498
<li>
536-
Links that link to the <code>--movie-detail</code> route
537-
with any <code>:id</code>
538-
get a <code>lime</code> color
539-
during the navigation.
499+
Links that link to the <code>--movie-detail</code> route
500+
with any <code>:id</code>
501+
get a <code>lime</code> color
502+
during the navigation.
540503
</li>
541504
<li>
542-
Links that link to the <code>--movie-detail</code> route
543-
whose target is <code>/movies/3</code>
544-
<em>(the “from” page)</em>
545-
get a <code>hotpink</code> color
546-
during the navigation.
505+
Links that link to the <code>--movie-detail</code> route
506+
whose target is <code>/movies/3</code>
507+
<em>(the “from” page)</em>
508+
get a <code>hotpink</code> color
509+
during the navigation.
547510
</li>
548511
</ul>
549512

550513
When navigating from <code>/</code> to <code>/movies/3</code>:
551514

552515
<ul>
553516
<li>
554-
Links that link to the <code>--movie-detail</code> route
555-
with any <code>:id</code>
556-
get a <code>lime</code> color
557-
during the navigation.
517+
Links that link to the <code>--movie-detail</code> route
518+
with any <code>:id</code>
519+
get a <code>lime</code> color
520+
during the navigation.
558521
</li>
559522
<li>
560-
Links that link to the <code>--movie-detail</code> route
561-
whose target is <code>/movies/3</code>
562-
<em>(the “to” page)</em>
563-
get a <code>yellow</code> color
564-
during the navigation.
523+
Links that link to the <code>--movie-detail</code> route
524+
whose target is <code>/movies/3</code>
525+
<em>(the “to” page)</em>
526+
get a <code>yellow</code> color
527+
during the navigation.
565528
</li>
566529
</ul>
567530

568531
</div>
569532

570533
<div class="example">
571534

572-
A an example of the '':active-navigation()'' pseudo-class
535+
A an example of the '':link-to()'' pseudo-class
573536
is this example which creates a view transition between
574537
a item in a list that contains a link (in this document)
575538
and the details page for that link (in a different document).
@@ -615,7 +578,7 @@ by matching the relevant parts of the navigation URL to the link URL.
615578
match, containing the language, can be different.)
616579
*/
617580
.movie-container:has(
618-
> .movie-title:active-navigation(with --movie-detail)) {
581+
> .movie-title:link-to(--movie-detail with (all from navigation-peer-url))) {
619582

620583
view-transition-name: movie-container;
621584

@@ -755,8 +718,8 @@ with <<navigation-condition>> defined as:
755718
<<navigation-type-test>> |
756719
<<navigation-phase-test>>
757720
758-
<dfn><<navigation-location-test>></dfn> = <<navigation-location-keyword>> : <<route-location>>
759-
<dfn><<navigation-location-keyword>></dfn> = at | with | from | to
721+
<dfn><<navigation-location-test>></dfn> = <<navigation-relation>> : <<route-location>>
722+
<dfn><<navigation-relation>></dfn> = at | with | from | to
760723
761724
<dfn><<navigation-location-between-test>></dfn> =
762725
between : <<route-location>> and <<route-location>>
@@ -865,9 +828,8 @@ This specification defines an additional function for the ''if()'' function's
865828
<dfn for="if()" function>navigation()</dfn> = navigation( <<navigation-condition>> )
866829
</pre>
867830

868-
ISSUE: This should probably have a more formal definition of the function,
869-
but I can't find the formal definitions of the existing ''if()'' functions
870-
to model it after.
831+
The ''if()/navigation()'' function is associated with the boolean result that
832+
its contained <<navigation-condition>> is associated with.
871833

872834
<h2 id="processing-model">Processing model</h2>
873835

0 commit comments

Comments
 (0)