Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 103 additions & 141 deletions css-navigation-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -45,43 +45,80 @@ url: https://drafts.csswg.org/css-view-transitions-1/#capture-the-image
<h3 id="route-value-type">The <<route-location>> value type</h3>

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

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

<dl class=switch>

: the <<route-location>> is a <<route-name>>
:: [=URL pattern/match|match a URL pattern=] is non-null given
<var>urlPattern</var> as
the [=URL pattern=] represented by the ''@route'' rule referenced by the name and
<var>input</var> as <var>input</var>.
:: 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).

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

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

</dl>

<div algorithm>
To <dfn>match URL pattern with params</dfn>
given a [=URL pattern=] <var>urlPattern</var>,
a [=/URL=] <var>input</var>,
and an optional <<url-pattern-param-matcher>> <var>paramMatcher</var> (default null):

1. Let <var>result</var> be the result of [=URL pattern/match|matching=] <var>urlPattern</var> against <var>input</var>.
1. If <var>result</var> is null, return false.
1. If <var>paramMatcher</var> is null, return true.
1. Let <var>paramMap</var> be null.
1. If <var>paramMatcher</var> is `all from ` <<url>>, then:
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>.
1. If <var>urlMatchResult</var> is null, return false.
1. Set <var>paramMap</var> to <var>urlMatchResult</var>'s [=combined URL pattern result groups=].
1. Otherwise, set <var>paramMap</var> to an [=ordered map=] that reflects the <<url-pattern-param>> entries in <var>paramMatcher</var>.
1. Let <var>combinedResult</var> be the [=combined URL pattern result groups=] of <var>result</var>.
1. [=list/iterate|For each=] (<var>groupName</var>, <var>groupValue</var>) in <var>paramMap</var>:
1. If <var>combinedResult</var>[<var>groupName</var>] does not [=map/exists=] or is not <var>groupValue</var>, return false.
1. Return true.

</div>

<div algorithm>
To get the <dfn>combined URL pattern result groups</dfn> of a {{URLPatternResult}} <var>result</var>:

1. Let <var>combinedResult</var> be a new [=ordered map=].
1. [=list/iterate|For each=] <var>key</var> in {{URLPatternResult/protocol}}, {{URLPatternResult/hostname}}, {{URLPatternResult/port}}, {{URLPatternResult/pathname}}, {{URLPatternResult/search}}, and {{URLPatternResult/hash}}:
1. Let <var>component</var> be <var>result</var>[<var>key</var>].
1. [=list/iterate|For each=] (<var>name</var>, <var>value</var>) in <var>component</var>[{{URLPatternComponentResult/groups}}]:
1. [=map/set=] <var>combinedResult</var>[<var>name</var>] = <var>value</var>.
1. Return <var>combinedResult</var>.

</div>

The <css>navigation-source-url</css> represents the [=current navigation URL=] given ''from''.
The <css>navigation-destination-url</css> represents the [=current navigation URL=] given ''to''.
The <css>navigation-current-url</css> represents the [=current navigation URL=] given ''at''.
The <css>navigation-peer-url</css> represents the [=current navigation URL=] given ''with''.
Comment thread
noamr marked this conversation as resolved.

ISSUE: bikeshed on naming these keywords.

<h3 id="at-route">Declaring named URL patterns: the ''@route'' rule</h3>

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

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

<pre class="prod def" nohighlight>
<pre class="prod def" dfn-type="type" nohighlight>
<dfn><<route-rule>></dfn> = @route <<dashed-ident>> { <<declaration-list>> }
</pre>

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

<pre class="prod def" nohighlight>
<pre class="prod def" dfn-type="type" nohighlight>
<dfn><<route-descriptor>></dfn> = <<pattern-descriptor>> |
<<init-descriptor>> |
<<base-descriptor>>
Expand Down Expand Up @@ -389,117 +426,43 @@ or <<route-location>> variants, or use the following alternative:
The '':link-to()'' pseudo-class takes a single argument, a <<route-location>>,
and the pseudo-class matches any element where both:
* the element matches '':any-link''
* the <<route-location>> [=route-location/matches=] the target of the link

<h3 id="active-navigation-pseudo-class">The '':active-navigation()'' pseudo-class</h3>

This specification defines a new
<dfn id="active-navigation-pseudo" selector>'':active-navigation()''</dfn>
functional pseudo-class
that matches link elements that link to a certain URL
that is related to a navigation that is currently active.

The '':active-navigation()'' pseudo-class takes a single argument, a <<active-navigation-condition>>,
and the pseudo-class matches any element where:
* the element matches '':any-link''
* the target of the link matches the <<active-navigation-condition>>, as defined below.

<pre class="prod def" dfn-type="type" nohighlight>
<dfn><<active-navigation-condition>></dfn> =
<<navigation-relation>>? [ <<route-location>> | link-href ]?
<dfn><<navigation-relation>></dfn> = at | with | from | to
</pre>

ISSUE: Should we use ''at''/''with''/''from''/''to'' or
''current''/''other''/''from''/''to''?

