1. Prerendering infrastructure
1.1.
Extensions
to
the
Document
interface
We’d
modify
[HTML]
's
centralized
definition
of
Document
as
follows:
partial interface Document {readonly attribute boolean prerendering ; // Under "special event handler IDL attributes that only apply to Document objects"attribute EventHandler onprerenderingchange ; };
The
onprerenderingchange
attribute
is
an
event
handler
IDL
attribute
corresponding
to
the
prerenderingchange
event
handler
event
type
.
(We
would
update
the
corresponding
table
in
[HTML]
,
which
currently
only
contains
onreadystatechange
.)
As
is
customary
for
[HTML]
,
the
definition
of
prerendering
would
be
located
in
another
section
of
the
spec;
we’d
place
it
in
the
new
section
introduced
below:
1.2. Prerendering navigables
The following section would be added as a new sub-section of [HTML] 's Navigables section.
Every navigable has a loading mode , which is one of the following:
-
"
default
" -
No special considerations are applied to content loaded in this navigable
-
"
prerender
" -
This navigable is displaying prerendered content
By
default,
a
navigable
's
loading
mode
is
"
default
".
A
navigable
whose
loading
mode
is
"
prerender
"
is
known
as
a
prerendering
navigable
.
A
prerendering
navigable
that
is
also
a
top-level
traversable
is
known
as
a
prerendering
traversable
.
Although there are only two values for the loading mode , we use a flexible structure in anticipation of other future loading modes, such as those provided by fenced frames, portals, and uncredentialed (cross-site) prerendering. It’s not yet clear whether that anticipation is correct; if, as those features gain full specifications, it turns out not to be, we will instead convert this into a boolean.
-
document .
prerendering
-
Returns
true
if
the
page
is
being
presented
in
a
non-interactive
"prerendering-like"
context.
In
the
future,
this
would
include
a
visible
document
in
a
<portal>
element, both when loaded into it or via predecessor adoption.
The
prerendering
getter
steps
are
to
return
true
if
this
has
a
non-null
node
navigable
that
is
a
prerendering
navigable
;
otherwise,
false.
Every
Document
has
a
prerendering
traversables
map
,
which
is
an
ordered
map
of
URLs
to
prerendering
traversables
.
This
is
used
to
fulfill
navigations
to
a
given
URL
by
instead
activating
the
corresponding
prerendering
traversable.
Every
Document
has
a
post-prerendering
activation
steps
list
,
which
is
a
list
where
each
item
is
a
series
of
algorithm
steps.
For
convenience,
we
define
the
post-prerendering
activation
steps
list
for
any
platform
object
platformObject
as:
- If platformObject is a node
-
-
Return platformObject ’s node document 's post-prerendering activation steps list .
-
- Otherwise
-
-
Assert: platformObject ’s relevant global object is a
Window
object.
-
Return platformObject ’s relevant global object 's associated Document 's post-prerendering activation steps list .
-
Every
Document
has
an
activation
start
time
,
which
is
initially
a
DOMHighResTimeStamp
with
a
time
value
of
zero.
To start user-agent initiated prerendering given a URL startingURL :
-
Assert : startingURL ’s scheme is an HTTP(S) scheme .
-
Let prerenderingTraversable be the result of creating a new top-level traversable given null and the empty string.
-
Set prerenderingTraversable ’s loading mode to "
prerender
". -
Navigate prerenderingTraversable to startingURL using prerenderingTraversable ’s active document .
We treat this initial navigations as prerenderingTraversable navigating itself, which will ensure all relevant security checks pass.
-
When the user indicates they wish to commit the navigation and create a new user-visible top-level traversable while doing so (e.g., by pressing Shift + Enter after typing in the address bar):
-
Update the user agent’s user interface to present prerenderingTraversable , e.g., by creating a new tab/window.
-
Finalize activation for prerenderingTraversable given startingURL ’s origin .
-
-
Alternately, when they use indicates they wish to commit the navigation into an existing top-level traversable predecessorTraversable (e.g., by pressing Enter after typing in the address bar):
-
Activate prerenderingTraversable in place of predecessorTraversable given "
push
".
-
The user might never indicate such a commitment, or might take long enough to do so that the user agent needs to reclaim the resources used by the prerender for some more immediate task. In that case the user agent can destroy prerenderingTraversable .
Document
referrerDoc
,
and
a
referrer
policy
referrerPolicy
:
-
Assert : startingURL ’s scheme is an HTTP(S) scheme .
-
If referrerDoc ’s node navigable is not a top-level traversable , then return.
Currently, prerendering from inside a child navigable is not specified or implemented. Doing so would involve tricky considerations around how the prerendered navigable appears in the navigable tree.
-
If referrerDoc ’s browsing context is an auxiliary browsing context , then return.
This avoids having to deal with any potential opener relationship between the prerendering traversable and referrerDoc ’s browsing context 's opener browsing context .
-
If referrerDoc ’s origin is not same site with startingURL ’s origin , then return.
Currently, cross-site prerendering is not specified or implemented, although we have various ideas about how it could work in this repository’s explainers.
-
If referrerDoc ’s prerendering traversables map [ startingURL ] exists , then return.
-
Let prerenderingTraversable be the result of creating a new top-level traversable .
-
Set prerenderingTraversable ’s loading mode to "
prerender
". -
Set referrerDoc ’s prerendering traversables map [ startingURL ] to prerenderingTraversable .
-
Set prerenderingTraversable ’s remove from referrer to be an algorithm which removes referrerDoc [ startingURL ].
As with all top-level traversables , the prerendering traversable can be destroyed for any reason, for example if it becomes unresponsive, performs a restricted operation, or if the user agent believes prerendering takes too many resources.
-
Navigate prerenderingTraversable to startingURL using referrerDoc , with referrerPolicy set to referrerPolicy .
-
Assert : successorTraversable ’s active document 's is initial about:blank is false.
-
If navigationId is not given, then let navigationId be the result of generating a random UUID .
-
Let referrerOrigin be predecessorTraversable ’s active document 's origin .
-
Set predecessorTraversable ’s ongoing navigation to navigationId .
This will have the effect of aborting any other ongoing navigations of predecessorTraversable .
-
In parallel , run these steps:
-
Let unloadPromptCanceled be the result of checking if unloading is user-canceled for predecessorTraversable ’s active document 's inclusive descendant navigables .
-
If unloadPromptCanceled is true, or predecessorTraversable ’s ongoing navigation is no longer navigationId , then abort these steps.
-
Queue a global task on the navigation and traversal task source given predecessorTraversable ’s active window to abort predecessorTraversable ’s active document .
-
Append session history traversal steps to predecessorTraversable to perform the following steps:
-
Assert : successorTraversable ’s current session history step is 0.
-
Assert : successorTraversable ’s session history entries 's size is 1.
-
Let successorEntry be successorTraversable ’s session history entries [0].
-
Remove successorEntry from successorTraversable ’s session history entries .
At this point, successorTraversable is empty and can be unobservably destroyed. (As long as the implementation takes care to keep successorEntry , including its document and that
Document
's browsing context , alive for the next step.) -
Finalize a cross-document navigation given predecessorTraversable , historyHandling , and successorEntry .
Because we have moved the entire session history entry , including the contained document 's browsing context , this means traversing across the associated history entries will cause a browsing context group switch, similar to what happens with the `
Cross-Origin-Opener-Policy
` header. Importantly, this will sever any opener relationships, in the same way as COOP. Such traversal includes both the actual activation process here, where we make successorEntry active, but also e.g. the user pressing the back button (or the page usinghistory.back()
) after activation, which will switch in the other direction. -
Update the user agent’s user interface to reflect this change, e.g., by updating the tab/window contents and the browser chrome.
-
Finalize activation for successorTraversable given referrerOrigin .
-
Perhaps we should do something with WebDriver BiDi here? See w3c/webdriver-bidi#321 . Right now the pre- in parallel part of the navigate algorithm will send WebDriver BiDi navigation started as if it were a normal navigation, but then nothing will happen to indicate the navigation finishes.
-
-
-
For each navigable of traversable ’s active document 's inclusive descendant navigables , queue a global task on the navigation and traversal task source , given navigable ’s active window , to perform the following steps:
-
For each origin → hintSet in navigable ’s prerender-scoped Accept-CH cache :
-
Set Accept-CH cache [ origin ] to hintSet .
-
-
Let doc be navigable ’s active document .
-
We should really propagate the loading mode change here, in the posted task. This is where implementations would update what is returned by
document.prerendering
. However, right now it lives on the traversable, so it gets magically updated when we move over the session history entry. Probably we need to move it to theDocument
. -
If doc ’s origin is the same as origin , then set doc ’s activation start time to the current high resolution time for doc ’s relevant global object .
-
Fire an event named
prerenderingchange
at doc . -
For each steps in doc ’s post-prerendering activation steps list :
-
Run steps .
These steps might return something, like a
Promise
. That is just an artifact of how the spec is modified; such return values can always be ignored. -
Assert: running steps did not throw an exception.
The order here is observable for
Document
s that share an event loop , but not for those in separate event loops. -
-
To ensure that the references for a prerendering traversable are cleared once it is destroyed , modify destroy a top-level traversable by appending the following step:
-
If traversable is a prerendering traversable and traversable ’s remove from referrer is not null, then call traversable ’s remove from referrer .
1.3. Modifications to creating navigables
-
Set navigable ’s loading mode to element ’s node navigable 's loading mode .
2. Navigation and session history
2.1. Allowing activation in place of navigation
-
If any of the following conditions hold:
-
navigable is not a top-level traversable ;
-
navigable is a prerendering traversable ;
-
navigable is a fenced frame ;
The concept of a fenced frame navigable is not yet defined but we need to link to it once it exists.
-
cspNavigationType is not "
other
"; or -
documentResource is not null
then return null.
-
-
Return navigable ’s active document 's prerendering traversables map [ url ], if it exists ; otherwise return null.
Patch the navigate algorithm to allow the activation of a prerendering traversable in place of a normal navigation as follows:
-
Let matchingPrerenderedNavigable be the result of getting the matching prerendering navigable given navigable , url , cspNavigationType , and documentResource .
-
If matchingPrerenderedNavigable is not null, then:
-
Wait until either matchingPrerenderedNavigable ’s active document 's is initial about:blank is false, or matchingPrerenderedNavigable is destroyed .
-
If matchingPrerenderedNavigable was not destroyed, then:
-
Activate matchingPrerenderedNavigable in place of navigable given historyHandling and navigationId .
-
Abort these steps.
-
-
2.2. Navigation fetch changes
-
Let initiatorOrigin be entry ’s document state 's initiator origin .
Append the following steps after the first sub-step under "While true:":
-
If navigable is a prerendering navigable and currentURL ’s origin is not same site with initiatorOrigin , then:
-
If navigable is a top-level traversable , then return null.
-
Otherwise, the user agent must wait to continue this algorithm until navigable ’s loading mode becomes "
normal
". At any point during this wait (including immediately), it may instead choose to destroy navigable ’s top-level traversable and return null from this algorithm.
-
Append the following steps toward the end of the algorithm, after the steps which check locationURL :
-
If navigable is a prerendering navigable , and responseOrigin is not same origin with initiatorOrigin , then:
-
Let loadingModes be the result of getting the supported loading modes for response .
-
If loadingModes does not contain `
credentialed-prerender
`, then return null.In the future we could possibly also allow the
uncredentialed-prerender
token to work here. However, since that is primarily intended for the cross site case, which isn’t specified or implemented yet, we don’t want to encourage its use in the wild, so for now we specify that prerendering fails if only theuncredentialed-prerender
token is found.
-
-
If navigable is a prerendering navigable , and any of the following hold:
-
failure is true;
-
navigationParams ’s request is null;
-
navigationParams ’s request 's current URL 's scheme is not a HTTP(S) scheme ;
-
navigationParams ’s response does not support prefetch ;
Responses which are ineligible for prefetch, e.g. because they have an error status, are not eligible for prerender either. A future version of this specification might allow responses to more clearly delineate the two. -
navigationParams ’s response has a `
Content-Disposition
` header specifying theattachment
disposition type; or
then:
-
Destroy navigable ’s top-level traversable .
-
Return.
-
-
If navigable is a prerendering navigable , then return without invoking the external software package.
We could also allow prerendering activations in place of redirects, not just in place of navigations. We’ve omitted that for now as it adds complexity and is not yet implemented anywhere to our knowledge.
2.3. Maintaining a trivial session history
-
If navigable is a prerendering navigable , then set historyHandling to "
replace
".
-
If navigable is a prerendering navigable , then set historyHandling to "
replace
".
2.4. Interaction with worker lifetime
A
worker
is
said
to
be
an
active
needed
worker
if
any
of
its
owners
are
either
Document
objects
that
are
fully
active
and
their
node
navigable
is
not
a
prerendering
navigable
,
or
active
needed
workers
.
This means that the worker’s script would load, but the execution would be suspended until the document is activated.
2.5.
Cleanup
upon
discarding
a
Document
Modify
the
destroy
algorithm
for
Document
s
by
appending
the
following
step:
-
Empty document ’s post-prerendering activation steps list .
3. Interaction with other specifications and concepts
3.1. Interaction with Page Visibility
Documents
in
prerendering
navigables
always
have
a
visibility
state
of
"
hidden
".
We
should
probably
explicitly
update
this,
similar
to
how
we
need
to
update
document.prerendering
.
3.2. Interaction with system focus
Prerendering traversables never have system focus .
3.3.
Extensions
to
the
PerformanceNavigationTiming
interface
Extend
the
PerformanceNavigationTiming
interface
as
follows:
partial interface PerformanceNavigationTiming {readonly attribute DOMHighResTimeStamp activationStart ; };
The
activationStart
getter
steps
are:
-
Return this 's relevant global object 's associated Document 's activation start time .
3.4. Interaction with Client Hint Cache
We need to ensure that the Accept-CH cache , which is owned by user agent as a global storage, is not modified while prerendering, but is properly updated after activation. The following modifications ensure this.
Each prerendering navigable has a prerender-scoped Accept-CH cache , which is an ordered map of origin to client hints sets .
This stores which client hints each origin has opted into receiving, until it can be copied to the global Accept-CH cache when activation is finalized .
-
Let navigable be settingsObject ’s global object 's navigable .
-
Let originMatchingEntries be the entries in the Accept-CH cache whose origin is same origin with settingsObject ’s origin .
-
If navigable is a prerendering navigable , then:
-
Let prerenderAcceptClientHintsCache be navigable ’s prerender-scoped Accept-CH cache .
-
Let origin be settingsObject ’s origin .
-
If prerenderAcceptClientHintsCache [ origin ] exists , then let originMatchingEntries be the entries in the prerenderAcceptClientHintsCache whose origin is same origin with origin .
-
-
Let navigable be settingsObject ’s global object 's navigable .
-
If navigable is a prerendering navigable , set navigable ’s prerender-scoped Accept-CH cache [ origin ] to hintSet .
-
Otherwise, set Accept-CH cache [ origin ] to hintSet .
4.
The
`
Supports-Loading-Mode
`
HTTP
response
header
The following section would be added as a sub-section of [HTML] 's Loading web pages section.
In
some
cases,
cross-origin
web
pages
might
not
be
prepared
to
be
loaded
in
a
novel
context.
To
allow
them
to
opt
in
to
being
loaded
in
such
ways,
the
`
Supports-Loading-Mode
`
HTTP
response
header
can
be
used.
This
header
is
a
structured
header
;
if
present
its
value
must
be
one
or
more
of
the
tokens
listed
below.
The parsing is actually done as a list of tokens , and unknown tokens will be ignored.
The
`
credentialed-prerender
`
token
indicates
that
the
response
can
be
used
to
create
a
prerendering
navigable
,
despite
the
prerendering
being
initiated
by
a
cross-origin
same-site
referrer.
Without
this
opt-in,
such
prerenders
will
fail,
as
outlined
in
§ 2.2
Navigation
fetch
changes
.
The
`
uncredentialed-prefetch
`
token
indicates
that
the
response
is
suitable
to
use
even
if
a
top-level
navigation
to
this
URL
would
ordinarily
send
credentials
such
as
cookies.
For
instance,
the
response
may
be
identical
or
it
may
be
semantically
equivalent
(e.g.,
an
HTML
resource
containing
script
which
can
update
the
document
after
navigation,
when
local
user
state
is
available).
To get the supported loading modes for a response response :
-
If response is a network error , then return an empty list.
-
Let slmHeader be the result of getting a structured field value given `
Supports-Loading-Mode
` and "list
" from response ’s header list . -
Return a list containing all elements of slmHeader that are tokens .
5. Preventing nonsensical behaviors
Some behaviors might make sense in most navigables , but do not make sense in prerendering navigables . This section enumerates specification patches to enforce such restrictions.
5.1. APIs for creating and navigating browsing contexts by name
Modify the definition of script-closable to prevent window closing while in a prerendering navigable :
A navigable is script-closable if either of the following is true:
-
it is an auxiliary browsing context that was created by script (as opposed to by an action of the user); or
-
it is a top-level traversable that is not a prerendering traversable and whose session history entries 's size is 1.
6. Preventing intrusive behaviors
Various behaviors are disallowed in prerendering navigables because they would be intrusive to the user, since the prerendered content is not being actively interacted with.
6.1. Downloading resources
Modify the download the hyperlink algorithm to ensure that downloads inside prerendering navigable are delayed until activation , by inserting the following before the step which goes in parallel :
-
If subject ’s node navigable is a prerendering navigable , then append the following step to subject ’s post-prerendering activation steps list and return.
6.2. User prompts
Window
window
,
by
prepending
the
following
step:
-
If window ’s navigable is a prerendering navigable , then return true.
print()
method
steps
by
prepending
the
following
step:
-
If this 's navigable is a prerendering navigable , then return.
6.3. Delaying async API results
Many specifications need to be patched so that, if a given algorithm invoked in a prerendering navigable , most of its work is deferred until the navigable’s top-level traversable is activated . This is tricky to do uniformly, as many of these specifications do not have great hygeine around using the event loop . Nevertheless, the following sections give our best attempt.
6.3.1.
The
[DelayWhilePrerendering]
extended
attribute
To
abstract
away
some
of
the
boilerplate
involved
in
delaying
the
action
of
asynchronous
methods
until
activation
,
we
introduce
the
[DelayWhilePrerendering]
Web
IDL
extended
attribute.
It
indicates
that
when
a
given
method
is
called
in
a
prerendering
navigable
,
it
will
immediately
return
a
pending
promise
and
do
nothing
else.
Only
upon
activation
will
the
usual
method
steps
take
place,
with
their
result
being
used
to
resolve
or
reject
the
previously-returned
promise.
The
[DelayWhilePrerendering]
extended
attribute
must
take
no
arguments,
and
must
only
appear
on
a
regular
or
static
operation
whose
return
type
is
a
promise
type
or
undefined
,
and
whose
exposure
set
contains
only
Window
.
[DelayWhilePrerendering]
extended
attribute
are
replaced
with
the
following:
-
Let realm be the current realm .
-
If the operation in question is a regular operation , then set realm to the relevant realm of this .
-
If realm ’s global object 's navigable is a prerendering navigable , then:
-
Let promise be a new promise , created in realm .
-
Append the following steps to this 's post-prerendering activation steps list :
-
If this operation’s return type is a promise type , then return promise .
-
-
Otherwise, return the result of running the originally-specified steps for this operation, with the same this and arguments.
6.3.2. Service Workers
Add
[DelayWhilePrerendering]
to
update()
,
unregister()
,
register(scriptURL,
options)
,
postMessage(message,
transfer)
,
and
postMessage(message,
options)
.
This allows prerendered page to take advantage of existing service workers, but not have any effect on the state of service worker registrations.
6.3.3. BroadcastChannel
Add
[DelayWhilePrerendering]
to
postMessage()
.
6.3.4. Geolocation API
getCurrentPosition()
method
steps
by
prepending
the
following
step:
-
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return.
watchPosition()
method
steps
by
prepending
the
following
step:
-
If this 's relevant global object 's navigable is a prerendering navigable , then:
-
Let watchId be an implementation-defined
unsigned long
, and note it as a post-prerendering activation geolocation watch process ID . -
Append the following steps to this 's post-prerendering activation steps list , with the modification that the watchId generated must use watchId as its ID, and return watchId .
-
clearWatch(watchId)
method
steps
by
prepending
the
following
step:
-
If this 's relevant global object 's navigable is a prerendering navigable , then:
-
If watchId is a post-prerendering activation geolocation watch process ID , then remove its corresponding steps from this 's post-prerendering activation steps list .
-
Return.
-
6.3.5. Web Serial API
Add
[DelayWhilePrerendering]
to
requestPort()
.
TODO:
the
below
could
probably
be
done
by
generalizing
[DelayWhilePrerendering]
to
use
owner
document
while
in
dedicated
workers.
getPorts()
method
steps
by
inserting
the
following
steps
after
the
initial
creation
of
promise
:
-
Let document be this 's relevant global object 's associated Document , if this 's relevant global object is a
Window
, or this 's relevant global object 's owner document, if this 's relevant global object is aDedicatedWorkerGlobalScope
. -
If document is null, then return a promise rejected with a "
SecurityError
"DOMException
. -
If document ’s node navigable is a prerendering navigable , then append the following steps to document ’s post-prerendering activation steps list and return promise .
6.3.6. Notifications API
Add
[DelayWhilePrerendering]
to
requestPermission()
.
Notification()
constructor
steps
by
replacing
the
step
which
goes
in
parallel
with
the
following:
-
If this 's relevant global object 's navigable is a prerendering navigable , then append these steps to this 's post-prerendering activation steps list . Otherwise, run these steps in parallel .
permission
static
getter
steps
by
replacing
them
with
the
following:
-
If the current global object 's navigable is a prerendering navigable , then return "
default
".This allows implementations to avoid looking up the actual permission state, which might not be synchronously accessible especially in the case of prerendering navigables . Web developers can then call
Notification.requestPermission()
, which per the above modifications will only actually do anything after activation. At that time we might discover that the permission is "granted
" or "denied
", so the browser might not actually ask the user like would normally be the case with "default
". But that’s OK: it’s not observable to web developer code. -
Otherwise, get the notifications permission state and return it.
6.3.7. Web MIDI API
Add
[DelayWhilePrerendering]
to
requestMIDIAccess()
.
6.3.8. Idle Detection API
Add
[DelayWhilePrerendering]
to
start()
.
The
other
interesting
method,
IdleDetector.requestPermission()
,
is
gated
on
transient
activation
.
However,
even
if
permission
was
previously
granted
for
the
origin
in
question,
we
delay
starting
any
idle
detectors
while
prerendering.
6.3.9. Generic Sensor API
start()
method
steps
by
inserting
the
following
steps
after
the
state
is
set
to
"
activating
":
-
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return.
-
If this .
[[state]]
is "idle
", then return.This ensures that if this portion of the algorithm was delayed due to prerendering, and in the meantime
stop()
was called, we do nothing upon activating the prerender.
6.3.10. Web NFC
Add
[DelayWhilePrerendering]
to
write()
and
scan()
.
6.3.11. Battery Status API
getBattery()
method
steps
by
prepending
the
following
step:
-
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return this . [[BatteryPromise]] .
6.3.12. Screen Orientation API
-
Let promise be a new promise.
-
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return promise .
-
If the user agent does not support locking the screen orientation, then reject promise with a "
NotSupportedError
"DOMException
and return promise . -
If the document 's active sandboxing flag set has the sandboxed orientation lock browsing context flag set, or the user agent doesn’t meet the pre-lock conditions to perform an orientation change, then reject promise with a "
SecurityError
"DOMException
and return promise . -
Set the document 's [[orientationPendingPromise]] to promise .
Add
[DelayWhilePrerendering]
to
unlock()
.
This
latter
modification
is
necessary
to
ensure
that
code
that
calls
screen.orientation.lock()
followed
by
screen.orientation.unlock()
produces
the
expected
results.
6.3.13. Gamepad
getGamepads()
method
steps
by
prepending
the
following
step:
-
If this 's relevant global object 's navigable is a prerendering navigable , then return an empty sequence.
Modify
the
discussion
of
the
gamepadconnected
and
gamepaddisconnected
events
to
specify
that
the
user
agent
must
not
dispatch
these
events
if
the
Window
object’s
navigable
is
a
prerendering
navigable
.
gamepadconnected
section
to
indicate
that
every
Document
document
’s
post-prerendering
activation
steps
list
should
gain
the
following
steps:
-
If document is allowed to use the "
gamepad
" feature, and document ’s relevant settings object is a secure context , and any gamepads are connected, then for each connected gamepad, fire an event namedgamepadconnected
at document ’s relevant global object usingGamepadEvent
, with itsgamepad
attribute initialized to a newGamepad
object representing the connected gamepad.
6.3.14. Encrypted Media Extensions
Add
[DelayWhilePrerendering]
to
requestMediaKeySystemAccess()
.
6.3.15. Media Autoplay
Modify
the
playing
the
media
resource
section
to
indicate
that
the
the
current
playback
position
of
a
HTMLMediaElement
must
increase
monotonically
only
when
the
Document
is
not
prerendering
.
6.3.16. Media Capture and Streams
Add
[DelayWhilePrerendering]
to
getUserMedia()
,
getUserMedia()
and
enumerateDevices()
.
MediaDevices
section
by
prepending
the
following
step
to
the
device
change
notification
steps
:
-
If this 's relevant global object 's navigable is a prerendering navigable , then return.
6.3.17. Web Audio API
The
concept,
allowed
to
start
,
is
used
in
the
spec,
but
details
are
left
implementation-defined
.
To
restrict
auto
playback
while
prerendering,
add
the
following
rule
in
the
AudioContext
interface
section.
The
AudioContext
is
never
allowed
to
start
while
prerendering.
Also
modify
AudioContext()
constructor
steps
to
have
the
following
step
before
returning
the
constructed
object.
-
Else if context is not allow to start only due to the prerendering, then append the following steps to context ’s post-prerendering activation steps list .
-
Set the [[control thread state]] on context to running .
-
Queue a control message to resume context .
-
Developers
might
call
resume()
while
prerendering.
In
that
case,
the
context
is
not
allow
to
start
,
and
appends
a
Promise
to
[[pending
resume
promises]]
.
The
Promise
will
be
resolved
in
the
activation
steps
above.
The
AudioScheduledSourceNode
interface
has
a
start(when)
method
and
the
AudioBufferSourceNode
interface
has
a
start(when,
offset,
duration)
method
that
might
affect
[[control
thread
state]]
.
But
they
don’t
as
the
context
is
not
allowed
to
start
and
it
prevents
the
algorithm
from
setting
the
[[control
thread
state]]
.
This
would
not
matter
because
the
node
can
automatically
start
when
the
context
starts.
6.3.18. Audio Output Devices API
Add
[DelayWhilePrerendering]
to
selectAudioOutput()
.
6.3.19. Push API
Add
[DelayWhilePrerendering]
to
subscribe()
.
6.3.20. Background Fetch
Add
[DelayWhilePrerendering]
to
fetch()
.
6.3.21. Storage API
Add
[DelayWhilePrerendering]
to
persist()
.
6.3.22. WebUSB API
Add
[DelayWhilePrerendering]
to
getDevices()
and
requestDevice()
.
6.3.23. Web Bluetooth
Add
[DelayWhilePrerendering]
to
getDevices()
and
requestDevice()
.
6.3.24. WebHID API
Add
[DelayWhilePrerendering]
to
getDevices()
and
requestDevice()
.
6.3.25. WebXR Device API
Add
[DelayWhilePrerendering]
to
requestSession()
.
6.3.26. Credential Management
Add
[DelayWhilePrerendering]
to
get()
,
store()
,
and
create()
.
6.3.27. Web Speech API
Add
[DelayWhilePrerendering]
to
speak(utterance)
,
cancel()
,
pause()
,
and
resume()
.
Add
[DelayWhilePrerendering]
to
start()
,
stop()
,
and
abort()
.
6.3.28. Web Locks API
Add
[DelayWhilePrerendering]
to
request(name,
callback)
,
request(name,
options,
callback)
,
and
query()
.
6.3.29. Custom Scheme Handlers
registerProtocolHandler(scheme,
url)
method
steps
by
overwriting
the
first
few
steps,
before
it
goes
in
parallel
,
as
follows:
Let ( normalizedScheme , normalizedURLString ) be the result of running normalize protocol handler parameters with scheme, url, and this 's relevant settings object .
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return.
unregisterProtocolHandler(scheme,
url)
method
steps
by
overwriting
the
first
few
steps,
before
it
goes
in
parallel
,
as
follows:
Let ( normalizedScheme , normalizedURLString ) be the result of running normalize protocol handler parameters with scheme, url, and this 's relevant settings object .
If this 's relevant global object 's navigable is a prerendering navigable , then append the following steps to this 's post-prerendering activation steps list and return.
6.4. Implicitly restricted APIs
Some APIs do not need modifications because they will automatically fail or no-op without a property that a prerendering navigable , its active window , or its active document will never have. These properties include:
-
the "
visible
" visibility state
We list known APIs here for completeness, to show which API surfaces we’ve audited.
APIs that require transient activation or sticky activation :
-
The prompt generated by the
beforeunload
event [HTML] -
element.requestFullscreen()
[FULLSCREEN]-
navigator.keyboard.lock()
[KEYBOARD-LOCK] , which requires fullscreen[KEYBOARD-LOCK] allows browsing contexts to enable keyboard lock easily but it has no effect except in fullscreen, which requires a user gesture. If that changes then this needs to be revisited.
-
-
showOpenFilePicker()
,showSaveFilePicker()
, andshowDirectoryPicker()
[FILE-SYSTEM-ACCESS] -
Firing of clipboard events. [CLIPBOARD-APIS]
APIs that require system focus :
-
The Asynchronous Clipboard API:
navigator.clipboard.read()
,navigator.clipboard.readText()
,navigator.clipboard.write()
,navigator.clipboard.writeText()
. [CLIPBOARD-APIS]
APIs
that
require
the
"
visible
"
visibility
state
:
More complicated cases:
-
Request Picture-in-Picture as invoked due to
video.requestPictureInPicture()
requires either transient activation , or the visibility state to have been "visible
". [PICTURE-IN-PICTURE]