Skip to content

Commit

Permalink
Infer a speculation rule's source from the other keys
Browse files Browse the repository at this point in the history
Fixes #169.
  • Loading branch information
jeremyroman authored Jan 11, 2024
1 parent 7d38051 commit 41cc015
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 29 deletions.
10 changes: 8 additions & 2 deletions speculation-rules.bs
Original file line number Diff line number Diff line change
Expand Up @@ -371,8 +371,14 @@ add the following step
To <dfn>parse a speculation rule</dfn> given a [=map=] |input|, a [=document=] |document|, and a [=URL=] |baseURL|, perform the following steps. They return a [=speculation rule=] or null.

1. If |input| has any [=map/key=] other than "`source`", "`urls`", "`where`", "`requires`", "`target_hint`","`referrer_policy`", "`relative_to`", "`eagerness`", and "`expects_no_vary_search`" then return null.
1. If |input|["`source`"] does not [=map/exist=] or is neither the [=string=] "`list`" nor the [=string=] "`document`", then return null.
1. Let |source| be |input|["`source`"].
1. Let |source| be null.
1. If |input|["`source`"] exists, then:
1. Set |source| to |input|["`source`"].
1. Otherwise, if |input|["`urls`"] [=map/exists=] and |input|["`where`"] does not [=map/exist=], then:
1. Set |source| to "`list`".
1. Otherwise, if |input|["`where`"] [=map/exists=] and |input|["`urls`"] does not [=map/exist=], then:
1. Set |source| to "`document`".
1. If |source| is neither the [=string=] "`list`" nor the [=string=] "`document`", then return null.
1. Let |urls| be an empty [=list=].
1. Let |predicate| be null.
1. If |source| is "`list`":
Expand Down
41 changes: 14 additions & 27 deletions triggers.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,12 +88,10 @@ The following example illustrates the basic idea:
<script type="speculationrules">
{
"prerender": [
{"source": "list",
"urls": ["/home", "/about"]}
{"urls": ["/home", "/about"]}
],
"prefetch": [
{"source": "list",
"urls": ["https://en.wikipedia.org/wiki/Hamster_racing"],
{"urls": ["https://en.wikipedia.org/wiki/Hamster_racing"],
"requires": ["anonymous-client-ip-when-cross-origin"]}
]
}
Expand All @@ -115,11 +113,13 @@ Since these are rules for optional behavior (the UA is always free not to specul

The rules are divided into a number of simple pieces that build on one another, and could be shipped largely independently, due to the conservative parsing strategy.

It was previously necessary for `"source"` to be specified explicitly for each rule; it is now possible to infer it in most cases. Some browser versions may not yet support this inference.

### List rules

Currently, the only type of rule specified is a _list_ rule, denoted by `"source": "list"`. A list rule has an express list of the _URLs_ to which the rule applies. The list can contain any URLs, even ones for which no link or other reference to the URL exists in the document. This is especially useful in cases where the expected navigation corresponds to a link that will be added dynamically, or to an anticipated script-initiated navigation.
A _list_ rule is denoted by `"source": "list"`, or implicitly by the presence of a `"urls"` key. A list rule has an express list of the _URLs_ to which the rule applies. The list can contain any URLs, even ones for which no link or other reference to the URL exists in the document. This is especially useful in cases where the expected navigation corresponds to a link that will be added dynamically, or to an anticipated script-initiated navigation.

These URLs will be parsed relative to the document base URL (if inline in a document) or relative to the external resource URL (if externally fetched).
These URLs are be parsed relative to the document base URL (if inline in a document) or relative to the external resource URL (if externally fetched).

### Requirements

Expand All @@ -129,8 +129,7 @@ Currently the only requirement that is specified is denoted by `"anonymous-clien

```json
{"prefetch": [
{"source": "list",
"urls": [
{"urls": [
"/item?id=32480009",
"https://support.signal.org/hc/en-us/articles/4850133017242",
"https://discord.com/blog/how-discord-supercharges-network-disks-for-extreme-low-latency",
Expand All @@ -152,7 +151,6 @@ To help with this, `"prerender"` rules can have a `"target_hint"` field, which c
<script type=speculationrules>
{
"prerender": [{
"source": "list",
"target_hint": "_blank",
"urls": ["page.html"]
}]
Expand All @@ -168,12 +166,10 @@ Note that if a page is truly unsure whether a given URL will be prerendered into
```json
{
"prerender": [
{"source": "list",
"target_hint": "_self",
{"target_hint": "_self",
"urls": ["page.html"]
},
{"source": "list",
"target_hint": "_blank",
{"target_hint": "_blank",
"urls": ["page.html"]
}]
}
Expand All @@ -189,8 +185,7 @@ For example:
```json
{
"prefetch": [
{"source": "list",
"urls": ["https://en.wikipedia.org/wiki/Lethe"],
{"urls": ["https://en.wikipedia.org/wiki/Lethe"],
"referrer_policy": "no-referrer"
}
]
Expand All @@ -206,7 +201,7 @@ Note that referrer policy matching is not done between the speculative request a

### Document rules

In addition to list rules, we envision _document_ rules, denoted by `"source": "document"`. These allow the user agent to find URLs for speculation from link elements in the page. They may include criteria which restrict which of these links can be used.
In addition to list rules, we envision _document_ rules, denoted by `"source": "document"` or implicitly by the presence of a `"where"` key. These allow the user agent to find URLs for speculation from link elements in the page. They may include criteria which restrict which of these links can be used.

The URL can be compared against [URL patterns][urlpattern] (parsed relative to the same base URL as URLs in list rules).

Expand Down Expand Up @@ -238,8 +233,7 @@ An example of using these would be the following, which marks up as safe-to-prer
```json
{
"prerender": [
{"source": "document",
"where": {"and": [
{"where": {"and": [
{"href_matches": "/*"},
{"not": {"href_matches": "/logout"}},
{"not": {"selector_matches": ".no-prerender"}}
Expand All @@ -262,7 +256,6 @@ For rule sets that are externally fetched, urls in list rules and url patterns i

```json
{
"source": "list",
"urls": ["/home", "/about"],
"relative_to": "document"
}
Expand All @@ -272,7 +265,6 @@ For document rules, `"relative_to"` can be paired directly with `"href_matches"`

```json
{
"source": "document",
"where": {"or": [
{"href_matches": "/home", "relative_to": "document"},
{"href_matches": "/about"}
Expand All @@ -298,17 +290,15 @@ The user agent takes this into consideration along with its own heuristics, so i
```json
{
"prefetch": [
{"source": "list",
"urls": [
{"urls": [
"https://en.wikipedia.org/wiki/Lethe",
"https://github.com/containers/krunvm"
],
"eagerness": "eager"
}
],
"prerender": [
{"source": "document",
"where": {"and": [
{"where": {"and": [
{"href_matches": "/*"},
{"not": {"href_matches": "/logout"}},
{"not": {"selector_matches": ".no-prerender"}}
Expand All @@ -327,7 +317,6 @@ We would like preloading to make use of the improved matching enabled by the [`N
<script type="speculationrules">
{
"prefetch": [{
"source": "list",
"urls": ["/products"]
}]
}
Expand All @@ -348,7 +337,6 @@ Furthermore, for prefetches triggered by the user agent's heuristics, not knowin
<script type="speculationrules">
{
"prefetch": [{
"source": "list",
"urls": ["/products"],
"eagerness": "conservative"
}]
Expand All @@ -365,7 +353,6 @@ To solve this, we have the speculation rules syntax provide a hint for what the
<script type="speculationrules">
{
"prefetch": [{
"source": "list",
"urls": ["/products"],
"expects_no_vary_search": "params=(\"id\")"
}]
Expand Down

0 comments on commit 41cc015

Please sign in to comment.