An <<active-navigation-condition>> matches the target <var>linkTarget</var> of the link when
the following steps return true:
1. Let <var>navigationURL</var> be
the [=current navigation URL=] of the document given the <<navigation-relation>> in <<active-navigation-condition>> (default ''with'').

1. If <var>navigationURL</var> is null, return false.
1. If ''link-href'' is present, or a <<route-location>> is not provided:
1. Return true if <var>linkTarget</var> [=url/equals=] <var>navigationURL</var>; Otherwise false.

1. If a <<route-location>> is present:
1. Let <var>targetMatchResult</var> be the result of
[=URL pattern/match|matching a URL pattern=]
given <var>urlPattern</var> and <var>linkTarget</var>.

1. Let <var>navigationMatchResult</var> be the result of
[=URL pattern/match|matching a URL pattern=] given
<var>urlPattern</var> and <var>navigationURL</var>.

1. If <var>navigationMatchResult</var> or <var>targetMatchResult</var> is null, return false.

1. For each property <var>prop</var> of {{URLPatternResult}} that is a
{{URLPatternComponentResult}}:

1. If {{URLPatternComponentResult/groups}} of <var>prop</var> of
<var>targetMatchResult</var> is not equal to
{{URLPatternComponentResult/groups}} of <var>prop</var> of
<var>navigationMatchResult</var>,
then return false.

ISSUE: Need to formally define equality of ordered maps.

1. Return true.
* the <<route-location>> [=route-location/matches=] the link's [^a/href^].

<div class="example">

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

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

<pre highlight=css>
@route --homepage {
pattern: url-pattern("/");
@route --movie-detail {
pattern: url-pattern("/movies/:id");
}

:link-to(--homepage) {
:link-to(--movie-detail with (all from navigation-peer-url)) {
color: lime;
}

:active-navigation(--homepage) {
color: hotpink;
}
</pre>

Links that link to the <code>--homepage</code> get a <code>lime</code> color.
When navigating to or from the <code>--homepage</code>,
their color changes to <code>hotpink</code> for as long as the animation is active.

Once the navigation has completed, the '':active-navigation()''
selector no longer applies, and those links revert back to <code>lime</code>.

</div>

<div class="example">

In the following examples, all links that link to the <code>--movie-detail</code> route,
get a <code>lime</code> color when a navigation is in progress.
We can use specific parameters to make a URL pattern more specific, not necessarily comparing with an ongoing navigation:

<pre highlight=css>
@route --movie-detail {
pattern: url-pattern("/movies/:id");
}

:active-navigation(--movie-detail) {
color: lime;
:link-to(--movie-detail with (id: 123)) {
color: var(--color-for-movie-of-the-week);
}
</pre>

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

<pre highlight=css>
:active-navigation(from --movie-detail) {
:link-to (--movie-detail with (all from navigation-source-url)) {
color: hotpink;
}

:active-navigation(to --movie-detail) {
:link-to(--movie-detail with (all from navigation-destination-url)) {
Comment thread
noamr marked this conversation as resolved.
color: yellow;
}
</pre>
Expand All @@ -508,68 +471,68 @@ When navigating from <code>/movies/1</code> to <code>/movies/2</code>:

<ul>
<li>
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
</li>
<li>
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/1</code>
<em>(the “from” page)</em>
get a <code>hotpink</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/1</code>
<em>(the “from” page)</em>
get a <code>hotpink</code> color
during the navigation.
</li>
<li>
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/2</code>
<em>(the “to” page)</em>
get a <code>yellow</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/2</code>
<em>(the “to” page)</em>
get a <code>yellow</code> color
during the navigation.
</li>
</ul>

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

<ul>
<li>
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
</li>
<li>
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/3</code>
<em>(the “from” page)</em>
get a <code>hotpink</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/3</code>
<em>(the “from” page)</em>
get a <code>hotpink</code> color
during the navigation.
</li>
</ul>

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

<ul>
<li>
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
with any <code>:id</code>
get a <code>lime</code> color
during the navigation.
</li>
<li>
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/3</code>
<em>(the “to” page)</em>
get a <code>yellow</code> color
during the navigation.
Links that link to the <code>--movie-detail</code> route
whose target is <code>/movies/3</code>
<em>(the “to” page)</em>
get a <code>yellow</code> color
during the navigation.
</li>
</ul>

</div>

<div class="example">

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

view-transition-name: movie-container;

Expand Down Expand Up @@ -755,8 +718,8 @@ with <<navigation-condition>> defined as:
<<navigation-type-test>> |
<<navigation-phase-test>>

<dfn><<navigation-location-test>></dfn> = <<navigation-location-keyword>> : <<route-location>>
<dfn><<navigation-location-keyword>></dfn> = at | with | from | to
<dfn><<navigation-location-test>></dfn> = <<navigation-relation>> : <<route-location>>
<dfn><<navigation-relation>></dfn> = at | with | from | to

<dfn><<navigation-location-between-test>></dfn> =
between : <<route-location>> and <<route-location>>
Expand Down Expand Up @@ -865,9 +828,8 @@ This specification defines an additional function for the ''if()'' function's
<dfn for="if()" function>navigation()</dfn> = navigation( <<navigation-condition>> )
</pre>

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

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

Expand Down