Speculation
Rules
Draft
Community
Group
Report
,
1
September
2025
This
version:
https://wicg.github.io/nav-speculation/speculation-rules.html
Issue
Tracking:
GitHub
Editors:
Jeremy
Roman
(
Google
)
Domenic
Denicola
(
Google
)
Copyright
©
2025
the
Contributors
to
the
Speculation
Rules
Specification,
published
by
the
Web
Platform
Incubator
Community
Group
under
the
W3C
Community
Contributor
License
Agreement
(CLA)
.
A
human-readable
summary
is
available.
Abstract
Extensions
to
speculation
rules
to
support
navigational
prerendering.
Status
of
this
document
This
specification
was
published
by
the
Web
Platform
Incubator
Community
Group
.
It
is
not
a
W3C
Standard
nor
is
it
on
the
W3C
Standards
Track.
Please
note
that
under
the
W3C
Community
Contributor
License
Agreement
(CLA)
there
is
a
limited
opt-out
and
other
conditions
apply.
Learn
more
about
W3C
Community
and
Business
Groups
.
Table
of
Contents
1
This
specification
is
moving
to
HTML
2
Parsing
3
Processing
model
4
Triggering
Index
Terms
defined
by
this
specification
Terms
defined
by
reference
References
Normative
References
1.
This
specification
is
moving
to
HTML
The
majority
of
this
specification
is
being
upstreamed
to
the
HTML
Standard:
see
whatwg/html#11426
and
whatwg/html#11123
.
The
rendered
specification
text
can
currently
be
found
at
this
PR
preview
.
What
remains
in
this
document
are
some
additional
patches
to
support
prerendering,
which
the
upstreamed
version
does
not
yet
cover.
Once
prefetch
is
also
upstreamed,
what
remains
in
this
document
will
likely
migrate
to
[PRERENDERING-REVAMPED]
.
2.
Parsing
Extend
the
speculation
rule
set
struct
with
one
additional
item
:
prerender
rules
,
a
list
of
speculation
rules
,
initially
empty
Extend
the
speculation
rule
struct
with
one
additional
item
:
target
navigable
name
hint
,
a
string
or
null
Modify
parse
a
speculation
rule
set
string
as
follows:
Remove
the
typesToTreatAsPrefetch
construct,
and
instead
parse
parsed
["
prerender
"]
into
the
prerender
rules
list,
in
an
identical
manner
to
what
is
done
for
parsed
["
prefetch
"]
and
the
prefetch
rules
.
Discard
rules
parsed
from
parsed
["
prefetch
"]
if
the
target
navigable
name
hint
is
not
null.
Discard
rules
parsed
from
parsed
["
prerender
"]
if
the
requirements
contain
"
anonymous-client-ip-when-cross-origin
".
Implementations
will
still
be
allowed
to
treat
prerender
candidates
as
prefetches,
per
the
modifications
in
§ 3
Processing
model
.
Modify
parse
a
speculation
rule
by
adding
the
following
steps:
Let
targetHint
be
null.
If
input
["
target_hint
"]
exists
:
If
input
["
target_hint
"]
is
not
a
valid
navigable
target
name
or
keyword
:
The
user
agent
may
report
a
warning
to
the
console
indicating
that
the
supplied
target
hint
was
invalid.
Return
null.
Set
targetHint
to
input
["
target_hint
"].
and
then
updating
the
final
step
which
returns
a
speculation
rule
to
include
setting
the
target
navigable
name
hint
to
targetHint
.
3.
Processing
model
A
prerender
candidate
is
a
speculative
load
candidate
with
the
following
additional
item
:
target
navigable
name
hint
,
a
valid
navigable
target
name
or
keyword
or
null
Update
the
inner
consider
speculative
loads
steps
algorithm
by
appending
the
following
steps
near
the
beginning,
after
assembling
prefetchCandidates
:
Let
prerenderCandidates
be
an
empty
list
.
For
each
ruleSet
of
document
’s
speculation
rule
sets
:
For
each
rule
of
ruleSet
’s
prerender
rules
:
For
each
url
of
rule
’s
URLs
:
Let
referrerPolicy
be
the
result
of
computing
a
speculative
load
referrer
policy
given
rule
and
null.
Append
a
new
prerender
candidate
with
URL
url
No-Vary-Search
hint
rule
’s
No-Vary-Search
hint
eagerness
rule
’s
eagerness
referrer
policy
referrerPolicy
tags
rule
’s
tags
target
navigable
name
hint
rule
’s
target
navigable
name
hint
to
prerenderCandidates
.
If
rule
’s
predicate
is
not
null,
then:
Let
links
be
the
result
of
finding
matching
links
given
document
and
rule
’s
predicate
.
For
each
link
of
links
:
Let
target
be
rule
’s
target
navigable
name
hint
.
If
target
is
null,
set
it
to
the
result
of
getting
an
element’s
target
given
link
.
Let
referrerPolicy
be
the
result
of
computing
a
speculative
load
referrer
policy
given
rule
and
link
.
Append
a
prerender
candidate
with
URL
link
’s
url
No-Vary-Search
hint
rule
’s
No-Vary-Search
hint
eagerness
rule
’s
eagerness
referrer
policy
referrerPolicy
tags
rule
’s
tags
target
navigable
name
hint
target
to
prerenderCandidates
.
Let
speculativeLoadCandidates
be
the
union
of
prefetchCandidates
and
prerenderCandidates
.
Update
subsequent
steps
for
canceling
not-still-being-speculated
prefetch
records
to
operate
on
speculativeLoadCandidates
instead
of
prefetchCandidates
.
Create
a
list
prerenderCandidateGroups
in
an
analogous
way
to
prefetchCandidateGroups
,
but
using
prerenderCandidates
instead
of
prefetchCandidates
.
Replace
the
step
which
performs
the
actual
prefetching
by
looping
over
prefetchCandidateGroups
with
the
following:
Let
speculativeLoadCandidateGroups
be
the
union
of
prefetchCandidateGroups
and
prerenderCandidateGroups
.
For
each
group
of
speculativeLoadCandidateGroups
:
The
user
agent
may
run
the
following
steps:
Let
candidate
be
group
[0].
Let
tagsToSend
be
the
result
of
collecting
tags
from
speculative
load
candidates
given
group
.
Let
prefetchRecord
be
a
new
prefetch
record
with
source
"
speculation
rules
"
URL
candidate
’s
URL
No-Vary-Search
hint
candidate
’s
No-Vary-Search
hint
referrer
policy
candidate
’s
referrer
policy
tags
tagsToSend
If
candidate
is
a
prefetch
candidate
,
then
set
prefetchRecord
’s
anonymization
policy
to
candidate
’s
anonymization
policy
.
If
candidate
is
a
prerender
candidate
,
then
the
user
agent
may
run
the
following
steps:
Set
prefetchRecord
’s
prerendering
traversable
to
"
to
be
created
".
Set
prefetchRecord
’s
prerendering
target
navigable
name
hint
to
candidate
’s
target
navigable
name
hint
.
Start
a
referrer-initiated
navigational
prerender
given
document
and
prefetchRecord
.
If
the
user
agent
did
not
run
the
previous
step,
then
start
a
referrer-initiated
navigational
prefetch
given
document
and
prefetchRecord
.
(And
keep
the
subsequent
discussion
of
when
to
execute
this
"may"
step.)
4.
Triggering
Update
the
attribute
change
steps
for
a
and
area
elements
to
also
monitor
the
target
attribute
and
consider
speculative
loads
if
it
changes.
Index
Terms
defined
by
this
specification
prerender
candidate
,
in
§ 3
prerender
rules
,
in
§ 2
target
navigable
name
hint
dfn
for
prerender
candidate
,
in
§ 3
dfn
for
speculation
rule
,
in
§ 2
Terms
defined
by
reference
[CONSOLE]
defines
the
following
terms:
report
a
warning
to
the
console
[DOM]
defines
the
following
terms:
attribute
change
steps
[HTML]
defines
the
following
terms:
a
anonymization
policy
area
collecting
tags
from
speculative
load
candidates
compute
a
speculative
load
referrer
policy
consider
speculative
loads
eagerness
(for
speculation
rule)
eagerness
(for
speculative
load
candidate)
finding
matching
links
get
an
element's
target
inner
consider
speculative
loads
steps
No-Vary-Search
hint
(for
speculation
rule)
No-Vary-Search
hint
(for
speculative
load
candidate)
parse
a
speculation
rule
parse
a
speculation
rule
set
string
predicate
prefetch
candidate
prefetch
rules
referrer
policy
requirements
speculation
rule
speculation
rule
set
speculation
rule
sets
speculative
load
candidate
tags
(for
speculation
rule)
tags
(for
speculative
load
candidate)
target
url
(for
HTMLHyperlinkElementUtils)
URL
(for
speculative
load
candidate)
URLs
valid
navigable
target
name
or
keyword
[INFRA]
defines
the
following
terms:
append
exist
for
each
item
list
string
struct
[PREFETCH]
defines
the
following
terms:
anonymization
policy
No-Vary-Search
hint
prefetch
record
prerendering
target
navigable
name
hint
prerendering
traversable
referrer
policy
source
start
a
referrer-initiated
navigational
prefetch
tags
URL
[PRERENDERING-REVAMPED]
defines
the
following
terms:
start
a
referrer-initiated
navigational
prerender
References
Normative
References
[CONSOLE]
Dominic
Farolino;
Robert
Kowalski;
Terin
Stock.
Console
Standard
.
Living
Standard.
URL:
https://console.spec.whatwg.org/
[DOM]
Anne
van
Kesteren.
DOM
Standard
.
Living
Standard.
URL:
https://dom.spec.whatwg.org/
[HTML]
Anne
van
Kesteren;
et
al.
HTML
Standard
.
Living
Standard.
URL:
https://html.spec.whatwg.org/multipage/
[INFRA]
Anne
van
Kesteren;
Domenic
Denicola.
Infra
Standard
.
Living
Standard.
URL:
https://infra.spec.whatwg.org/
[PREFETCH]
Prefetch
.
Draft
Community
Group
Report.
URL:
https://wicg.github.io/nav-speculation/prefetch.html
[PRERENDERING-REVAMPED]
Prerendering
Revamped
.
Draft
Community
Group
Report.
URL:
https://wicg.github.io/nav-speculation/prerendering.html
/*
Boilerplate:
script-dom-helper
*/
"use
strict";
function
query(sel)
{
return
document.querySelector(sel);
}
function
queryAll(sel)
{
return
[...document.querySelectorAll(sel)];
}
function
iter(obj)
{
if(!obj)
return
[];
var
it
=
obj[Symbol.iterator];
if(it)
return
it;
return
Object.entries(obj);
}
function
mk(tagname,
attrs,
...children)
{
const
el
=
document.createElement(tagname);
for(const
[k,v]
of
iter(attrs))
{
if(k.slice(0,3)
==
"_on")
{
const
eventName
=
k.slice(3);
el.addEventListener(eventName,
v);
}
else
if(k[0]
==
"_")
{
//
property,
not
attribute
el[k.slice(1)]
=
v;
}
else
{
if(v
===
false
||
v
==
null)
{
continue;
}
else
if(v
===
true)
{
el.setAttribute(k,
"");
continue;
}
else
{
el.setAttribute(k,
v);
}
}
}
append(el,
children);
return
el;
}
/*
Create
shortcuts
for
every
known
HTML
element
*/
[
"a",
"abbr",
"acronym",
"address",
"applet",
"area",
"article",
"aside",
"audio",
"b",
"base",
"basefont",
"bdo",
"big",
"blockquote",
"body",
"br",
"button",
"canvas",
"caption",
"center",
"cite",
"code",
"col",
"colgroup",
"datalist",
"dd",
"del",
"details",
"dfn",
"dialog",
"div",
"dl",
"dt",
"em",
"embed",
"fieldset",
"figcaption",
"figure",
"font",
"footer",
"form",
"frame",
"frameset",
"head",
"header",
"h1",
"h2",
"h3",
"h4",
"h5",
"h6",
"hr",
"html",
"i",
"iframe",
"img",
"input",
"ins",
"kbd",
"label",
"legend",
"li",
"link",
"main",
"map",
"mark",
"meta",
"meter",
"nav",
"nobr",
"noscript",
"object",
"ol",
"optgroup",
"option",
"output",
"p",
"param",
"pre",
"progress",
"q",
"s",
"samp",
"script",
"section",
"select",
"small",
"source",
"span",
"strike",
"strong",
"style",
"sub",
"summary",
"sup",
"table",
"tbody",
"td",
"template",
"textarea",
"tfoot",
"th",
"thead",
"time",
"title",
"tr",
"u",
"ul",
"var",
"video",
"wbr",
"xmp",
].forEach(tagname=>
{
mk[tagname]
=
(...args)
=>
mk(tagname,
...args);
});
function*
nodesFromChildList(children)
{
for(const
child
of
children.flat(Infinity))
{
if(child
instanceof
Node)
{
yield
child;
}
else
{
yield
new
Text(child);
}
}
}
function
append(el,
...children)
{
for(const
child
of
nodesFromChildList(children))
{
if(el
instanceof
Node)
el.appendChild(child);
else
el.push(child);
}
return
el;
}
function
insertAfter(el,
...children)
{
for(const
child
of
nodesFromChildList(children))
{
el.parentNode.insertBefore(child,
el.nextSibling);
}
return
el;
}
function
clearContents(el)
{
el.innerHTML
=
"";
return
el;
}
function
parseHTML(markup)
{
if(markup.toLowerCase().trim().indexOf('
<!doctype') === 0) { const doc = document.implementation.createHTMLDocument(""); doc.documentElement.innerHTML = markup; return doc; } else { const el = mk.template({}); el.innerHTML = markup; return el.content; } }
/* Boilerplate: script-dfn-panel */ "use strict"; { let dfnPanelData = { "00064bc4": {"dfnID":"00064bc4","dfnText":"get an element's target","external":true,"refSections":[{"refs":[{"id":"ref-for-get-an-element's-target"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/semantics.html#get-an-element's-target"}, "043ab775": {"dfnID":"043ab775","dfnText":"predicate","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-predicate"},{"id":"ref-for-sr-predicate\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-predicate"}, "05390e01": {"dfnID":"05390e01","dfnText":"start a referrer-initiated navigational prefetch","external":true,"refSections":[{"refs":[{"id":"ref-for-start-a-referrer-initiated-navigational-prefetch"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch"}, "0698d556": {"dfnID":"0698d556","dfnText":"string","external":true,"refSections":[{"refs":[{"id":"ref-for-string"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#string"}, "1243a891": {"dfnID":"1243a891","dfnText":"exist","external":true,"refSections":[{"refs":[{"id":"ref-for-map-exists"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#map-exists"}, "16808e53": {"dfnID":"16808e53","dfnText":"parse a speculation rule set string","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set"},{"id":"ref-for-speculation-rule-set\u2460"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "16d07e10": {"dfnID":"16d07e10","dfnText":"for each","external":true,"refSections":[{"refs":[{"id":"ref-for-list-iterate"},{"id":"ref-for-list-iterate\u2460"},{"id":"ref-for-list-iterate\u2461"},{"id":"ref-for-list-iterate\u2462"},{"id":"ref-for-list-iterate\u2463"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list-iterate"}, "3637d409": {"dfnID":"3637d409","dfnText":"eagerness (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-eagerness"},{"id":"ref-for-sr-eagerness\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness"}, "36706746": {"dfnID":"36706746","dfnText":"valid navigable target name or keyword","external":true,"refSections":[{"refs":[{"id":"ref-for-valid-navigable-target-name-or-keyword"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-valid-navigable-target-name-or-keyword\u2460"}],"title":"3. Processing model"}],"url":"https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword"}, "37e32f12": {"dfnID":"37e32f12","dfnText":"report a warning to the console","external":true,"refSections":[{"refs":[{"id":"ref-for-report-a-warning-to-the-console"}],"title":"2. Parsing"}],"url":"https://console.spec.whatwg.org/#report-a-warning-to-the-console"}, "44ae7369": {"dfnID":"44ae7369","dfnText":"No-Vary-Search hint (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-nvs-hint"},{"id":"ref-for-sl-candidate-nvs-hint\u2460"},{"id":"ref-for-sl-candidate-nvs-hint\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint"}, "482fd8d4": {"dfnID":"482fd8d4","dfnText":"No-Vary-Search hint (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-nvs-hint"},{"id":"ref-for-sr-nvs-hint\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint"}, "4ce800e8": {"dfnID":"4ce800e8","dfnText":"No-Vary-Search hint","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-no-vary-search-hint"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint"}, "4d80a6e7": {"dfnID":"4d80a6e7","dfnText":"referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-referrer-policy"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy"}, "5303d536": {"dfnID":"5303d536","dfnText":"tags (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-tags"},{"id":"ref-for-sl-candidate-tags\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags"}, "53275e46": {"dfnID":"53275e46","dfnText":"append","external":true,"refSections":[{"refs":[{"id":"ref-for-list-append"},{"id":"ref-for-list-append\u2460"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list-append"}, "5a57d186": {"dfnID":"5a57d186","dfnText":"anonymization policy","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-anonymization-policy"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy"}, "5bc14177": {"dfnID":"5bc14177","dfnText":"URL","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-url"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url"}, "631182ca": {"dfnID":"631182ca","dfnText":"inner consider speculative loads steps","external":true,"refSections":[{"refs":[{"id":"ref-for-inner-consider-speculative-loads-steps"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps"}, "6393b8ef": {"dfnID":"6393b8ef","dfnText":"prefetch rules","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-set-prefetch"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch"}, "649608b9": {"dfnID":"649608b9","dfnText":"list","external":true,"refSections":[{"refs":[{"id":"ref-for-list"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-list\u2460"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#list"}, "68bf3d31": {"dfnID":"68bf3d31","dfnText":"a","external":true,"refSections":[{"refs":[{"id":"ref-for-the-a-element"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element"}, "6da138da": {"dfnID":"6da138da","dfnText":"source","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-source"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source"}, "6ff9cf24": {"dfnID":"6ff9cf24","dfnText":"parse a speculation rule","external":true,"refSections":[{"refs":[{"id":"ref-for-parse-a-speculation-rule"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule"}, "7684ffde": {"dfnID":"7684ffde","dfnText":"speculation rule","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule"},{"id":"ref-for-speculation-rule\u2460"},{"id":"ref-for-speculation-rule\u2461"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule"}, "769b0f6e": {"dfnID":"769b0f6e","dfnText":"collecting tags from speculative load candidates","external":true,"refSections":[{"refs":[{"id":"ref-for-collect-tags-from-speculative-load-candidates"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates"}, "86e3118f": {"dfnID":"86e3118f","dfnText":"tags","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-tags"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags"}, "87c3c6f6": {"dfnID":"87c3c6f6","dfnText":"anonymization policy","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-anonymization-policy"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy"}, "91dda5f9": {"dfnID":"91dda5f9","dfnText":"prerendering traversable","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-prerendering-traversable"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable"}, "980dda1d": {"dfnID":"980dda1d","dfnText":"speculation rule set","external":true,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set"},{"id":"ref-for-speculation-rule-set\u2460"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"}, "984221ca": {"dfnID":"984221ca","dfnText":"struct","external":true,"refSections":[{"refs":[{"id":"ref-for-struct"},{"id":"ref-for-struct\u2460"}],"title":"2. Parsing"}],"url":"https://infra.spec.whatwg.org/#struct"}, "99c55261": {"dfnID":"99c55261","dfnText":"prefetch record","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record"},{"id":"ref-for-prefetch-record\u2460"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record"}, "9a8e15f0": {"dfnID":"9a8e15f0","dfnText":"target","external":true,"refSections":[{"refs":[{"id":"ref-for-attr-hyperlink-target"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target"}, "9fe18dd3": {"dfnID":"9fe18dd3","dfnText":"start a referrer-initiated navigational prerender","external":true,"refSections":[{"refs":[{"id":"ref-for-start-a-referrer-initiated-navigational-prerender"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender"}, "a16866c7": {"dfnID":"a16866c7","dfnText":"eagerness (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-eagerness"},{"id":"ref-for-sl-candidate-eagerness\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness"}, "a1a807e5": {"dfnID":"a1a807e5","dfnText":"area","external":true,"refSections":[{"refs":[{"id":"ref-for-the-area-element"}],"title":"4. Triggering"}],"url":"https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element"}, "a20ea266": {"dfnID":"a20ea266","dfnText":"URLs","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-urls"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-urls"}, "a47f7739": {"dfnID":"a47f7739","dfnText":"prerendering target navigable name hint","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-record-prerendering-target-navigable-name-hint"}],"title":"3. Processing model"}],"url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint"}, "a4d78a5c": {"dfnID":"a4d78a5c","dfnText":"speculation rule sets","external":true,"refSections":[{"refs":[{"id":"ref-for-document-sr-sets"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets"}, "b141168a": {"dfnID":"b141168a","dfnText":"URL (for speculative load candidate)","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-url"},{"id":"ref-for-sl-candidate-url\u2460"},{"id":"ref-for-sl-candidate-url\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url"}, "c6371648": {"dfnID":"c6371648","dfnText":"finding matching links","external":true,"refSections":[{"refs":[{"id":"ref-for-finding-matching-links"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links"}, "c666e05d": {"dfnID":"c666e05d","dfnText":"speculative load candidate","external":true,"refSections":[{"refs":[{"id":"ref-for-speculative-load-candidate"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate"}, "c7c0dde1": {"dfnID":"c7c0dde1","dfnText":"url (for HTMLHyperlinkElementUtils)","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-hyperlink-url"}],"title":"3. Processing model"}],"url":"https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url"}, "c88f3887": {"dfnID":"c88f3887","dfnText":"item","external":true,"refSections":[{"refs":[{"id":"ref-for-struct-item"},{"id":"ref-for-struct-item\u2460"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-struct-item\u2461"}],"title":"3. Processing model"}],"url":"https://infra.spec.whatwg.org/#struct-item"}, "c8c44926": {"dfnID":"c8c44926","dfnText":"prefetch candidate","external":true,"refSections":[{"refs":[{"id":"ref-for-prefetch-candidate"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate"}, "d1a6c008": {"dfnID":"d1a6c008","dfnText":"attribute change steps","external":true,"refSections":[{"refs":[{"id":"ref-for-concept-element-attributes-change-ext"}],"title":"4. Triggering"}],"url":"https://dom.spec.whatwg.org/#concept-element-attributes-change-ext"}, "e014bb81": {"dfnID":"e014bb81","dfnText":"consider speculative loads","external":true,"refSections":[{"refs":[{"id":"ref-for-consider-speculative-loads"}],"title":"4. Triggering"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads"}, "e535a7f6": {"dfnID":"e535a7f6","dfnText":"compute a speculative load referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-compute-speculative-load-referrer-policy"},{"id":"ref-for-compute-speculative-load-referrer-policy\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy"}, "ea540423": {"dfnID":"ea540423","dfnText":"requirements","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-requirements"}],"title":"2. Parsing"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-requirements"}, "ed08d686": {"dfnID":"ed08d686","dfnText":"tags (for speculation rule)","external":true,"refSections":[{"refs":[{"id":"ref-for-sr-tags"},{"id":"ref-for-sr-tags\u2460"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sr-tags"}, "f64cd240": {"dfnID":"f64cd240","dfnText":"referrer policy","external":true,"refSections":[{"refs":[{"id":"ref-for-sl-candidate-referrer-policy"},{"id":"ref-for-sl-candidate-referrer-policy\u2460"},{"id":"ref-for-sl-candidate-referrer-policy\u2461"}],"title":"3. Processing model"}],"url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy"}, "prerender-candidate": {"dfnID":"prerender-candidate","dfnText":"prerender candidate","external":false,"refSections":[{"refs":[{"id":"ref-for-prerender-candidate"},{"id":"ref-for-prerender-candidate\u2460"},{"id":"ref-for-prerender-candidate\u2461"}],"title":"3. Processing model"}],"url":"#prerender-candidate"}, "prerender-candidate-target-navigable-name-hint": {"dfnID":"prerender-candidate-target-navigable-name-hint","dfnText":"target navigable name hint","external":false,"refSections":[{"refs":[{"id":"ref-for-prerender-candidate-target-navigable-name-hint"},{"id":"ref-for-prerender-candidate-target-navigable-name-hint\u2460"},{"id":"ref-for-prerender-candidate-target-navigable-name-hint\u2461"}],"title":"3. Processing model"}],"url":"#prerender-candidate-target-navigable-name-hint"}, "speculation-rule-set-prerender-rules": {"dfnID":"speculation-rule-set-prerender-rules","dfnText":"prerender rules","external":false,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-set-prerender-rules"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-speculation-rule-set-prerender-rules\u2460"}],"title":"3. Processing model"}],"url":"#speculation-rule-set-prerender-rules"}, "speculation-rule-target-navigable-name-hint": {"dfnID":"speculation-rule-target-navigable-name-hint","dfnText":"target navigable name hint","external":false,"refSections":[{"refs":[{"id":"ref-for-speculation-rule-target-navigable-name-hint"},{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2460"}],"title":"2. Parsing"},{"refs":[{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2461"},{"id":"ref-for-speculation-rule-target-navigable-name-hint\u2462"}],"title":"3. Processing model"}],"url":"#speculation-rule-target-navigable-name-hint"}, }; document.addEventListener("DOMContentLoaded", ()=>
{
genAllDfnPanels();
document.body.addEventListener("click",
(e)
=>
{
//
If
not
handled
already,
just
hide
all
dfn
panels.
hideAllDfnPanels();
});
});
window.addEventListener("resize",
()
=>
{
//
Pin
any
visible
dfn
panel
queryAll(".dfn-panel.on,
.dfn-panel.activated").forEach(el=>
positionDfnPanel(el));
});
function
genAllDfnPanels()
{
for(const
panelData
of
Object.values(dfnPanelData))
{
const
dfnID
=
panelData.dfnID;
const
dfn
=
document.getElementById(dfnID);
if(!dfn)
{
console.log(`Can't
find
dfn#${dfnID}.`,
panelData);
continue;
}
dfn.panelData
=
panelData;
insertDfnPopupAction(dfn);
}
}
function
genDfnPanel(dfn,
{
dfnID,
url,
dfnText,
refSections,
external
})
{
const
dfnPanel
=
mk.aside({
class:
"dfn-panel
on",
id:
`infopanel-for-${dfnID}`,
"data-for":
dfnID,
"aria-labelled-by":`infopaneltitle-for-${dfnID}`,
},
mk.span({id:`infopaneltitle-for-${dfnID}`,
style:"display:none"},
`Info
about
the
'${dfnText}'
${external?"external":""}
reference.`),
mk.a({href:url,
class:"dfn-link"},
url),
refSections.length
==
0
?
[]
:
mk.b({},
"Referenced
in:"),
mk.ul({},
...refSections.map(section=>
mk.li({},
...section.refs.map((ref,
refI)=>
[
mk.a({
href:
`#${ref.id}`
},
(refI
==
0)
?
section.title
:
`(${refI
+
1})`
),
"
",
]
),
),
),
),
genLinkingSyntaxes(dfn),
);
dfnPanel.addEventListener('click',
(event)
=>
{
if
(event.target.nodeName
==
'A')
{
scrollToTargetAndHighlight(event);
pinDfnPanel(dfnPanel);
}
event.stopPropagation();
refocusOnTarget(event);
});
dfnPanel.addEventListener('keydown',
(event)
=>
{
if(event.keyCode
==
27)
{
//
Escape
key
hideDfnPanel({dfnPanel});
event.stopPropagation();
event.preventDefault();
}
});
dfnPanel.dfn
=
dfn;
dfn.dfnPanel
=
dfnPanel;
return
dfnPanel;
}
function
hideAllDfnPanels()
{
//
Delete
the
currently-active
dfn
panel.
queryAll(".dfn-panel").forEach(dfnPanel=>
hideDfnPanel({dfnPanel}));
}
function
showDfnPanel(dfn)
{
hideAllDfnPanels();
//
Only
display
one
at
a
time.
dfn.setAttribute("aria-expanded",
"true");
const
dfnPanel
=
genDfnPanel(dfn,
dfn.panelData);
//
Give
the
dfn
a
unique
tabindex,
and
then
//
give
all
the
tabbable
panel
bits
successive
indexes.
let
tabIndex
=
100;
dfn.tabIndex
=
tabIndex++;
const
tabbable
=
dfnPanel.querySelectorAll(":is(a,
button)");
for
(const
el
of
tabbable)
{
el.tabIndex
=
tabIndex++;
}
append(document.body,
dfnPanel);
positionDfnPanel(dfnPanel);
}
function
positionDfnPanel(dfnPanel)
{
const
dfn
=
dfnPanel.dfn;
const
dfnPos
=
getBounds(dfn);
dfnPanel.style.top
=
dfnPos.bottom
+
"px";
dfnPanel.style.left
=
dfnPos.left
+
"px";
const
panelPos
=
dfnPanel.getBoundingClientRect();
const
panelMargin
=
8;
const
maxRight
=
document.body.parentNode.clientWidth
-
panelMargin;
if
(panelPos.right
>
maxRight)
{
const
overflowAmount
=
panelPos.right
-
maxRight;
const
newLeft
=
Math.max(panelMargin,
dfnPos.left
-
overflowAmount);
dfnPanel.style.left
=
newLeft
+
"px";
}
}
function
pinDfnPanel(dfnPanel)
{
//
Switch
it
to
"activated"
state,
which
pins
it.
dfnPanel.classList.add("activated");
dfnPanel.style.position
=
"fixed";
dfnPanel.style.left
=
null;
dfnPanel.style.top
=
null;
}
function
hideDfnPanel({dfn,
dfnPanel})
{
if(!dfnPanel)
dfnPanel
=
dfn.dfnPanel;
if(!dfn)
dfn
=
dfnPanel.dfn;
dfn.dfnPanel
=
undefined;
dfnPanel.dfn
=
undefined;
dfn.setAttribute("aria-expanded",
"false");
dfn.tabIndex
=
undefined;
dfnPanel.remove()
}
function
toggleDfnPanel(dfn)
{
if(dfn.dfnPanel)
{
hideDfnPanel(dfn);
}
else
{
showDfnPanel(dfn);
}
}
function
insertDfnPopupAction(dfn)
{
dfn.setAttribute('role',
'button');
dfn.setAttribute('aria-expanded',
'false')
dfn.tabIndex
=
0;
dfn.classList.add('has-dfn-panel');
dfn.addEventListener('click',
(event)
=>
{
toggleDfnPanel(dfn);
event.stopPropagation();
});
dfn.addEventListener('keypress',
(event)
=>
{
const
kc
=
event.keyCode;
//
32->
Space,
13->
Enter
if(kc
==
32
||
kc
==
13)
{
toggleDfnPanel(dfn);
event.stopPropagation();
event.preventDefault();
}
});
}
function
refocusOnTarget(event)
{
const
target
=
event.target;
setTimeout(()
=>
{
//
Refocus
on
the
event.target
element.
//
This
is
needed
after
browser
scrolls
to
the
destination.
target.focus();
});
}
//
TODO:
shared
util
//
Returns
the
root-level
absolute
position
{left
and
top}
of
element.
function
getBounds(el,
relativeTo=document.body)
{
const
relativeRect
=
relativeTo.getBoundingClientRect();
const
elRect
=
el.getBoundingClientRect();
const
top
=
elRect.top
-
relativeRect.top;
const
left
=
elRect.left
-
relativeRect.left;
return
{
top,
left,
bottom:
top
+
elRect.height,
right:
left
+
elRect.width,
}
}
function
scrollToTargetAndHighlight(event)
{
let
hash
=
event.target.hash;
if
(hash)
{
hash
=
decodeURIComponent(hash.substring(1));
const
dest
=
document.getElementById(hash);
if
(dest)
{
dest.classList.add('highlighted');
setTimeout(()
=>
dest.classList.remove('highlighted'),
1000);
}
}
}
//
Functions,
divided
by
link
type,
that
wrap
an
autolink's
//
contents
with
the
appropriate
outer
syntax.
//
Alternately,
a
string
naming
another
type
they
format
//
the
same
as.
function
needsFor(type)
{
switch(type)
{
case
"descriptor":
case
"value":
case
"element-attr":
case
"attr-value":
case
"element-state":
case
"method":
case
"constructor":
case
"argument":
case
"attribute":
case
"const":
case
"dict-member":
case
"event":
case
"enum-value":
case
"stringifier":
case
"serializer":
case
"iterator":
case
"maplike":
case
"setlike":
case
"state":
case
"mode":
case
"context":
case
"facet":
return
true;
default:
return
false;
}
}
function
refusesFor(type)
{
switch(type)
{
case
"property":
case
"element":
case
"interface":
case
"namespace":
case
"callback":
case
"dictionary":
case
"enum":
case
"exception":
case
"typedef":
case
"http-header":
case
"permission":
return
true;
default:
return
false;
}
}
function
linkFormatterFromType(type)
{
switch(type)
{
case
'scheme':
case
'permission':
case
'dfn':
return
(text)
=>
`[=${text}=]`;
case
'abstract-op':
return
(text)
=>
`[\$${text}\$]`;
case
'function':
case
'at-rule':
case
'selector':
case
'value':
return
(text)
=>
`''${text}''`;
case
'http-header':
return
(text)
=>
`[:${text}:]`;
case
'interface':
case
'constructor':
case
'method':
case
'argument':
case
'attribute':
case
'callback':
case
'dictionary':
case
'dict-member':
case
'enum':
case
'enum-value':
case
'exception':
case
'const':
case
'typedef':
case
'stringifier':
case
'serializer':
case
'iterator':
case
'maplike':
case
'setlike':
case
'extended-attribute':
case
'event':
case
'idl':
return
(text)
=>
`{{${text}}}`;
case
'element-state':
case
'element-attr':
case
'attr-value':
case
'element':
return
(element)
=>
`
`;
case 'grammar': return (text) => `${text} (within a )`;
case 'type': return (text)=> ``;
case 'descriptor':
case 'property': return (text) => `'${text}'`;
default: return;
};
};
function genLinkingSyntaxes(dfn) {
if(dfn.tagName != "DFN") return;
const type = dfn.getAttribute('data-dfn-type');
if(!type) {
console.log(` doesn't have a data-dfn-type:`, dfn);
return [];
}
// Return a function that wraps link text based on the type
const linkFormatter = linkFormatterFromType(type);
if(!linkFormatter) {
console.log(` has an unknown data-dfn-type:`, dfn);
return [];
}
let ltAlts;
if(dfn.hasAttribute('data-lt')) {
ltAlts = dfn.getAttribute('data-lt')
.split("|")
.map(x=>x.trim());
} else {
ltAlts = [dfn.textContent.trim()];
}
if(type == "type") {
// lt of "", but "foo" is the interior;
// is how you write it with a for,
// not or whatever.
for(var i = 0; i < ltAlts.length; i++) {
const lt = ltAlts[i];
const match = //.exec(lt);
if(match) { ltAlts[i] = match[1]; }
}
}
let forAlts;
if(dfn.hasAttribute('data-dfn-for')) {
forAlts = dfn.getAttribute('data-dfn-for')
.split(",")
.map(x=>x.trim());
} else {
forAlts = [''];
}
let linkingSyntaxes = [];
if(!needsFor(type)) {
for(const lt of ltAlts) {
linkingSyntaxes.push(linkFormatter(lt));
}
}
if(!refusesFor(type)) {
for(const f of forAlts) {
linkingSyntaxes.push(linkFormatter(`${f}/${ltAlts[0]}`))
}
}
return [
mk.b({}, 'Possible linking syntaxes:'),
mk.ul({},
...linkingSyntaxes.map(link => {
const copyLink = async () =>
await navigator.clipboard.writeText(link);
return mk.li({},
mk.div({ class: 'link-item' },
mk.button({
class: 'copy-icon', title: 'Copy',
type: 'button',
_onclick: copyLink,
tabindex: 0,
}, mk.span({ class: 'icon' }) ),
mk.span({}, link)
)
);
})
)
];
}
}
/* Boilerplate: script-ref-hints */
"use strict";
{
let refsData = {
"#prerender-candidate": {"displayText":"prerender candidate","export":true,"for_":[],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"prerender candidate","type":"dfn","url":"#prerender-candidate"},
"#prerender-candidate-target-navigable-name-hint": {"displayText":"target navigable name hint","export":true,"for_":["prerender candidate"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"target navigable name hint","type":"dfn","url":"#prerender-candidate-target-navigable-name-hint"},
"#speculation-rule-set-prerender-rules": {"displayText":"prerender rules","export":true,"for_":["speculation rule set"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"prerender rules","type":"dfn","url":"#speculation-rule-set-prerender-rules"},
"#speculation-rule-target-navigable-name-hint": {"displayText":"target navigable name hint","export":true,"for_":["speculation rule"],"level":"1","normative":true,"shortname":"speculation-rules","spec":"speculation-rules-1","status":"local","text":"target navigable name hint","type":"dfn","url":"#speculation-rule-target-navigable-name-hint"},
"50adabbe_https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set": {"displayText":"parse a speculation rule set string","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"parse a speculation rule set string","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"},
"https://console.spec.whatwg.org/#report-a-warning-to-the-console": {"displayText":"report a warning to the console","export":true,"for_":[],"level":"1","normative":true,"shortname":"console","spec":"console","status":"current","text":"report a warning to the console","type":"dfn","url":"https://console.spec.whatwg.org/#report-a-warning-to-the-console"},
"https://dom.spec.whatwg.org/#concept-element-attributes-change-ext": {"displayText":"attribute change steps","export":true,"for_":[],"level":"1","normative":true,"shortname":"dom","spec":"dom","status":"current","text":"attribute change steps","type":"dfn","url":"https://dom.spec.whatwg.org/#concept-element-attributes-change-ext"},
"https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword": {"displayText":"valid navigable target name or keyword","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"valid navigable target name or keyword","type":"dfn","url":"https://html.spec.whatwg.org/multipage/document-sequences.html#valid-navigable-target-name-or-keyword"},
"https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element": {"displayText":"area","export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"area","type":"element","url":"https://html.spec.whatwg.org/multipage/image-maps.html#the-area-element"},
"https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target": {"displayText":"target","export":true,"for_":["a","area"],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"target","type":"element-attr","url":"https://html.spec.whatwg.org/multipage/links.html#attr-hyperlink-target"},
"https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url": {"displayText":"url","export":true,"for_":["HTMLHyperlinkElementUtils"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"url","type":"dfn","url":"https://html.spec.whatwg.org/multipage/links.html#concept-hyperlink-url"},
"https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element": {"displayText":"a","export":true,"for_":[],"level":"1","normative":true,"shortname":"html","spec":"html","status":"current","text":"a","type":"element","url":"https://html.spec.whatwg.org/multipage/text-level-semantics.html#the-a-element"},
"https://infra.spec.whatwg.org/#list": {"displayText":"list","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"list","type":"dfn","url":"https://infra.spec.whatwg.org/#list"},
"https://infra.spec.whatwg.org/#list-append": {"displayText":"append","export":true,"for_":["list"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"append","type":"dfn","url":"https://infra.spec.whatwg.org/#list-append"},
"https://infra.spec.whatwg.org/#list-iterate": {"displayText":"for each","export":true,"for_":["list","set"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"for each","type":"dfn","url":"https://infra.spec.whatwg.org/#list-iterate"},
"https://infra.spec.whatwg.org/#map-exists": {"displayText":"exist","export":true,"for_":["map"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"exist","type":"dfn","url":"https://infra.spec.whatwg.org/#map-exists"},
"https://infra.spec.whatwg.org/#string": {"displayText":"string","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"string","type":"dfn","url":"https://infra.spec.whatwg.org/#string"},
"https://infra.spec.whatwg.org/#struct": {"displayText":"struct","export":true,"for_":[],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"struct","type":"dfn","url":"https://infra.spec.whatwg.org/#struct"},
"https://infra.spec.whatwg.org/#struct-item": {"displayText":"item","export":true,"for_":["struct","tuple"],"level":"1","normative":true,"shortname":"infra","spec":"infra","status":"current","text":"item","type":"dfn","url":"https://infra.spec.whatwg.org/#struct-item"},
"https://whatpr.org/html/11426/semantics.html#get-an-element's-target": {"displayText":"get an element's target","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"get an element's target","type":"dfn","url":"https://whatpr.org/html/11426/semantics.html#get-an-element's-target"},
"https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates": {"displayText":"collecting tags from speculative load candidates","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"collecting tags from speculative load candidates","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#collect-tags-from-speculative-load-candidates"},
"https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy": {"displayText":"compute a speculative load referrer policy","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"compute a speculative load referrer policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#compute-speculative-load-referrer-policy"},
"https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads": {"displayText":"consider speculative loads","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"consider speculative loads","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#consider-speculative-loads"},
"https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets": {"displayText":"speculation rule sets","export":true,"for_":["Document"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule sets","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#document-sr-sets"},
"https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links": {"displayText":"finding matching links","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"finding matching links","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#finding-matching-links"},
"https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps": {"displayText":"inner consider speculative loads steps","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"inner consider speculative loads steps","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#inner-consider-speculative-loads-steps"},
"https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule": {"displayText":"parse a speculation rule","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"parse a speculation rule","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#parse-a-speculation-rule"},
"https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate": {"displayText":"prefetch candidate","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"prefetch candidate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#prefetch-candidate"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy": {"displayText":"anonymization policy","export":true,"for_":["prefetch candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"anonymization policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-anonymization-policy"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness": {"displayText":"eagerness","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"eagerness","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-eagerness"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"no-vary-search hint","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-nvs-hint"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy": {"displayText":"referrer policy","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"referrer policy","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-referrer-policy"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags": {"displayText":"tags","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"tags","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-tags"},
"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url": {"displayText":"URL","export":true,"for_":["speculative load candidate"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"url","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sl-candidate-url"},
"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule": {"displayText":"speculation rule","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule"},
"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set": {"displayText":"speculation rule set","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculation rule set","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculation-rule-set"},
"https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate": {"displayText":"speculative load candidate","export":true,"for_":[],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"speculative load candidate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#speculative-load-candidate"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness": {"displayText":"eagerness","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"eagerness","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-eagerness"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"no-vary-search hint","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-nvs-hint"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-predicate": {"displayText":"predicate","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"predicate","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-predicate"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-requirements": {"displayText":"requirements","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"requirements","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-requirements"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch": {"displayText":"prefetch rules","export":true,"for_":["speculation rule set"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"prefetch rules","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-set-prefetch"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-tags": {"displayText":"tags","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"tags","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-tags"},
"https://whatpr.org/html/11426/speculative-loading.html#sr-urls": {"displayText":"URLs","export":true,"for_":["speculation rule"],"level":"","normative":true,"shortname":"html","spec":"html","status":"anchor-block","text":"urls","type":"dfn","url":"https://whatpr.org/html/11426/speculative-loading.html#sr-urls"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record": {"displayText":"prefetch record","export":true,"for_":[],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prefetch record","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy": {"displayText":"anonymization policy","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"anonymization policy","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-anonymization-policy"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint": {"displayText":"No-Vary-Search hint","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"no-vary-search hint","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-no-vary-search-hint"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint": {"displayText":"prerendering target navigable name hint","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prerendering target navigable name hint","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-target-navigable-name-hint"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable": {"displayText":"prerendering traversable","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"prerendering traversable","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-prerendering-traversable"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy": {"displayText":"referrer policy","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"referrer policy","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-referrer-policy"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source": {"displayText":"source","export":true,"for_":["prefetch record"],"level":"","normative":true,"shortname":"prefetch","spec":"prefetch","status":"anchor-block","text":"source","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-source"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags": {"displayText":"tags","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"tags","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-tags"},
"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url": {"displayText":"URL","export":true,"for_":["prefetch record"],"level":"1","normative":true,"shortname":"prefetch","spec":"prefetch","status":"current","text":"url","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#prefetch-record-url"},
"https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch": {"displayText":"start a referrer-initiated navigational prefetch","export":true,"for_":[],"level":"","normative":true,"shortname":"prefetch","spec":"prefetch","status":"anchor-block","text":"start a referrer-initiated navigational prefetch","type":"dfn","url":"https://wicg.github.io/nav-speculation/prefetch.html#start-a-referrer-initiated-navigational-prefetch"},
"https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender": {"displayText":"start a referrer-initiated navigational prerender","export":true,"for_":[],"level":"","normative":true,"shortname":"prerendering-revamped","spec":"prerendering-revamped","status":"anchor-block","text":"start a referrer-initiated navigational prerender","type":"dfn","url":"https://wicg.github.io/nav-speculation/prerendering.html#start-a-referrer-initiated-navigational-prerender"},
};
function mkRefHint(link, ref) {
const linkText = link.textContent;
let dfnTextElements = '';
if (ref.displayText.toLowerCase() != linkText.toLowerCase()) {
// Give the original term if it's being displayed in a different way.
// But allow casing differences, they're insignificant.
dfnTextElements =
mk.li({},
mk.b({}, "Term: "),
mk.span({}, ref.displayText)
);
}
const forList = ref.for_;
let forListElements;
if(forList.length == 0) {
forListElements = [];
} else if(forList.length == 1) {
forListElements = mk.li({},
mk.b({}, "For: "),
mk.span({}, forList[0]),
);
} else {
forListElements = mk.li({},
mk.b({}, "For: "),
mk.ul({},
...forList.map(forItem =>
mk.li({},
mk.span({}, forItem)
),
),
),
);
}
const url = ref.url;
const safeUrl = encodeURIComponent(url);
const hintPanel = mk.aside({
class: "ref-hint",
id: `ref-hint-for-${safeUrl}`,
"data-for": url,
"aria-labelled-by": `ref-hint-for-${safeUrl}`,
},
mk.ul({},
dfnTextElements,
mk.li({},
mk.b({}, "URL: "),
mk.a({ href: url, class: "ref" }, url),
),
mk.li({},
mk.b({}, "Type: "),
mk.span({}, `${ref.type}`),
),
mk.li({},
mk.b({}, "Spec: "),
mk.span({}, `${ref.spec ? ref.spec : ''}`),
),
forListElements
),
);
hintPanel.forLink = link;
setupRefHintEventListeners(link, hintPanel);
return hintPanel;
}
function hideAllRefHints() {
queryAll(".ref-hint").forEach(el=>hideRefHint(el));
}
function hideRefHint(refHint) {
const link = refHint.forLink;
link.setAttribute("aria-expanded", "false");
if(refHint.teardownEventListeners) {
refHint.teardownEventListeners();
}
refHint.remove();
}
function showRefHint(link) {
if(link.classList.contains("dfn-link")) return;
const url = link.getAttribute("href");
const refHintKey = link.getAttribute("data-refhint-key");
let key = url;
if(refHintKey) {
key = refHintKey + "_" + url;
}
const ref = refsData[key];
if(!ref) return;
hideAllRefHints(); // Only display one at this time.
const refHint = mkRefHint(link, ref);
append(document.body, refHint);
link.setAttribute("aria-expanded", "true");
positionRefHint(refHint);
}
function setupRefHintEventListeners(link, refHint) {
if (refHint.teardownEventListeners) return;
// Add event handlers to hide the refHint after the user moves away
// from both the link and refHint, if not hovering either within one second.
let timeout = null;
const startHidingRefHint = (event) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
hideRefHint(refHint);
}, 1000);
}
const resetHidingRefHint = (event) => {
if (timeout) clearTimeout(timeout);
timeout = null;
};
link.addEventListener("mouseleave", startHidingRefHint);
link.addEventListener("mouseenter", resetHidingRefHint);
link.addEventListener("blur", startHidingRefHint);
link.addEventListener("focus", resetHidingRefHint);
refHint.addEventListener("mouseleave", startHidingRefHint);
refHint.addEventListener("mouseenter", resetHidingRefHint);
refHint.addEventListener("blur", startHidingRefHint);
refHint.addEventListener("focus", resetHidingRefHint);
refHint.teardownEventListeners = () => {
// remove event listeners
resetHidingRefHint();
link.removeEventListener("mouseleave", startHidingRefHint);
link.removeEventListener("mouseenter", resetHidingRefHint);
link.removeEventListener("blur", startHidingRefHint);
link.removeEventListener("focus", resetHidingRefHint);
refHint.removeEventListener("mouseleave", startHidingRefHint);
refHint.removeEventListener("mouseenter", resetHidingRefHint);
refHint.removeEventListener("blur", startHidingRefHint);
refHint.removeEventListener("focus", resetHidingRefHint);
};
}
function positionRefHint(refHint) {
const link = refHint.forLink;
const linkPos = getBounds(link);
refHint.style.top = linkPos.bottom + "px";
refHint.style.left = linkPos.left + "px";
const panelPos = refHint.getBoundingClientRect();
const panelMargin = 8;
const maxRight = document.body.parentNode.clientWidth - panelMargin;
if (panelPos.right > maxRight) {
const overflowAmount = panelPos.right - maxRight;
const newLeft = Math.max(panelMargin, linkPos.left - overflowAmount);
refHint.style.left = newLeft + "px";
}
}
// TODO: shared util
// Returns the root-level absolute position {left and top} of element.
function getBounds(el, relativeTo=document.body) {
const relativeRect = relativeTo.getBoundingClientRect();
const elRect = el.getBoundingClientRect();
const top = elRect.top - relativeRect.top;
const left = elRect.left - relativeRect.left;
return {
top,
left,
bottom: top + elRect.height,
right: left + elRect.width,
}
}
function showRefHintListener(e) {
// If the target isn't in a link (or is a link),
// just ignore it.
let link = e.target.closest("a");
if(!link) return;
// If the target is in a ref-hint panel
// (aka a link in the already-open one),
// also just ignore it.
if(link.closest(".ref-hint")) return;
// Otherwise, show the panel for the link.
showRefHint(link);
}
function hideAllHintsListener(e) {
// If the click is inside a ref-hint panel, ignore it.
if(e.target.closest(".ref-hint")) return;
// Otherwise, close all the current panels.
hideAllRefHints();
}
document.addEventListener("DOMContentLoaded", () => {
document.body.addEventListener("mousedown", showRefHintListener);
document.body.addEventListener("focus", showRefHintListener);
document.body.addEventListener("click", hideAllHintsListener);
});
window.addEventListener("resize", () => {
// Hide any open ref hint.
hideAllRefHints();
});
}
/* Boilerplate: script-var-click-highlighting */
"use strict";
{
/*
Color-choosing design:
* Colors are ordered by goodness.
* On clicking a var, give it the earliest color
with the lowest usage in the algorithm.
* On re-clicking, re-use the var's most recent color
if that's not currently being used elsewhere.
*/
const COLOR_COUNT = 7;
document.addEventListener("click", e=>{
if(e.target.nodeName == "VAR") {
highlightSameAlgoVars(e.target);
}
});
function highlightSameAlgoVars(v) {
// Find the algorithm container.
let algoContainer = findAlgoContainer(v);
// Not highlighting document-global vars,
// too likely to be unrelated.
if(algoContainer == null) return;
const varName = nameFromVar(v);
if(!v.hasAttribute("data-var-color")) {
const newColor = chooseHighlightColor(algoContainer, v);
for(const el of algoContainer.querySelectorAll("var")) {
if(nameFromVar(el) == varName) {
el.setAttribute("data-var-color", newColor);
el.setAttribute("data-var-last-color", newColor);
}
}
} else {
for(const el of algoContainer.querySelectorAll("var")) {
if(nameFromVar(el) == varName) {
el.removeAttribute("data-var-color");
}
}
}
}
function findAlgoContainer(el) {
while(el != document.body) {
if(el.hasAttribute("data-algorithm")) return el;
el = el.parentNode;
}
return null;
}
function nameFromVar(el) {
return el.textContent.replace(/(\s|\xa0)+/g, " ").trim();
}
function colorCountsFromContainer(container) {
const namesFromColor = Array.from({length:COLOR_COUNT}, x=>new Set());
for(let v of container.querySelectorAll("var[data-var-color]")) {
let color = +v.getAttribute("data-var-color");
namesFromColor[color].add(nameFromVar(v));
}
return namesFromColor.map(x=>x.size);
}
function leastUsedColor(colors) {
// Find the earliest color with the lowest count.
let minCount = Infinity;
let minColor = null;
for(var i = 0; i < colors.length; i++) {
if(colors[i] < minCount) {
minColor = i;
minCount = colors[i];
}
}
return minColor;
}
function chooseHighlightColor(container, v) {
const colorCounts = colorCountsFromContainer(container);
if(v.hasAttribute("data-var-last-color")) {
let color = +v.getAttribute("data-var-last-color");
if(colorCounts[color] == 0) return color;
}
return leastUsedColor(colorCounts);
}
}