From 2b709f64473a1c78ae983762c90f989f55730412 Mon Sep 17 00:00:00 2001
From: Noam Rosenthal
Date: Sun, 31 May 2026 21:42:19 +0100
Subject: [PATCH] Refactor processing model
---
css-navigation-1/Overview.bs | 300 +++++++++++------------------------
1 file changed, 93 insertions(+), 207 deletions(-)
diff --git a/css-navigation-1/Overview.bs b/css-navigation-1/Overview.bs
index 43d831f9f4d..96ac826dcbe 100644
--- a/css-navigation-1/Overview.bs
+++ b/css-navigation-1/Overview.bs
@@ -23,6 +23,8 @@ url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-naviga
type: dfn; spec: html; text: from entry;
url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#window-navigation-api
type: dfn; spec: html; text: navigation API;
+url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-current-entry
+ type: dfn; spec: html; text: current entry; for: navigation API;
url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#ongoing-navigate-event
type: dfn; spec: html; text: ongoing navigate event;
url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#concept-navigation-transition
@@ -31,6 +33,8 @@ url: https://html.spec.whatwg.org/multipage/nav-history-apis.html#navigation-act
type: dfn; spec: html; text: activation;
url: https://html.spec.whatwg.org/multipage/browsing-the-web.html#has-been-revealed
type: dfn; spec: html; text: has been revealed;
+url: https://html.spec.whatwg.org/multipage/browsing-the-web.html#ongoing-navigation
+ type: dfn; spec: html; text: ongoing navigation;
url: https://drafts.csswg.org/css-view-transitions-1/#capture-the-image
type: dfn; spec: css-view-transitions-1; text: capture the image;
@@ -225,7 +229,7 @@ intentionally does not provide a serialization.
A <> is defined to
-match a URL input if:
+match a [=/URL=]-or-null input if input is non-null, and:
@@ -243,7 +247,7 @@ A <> is defined to
input as input.
: the <> is a <>
-:: The given URL [=url/equals=] input.
+:: The given [=/URL=] [=url/equals=] input.
@@ -389,31 +393,14 @@ as follows:
:: The result is the result of the child subexpression.
: <>
-:: : at: <>
- :: The result is true if
- the [=current at URL=] at of the document is non-null and
- the <> [=route-location/matches=] at.
-
- : with: <>
- :: The result is true if
- the [=current with URL=] other of the document is non-null and
- the <> [=route-location/matches=] other.
-
- : from: <>
- :: The result is true if
- the [=current from URL=] from of the document is non-null and
- the <> [=route-location/matches=] from.
-
- : to: <>
- :: The result is true if
- the [=current to URL=] to of the document is non-null and
- the <> [=route-location/matches=] to.
+:: The result is true if
+ the <> [=route-location/matches=] [=current navigation URL=] of the document given the <>.
: <>
:: : between: <> and <>
:: The result is true if
- the [=current from URL=] from of the document is non-null,
- the [=current to URL=] to of the document is non-null,
+ the [=current navigation URL=] from of the document given ''from'' is non-null,
+ the [=current navigation URL=] to of the document ''to'' is non-null,
one of the two <>s
[=route-location/matches=] from,
and the other of the two <>s
@@ -424,24 +411,15 @@ as follows:
:: True if the [=current navigation type=] is {{NavigationType/traverse}}.
: history: back
:: True if the [=current navigation type=] is {{NavigationType/traverse}} and
- the [=current navigation delta=] is less than 0.
+ the document's [=current navigation state=]'s [=navigation state/new index=] is less than its [=navigation state/old index=].
: history: forward
:: True if the [=current navigation type=] is {{NavigationType/traverse}} and
- the [=current navigation delta=] is greater than 0.
+ the document's [=current navigation state=]'s [=navigation state/new index=] is greater than its [=navigation state/old index=].
: history: reload
:: True if the [=current navigation type=] is {{NavigationType/reload}}.
: <>
-:: : phase: loading
- :: The navigation is not yet {{NavigationTransition/committed}}. For a cross-document navigation, this means the old page is still active.
- The ''from'' and ''at'' URLs are equal to each other, as well as the ''to'' and ''with'' URLs.
- : phase: ready
- :: The old page is still active, but the response for the new page is ready.
-
- NOTE: Only applies to cross-document navigations.
- : phase: committed
- :: The navigation is not yet {{NavigationTransition/committed}}. For a cross-document navigation, this means the new page has been activated.
- The ''to'' and ''at'' URLs are equal to each other, as well as the ''with'' and ''from'' URLs.
+:: The [=current navigation state=] is not null, and its [=navigation state/phase=] matches the given ''phase'' value.
: <>
::
@@ -451,15 +429,6 @@ as follows:
It exists only for future-compatibility,
so that new syntax additions do not invalidate too much of a <> in older user agents.
-A document's navigation API is
-the result of the following steps on document:
-
-1. Let window be the {{Window}} whose [=associated Document=] is document, or null if there is no such {{Window}}.
-
-1. If window is null, return null.
-
-1. Return window's [=navigation API=].
-
The condition of the ''@navigation'' rule
is the result of the <> in its prelude.
@@ -500,7 +469,9 @@ This specification defines a new
'':trigger-link''
that matches link elements that trigger the current navigation.
-The ''trigger-link'' pseudo-class matches an [^a^] or [^area^] element which is the {{NavigateEvent/sourceElement}} of an [=ongoing navigate event=].
+The '':trigger-link'' pseudo-class matches any element where both:
+* the element matches '':any-link''
+* the [=current navigation state=] is not null, and element is its [=navigation state/source element=].
Issue: should this apply to forms or submit buttons?
@@ -624,36 +595,25 @@ and the pseudo-class matches any element where:
<> = at | with | from | to
-NOTE: The ''link-href'' keyword is an explicit way to represent the default,
-but there is no difference between specifying it explicitly or omitting it.
-
ISSUE: Should we use ''at''/''with''/''from''/''to'' or
''current''/''other''/''from''/''to''?
-The active navigation URL for an <> is:
-
-- If the <> is ''at''
-
- The [=current at URL=] of the document
-
- If the <> is ''with'' or is omitted
-
- The [=current with URL=] of the document
-
- If the <> is ''from''
-
- The [=current from URL=] of the document
-
- If the <> is ''to''
-
- The [=current to URL=] of the document
-
-
An <> matches the target linkTarget of the link when
the following steps return true:
1. Let navigationURL be
- the [=active navigation URL=] of the <>
+ the [=current navigation URL=] of the document given the <> in <> (default ''with'').
+
1. If navigationURL is null, return false.
+1. If ''link-href'' is present, or a <> is not provided:
+ 1. Return true if linkTarget [=url/equals=] navigationURL; Otherwise false.
+
1. If a <> is present:
1. Let targetMatchResult be the result of
- [=URL pattern/match|match a URL pattern=]
+ [=URL pattern/match|matching a URL pattern=]
given urlPattern and linkTarget.
1. Let navigationMatchResult be the result of
- [=URL pattern/match|match a URL pattern=] given
+ [=URL pattern/match|matching a URL pattern=] given
urlPattern and navigationURL.
1. If navigationMatchResult or targetMatchResult is null, return false.
@@ -671,185 +631,111 @@ the following steps return true:
1. Return true.
-1. Otherwise:
-
- 1. Return true if linkTarget [=url/equals=] navigationURL.
-
- 1. Return false.
-
NOTE: Some of the design discussion for this feature has been in
w3c/csswg-drafts#13163.
-Definitions of current navigation state
-
-Both the ''@navigation'' rule and the '':link-to()'' pseudo-class
-rely on the following definitions of [=current at URL=]
-the [=current with URL=], [=current from URL=], and [=current to URL=].
-
-The current from URL of a [=/document=] is a URL or null.
-It is defined as follows:
-
-1. If the [=document's navigation API=] of the document is non-null and
- its [=transition=] is non-null,
- its [=from entry=]'s {{NavigationHistoryEntry/url}}.
-
- NOTE: This part is for when the old document in the navigation
- is still the current document.
-
-1. If the [=document's navigation API=] of the document is non-null,
- its [=activation=] is non-null,
- the activation's {{NavigationActivation/from}} is non-null, and
- the document's [=has been revealed=] is false or
- was false at the start of the current [=task=],
- the activation's {{NavigationActivation/from}}'s
- {{NavigationHistoryEntry/url}}.
-
- NOTE: This part is for when the new document in the navigation
- has become the current document.
-
-1. Otherwise, null.
-
- NOTE: The previous two branches can also produce null results.
+Processing model
-The current to URL of a [=/document=] is a URL or null.
-It is defined as follows:
+The at rules and pseudo-classes defined in this document rely on the [=current navigation state=].
-1. If the [=document's navigation API=] of the document is non-null and
- its [=ongoing navigate event=] is non-null:
+A navigation state is a [=struct=] with the following items:
- 1. if the {{pageswap}} event has fired since that navigation began,
- and its {{PageSwapEvent/activation}} was non-null,
- and that {{PageSwapEvent/activation}}'s
- {{NavigationActivation/entry}}'s
- {{NavigationHistoryEntry/url}} is non-null,
- then that
- {{NavigationHistoryEntry/url}}.
+
+ : old URL
+ : new URL
+ :: a [=/URL=]
+
+ : type
+ :: a {{NavigationType}}
+
+ : old index
+ : new index
+ :: an integer
- NOTE: This part does expose the result of redirects.
+ : phase
+ :: `loading`, `ready`, or `committed`.
- NOTE: This part is not relevant to normal page rendering.
- However, it can be relevant to what is rendered
- when [=capturing the image=]
- for a [[css-view-transitions-2#cross-document-view-transitions|cross-document view transition]].
-
- ISSUE: Is the final "non-null" check needed?
-
- 1. otherwise, the [=ongoing navigate event=]'s
- {{NavigateEvent/destination}}'s
- {{NavigationDestination/url}}
-
- NOTE: This part does not expose the result of redirects.
-
- ISSUE: This assumes that the [=ongoing navigate event=]
- and the [=transition=] have the same lifetime,
- but this isn't really
- true if the event is intercepted.
- After
- whatwg/html#11690 /
- whatwg/html#11692.
- we could probably define this more like "from" above.
- But which lifetime is the one we want?
-
- NOTE: This part is for when the old document in the navigation
- is still the current document.
-
-1. If the [=document's navigation API=] of the document is non-null and
- its [=activation=] is non-null,
- the document's [=has been revealed=] is false or
- was false at the start of the current [=task=],
- and the activation's {{NavigationActivation/entry}}'s
- {{NavigationHistoryEntry/url}}.
+ : source element
+ :: null or an {{Element}}.
+
- NOTE: This part is for when the new document in the navigation
- has become the current document.
+
+To get the current navigation state of a {{Document}} |document|:
- ISSUE: Does it make sense to expose this when
- the activation's {{NavigationActivation/from}} is null,
- and thus there is no [=current from URL=]?
+1. If |document| is not [=Document/fully active=], return null.
-1. Otherwise, null.
+1. Let |navigation| be |document|'s [=relevant global object=]'s [=navigation API=].
- NOTE: The previous two branches can also produce null results.
+1. Let |activation| be |navigation|'s {{Navigation/activation}}.
-ISSUE: The above definitions of from and to apparently don't work right
-if you start a same-document navigation (e.g., with {{History/pushState}})
-in the middle of a cross-document navigation.
+1. If |document| has not [=has been revealed|been revealed=]:
+ 1. If |activation| is null, return null.
-The current at URL of a [=/document=] is a URL or null.
-It is defined as follows:
+ 1. [=Assert=]: |activation|'s {{NavigationActivation/entry}} is not null.
-1. ISSUE: Write this! (It should be null if there is no active navigation,
- and the same as the document's [=Document/URL=] if there is.)
+ 1. Return a new [=navigation state=] whose
+ [=navigation state/old URL=] is |activation|'s {{NavigationActivation/from}}'s {{NavigationHistoryEntry/url}},
+ [=navigation state/new URL=] is |activation|'s {{NavigationActivation/entry}}'s {{NavigationHistoryEntry/url}},
+ [=navigation state/type=] is |activation|'s {{NavigationActivation/navigationType}},
+ [=navigation state/old index=] is |activation|'s {{NavigationActivation/from}}'s {{NavigationHistoryEntry/index}},
+ [=navigation state/new index=] is |activation|'s {{NavigationActivation/entry}}'s {{NavigationHistoryEntry/index}},
+ [=navigation state/phase=] is `committed`,
+ and [=navigation state/source element=] is null.
-The current with URL of a [=/document=] is a URL or null.
-It is defined as follows:
+ Note: this means that navigations that occur before the page is revealed, e.g. calling {{History/pushState()}} in the head do not reflect in CSS.
-1. ISSUE: Write this! (It should be like [=current to URL=] and [=current from URL=]
- but always referring to the other Document in the navigation.)
+1. Let |navigateEvent| be the [=ongoing navigate event=] of |navigation|.
-The current navigation type of a [=/document=] is a {{NavigationType}} or null.
-It is defined as follows:
+1. Let |phase| be `loading`.
-1. If the [=document's navigation API=] of the document is non-null and
- its [=transition=] is non-null,
- the transition's {{NavigationTransition/navigationType}}.
+1. If |navigateEvent| is null and |navigation|'s [=traversing navigate event=] is not null:
+ 1. Set |navigateEvent| to |navigation|'s [=traversing navigate event=].
- NOTE: This part is for when the old document in the navigation
- is still the current document.
+ 1. Set |phase| to `ready`.
-1. If the [=document's navigation API=] of the document is non-null and
- its [=activation=] is non-null,
- the document's [=has been revealed=] is false or
- was false at the start of the current [=task=],
- the activation's {{NavigationActivation/navigationType}}.
+1. If |navigateEvent| is null, return null.
- NOTE: This part is for when the new document in the navigation
- has become the current document.
+1. Return a new [=navigation state=] whose
+ [=navigation state/old URL=] is |document|'s [=Document/URL=],
+ [=navigation state/new URL=] is |navigateEvent|'s {{NavigateEvent/destination}}'s {{NavigationDestination/url}},
+ [=navigation state/type=] is |ongoingNavigateEvent|'s {{NavigateEvent/navigationType}},
+ [=navigation state/old index=] is |navigation|'s [=navigation API/current entry=]'s {{NavigationHistoryEntry/index}},
+ [=navigation state/new index=] is |navigateEvent|'s {{NavigateEvent/destination}}'s {{NavigationDestination/index}},
+ [=navigation state/phase=] is |phase|,
+ and [=navigation state/source element=] is |ongoingNavigateEvent|'s {{NavigateEvent/sourceElement}}.
-1. Otherwise, null.
+
-The current navigation delta of a [=/document=] is a {{NavigationType}} or null.
-It is defined as follows:
+To get the current navigation URL given a {{Document}} |document| and a <> |relation|:
-1. If the [=document's navigation API=] of the document is non-null and
- its [=transition=] is non-null,
+1. Let |state| be |document|'s [=current navigation state=].
+1. If |state| is null, return null.
+1. Return the result of switching on |relation|:
- 1. If the transition's {{NavigationTransition/navigationType}} is not {{NavigationType/traverse}}, null.
+
+: ''to''
+:: |state|'s [=navigation state/new URL=].
- 1. Otherwise,
- the transition's {{NavigationTransition/to}}'s {{NavigationDestination/index}}
- minus
- the transition's {{NavigationTransition/from}}'s {{NavigationHistoryEntry/index}}.
+: ''from''
+:: |state|'s [=navigation state/old URL=].
- NOTE: This part is for when the old document in the navigation
- is still the current document.
+: ''at''
+:: |state|'s [=navigation state/new URL=] if |state|'s [=navigation state/phase=] is `committed`; Otherwise |state|'s [=navigation state/old URL=].
-1. If the [=document's navigation API=] of the document is non-null,
- its [=activation=] is non-null,
- the activation's {{NavigationActivation/from}} is non-null, and
- the document's [=has been revealed=] is false or
- was false at the start of the current [=task=],
+: ''with''
+:: |state|'s [=navigation state/old URL=] if |state|'s [=navigation state/phase=] is `committed`; Otherwise |state|'s [=navigation state/new URL=].
- 1. If the activation's {{NavigationActivation/navigationType}} is not {{NavigationType/traverse}}, null.
+
- 1. Otherwise,
- the activation's {{NavigationActivation/entry}}'s {{NavigationHistoryEntry/index}}
- minus
- the activation's {{NavigationActivation/from}}'s {{NavigationHistoryEntry/index}}.
+To get the current navigation type of a [=/document=] |document|:
+ 1. If |document|'s [=current navigation state=] is non-null, return its [=navigation state/type=].
+ 1. Return null.
- NOTE: This part is for when the new document in the navigation
- has become the current document.
+The traversing navigate event is the [=ongoing navigate event=] which was reset when the [=ongoing navigation=] is set to `traversal`.
-1. Otherwise, null.
-ISSUE: Generally improve integration with the HTML spec for these definitions,
-instead of monkeypatching.
-This includes the interaction with [=has been revealed=]
-and the interaction with the {{pageswap}} event,
-and other things where this section links to non-exported definitions.
-ISSUE: Generally figure out if these definitions should care about
-the [=ongoing navigate event=] or the [=transition=].
+ISSUE: Improve integration with the HTML standard, especially the concept of [=traversing navigate event=] and unexported definitions.
Privacy Considerations