WindowOrWorkerGlobalScope
mixin
Various mechanisms can cause author-provided executable code to run in the context of a document. These mechanisms include, but are probably not limited to:
script
elements.
javascript:
URLs
.
addEventListener()
,
by
explicit
event
handler
content
attributes
,
by
event
handler
IDL
attributes
,
or
otherwise.
JavaScript defines the concept of an agent . This section gives the mapping of that language-level concept on to the web platform.
Conceptually, the agent concept is an architecture-independent, idealized "thread" in which JavaScript code runs. Such code can involve multiple globals/ realms that can synchronously access each other, and thus needs to run in a single execution thread.
Two
Window
objects
having
the
same
agent
does
not
indicate
they
can
directly
access
all
objects
created
in
each
other's
realms.
They
would
have
to
be
same
origin-domain
;
see
IsPlatformObjectSameOrigin
.
The following types of agents exist on the web platform:
Contains
various
Window
objects
which
can
potentially
reach
each
other,
either
directly
or
by
using
document.domain
.
If
the
encompassing
agent
cluster
's
is
origin-keyed
is
true,
then
all
the
Window
objects
will
be
same
origin
,
can
reach
each
other
directly,
and
document.domain
will
no-op.
Two
Window
objects
that
are
same
origin
can
be
in
different
similar-origin
window
agents
,
for
instance
if
they
are
each
in
their
own
browsing
context
group
.
Contains
a
single
DedicatedWorkerGlobalScope
.
Contains
a
single
SharedWorkerGlobalScope
.
Contains
a
single
ServiceWorkerGlobalScope
.
Contains
a
single
WorkletGlobalScope
object.
Although a given worklet can have multiple realms, each such realm needs its own agent, as each realm can be executing code independently and at the same time as the others.
Only
shared
and
dedicated
worker
agents
allow
the
use
of
JavaScript
Atomics
APIs
to
potentially
block
.
To create an agent , given a boolean canBlock :
Let signifier be a new unique internal value.
Let candidateExecution be a new candidate execution .
Let agent be a new agent whose [[CanBlock]] is canBlock , [[Signifier]] is signifier , [[CandidateExecution]] is candidateExecution , and [[IsLockFree1]], [[IsLockFree2]], and [[LittleEndian]] are set at the implementation's discretion.
Set agent 's event loop to a new event loop .
Return agent .
The relevant agent for a platform object platformObject is platformObject 's relevant Realm 's agent . This pointer is not yet defined in the JavaScript specification; see tc39/ecma262#1357 .
The agent equivalent of the current Realm Record is the surrounding agent .
JavaScript also defines the concept of an agent cluster , which this standard maps to the web platform by placing agents appropriately when they are created using the obtain a similar-origin window agent or obtain a worker/worklet agent algorithms.
The
agent
cluster
concept
is
crucial
for
defining
the
JavaScript
memory
model,
and
in
particular
among
which
agents
the
backing
data
of
SharedArrayBuffer
objects
can
be
shared.
Conceptually, the agent cluster concept is an architecture-independent, idealized "process boundary" that groups together multiple "threads" ( agents ). The agent clusters defined by the specification are generally more restrictive than the actual process boundaries implemented in user agents. By enforcing these idealized divisions at the specification level, we ensure that web developers see interoperable behavior with regard to shared memory, even in the face of varying and changing user agent process models.
An
agent
cluster
has
an
associated
cross-origin
isolation
mode
,
which
is
a
cross-origin
isolation
mode
.
It
is
initially
"
none
".
An agent cluster has an associated is origin-keyed (a boolean), which is initially false.
The following defines the allocation of the agent clusters of similar-origin window agents .
An agent cluster key is a site or tuple origin . Without web developer action to achieve origin-keyed agent clusters , it will be a site .
An equivalent formulation is that an agent cluster key can be a scheme-and-host or an origin .
To obtain a similar-origin window agent , given an origin origin , a browsing context group group , and a boolean requestsOAC , run these steps:
Let site be the result of obtaining a site with origin .
Let key be site .
If
group
's
cross-origin
isolation
mode
is
not
"
none
",
then
set
key
to
origin
.
Otherwise, if group 's historical agent cluster key map [ origin ] exists , then set key to group 's historical agent cluster key map [ origin ].
Otherwise:
If requestsOAC is true, then set key to origin .
Set group 's historical agent cluster key map [ origin ] to key .
If group 's agent cluster map [ key ] does not exist , then:
Let agentCluster be a new agent cluster .
Set agentCluster 's cross-origin isolation mode to group 's cross-origin isolation mode .
Set agentCluster 's is origin-keyed to true if key equals origin ; otherwise false.
Add the result of creating an agent , given false, to agentCluster .
Set group 's agent cluster map [ key ] to agentCluster .
Return the single similar-origin window agent contained in group 's agent cluster map [ key ].
This means that there is only one similar-origin window agent per browsing context agent cluster. (However, dedicated worker and worklet agents might be in the same cluster.)
The following defines the allocation of the agent clusters of all other types of agents.
To obtain a worker/worklet agent , given an environment settings object or null outside settings , a boolean isTopLevel , and a boolean canBlock , run these steps:
Let agentCluster be null.
If isTopLevel is true, then:
Set agentCluster to a new agent cluster .
Set agentCluster 's is origin-keyed to true.
These
workers
can
be
considered
to
be
origin-keyed.
However,
this
is
not
exposed
through
any
APIs
(in
the
way
that
originAgentCluster
exposes
the
origin-keyedness
for
windows).
Otherwise:
Assert: outside settings is not null.
Let ownerAgent be outside settings 's Realm 's agent.
Set agentCluster to the agent cluster which contains ownerAgent .
Let agent be the result of creating an agent given canBlock .
Add agent to agentCluster .
Return agent .
To obtain a dedicated/shared worker agent , given an environment settings object outside settings and a boolean isShared , return the result of obtaining a worker/worklet agent given outside settings , isShared , and true.
To obtain a worklet agent , given an environment settings object outside settings , return the result of obtaining a worker/worklet agent given outside settings , false, and false.
To obtain a service worker agent , return the result of obtaining a worker/worklet agent given null, true, and false.
The JavaScript specification introduces the realm concept, representing a global environment in which script is run. Each realm comes with an implementation-defined global object ; much of this specification is devoted to defining that global object and its properties.
For
web
specifications,
it
is
often
useful
to
associate
values
or
algorithms
with
a
realm/global
object
pair.
When
the
values
are
specific
to
a
particular
type
of
realm,
they
are
associated
directly
with
the
global
object
in
question,
e.g.,
in
the
definition
of
the
Window
or
WorkerGlobalScope
interfaces.
When
the
values
have
utility
across
multiple
realms,
we
use
the
environment
settings
object
concept.
Finally, in some cases it is necessary to track associated values before a realm/global object/environment settings object even comes into existence (for example, during navigation ). These values are tracked in the environment concept.
An environment is an object that identifies the settings of a current or potential execution environment. An environment has the following fields:
An opaque string that uniquely identifies this environment .
A URL that represents the location of the resource with which this environment is associated.
In
the
case
of
a
Window
environment
settings
object
,
this
URL
might
be
distinct
from
its
global
object
's
associated
Document
's
URL
,
due
to
mechanisms
such
as
history.pushState()
which
modify
the
latter.
Null or a URL that represents the creation URL of the "top-level" environment . It is null for workers and worklets.
A for now implementation-defined value, null, or an origin . For a "top-level" potential execution environment it is null (i.e., when there is no response yet); otherwise it is the "top-level" environment 's origin . For a dedicated worker or worklet it is the top-level origin of its creator. For a shared or service worker it is an implementation-defined value.
This is distinct from the top-level creation URL 's origin when sandboxing, workers, and worklets are involved.
Null or a target browsing context for a navigation request .
Null or a service worker that controls the environment .
A flag that indicates whether the environment setup is done. It is initially unset.
Specifications may define environment discarding steps for environments. The steps take an environment as input.
The environment discarding steps are run for only a select few environments: the ones that will never become execution ready because, for example, they failed to load.
An environment settings object is an environment that additionally specifies algorithms for:
A JavaScript execution context shared by all scripts that use this settings object, i.e. all scripts in a given JavaScript realm . When we run a classic script or run a module script , this execution context becomes the top of the JavaScript execution context stack , on top of which another execution context specific to the script in question is pushed. (This setup ensures ParseScript and Source Text Module Record 's Evaluate know which Realm to use.)
A module map that is used when importing JavaScript modules.
A character encoding used to encode URLs by APIs called by scripts that use this environment settings object .
A URL used by APIs called by scripts that use this environment settings object to parse URLs .
An origin used in security checks.
A policy container containing policies used for security checks.
A boolean representing whether scripts that use this environment settings object are allowed to use APIs that require cross-origin isolation.
An environment settings object also has an outstanding rejected promises weak set and an about-to-be-notified rejected promises list , used to track unhandled promise rejections . The outstanding rejected promises weak set must not create strong references to any of its members, and implementations are free to limit its size, e.g. by removing old entries from it when new ones are added.
An environment settings object 's responsible event loop is its global object 's relevant agent 's event loop .
A global object is a JavaScript object that is the [[GlobalObject]] field of a JavaScript realm .
In
this
specification,
all
JavaScript
realms
are
created
with
global
objects
that
are
either
Window
or
WorkerGlobalScope
objects.
There is always a 1-to-1-to-1 mapping between JavaScript realms , global objects , and environment settings objects :
A JavaScript realm has a [[HostDefined]] field, which contains the Realm's settings object .
A JavaScript realm has a [[GlobalObject]] field, which contains the Realm's global object .
Each global object in this specification is created during the creation of a corresponding JavaScript realm , known as the global object's Realm .
Each global object in this specification is created alongside a corresponding environment settings object , known as its relevant settings object .
An environment settings object 's realm execution context 's Realm component is the environment settings object's Realm .
An environment settings object 's Realm then has a [[GlobalObject]] field, which contains the environment settings object's global object .
To create a new JavaScript realm in an agent agent , optionally with instructions to create a global object or a global this binding (or both), the following steps are taken:
Perform InitializeHostDefinedRealm () with the provided customizations for creating the global object and the global this binding.
Let realm execution context be the running JavaScript execution context .
This is the JavaScript execution context created in the previous step.
Remove realm execution context from the JavaScript execution context stack .
Let realm be realm execution context 's Realm component.
Set realm 's agent to agent . This pointer is not yet defined in the JavaScript specification; see tc39/ecma262#1357 .
If
agent
's
agent
cluster
's
cross-origin
isolation
mode
is
"
none
",
then:
Let global be realm 's global object .
Let
status
be
!
global
.[[Delete]]("
SharedArrayBuffer
").
Assert: status is true.
This
is
done
for
compatibility
with
web
content
and
there
is
some
hope
that
this
can
be
removed
in
the
future.
Web
developers
can
still
get
at
the
constructor
through
new
WebAssembly.Memory({
shared:true,
initial:0,
maximum:0
}).buffer.constructor
.
Return realm execution context .
When defining algorithm steps throughout this specification, it is often important to indicate what JavaScript realm is to be used—or, equivalently, what global object or environment settings object is to be used. In general, there are at least four possibilities:
Note how the entry , incumbent , and current concepts are usable without qualification, whereas the relevant concept must be applied to a particular platform object .
The incumbent and entry concepts should not be used by new specifications, as they are excessively complicated and unintuitive to work with. We are working to remove almost all existing uses from the platform: see issue #1430 for incumbent , and issue #1431 for entry .
In
general,
web
platform
specifications
should
use
the
relevant
concept,
applied
to
the
object
being
operated
on
(usually
the
this
value
of
the
current
method).
This
mismatches
the
JavaScript
specification,
where
current
is
generally
used
as
the
default
(e.g.
in
determining
the
JavaScript
realm
whose
Array
constructor
should
be
used
to
construct
the
result
in
Array.prototype.map
).
But
this
inconsistency
is
so
embedded
in
the
platform
that
we
have
to
accept
it
going
forward.
Consider
the
following
pages,
with
a.html
being
loaded
in
a
browser
window,
b.html
being
loaded
in
an
iframe
as
shown,
and
c.html
and
d.html
omitted
(they
can
simply
be
empty
documents):
<!-- a.html -->
<!DOCTYPE html>
<html lang="en">
<title>Entry page</title>
<iframe src="b.html"></iframe>
<button onclick="frames[0].hello()">Hello</button>
<!--b.html -->
<!DOCTYPE html>
<html lang="en">
<title>Incumbent page</title>
<iframe src="c.html" id="c"></iframe>
<iframe src="d.html" id="d"></iframe>
<script>
const c = document.querySelector("#c").contentWindow;
const d = document.querySelector("#d").contentWindow;
window.hello = () => {
c.print.call(d);
};
</script>
Each page has its own browsing context , and thus its own JavaScript realm , global object , and environment settings object .
When
the
print()
method
is
called
in
response
to
pressing
the
button
in
a.html
,
then:
The
entry
Realm
is
that
of
a.html
.
The
incumbent
Realm
is
that
of
b.html
.
The
current
Realm
is
that
of
c.html
(since
it
is
the
print()
method
from
c.html
whose
code
is
running).
The
relevant
Realm
of
the
object
on
which
the
print()
method
is
being
called
is
that
of
d.html
.
One
reason
why
the
relevant
concept
is
generally
a
better
default
choice
than
the
current
concept
is
that
it
is
more
suitable
for
creating
an
object
that
is
to
be
persisted
and
returned
multiple
times.
For
example,
the
navigator.getBattery()
method
creates
promises
in
the
relevant
Realm
for
the
Navigator
object
on
which
it
is
invoked.
This
has
the
following
impact:
[BATTERY]
<!-- outer.html -->
<!DOCTYPE html>
<html lang="en">
<title>Relevant Realm demo: outer page</title>
<script>
function doTest() {
const promise = navigator.getBattery.call(frames[0].navigator);
console.log(promise instanceof Promise); // logs false
console.log(promise instanceof frames[0].Promise); // logs true
frames[0].hello();
}
</script>
<iframe src="inner.html" onload="doTest()"></iframe>
<!-- inner.html -->
<!DOCTYPE html>
<html lang="en">
<title>Relevant Realm demo: inner page</title>
<script>
function hello() {
const promise = navigator.getBattery();
console.log(promise instanceof Promise); // logs true
console.log(promise instanceof parent.Promise); // logs false
}
</script>
If
the
algorithm
for
the
getBattery()
method
had
instead
used
the
current
Realm
,
all
the
results
would
be
reversed.
That
is,
after
the
first
call
to
getBattery()
in
outer.html
,
the
Navigator
object
in
inner.html
would
be
permanently
storing
a
Promise
object
created
in
outer.html
's
JavaScript
realm
,
and
calls
like
that
inside
the
hello()
function
would
thus
return
a
promise
from
the
"wrong"
realm.
Since
this
is
undesirable,
the
algorithm
instead
uses
the
relevant
Realm
,
giving
the
sensible
results
indicated
in
the
comments
above.
The rest of this section deals with formally defining the entry , incumbent , current , and relevant concepts.
The process of calling scripts will push or pop realm execution contexts onto the JavaScript execution context stack , interspersed with other execution contexts .
With this in hand, we define the entry execution context to be the most recently pushed item in the JavaScript execution context stack that is a realm execution context . The entry Realm is the entry execution context 's Realm component.
Then, the entry settings object is the environment settings object of the entry Realm .
Similarly, the entry global object is the global object of the entry Realm .
All JavaScript execution contexts must contain, as part of their code evaluation state, a skip-when-determining-incumbent counter value, which is initially zero. In the process of preparing to run a callback and cleaning up after running a callback , this value will be incremented and decremented.
Every event loop has an associated backup incumbent settings object stack , initially empty. Roughly speaking, it is used to determine the incumbent settings object when no author code is on the stack, but author code is responsible for the current algorithm having been run in some way. The process of preparing to run a callback and cleaning up after running a callback manipulate this stack. [WEBIDL]
When Web IDL is used to invoke author code, or when HostEnqueuePromiseJob invokes a promise job, they use the following algorithms to track relevant data for determining the incumbent settings object :
To prepare to run a callback with an environment settings object settings :
Push settings onto the backup incumbent settings object stack .
Let context be the topmost script-having execution context .
If context is not null, increment context 's skip-when-determining-incumbent counter .
To clean up after running a callback with an environment settings object settings :
Let context be the topmost script-having execution context .
This will be the same as the topmost script-having execution context inside the corresponding invocation of prepare to run a callback .
If context is not null, decrement context 's skip-when-determining-incumbent counter .
Assert: the topmost entry of the backup incumbent settings object stack is settings .
Remove settings from the backup incumbent settings object stack .
Here, the topmost script-having execution context is the topmost entry of the JavaScript execution context stack that has a non-null ScriptOrModule component, or null if there is no such entry in the JavaScript execution context stack .
With all this in place, the incumbent settings object is determined as follows:
Let context be the topmost script-having execution context .
If context is null, or if context 's skip-when-determining-incumbent counter is greater than zero, then:
Assert: the backup incumbent settings object stack is not empty.
This assert would fail if you try to obtain the incumbent settings object from inside an algorithm that was triggered neither by calling scripts nor by Web IDL invoking a callback. For example, it would trigger if you tried to obtain the incumbent settings object inside an algorithm that ran periodically as part of the event loop , with no involvement of author code. In such cases the incumbent concept cannot be used.
Return the topmost entry of the backup incumbent settings object stack .
Return context 's Realm component's settings object .
Then, the incumbent Realm is the Realm of the incumbent settings object .
Similarly, the incumbent global object is the global object of the incumbent settings object .
The following series of examples is intended to make it clear how all of the different mechanisms contribute to the definition of the incumbent concept:
Consider the following starter example:
<!DOCTYPE html>
<iframe></iframe>
<script>
frames[0].postMessage("some data", "*");
</script>
There
are
two
interesting
environment
settings
objects
here:
that
of
window
,
and
that
of
frames[0]
.
Our
concern
is:
what
is
the
incumbent
settings
object
at
the
time
that
the
algorithm
for
postMessage()
executes?
It
should
be
that
of
window
,
to
capture
the
intuitive
notion
that
the
author
script
responsible
for
causing
the
algorithm
to
happen
is
executing
in
window
,
not
frames[0]
.
This
makes
sense:
the
window
post
message
steps
use
the
incumbent
settings
object
to
determine
the
source
property
of
the
resulting
MessageEvent
,
and
in
this
case
window
is
definitely
the
source
of
the
message.
Let
us
now
explain
how
the
steps
given
above
give
us
our
intuitively-desired
result
of
window
's
relevant
settings
object
.
When
the
window
post
message
steps
look
up
the
incumbent
settings
object
,
the
topmost
script-having
execution
context
will
be
that
corresponding
to
the
script
element:
it
was
pushed
onto
the
JavaScript
execution
context
stack
as
part
of
ScriptEvaluation
during
the
run
a
classic
script
algorithm.
Since
there
are
no
Web
IDL
callback
invocations
involved,
the
context's
skip-when-determining-incumbent
counter
is
zero,
so
it
is
used
to
determine
the
incumbent
settings
object
;
the
result
is
the
environment
settings
object
of
window
.
(Note
how
the
environment
settings
object
of
frames[0]
is
the
relevant
settings
object
of
this
at
the
time
the
postMessage()
method
is
called,
and
thus
is
involved
in
determining
the
target
of
the
message.
Whereas
the
incumbent
is
used
to
determine
the
source
.)
Consider the following more complicated example:
<!DOCTYPE html>
<iframe></iframe>
<script>
const bound = frames[0].postMessage.bind(frames[0], "some data", "*");
window.setTimeout(bound);
</script>
This
example
is
very
similar
to
the
previous
one,
but
with
an
extra
indirection
through
Function.prototype.bind
as
well
as
setTimeout()
.
But,
the
answer
should
be
the
same:
invoking
algorithms
asynchronously
should
not
change
the
incumbent
concept.
This time, the result involves more complicated mechanisms:
When
bound
is
converted
to
a
Web
IDL
callback
type,
the
incumbent
settings
object
is
that
corresponding
to
window
(in
the
same
manner
as
in
our
starter
example
above).
Web
IDL
stores
this
as
the
resulting
callback
value's
callback
context
.
When
the
task
posted
by
setTimeout()
executes,
the
algorithm
for
that
task
uses
Web
IDL
to
invoke
the
stored
callback
value.
Web
IDL
in
turn
calls
the
above
prepare
to
run
a
callback
algorithm.
This
pushes
the
stored
callback
context
onto
the
backup
incumbent
settings
object
stack
.
At
this
time
(inside
the
timer
task)
there
is
no
author
code
on
the
stack,
so
the
topmost
script-having
execution
context
is
null,
and
nothing
gets
its
skip-when-determining-incumbent
counter
incremented.
Invoking
the
callback
then
calls
bound
,
which
in
turn
calls
the
postMessage()
method
of
frames[0]
.
When
the
postMessage()
algorithm
looks
up
the
incumbent
settings
object
,
there
is
still
no
author
code
on
the
stack,
since
the
bound
function
just
directly
calls
the
built-in
method.
So
the
topmost
script-having
execution
context
will
be
null:
the
JavaScript
execution
context
stack
only
contains
an
execution
context
corresponding
to
postMessage()
,
with
no
ScriptEvaluation
context
or
similar
below
it.
This
is
where
we
fall
back
to
the
backup
incumbent
settings
object
stack
.
As
noted
above,
it
will
contain
as
its
topmost
entry
the
relevant
settings
object
of
window
.
So
that
is
what
is
used
as
the
incumbent
settings
object
while
executing
the
postMessage()
algorithm.
Consider this final, even more convoluted example:
<!-- a.html -->
<!DOCTYPE html>
<button>click me</button>
<iframe></iframe>
<script>
const bound = frames[0].location.assign.bind(frames[0].location, "https://example.com/");
document.querySelector("button").addEventListener("click", bound);
</script>
<!-- b.html -->
<!DOCTYPE html>
<iframe src="a.html"></iframe>
<script>
const iframe = document.querySelector("iframe");
iframe.onload = function onLoad() {
iframe.contentWindow.document.querySelector("button").click();
};
</script>
Again
there
are
two
interesting
environment
settings
objects
in
play:
that
of
a.html
,
and
that
of
b.html
.
When
the
location.assign()
method
triggers
the
Location
-object
navigate
algorithm,
what
will
be
the
incumbent
settings
object
?
As
before,
it
should
intuitively
be
that
of
a.html
:
the
click
listener
was
originally
scheduled
by
a.html
,
so
even
if
something
involving
b.html
causes
the
listener
to
fire,
the
incumbent
responsible
is
that
of
a.html
.
The
callback
setup
is
similar
to
the
previous
example:
when
bound
is
converted
to
a
Web
IDL
callback
type,
the
incumbent
settings
object
is
that
corresponding
to
a.html
,
which
is
stored
as
the
callback's
callback
context
.
When
the
click()
method
is
called
inside
b.html
,
it
dispatches
a
click
event
on
the
button
that
is
inside
a.html
.
This
time,
when
the
prepare
to
run
a
callback
algorithm
executes
as
part
of
event
dispatch,
there
is
author
code
on
the
stack;
the
topmost
script-having
execution
context
is
that
of
the
onLoad
function,
whose
skip-when-determining-incumbent
counter
gets
incremented.
Additionally,
a.html
's
environment
settings
object
(stored
as
the
EventHandler
's
callback
context
)
is
pushed
onto
the
backup
incumbent
settings
object
stack
.
Now,
when
the
Location
-object
navigate
algorithm
looks
up
the
incumbent
settings
object
,
the
topmost
script-having
execution
context
is
still
that
of
the
onLoad
function
(due
to
the
fact
we
are
using
a
bound
function
as
the
callback).
Its
skip-when-determining-incumbent
counter
value
is
one,
however,
so
we
fall
back
to
the
backup
incumbent
settings
object
stack
.
This
gives
us
the
environment
settings
object
of
a.html
,
as
expected.
Note
that
this
means
that
even
though
it
is
the
iframe
inside
a.html
that
navigates,
it
is
a.html
itself
that
is
used
as
the
source
browsing
context
,
which
determines
among
other
things
the
request
client
.
This
is
perhaps
the
only
justifiable
use
of
the
incumbent
concept
on
the
web
platform
;
in
all
other
cases
the
consequences
of
using
it
are
simply
confusing
and
we
hope
to
one
day
switch
them
to
use
current
or
relevant
as
appropriate.
The JavaScript specification defines the current Realm Record , sometimes abbreviated to the "current Realm". [JAVASCRIPT]
Then, the current settings object is the environment settings object of the current Realm Record .
Similarly, the current global object is the global object of the current Realm Record .
The relevant Realm for a platform object is the value of its [[Realm]] field .
Then, the relevant settings object for a platform object o is the environment settings object of the relevant Realm for o .
Similarly, the relevant global object for a platform object o is the global object of the relevant Realm for o .
Scripting is enabled for an environment settings object settings when all of the following conditions are true:
Window
object,
or
settings
's
global
object
's
associated
Document
's
active
sandboxing
flag
set
does
not
have
its
sandboxed
scripts
browsing
context
flag
set.
Scripting is disabled for an environment settings object when scripting is not enabled for it, i.e., when any of the above conditions are false.
Scripting is enabled for a node node if node 's node document 's browsing context is non-null, and scripting is enabled for node 's relevant settings object .
Scripting is disabled for a node when scripting is not enabled , i.e., when its node document 's browsing context is null or when scripting is disabled for its relevant settings object .
An environment environment is a secure context if the following algorithm returns true:
If environment is an environment settings object , then:
Let global be environment 's global object .
If
global
is
a
WorkerGlobalScope
,
then:
If global 's owner set [0]'s relevant settings object is a secure context , then return true.
We only need to check the 0th item since they will necessarily all be consistent.
Return false.
If
global
is
a
WorkletGlobalScope
,
then
return
true.
Worklets can only be created in secure contexts.
If
the
result
of
Is
url
potentially
trustworthy?
given
environment
's
top-level
creation
URL
is
"
Potentially
Trustworthy
",
then
return
true.
Return false.
An environment is a non-secure context if it is not a secure context .
A script is one of three possible structs . All scripts have:
An environment settings object , containing various settings that are shared with other scripts in the same context.
One of the following:
a script record , for classic scripts ;
a Source Text Module Record , for JavaScript module scripts ;
a Synthetic Module Record , for CSS module scripts and JSON module scripts
null, representing a parsing failure.
A JavaScript value, which has meaning only if the record is null, indicating that the corresponding script source text could not be parsed.
This value is used for internal tracking of immediate parse errors when creating scripts , and is not to be used directly. Instead, consult the error to rethrow when determining "what went wrong" for this script.
A JavaScript value representing an error that will prevent evaluation from succeeding. It will be re-thrown by any attempts to run the script.
This could be the script's parse error , but in the case of a module script it could instead be the parse error from one of its dependencies, or an error from resolve a module specifier .
Since this exception value is provided by the JavaScript specification, we know that it is never null, so we use null to signal that no error has occurred.
A base URL used for resolving module specifiers . This will either be the URL from which the script was obtained, for external scripts, or the document base URL of the containing document, for inline scripts.
A classic script is a type of script that has the following additional item :
A boolean which, if true, means that error information will not be provided for errors in this script. This is used to mute errors for cross-origin scripts, since that can leak private information.
A module script is another type of script . It has no additional items .
Module scripts can be classified into three types:
A module script is a JavaScript module script if its record is a Source Text Module Record .
A module script is a CSS module script if its record is a Synthetic Module Record , and it was created via the create a CSS module script algorithm. CSS module scripts represent a parsed CSS stylesheet.
A module script is a JSON module script if its record is a Synthetic Module Record , and it was created via the create a JSON module script algorithm. JSON module scripts represent a parsed JSON document.
As CSS stylesheets and JSON documents do not import dependent modules, and do not throw exceptions on evaluation, the fetch options and base URL of CSS module scripts and JSON module scripts and are always null.
The active script is determined by the following algorithm:
Let record be GetActiveScriptOrModule ().
If record is null, return null.
Return record .[[HostDefined]].
The
active
script
concept
is
so
far
only
used
by
the
import()
feature,
to
determine
the
base
URL
to
use
for
resolving
relative
module
specifiers.
This section introduces a number of algorithms for fetching scripts, taking various necessary inputs and resulting in classic or module scripts .
Script fetch options is a struct with the following items :
The cryptographic nonce metadata used for the initial fetch and for fetching any imported modules
The integrity metadata used for the initial fetch
The parser metadata used for the initial fetch and for fetching any imported modules
The credentials mode used for the initial fetch (for module scripts ) and for fetching any imported modules (for both module scripts and classic scripts )
The referrer policy used for the initial fetch and for fetching any imported modules
The boolean value of render-blocking used for the initial fetch and for fetching any imported modules. Unless otherwise stated, its value is false.
Recall
that
via
the
import()
feature,
classic
scripts
can
import
module
scripts
.
The
default
classic
script
fetch
options
are
a
script
fetch
options
whose
cryptographic
nonce
is
the
empty
string,
integrity
metadata
is
the
empty
string,
parser
metadata
is
"
not-parser-inserted
",
credentials
mode
is
"
same-origin
",
and
referrer
policy
is
the
empty
string.
Given a request request and a script fetch options options , we define:
Set request 's cryptographic nonce metadata to options 's cryptographic nonce , its integrity metadata to options 's integrity metadata , its parser metadata to options 's parser metadata , its referrer policy to options 's referrer policy , and its render-blocking to options 's render-blocking .
Set request 's cryptographic nonce metadata to options 's cryptographic nonce , its integrity metadata to options 's integrity metadata , its parser metadata to options 's parser metadata , its credentials mode to options 's credentials mode , its referrer policy to options 's referrer policy , and its render-blocking to options 's render-blocking .
For any given script fetch options options , the descendant script fetch options are a new script fetch options whose items all have the same values, except for the integrity metadata , which is instead the empty string.
The
algorithms
below
can
be
customized
by
optionally
supplying
a
custom
perform
the
fetch
hook,
which
takes
a
request
and
an
is
top-level
flag.
The
algorithm
must
complete
with
a
response
(which
may
be
a
network
error
),
either
synchronously
(when
using
fetch
a
classic
worker-imported
script
)
or
asynchronously
(otherwise).
The
is
top-level
flag
will
be
set
for
all
classic
script
fetches,
and
for
the
initial
fetch
when
fetching
an
external
module
script
graph
,
fetching
a
module
worker
script
graph
,
or
fetching
an
import()
module
script
graph
,
but
not
for
the
fetches
resulting
from
import
statements
encountered
throughout
the
graph.
By default, not supplying the perform the fetch will cause the below algorithms to simply fetch the given request , with algorithm-specific customizations to the request and validations of the resulting response .
To layer your own customizations on top of these algorithm-specific ones, supply a perform the fetch hook that modifies the given request , fetches it, and then performs specific validations of the resulting response (completing with a network error if the validations fail).
The hook can also be used to perform more subtle customizations, such as keeping a cache of responses and avoiding performing a fetch at all.
Service Workers is an example of a specification that runs these algorithms with its own options for the hook. [SW]
Now for the algorithms themselves.
To fetch a classic script given a url , a settings object , some options , a CORS setting , and a character encoding , run these steps. The algorithm will asynchronously complete with either null (on failure) or a new classic script (on success).
Let
request
be
the
result
of
creating
a
potential-CORS
request
given
url
,
"
script
",
and
CORS
setting
.
Set request 's client to settings object .
Set up the classic script request given request and options .
If the caller specified custom steps to perform the fetch , perform them on request , with the is top-level flag set. Return from this algorithm, and when the custom perform the fetch steps complete with response response , run the remaining steps.
Otherwise, fetch request . Return from this algorithm, and run the remaining steps as part of the fetch's processResponseConsumeBody given response response .
response can be either CORS-same-origin or CORS-cross-origin . This only affects how error reporting happens.
Finalize
and
report
timing
with
response
,
settings
object
's
global
object
,
and
"
script
".
Set response to response 's unsafe response .
If
response
's
type
is
"
error
",
or
response
's
status
is
not
an
ok
status
,
then
asynchronously
complete
this
algorithm
with
null,
and
return.
For historical reasons, this algorithm does not include MIME type checking, unlike the other script-fetching algorithms in this section.
Let potentialMIMETypeForEncoding be the result of extracting a MIME type given response 's header list .
Set character encoding to the result of legacy extracting an encoding given potentialMIMETypeForEncoding and character encoding .
This intentionally ignores the MIME type essence .
Let source text be the result of decoding response 's body to Unicode, using character encoding as the fallback encoding.
The decode algorithm overrides character encoding if the file contains a BOM.
Let muted errors be true if response was CORS-cross-origin , and false otherwise.
Let script be the result of creating a classic script given source text , settings object , response 's url , options , and muted errors .
To fetch a classic worker script given a url , a fetch client settings object , a destination , and a script settings object , run these steps. The algorithm will asynchronously complete with either null (on failure) or a new classic script (on success).
Let
request
be
a
new
request
whose
URL
is
url
,
client
is
fetch
client
settings
object
,
destination
is
destination
,
mode
is
"
same-origin
",
credentials
mode
is
"
same-origin
",
parser
metadata
is
"
not
parser-inserted
",
and
whose
use-URL-credentials
flag
is
set.
If the caller specified custom steps to perform the fetch , perform them on request , with the is top-level flag set. Return from this algorithm, and when the custom perform the fetch steps complete with response response , run the remaining steps.
Otherwise, fetch request . Return from this algorithm, and run the remaining steps as part of the fetch's processResponseConsumeBody given response response .
Finalize
and
report
timing
with
response
,
fetch
client
settings
object
's
global
object
,
and
"
other
".
Set response to response 's unsafe response .
If either of the following conditions are met:
then asynchronously complete this algorithm with null, and return.
If both of the following conditions are met:
response 's url 's scheme is an HTTP(S) scheme ; and
the result of extracting a MIME type from response 's header list is not a JavaScript MIME type ,
then asynchronously complete this algorithm with null, and return.
Other fetch schemes are exempted from MIME type checking for historical web-compatibility reasons. We might be able to tighten this in the future; see issue #3255 .
Let source text be the result of UTF-8 decoding response 's body .
Let script be the result of creating a classic script using source text , script settings object , response 's url , and the default classic script fetch options .
To fetch a classic worker-imported script given a url and a settings object , run these steps. The algorithm will synchronously complete with a classic script on success, or throw an exception on failure.
Let
request
be
a
new
request
whose
URL
is
url
,
client
is
settings
object
,
destination
is
"
script
",
parser
metadata
is
"
not
parser-inserted
",
synchronous
flag
is
set,
and
whose
use-URL-credentials
flag
is
set.
If the caller specified custom steps to perform the fetch , perform them on request , with the is top-level flag set. Let response be the result.
Otherwise, fetch request , and let response be the result.
Unlike other algorithms in this section, the fetching process is synchronous here. Thus any perform the fetch steps will also finish their work synchronously.
Finalize
and
report
timing
with
response
,
settings
object
's
global
object
,
and
"
other
".
Set response to response 's unsafe response .
If any of the following conditions are met:
response
's
type
is
"
error
";
or
the result of extracting a MIME type from response 's header list is not a JavaScript MIME type ,
then
throw
a
"
NetworkError
"
DOMException
.
Let source text be the result of UTF-8 decoding response 's body .
Let muted errors be true if response was CORS-cross-origin , and false otherwise.
Let script be the result of creating a classic script given source text , settings object , response 's url , the default classic script fetch options , and muted errors .
Return script .
To fetch an external module script graph given a url , a settings object , and some options , run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Fetch
a
single
module
script
given
url
,
settings
object
,
"
script
",
options
,
settings
object
,
"
client
",
and
with
the
top-level
module
fetch
flag
set.
If
the
caller
of
this
algorithm
specified
custom
perform
the
fetch
steps,
pass
those
along
as
well.
Wait
until
the
algorithm
asynchronously
completes
with
result
.
If result is null, asynchronously complete this algorithm with null, and return.
Let
visited
set
be
«
(
url
,
"
javascript
")
».
Fetch the descendants of and link result given settings object , destination , and visited set . When this asynchronously completes with final result , asynchronously complete this algorithm with final result .
To fetch an import() module script graph given a moduleRequest , a base URL , a settings object , and some options , run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Let url be the result of resolving a module specifier given base URL and moduleRequest .[[Specifier]].
If url is failure, then asynchronously complete this algorithm with null, and return.
Assert:
moduleRequest
.[[Assertions]]
does
not
contain
any
Record
entry
such
that
entry
.[[Key]]
is
not
"
type
",
because
we
only
asked
for
"
type
"
assertions
in
HostGetSupportedImportAssertions
.
Let moduleType be the result of running the module type from module request steps given moduleRequest .
If the result of running the module type allowed steps given moduleType and settings object is false, then asynchronously complete this algorithm with null, and return.
Fetch
a
single
module
script
given
url
,
settings
object
,
"
script
",
options
,
settings
object
,
"
client
",
moduleRequest
,
and
with
the
top-level
module
fetch
flag
set.
If
the
caller
of
this
algorithm
specified
custom
perform
the
fetch
steps,
pass
those
along
as
well.
Wait
until
the
algorithm
asynchronously
completes
with
result
.
If result is null, asynchronously complete this algorithm with null, and return.
Let visited set be « ( url , moduleType ) ».
Fetch the descendants of and link result given settings object , destination , and visited set . When this asynchronously completes with final result , asynchronously complete this algorithm with final result .
To fetch a modulepreload module script graph given a url , a destination , a settings object , and some options , run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success), although it will perform optional steps even after completing.
Fetch
a
single
module
script
given
url
,
settings
object
,
destination
,
options
,
settings
object
,
"
client
",
and
with
the
top-level
module
fetch
flag
set.
Wait
until
algorithm
asynchronously
completes
with
result
.
Asynchronously complete this algorithm with result , but do not return.
If result is not null, optionally perform the following steps:
Let
visited
set
be
«
(
url
,
"
javascript
")
».
Fetch the descendants of and link result given settings object , destination , and visited set .
Generally, performing these steps will be beneficial for performance, as it allows pre-loading the modules that will invariably be requested later, via algorithms such as fetch an external module script graph that fetch the entire graph. However, user agents might wish to skip them in bandwidth-constrained situations, or situations where the relevant fetches are already in flight.
To fetch an inline module script graph given a source text , base URL , settings object , and options , run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Let script be the result of creating a JavaScript module script using source text , settings object , base URL , and options .
If script is null, asynchronously complete this algorithm with null, and return.
Let visited set be an empty set .
Fetch
the
descendants
of
and
link
script
,
given
settings
object
,
the
destination
"
script
",
and
visited
set
.
When
this
asynchronously
completes
with
final
result
,
asynchronously
complete
this
algorithm
with
final
result
.
To fetch a module worker script graph given a url , a fetch client settings object , a destination , a credentials mode , and a module map settings object , fetch a worklet/module worker script graph given url , fetch client settings object , destination , credentials mode , and module map settings object , asynchronously completing with the asynchronous completion result of that algorithm.
To fetch a worklet script graph given a url , a fetch client settings object , a destination , a credentials mode , a module map settings object , and a module responses map , fetch a worklet/module worker script graph given url , fetch client settings object , destination , credentials mode , and module map settings object , asynchronously completing with the asynchronous completion result of that algorithm. Use the following custom steps to perform the fetch given response :
Let requestURL be request 's URL .
If
moduleResponsesMap
[
requestURL
]
is
"
fetching
",
wait
in
parallel
until
that
entry's
value
changes,
then
queue
a
task
on
the
networking
task
source
to
proceed
with
running
the
following
steps.
If moduleResponsesMap [ requestURL ] exists , then asynchronously complete the perform the fetch steps with moduleResponsesMap [ requestURL ].
Set
moduleResponsesMap
[
requestURL
]
to
"
fetching
".
Fetch request , with processResponseConsumeBody set to the following steps given response response :
Set moduleResponsesMap [ requestURL ] to response .
Asynchronously complete the perform the fetch steps with response .
The following algorithms are meant for internal use by this specification only as part of fetching an external module script graph or other similar concepts above, and should not be used directly by other specifications.
This diagram illustrates how these algorithms relate to the ones above, as well as to each other:
To fetch a worklet/module worker script graph given a url , a fetch client settings object , a destination , a credentials mode , and a module map settings object , run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Let
options
be
a
script
fetch
options
whose
cryptographic
nonce
is
the
empty
string,
integrity
metadata
is
the
empty
string,
parser
metadata
is
"
not-parser-inserted
",
credentials
mode
is
credentials
mode
,
and
referrer
policy
is
the
empty
string.
Fetch
a
single
module
script
given
url
,
fetch
client
settings
object
,
destination
,
options
,
module
map
settings
object
,
"
client
",
and
with
the
top-level
module
fetch
flag
set.
If
the
caller
of
this
algorithm
specified
custom
perform
the
fetch
steps,
pass
those
along
as
well.
Wait
until
the
algorithm
asynchronously
completes
with
result
.
If result is null, asynchronously complete this algorithm with null, and return.
Let
visited
set
be
«
(
url
,
"
javascript
")
».
Fetch the descendants of and link result given fetch client settings object , destination , and visited set . When this asynchronously completes with final result , asynchronously complete this algorithm with final result .
To fetch the descendants of and link a module script module script , given a fetch client settings object , a destination , and a visited set , run these steps. The algorithm will asynchronously complete with either null (on failure) or with module script (on success).
Fetch the descendants of module script , given fetch client settings object , destination , and visited set .
Return from this algorithm, and run the following steps when fetching the descendants of a module script asynchronously completes with result .
If result is null, then asynchronously complete this algorithm with result .
In this case, there was an error fetching one or more of the descendants. We will not attempt to link.
Let parse error be the result of finding the first parse error given result .
If parse error is null, then:
Let record be result 's record .
Perform record . Link ().
This step will recursively call Link on all of the module's unlinked dependencies.
If this throws an exception, set result 's error to rethrow to that exception.
Otherwise, set result 's error to rethrow to parse error .
Asynchronously complete this algorithm with result .
To fetch the descendants of a module script module script , given a fetch client settings object , a destination , and a visited set , run these steps. The algorithm will asynchronously complete with either null (on failure) or with module script (on success).
If module script 's record is null, then asynchronously complete this algorithm with module script and return.
Let record be module script 's record .
If record is not a Cyclic Module Record , or if record .[[RequestedModules]] is empty , asynchronously complete this algorithm with module script .
Let moduleRequests be a new empty list .
For each ModuleRequest Record requested of record .[[RequestedModules]],
Let url be the result of resolving a module specifier given module script 's base URL and requested .[[Specifier]].
Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two arguments.
Let moduleType be the result of running the module type from module request steps given requested .
If visited set does not contain ( url , moduleType ), then:
Let options be the descendant script fetch options for module script 's fetch options .
Assert: options is not null, as module script is a JavaScript module script .
For each moduleRequest in moduleRequests , perform the internal module script graph fetching procedure given moduleRequest , fetch client settings object , destination , options , module script 's settings object , visited set , and module script 's base URL . If the caller of this algorithm specified custom perform the fetch steps, pass those along while performing the internal module script graph fetching procedure .
These invocations of the internal module script graph fetching procedure should be performed in parallel to each other.
If any of the invocations of the internal module script graph fetching procedure asynchronously complete with null, asynchronously complete this algorithm with null, and return.
Otherwise, wait until all of the internal module script graph fetching procedure invocations have asynchronously completed. Asynchronously complete this algorithm with module script .
To perform the internal module script graph fetching procedure given a moduleRequest , a fetch client settings object , a destination , some options , a module map settings object , a visited set , and a referrer , perform these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Let url be the result of resolving a module specifier given referrer and moduleRequest .[[Specifier]].
Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two arguments.
Let moduleType be the result of running the module type from module request steps given moduleRequest .
Assert: visited set contains ( url , moduleType ).
Fetch a single module script given url , fetch client settings object , destination , options , module map settings object , referrer , moduleRequest , and with the top-level module fetch flag unset. If the caller of this algorithm specified custom perform the fetch steps, pass those along while fetching a single module script .
Return from this algorithm, and run the following steps when fetching a single module script asynchronously completes with result :
If result is null, asynchronously complete this algorithm with null, and return.
Fetch the descendants of result given fetch client settings object , destination , and visited set .
When the appropriate algorithm asynchronously completes with final result , asynchronously complete this algorithm with final result .
To fetch a single module script , given a url , a fetch client settings object , a destination , some options , a module map settings object , a referrer , an optional moduleRequest , and a top-level module fetch flag, run these steps. The algorithm will asynchronously complete with either null (on failure) or a module script (on success).
Let
moduleType
be
"
javascript
".
If moduleRequest was given, then set moduleType to the result of running the module type from module request steps given moduleRequest .
Assert: the result of running the module type allowed steps given moduleType and module map settings object is true. Otherwise we would not have reached this point because a failure would have been raised when inspecting moduleRequest .[[Assertions]] in create a JavaScript module script or fetch an import() module script graph .
Let moduleMap be module map settings object 's module map .
If
moduleMap
[(
url
,
moduleType
)]
is
"
fetching
",
wait
in
parallel
until
that
entry's
value
changes,
then
queue
a
task
on
the
networking
task
source
to
proceed
with
running
the
following
steps.
If moduleMap [( url , moduleType )] exists , asynchronously complete this algorithm with moduleMap [ url / moduleType ], and return.
Set
moduleMap
[(
url
,
moduleType
)]
to
"
fetching
".
Let
request
be
a
new
request
whose
URL
is
url
,
destination
is
destination
,
mode
is
"
cors
",
referrer
is
referrer
,
and
client
is
fetch
client
settings
object
.
If
destination
is
"
worker
",
"
sharedworker
",
or
"
serviceworker
",
and
the
top-level
module
fetch
flag
is
set,
then
set
request
's
mode
to
"
same-origin
".
Set up the module script request given request and options .
If the caller specified custom steps to perform the fetch , perform them on request , setting the is top-level flag if the top-level module fetch flag is set. Return from this algorithm, and when the custom perform the fetch steps complete with response response , run the remaining steps.
Otherwise, fetch request . Return from this algorithm, and run the remaining steps as part of the fetch's processResponseConsumeBody given response response .
response is always CORS-same-origin .
Finalize
and
report
timing
with
response
,
fetch
client
settings
object
's
global
object
,
and
"
other
".
If either of the following conditions are met:
then set moduleMap [( url , moduleType )] to null, asynchronously complete this algorithm with null, and return.
Let source text be the result of UTF-8 decoding response 's body .
Let MIME type be the result of extracting a MIME type from response 's header list .
Let module script be null.
If
MIME
type
is
a
JavaScript
MIME
type
and
moduleType
is
"
javascript
",
then
set
module
script
to
the
result
of
creating
a
JavaScript
module
script
given
source
text
,
module
map
settings
object
,
response
's
url
,
and
options
.
If
the
MIME
type
essence
of
MIME
type
is
"
text/css
"
and
moduleType
is
"
css
",
then
set
module
script
to
the
result
of
creating
a
CSS
module
script
given
source
text
and
module
map
settings
object
.
If
MIME
type
essence
is
a
JSON
MIME
type
and
moduleType
is
"
json
",
then
set
module
script
to
the
result
of
creating
a
JSON
module
script
given
source
text
and
module
map
settings
object
.
Set moduleMap [( url , moduleType )] to module script , and asynchronously complete this algorithm with module script .
It is intentional that the module map is keyed by the request URL , whereas the base URL for the module script is set to the response URL . The former is used to deduplicate fetches, while the latter is used for URL resolution.
To find the first parse error given a root moduleScript and an optional discoveredSet :
Let moduleMap be moduleScript 's settings object 's module map .
If discoveredSet was not given, let it be an empty set .
Append moduleScript to discoveredSet .
If moduleScript 's record is null, then return moduleScript 's parse error .
If moduleScript 's record is not a Cyclic Module Record , then return null.
Let moduleRequests be the value of moduleScript 's record 's [[RequestedModules]] internal slot.
For each moduleRequest of moduleRequests :
Let childURL be the result of resolving a module specifier given moduleScript 's base URL and moduleRequest .[[Specifier]]. (This will never fail, as otherwise moduleScript would have been marked as itself having a parse error .)
Let moduleType be the result of running the module type from module request steps given moduleRequest .
Let childModule be moduleMap [( childURL , moduleType )].
Assert:
childModule
is
a
module
script
(i.e.,
it
is
not
"
fetching
"
or
null);
by
now
all
module
scripts
in
the
graph
rooted
at
moduleScript
will
have
successfully
been
fetched.
Let childParseError be the result of finding the first parse error given childModule and discoveredSet .
If childParseError is not null, return childParseError .
Return null.
To create a classic script , given a string source , an environment settings object settings , a URL baseURL , some script fetch options options , and an optional boolean mutedErrors (default false):
If
mutedErrors
is
true,
then
set
baseURL
to
about:blank
.
When mutedErrors is true, baseURL is the script's CORS-cross-origin response 's url , which shouldn't be exposed to JavaScript. Therefore, baseURL is sanitized here.
If scripting is disabled for settings , then set source to the empty string.
Let script be a new classic script that this algorithm will subsequently initialize.
Set script 's settings object to settings .
Set script 's base URL to baseURL .
Set script 's fetch options to options .
Set script 's muted errors to mutedErrors .
Set script 's parse error and error to rethrow to null.
Let result be ParseScript ( source , settings 's Realm , script ).
Passing script as the last parameter here ensures result .[[HostDefined]] will be script .
If result is a list of errors, then:
Set script 's parse error and its error to rethrow to result [0].
Return script .
Set script 's record to result .
Return script .
To create a JavaScript module script , given a string source , an environment settings object settings , a URL baseURL , and some script fetch options options :
If scripting is disabled for settings , then set source to the empty string.
Let script be a new module script that this algorithm will subsequently initialize.
Set script 's settings object to settings .
Set script 's base URL to baseURL .
Set script 's fetch options to options .
Set script 's parse error and error to rethrow to null.
Let result be ParseModule ( source , settings 's Realm , script ).
Passing script as the last parameter here ensures result .[[HostDefined]] will be script .
If result is a list of errors, then:
Set script 's parse error to result [0].
Return script .
Assert:
requested
.[[Assertions]]
does
not
contain
any
Record
entry
such
that
entry
.[[Key]]
is
not
"
type
",
because
we
only
asked
for
"
type
"
assertions
in
HostGetSupportedImportAssertions
.
For each ModuleRequest record requested of result .[[RequestedModules]]:
Let url be the result of resolving a module specifier given script 's base URL and requested .[[Specifier]].
Let moduleType be the result of running the module type from module request steps given requested .
If url is failure, or if the result of running the module type allowed steps given moduleType and settings is false, then:
Let
error
be
a
new
TypeError
exception.
Set script 's parse error to error .
Return script .
This step is essentially validating all of the requested module specifiers and type assertions. We treat a module with unresolvable module specifiers or unsupported type assertions the same as one that cannot be parsed; in both cases, a syntactic issue makes it impossible to ever contemplate linking the module later.
Set script 's record to result .
Return script .
To create a CSS module script , given a string source and an environment settings object settings :
Let script be a new module script that this algorithm will subsequently initialize.
Set script 's settings object to settings .
Set script 's base URL and fetch options to null.
Set script 's parse error and error to rethrow to null.
Let
sheet
be
the
result
of
running
the
steps
to
create
a
constructed
CSSStyleSheet
with
an
empty
dictionary
as
the
argument.
Run
the
steps
to
synchronously
replace
the
rules
of
a
CSSStyleSheet
on
sheet
given
source
.
If this throws an exception, set script 's parse error to that exception, and return script .
The
steps
to
synchronously
replace
the
rules
of
a
CSSStyleSheet
will
throw
if
source
contains
any
@import
rules.
This
is
by-design
for
now
because
there
is
not
yet
an
agreement
on
how
to
handle
these
for
CSS
module
scripts;
therefore
they
are
blocked
altogether
until
a
consensus
is
reached.
Set script 's record to the result of CreateDefaultExportSyntheticModule ( sheet ).
Return script .
To create a JSON module script , given a string source and an environment settings object settings :
Let script be a new module script that this algorithm will subsequently initialize.
Set script 's settings object to settings .
Set script 's base URL and fetch options to null.
Set script 's parse error and error to rethrow to null.
Let result be ParseJSONModule ( source ).
If this throws an exception, set script 's parse error to that exception, and return script .
Set script 's record to result .
Return script .
The module type from module request steps, given a ModuleRequest Record moduleRequest , are as follows:
Let
moduleType
be
"
javascript
".
If
moduleRequest
.[[Assertions]]
has
a
Record
entry
such
that
entry
.[[Key]]
is
"
type
",
then:
If
entry
.[[Value]]
is
"
javascript
",
then
set
moduleType
to
null.
This
specification
uses
the
"
javascript
"
module
type
internally
for
JavaScript
module
scripts
,
so
this
step
is
needed
to
prevent
modules
from
being
imported
using
a
"
javascript
"
type
assertion
(a
null
moduleType
will
cause
the
module
type
allowed
check
to
fail).
Otherwise, set moduleType to entry .[[Value]].
Return moduleType .
The module type allowed steps, given a string moduleType and an environment settings object settings , are as follows:
If
moduleType
is
not
"
javascript
",
"
css
",
or
"
json
",
then
return
false.
If
moduleType
is
"
css
"
and
the
CSSStyleSheet
interface
is
not
exposed
in
settings
's
Realm
,
then
return
false.
Return true.
To run a classic script given a classic script script and an optional boolean rethrow errors (default false):
Let settings be the settings object of script .
Check if we can run script with settings . If this returns "do not run" then return NormalCompletion (empty).
Prepare to run script given settings .
Let evaluationStatus be null.
If script 's error to rethrow is not null, then set evaluationStatus to Completion { [[Type]]: throw, [[Value]]: script 's error to rethrow , [[Target]]: empty }.
Otherwise, set evaluationStatus to ScriptEvaluation ( script 's record ).
If ScriptEvaluation does not complete because the user agent has aborted the running script , leave evaluationStatus as null.
If evaluationStatus is an abrupt completion , then:
If rethrow errors is true and script 's muted errors is false, then:
Clean up after running script with settings .
Rethrow evaluationStatus .[[Value]].
If rethrow errors is true and script 's muted errors is true, then:
Clean up after running script with settings .
Throw
a
"
NetworkError
"
DOMException
.
Otherwise, rethrow errors is false. Perform the following steps:
Report the exception given by evaluationStatus .[[Value]] for script .
Clean up after running script with settings .
Return evaluationStatus .
Clean up after running script with settings .
If evaluationStatus is a normal completion, then return evaluationStatus .
If
we've
reached
this
point,
evaluationStatus
was
left
as
null
because
the
script
was
aborted
prematurely
during
evaluation.
Return
Completion
{
[[Type]]:
throw,
[[Value]]:
a
new
"
QuotaExceededError
"
DOMException
,
[[Target]]:
empty
}.
To run a module script given a module script script and an optional boolean preventErrorReporting (default false):
Let settings be the settings object of script .
Check if we can run script with settings . If this returns "do not run", then return a promise resolved with undefined.
Prepare to run script given settings .
Let evaluationPromise be null.
If script 's error to rethrow is not null, then set evaluationPromise to a promise rejected with script 's error to rethrow .
Otherwise:
Let record be script 's record .
Set evaluationPromise to record . Evaluate ().
This step will recursively evaluate all of the module's dependencies.
If
Evaluate
fails
to
complete
as
a
result
of
the
user
agent
aborting
the
running
script
,
then
set
evaluationPromise
to
a
promise
rejected
with
a
new
"
QuotaExceededError
"
DOMException
.
If preventErrorReporting is false, then upon rejection of evaluationPromise with reason , report the exception given by reason for script .
Clean up after running script with settings .
Return evaluationPromise .
The steps to check if we can run script with an environment settings object settings are as follows. They return either "run" or "do not run".
If
the
global
object
specified
by
settings
is
a
Window
object
whose
Document
object
is
not
fully
active
,
then
return
"do
not
run".
If scripting is disabled for settings , then return "do not run".
Return "run".
The steps to prepare to run script with an environment settings object settings are as follows:
Push settings 's realm execution context onto the JavaScript execution context stack ; it is now the running JavaScript execution context .
Add settings to the currently running task 's script evaluation environment settings object set .
The steps to clean up after running script with an environment settings object settings are as follows:
Assert: settings 's realm execution context is the running JavaScript execution context .
Remove settings 's realm execution context from the JavaScript execution context stack .
If the JavaScript execution context stack is now empty, perform a microtask checkpoint . (If this runs scripts, these algorithms will be invoked reentrantly.)
These algorithms are not invoked by one script directly calling another, but they can be invoked reentrantly in an indirect manner, e.g. if a script dispatches an event which has event listeners registered.
The running script is the script in the [[HostDefined]] field in the ScriptOrModule component of the running JavaScript execution context .
Although
the
JavaScript
specification
does
not
account
for
this
possibility,
it's
sometimes
necessary
to
abort
a
running
script
.
This
causes
any
ScriptEvaluation
or
Source
Text
Module
Record
Evaluate
invocations
to
cease
immediately,
emptying
the
JavaScript
execution
context
stack
without
triggering
any
of
the
normal
mechanisms
like
finally
blocks.
[JAVASCRIPT]
User
agents
may
impose
resource
limitations
on
scripts,
for
example
CPU
quotas,
memory
limits,
total
execution
time
limits,
or
bandwidth
limitations.
When
a
script
exceeds
a
limit,
the
user
agent
may
either
throw
a
"
QuotaExceededError
"
DOMException
,
abort
the
script
without
an
exception,
prompt
the
user,
or
throttle
script
execution.
For example, the following script never terminates. A user agent could, after waiting for a few seconds, prompt the user to either terminate the script or let it continue.
<script>
while (true) { /* loop */ }
</script>
User
agents
are
encouraged
to
allow
users
to
disable
scripting
whenever
the
user
is
prompted
either
by
a
script
(e.g.
using
the
window.alert()
API)
or
because
of
a
script's
actions
(e.g.
because
it
has
exceeded
a
time
limit).
If scripting is disabled while a script is executing, the script should be terminated immediately.
User agents may allow users to specifically disable scripts just for the purposes of closing a browsing context .
For
example,
the
prompt
mentioned
in
the
example
above
could
also
offer
the
user
with
a
mechanism
to
just
close
the
page
entirely,
without
running
any
unload
event
handlers.
Support in all current engines.
self.
reportError
(
e
)
Dispatches
an
error
event
at
the
global
object
for
the
given
value
e
,
in
the
same
fashion
as
an
unhandled
exception.
When the user agent is required to report an error for a particular script script with a particular position line : col , using a particular target target , it must run these steps, after which the error is either handled or not handled :
If target is in error reporting mode , then return; the error is not handled .
Let target be in error reporting mode .
Let
message
be
an
implementation-defined
string
describing
the
error
in
a
helpful
manner.
Let
errorValue
be
the
value
that
represents
the
error:
in
the
case
of
an
uncaught
exception,
that
would
be
the
value
that
was
thrown;
in
the
case
of
a
JavaScript
error
that
would
be
an
Error
object.
If
there
is
no
corresponding
value,
then
the
null
value
must
be
used
instead.
Let urlString be the result of applying the URL serializer to the URL record that corresponds to the resource from which script was obtained.
The
resource
containing
the
script
will
typically
be
the
file
from
which
the
Document
was
parsed,
e.g.
for
inline
script
elements
or
event
handler
content
attributes
;
or
the
JavaScript
file
that
the
script
was
in,
for
external
scripts.
Even
for
dynamically-generated
scripts,
user
agents
are
strongly
encouraged
to
attempt
to
keep
track
of
the
original
source
of
a
script.
For
example,
if
an
external
script
uses
the
document.write()
API
to
insert
an
inline
script
element
during
parsing,
the
URL
of
the
resource
containing
the
script
would
ideally
be
reported
as
being
the
external
script,
and
the
line
number
might
ideally
be
reported
as
the
line
with
the
document.write()
call
or
where
the
string
passed
to
that
call
was
first
constructed.
Naturally,
implementing
this
can
be
somewhat
non-trivial.
User
agents
are
similarly
encouraged
to
keep
careful
track
of
the
original
line
numbers,
even
in
the
face
of
document.write()
calls
mutating
the
document
as
it
is
parsed,
or
event
handler
content
attributes
spanning
multiple
lines.
If
script
is
a
classic
script
and
script
's
muted
errors
is
true,
then
set
message
to
"
Script
error.
",
urlString
to
the
empty
string,
line
and
col
to
0,
and
errorValue
to
null.
Let notHandled be true.
If
target
implements
EventTarget
,
then
set
notHandled
to
the
result
of
firing
an
event
named
error
at
target
,
using
ErrorEvent
,
with
the
cancelable
attribute
initialized
to
true,
the
message
attribute
initialized
to
message
,
the
filename
attribute
initialized
to
urlString
,
the
lineno
attribute
initialized
to
line
,
the
colno
attribute
initialized
to
col
,
and
the
error
attribute
initialized
to
errorValue
.
Let target no longer be in error reporting mode .
If notHandled is false, then the error is handled . Otherwise, the error is not handled .
Returning true in an event handler cancels the event per the event handler processing algorithm .
When the user agent is to report an exception E , the user agent must report the error for the relevant script , with the problematic position (line number and column number) in the resource containing the script, using the global object specified by the script's settings object as the target. If the error is still not handled after this, then the error may be reported to a developer console.
The existence of both report an error and report an exception is confusing, and both algorithms have known problems. You can track future cleanup in this area in issue #958 .
The
reportError(
e
)
method
steps
are
to
report
the
exception
e
.
Support in all current engines.
The
ErrorEvent
interface
is
defined
as
follows:
[Exposed=*]
interface ErrorEvent : Event {
constructor(DOMString type, optional ErrorEventInit eventInitDict = {});
readonly attribute DOMString message;
readonly attribute USVString filename;
readonly attribute unsigned long lineno;
readonly attribute unsigned long colno;
readonly attribute any error;
};
dictionary ErrorEventInit : EventInit {
DOMString message = "";
USVString filename = "";
unsigned long lineno = 0;
unsigned long colno = 0;
any error;
};
The
message
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
error
message.
The
filename
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
URL
of
the
script
in
which
the
error
originally
occurred.
The
lineno
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
line
number
where
the
error
occurred
in
the
script.
The
colno
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
column
number
where
the
error
occurred
in
the
script.
The
error
attribute
must
return
the
value
it
was
initialized
to.
It
must
initially
be
initialized
to
undefined.
Where
appropriate,
it
is
set
to
the
object
representing
the
error
(e.g.,
the
exception
object
in
the
case
of
an
uncaught
exception).
Support in all current engines.
In
addition
to
synchronous
runtime
script
errors
,
scripts
may
experience
asynchronous
promise
rejections,
tracked
via
the
unhandledrejection
and
rejectionhandled
events.
Tracking
these
rejections
is
done
via
the
HostPromiseRejectionTracker
abstract
operation,
but
reporting
them
is
defined
here.
To notify about rejected promises on a given environment settings object settings object :
Let list be a copy of settings object 's about-to-be-notified rejected promises list .
If list is empty, return.
Clear settings object 's about-to-be-notified rejected promises list .
Let global be settings object 's global object .
Queue a global task on the DOM manipulation task source given global to run the following substep:
For each promise p in list :
If p 's [[PromiseIsHandled]] internal slot is true, continue to the next iteration of the loop.
Let
notHandled
be
the
result
of
firing
an
event
named
unhandledrejection
at
global
,
using
PromiseRejectionEvent
,
with
the
cancelable
attribute
initialized
to
true,
the
promise
attribute
initialized
to
p
,
and
the
reason
attribute
initialized
to
the
value
of
p
's
[[PromiseResult]]
internal
slot.
If notHandled is false, then the promise rejection is handled . Otherwise, the promise rejection is not handled .
If p 's [[PromiseIsHandled]] internal slot is false, add p to settings object 's outstanding rejected promises weak set .
This algorithm results in promise rejections being marked as handled or not handled . These concepts parallel handled and not handled script errors. If a rejection is still not handled after this, then the rejection may be reported to a developer console.
Support in all current engines.
The
PromiseRejectionEvent
interface
is
defined
as
follows:
[Exposed=*]
interface PromiseRejectionEvent : Event {
constructor(DOMString type, PromiseRejectionEventInit eventInitDict);
readonly attribute Promise<any> promise;
readonly attribute any reason;
};
dictionary PromiseRejectionEventInit : EventInit {
required Promise<any> promise;
any reason;
};
Support in all current engines.
The
promise
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
promise
which
this
notification
is
about.
Support in all current engines.
The
reason
attribute
must
return
the
value
it
was
initialized
to.
It
represents
the
rejection
reason
for
the
promise.
The JavaScript specification contains a number of implementation-defined abstract operations, that vary depending on the host environment. This section defines them for user agent hosts.
JavaScript contains an implementation-defined HostEnsureCanCompileStrings ( realm ) abstract operation. User agents must use the following implementation: [JAVASCRIPT]
Perform ? EnsureCSPDoesNotBlockStringCompilation ( realm ). [CSP]
JavaScript contains an implementation-defined HostPromiseRejectionTracker ( promise , operation ) abstract operation. User agents must use the following implementation: [JAVASCRIPT]
Let script be the running script .
If script is a classic script and script 's muted errors is true, terminate these steps.
Let settings object be script 's settings object .
If
operation
is
"reject"
,
Add promise to settings object 's about-to-be-notified rejected promises list .
If
operation
is
"handle"
,
If settings object 's about-to-be-notified rejected promises list contains promise , then remove promise from that list and return.
If settings object 's outstanding rejected promises weak set does not contain promise , then return.
Remove promise from settings object 's outstanding rejected promises weak set .
Let global be settings object 's global object .
Queue
a
global
task
on
the
DOM
manipulation
task
source
given
global
to
fire
an
event
named
rejectionhandled
at
global
,
using
PromiseRejectionEvent
,
with
the
promise
attribute
initialized
to
promise
,
and
the
reason
attribute
initialized
to
the
value
of
promise
's
[[PromiseResult]]
internal
slot.
Reference/Global_Objects/Promise#Incumbent_settings_object_tracking
Support in one engine only.
The
JavaScript
specification
defines
Jobs
to
be
scheduled
and
run
later
by
the
host,
as
well
as
JobCallback
Records
which
encapsulate
JavaScript
functions
that
are
called
as
part
of
jobs.
The
JavaScript
specification
contains
a
number
of
implementation-defined
abstract
operations
that
lets
the
host
define
how
jobs
are
scheduled
and
how
JobCallbacks
are
handled.
HTML
uses
these
abstract
operations
to
track
the
incumbent
settings
object
in
promises
and
FinalizationRegistry
callbacks
by
saving
and
restoring
the
incumbent
settings
object
and
a
JavaScript
execution
context
for
the
active
script
in
JobCallbacks.
This
section
defines
them
for
user
agent
hosts.
JavaScript contains an implementation-defined HostCallJobCallback ( callback , V , argumentsList ) abstract operation to let hosts restore state when invoking JavaScript callbacks from inside tasks. User agents must use the following implementation: [JAVASCRIPT]
Let incumbent settings be callback .[[HostDefined]].[[IncumbentSettings]].
Let script execution context be callback .[[HostDefined]].[[ActiveScriptContext]].
Prepare to run a callback with incumbent settings .
This affects the incumbent concept while the callback runs.
If script execution context is not null, then push script execution context onto the JavaScript execution context stack .
This affects the active script while the callback runs.
Let result be Call ( callback .[[Callback]], V , argumentsList ).
If script execution context is not null, then pop script execution context from the JavaScript execution context stack .
Clean up after running a callback with incumbent settings .
Return result .
JavaScript
has
the
ability
to
register
objects
with
FinalizationRegistry
objects,
in
order
to
schedule
a
cleanup
action
if
they
are
found
to
be
garbage
collected.
The
JavaScript
specification
contains
an
implementation-defined
HostEnqueueFinalizationRegistryCleanupJob
(
finalizationRegistry
)
abstract
operation
to
schedule
the
cleanup
action.
The
timing
and
occurrence
of
cleanup
work
is
implementation-defined
in
the
JavaScript
specification.
User
agents
might
differ
in
when
and
whether
an
object
is
garbage
collected,
affecting
both
whether
the
return
value
of
the
WeakRef.prototype.deref()
method
is
undefined,
and
whether
FinalizationRegistry
cleanup
callbacks
occur.
There
are
well-known
cases
in
popular
web
browsers
where
objects
are
not
accessible
to
JavaScript,
but
they
remain
retained
by
the
garbage
collector
indefinitely.
HTML
clears
kept-alive
WeakRef
objects
in
the
perform
a
microtask
checkpoint
algorithm.
Authors
would
be
best
off
not
depending
on
the
timing
details
of
garbage
collection
implementations.
Cleanup actions do not take place interspersed with synchronous JavaScript execution, but rather happen in queued tasks . User agents must use the following implementation: [JAVASCRIPT]
Let global be finalizationRegistry .[[Realm]]'s global object .
Queue a global task on the JavaScript engine task source given global to perform the following steps:
Let entry be finalizationRegistry .[[CleanupCallback]].[[Callback]].[[Realm]]'s environment settings object .
Check if we can run script with entry . If this returns "do not run", then return.
Prepare to run script with entry .
This affects the entry concept while the cleanup callback runs.
Let result be the result of performing CleanupFinalizationRegistry ( finalizationRegistry ).
Clean up after running script with entry .
If result is an abrupt completion , then report the exception given by result .[[Value]].
JavaScript contains an implementation-defined HostEnqueuePromiseJob ( job , realm ) abstract operation to schedule Promise-related operations. HTML schedules these operations in the microtask queue. User agents must use the following implementation: [JAVASCRIPT]
If realm is not null, then let job settings be the settings object for realm . Otherwise, let job settings be null.
If
realm
is
not
null,
it
is
the
Realm
of
the
author
code
that
will
run.
When
job
is
returned
by
NewPromiseReactionJob
,
it
is
the
realm
of
the
promise's
handler
function.
When
job
is
returned
by
NewPromiseResolveThenableJob
,
it
is
the
realm
of
the
then
function.
If
realm
is
null,
either
no
author
code
will
run
or
author
code
is
guaranteed
to
throw.
For
the
former,
the
author
may
not
have
passed
in
code
to
run,
such
as
in
promise.then(null,
null)
.
For
the
latter,
it
is
because
a
revoked
Proxy
was
passed.
In
both
cases,
all
the
steps
below
that
would
otherwise
use
job
settings
get
skipped.
Queue a microtask on the surrounding agent 's event loop to perform the following steps:
If job settings is not null, then check if we can run script with job settings . If this returns "do not run" then return.
If job settings is not null, then prepare to run script with job settings .
This affects the entry concept while the job runs.
Let result be job ().
job
is
an
abstract
closure
returned
by
NewPromiseReactionJob
or
NewPromiseResolveThenableJob
.
The
promise's
handler
function
when
job
is
returned
by
NewPromiseReactionJob
,
and
the
then
function
when
job
is
returned
by
NewPromiseResolveThenableJob
,
are
wrapped
in
JobCallback
Records
.
HTML
saves
the
incumbent
settings
object
and
a
JavaScript
execution
context
for
to
the
active
script
in
HostMakeJobCallback
and
restores
them
in
HostCallJobCallback
.
If job settings is not null, then clean up after running script with job settings .
If result is an abrupt completion , then report the exception given by result .[[Value]].
JavaScript contains an implementation-defined HostMakeJobCallback ( callable ) abstract operation to let hosts attach state to JavaScript callbacks that are called from inside task s. User agents must use the following implementation: [JAVASCRIPT]
Let incumbent settings be the incumbent settings object .
Let active script be the active script .
Let script execution context be null.
If active script is not null, set script execution context to a new JavaScript execution context , with its Function field set to null, its Realm field set to active script 's settings object 's Realm , and its ScriptOrModule set to active script 's record .
As seen below, this is used in order to propagate the current active script forward to the time when the job callback is invoked.
A case where active script is non-null, and saving it in this way is useful, is the following:
Promise.resolve('import(`./example.mjs`)').then(eval);
Without
this
step
(and
the
steps
that
use
it
in
HostCallJobCallback
),
there
would
be
no
active
script
when
the
import()
expression
is
evaluated,
since
eval()
is
a
built-in
function
that
does
not
originate
from
any
particular
script
.
With
this
step
in
place,
the
active
script
is
propagated
from
the
above
code
into
the
job,
allowing
import()
to
use
the
original
script's
base
URL
appropriately.
active script can be null if the user clicks on the following button:
<button
onclick="Promise.resolve('import(`./example.mjs`)').then(eval)">Click
me</button>
In this case, the JavaScript function for the event handler will be created by the get the current value of the event handler algorithm, which creates a function with null [[ScriptOrModule]] value. Thus, when the promise machinery calls HostMakeJobCallback , there will be no active script to pass along.
As
a
consequence,
this
means
that
when
the
import()
expression
is
evaluated,
there
will
still
be
no
active
script
.
Fortunately
that
is
handled
by
our
implementations
of
HostResolveImportedModule
and
HostImportModuleDynamically
,
by
falling
back
to
using
the
current
settings
object
's
API
base
URL
.
Return the JobCallback Record { [[Callback]]: callable , [[HostDefined]]: { [[IncumbentSettings]]: incumbent settings , [[ActiveScriptContext]]: script execution context } }.
The
JavaScript
specification
defines
a
syntax
for
modules,
as
well
as
some
host-agnostic
parts
of
their
processing
model.
This
specification
defines
the
rest
of
their
processing
model:
how
the
module
system
is
bootstrapped,
via
the
script
element
with
type
attribute
set
to
"
module
",
and
how
modules
are
fetched,
resolved,
and
executed.
[JAVASCRIPT]
Although
the
JavaScript
specification
speaks
in
terms
of
"scripts"
versus
"modules",
in
general
this
specification
speaks
in
terms
of
classic
scripts
versus
module
scripts
,
since
both
of
them
use
the
script
element.
modulePromise
=
import(
specifier
)
Returns
a
promise
for
the
module
namespace
object
for
the
module
script
identified
by
specifier
.
This
allows
dynamic
importing
of
module
scripts
at
runtime,
instead
of
statically
using
the
import
statement
form.
The
specifier
will
be
resolved
relative
to
the
active
script
's
base
URL
.
The returned promise will be rejected if an invalid specifier is given, or if a failure is encountered while fetching or evaluating the resulting module graph.
This syntax can be used inside both classic and module scripts . It thus provides a bridge into the module-script world, from the classic-script world.
url
=
import.meta
.
url
Returns the active module script 's base URL .
This syntax can only be used inside module scripts .
url
=
import.meta
.
resolve
(
specifier
,
baseURL
)
Returns
specifier
,
resolved
relative
to
an
optionally
provided
baseURL
,
which
defaults
to
the
active
script
's
base
URL
.
That
is,
this
returns
the
URL
that
would
be
imported
by
using
import(
specifier
)
from
a
module
located
at
baseURL
.
The
URL
parser
is
applied
to
the
baseURL
argument
when
provided,
throwing
a
.
TypeError
if
it
is
not
a
valid
URL.
Throws
a
TypeError
exception
if
an
invalid
specifier
is
given.
This syntax can only be used inside module scripts .
A
module
map
is
a
map
keyed
by
tuples
consisting
of
a
URL
record
and
a
string
.
The
URL
record
is
the
request
URL
at
which
the
module
was
fetched,
and
the
string
indicates
the
type
of
the
module
(e.g.
"
javascript
").
The
module
map
's
values
are
either
a
module
script
,
null
(used
to
represent
failed
fetches),
or
a
placeholder
value
"
fetching
".
Module
maps
are
used
to
ensure
that
imported
module
scripts
are
only
fetched,
parsed,
and
evaluated
once
per
Document
or
worker
.
Since
module
maps
are
keyed
by
(URL,
module
type),
the
following
code
will
create
three
separate
entries
in
the
module
map
,
since
it
results
in
three
different
(URL,
module
type)
tuples
(all
with
"
javascript
"
type):
import "https://example.com/module.mjs";
import "https://example.com/module.mjs#map-buster";
import
"https://example.com/module.mjs?debug=true";
That is, URL queries and fragments can be varied to create distinct entries in the module map ; they are not ignored. Thus, three separate fetches and three separate module evaluations will be performed.
In contrast, the following code would only create a single entry in the module map , since after applying the URL parser to these inputs, the resulting URL records are equal:
import "https://example.com/module2.mjs";
import "https:example.com/module2.mjs";
import "https://///example.com\\module2.mjs";
import
"https://example.com/foo/../module2.mjs";
So in this second example, only one fetch and one module evaluation will occur.
Note that this behavior is the same as how shared workers are keyed by their parsed constructor url .
Since
module
type
is
also
part
of
the
module
map
key,
the
following
code
will
create
two
separate
entries
in
the
module
map
(the
type
is
"
javascript
"
for
the
first,
and
"
css
"
for
the
second):
<script type=module>
import "https://example.com/module";
</script>
<script type=module>
import "https://example.com/module" assert { type: "css" };
</script>
This can result in two separate fetches and two separate module evaluations being performed. This is a willful violation of a constraint recommended (but not required) by the import assertions specification stating that each call to HostResolveImportedModule with the same ( referencingScriptOrModule , moduleRequest .[[Specifier]]) pair must return the same Module Record . [JSIMPORTASSERTIONS]
In practice, due to the as-yet-unspecified memory cache (see issue #6110 ) the resource may only be fetched once in WebKit and Blink-based browsers. Additionally, as long as all module types are mutually exclusive, the module type check in fetch a single module script will fail for at least one of the imports, so at most one module evaluation will occur.
The purpose of including the type in the module map key is so that an import with the wrong type assertion does not prevent a different import of the same specifier but with the correct type from succeeding.
JavaScript
module
scripts
are
the
default
import
type
when
importing
from
another
JavaScript
module;
that
is,
when
an
import
statement
lacks
a
type
import
assertion
the
imported
module
script's
type
will
be
JavaScript.
Attempting
to
import
a
JavaScript
resource
using
an
import
statement
with
a
type
import
assertion
will
fail:
<script type="module">
// All of the following will fail, assuming that the imported .mjs files are served with a
// JavaScript MIME type. JavaScript module scripts are the default and cannot be imported with
// any import type assertion.
import foo from "./foo.mjs" assert { type: "javascript" };
import foo2 from "./foo2.mjs" assert { type: "js" };
import foo3 from "./foo3.mjs" assert { type: "" };
await import("./foo4.mjs", { assert: { type: null } });
await import("./foo5.mjs", { assert: { type: undefined } });
</script>
To resolve a module specifier given a URL base URL and a string specifier , perform the following steps. It will return either a URL record or failure.
Apply the URL parser to specifier . If the result is not failure, return the result.
If
specifier
does
not
start
with
the
character
U+002F
SOLIDUS
(
/
),
the
two-character
sequence
U+002E
FULL
STOP,
U+002F
SOLIDUS
(
./
),
or
the
three-character
sequence
U+002E
FULL
STOP,
U+002E
FULL
STOP,
U+002F
SOLIDUS
(
../
),
return
failure.
This
restriction
is
in
place
so
that
in
the
future
we
can
allow
custom
module
loaders
to
give
special
meaning
to
"bare"
import
specifiers,
like
import
"jquery"
or
import
"web/crypto"
.
For
now
any
such
imports
will
fail,
instead
of
being
treated
as
relative
URLs.
Return the result of applying the URL parser to specifier with base URL .
The following are valid module specifiers according to the above algorithm:
https://example.com/apples.mjs
http:example.com\pears.js
(becomes
http://example.com/pears.js
as
step
1
parses
with
no
base
URL)
//example.com/bananas
./strawberries.mjs.cgi
../lychees
/limes.jsx
data:text/javascript,export
default
'grapes';
blob:https://whatwg.org/d0360e2f-caee-469f-9a2f-87d5b0456f6f
The following are valid module specifiers according to the above algorithm, but will invariably cause failures when they are fetched :
javascript:export
default
'artichokes';
data:text/plain,export
default
'kale';
about:legumes
wss://example.com/celery
The following are not valid module specifiers according to the above algorithm:
https://eggplant:b/c
pumpkins.js
.tomato
..zucchini.mjs
.\yam.es
Reference/Operators/import.meta
Support in all current engines.
JavaScript contains an implementation-defined HostGetImportMetaProperties abstract operation. User agents must use the following implementation: [JAVASCRIPT]
Let moduleScript be moduleRecord .[[HostDefined]].
Assert: moduleScript 's base URL is not null, as moduleScript is a JavaScript module script .
Let urlString be moduleScript 's base URL , serialized .
Let steps be the following steps, given the argument specifier :
Set specifier to ? ToString ( specifier ).
Let url be the result of resolving a module specifier given moduleScript 's base URL and specifier .
If
url
is
failure,
then
throw
a
TypeError
exception.
Return the serialization of url .
Let
resolveFunction
be
!
CreateBuiltinFunction
(
steps
,
1,
"
resolve
",
«
»).
Return
«
Record
{
[[Key]]:
"
url
",
[[Value]]:
urlString
},
Record
{
[[Key]]:
"
resolve
",
[[Value]]:
resolveFunction
}
».
JavaScript contains an implementation-defined HostImportModuleDynamically abstract operation. User agents must use the following implementation: [JAVASCRIPT]
Let settings object be the current settings object .
If
settings
object
's
global
object
implements
WorkletGlobalScope
or
ServiceWorkerGlobalScope
,
then:
Let
completion
be
Completion
{
[[Type]]:
throw,
[[Value]]:
a
new
TypeError
,
[[Target]]:
empty
}.
Perform FinishDynamicImport ( referencingScriptOrModule , moduleRequest , promiseCapability , completion ).
Return.
Let base URL be settings object 's API base URL .
Let fetch options be the default classic script fetch options .
If referencingScriptOrModule is not null, then:
Let referencing script be referencingScriptOrModule .[[HostDefined]].
Set settings object to referencing script 's settings object .
Set base URL to referencing script 's base URL .
Set fetch options to the descendant script fetch options for referencing script 's fetch options .
Assert: Neither base URL nor fetch options is null, as referencing script is a classic script or a JavaScript module script .
As explained above for HostResolveImportedModule , in the common case, referencingScriptOrModule is non-null.
Fetch an import() module script graph given moduleRequest , base URL , settings object , and fetch options . Wait until the algorithm asynchronously completes with result .
Let promise be null.
If
result
is
null,
then
set
promise
to
a
promise
rejected
with
a
new
TypeError
.
Otherwise, set promise to the result of running a module script given result and true.
Perform FinishDynamicImport ( referencingScriptOrModule , moduleRequest , promiseCapability , promise ).
Return undefined.
JavaScript contains an implementation-defined HostResolveImportedModule abstract operation. User agents must use the following implementation: [JAVASCRIPT]
Let settings object be the current settings object .
Let base URL be settings object 's API base URL .
If referencingScriptOrModule is not null, then:
Let referencing script be referencingScriptOrModule .[[HostDefined]].
Set settings object to referencing script 's settings object .
Set base URL to referencing script 's base URL .
Assert: base URL is not null, as referencing script is a classic script or a JavaScript module script .
referencingScriptOrModule is not usually null, but will be so for event handlers per the get the current value of the event handler algorithm. For example, given:
<button
onclick="import('./foo.mjs')">Click
me</button>
If
a
click
event
occurs,
then
at
the
time
the
import()
expression
runs,
GetActiveScriptOrModule
will
return
null,
which
will
be
passed
to
this
abstract
operation
when
HostResolveImportedModule
is
called
by
FinishDynamicImport
.
Let moduleMap be settings object 's module map .
Let url be the result of resolving a module specifier given base URL and moduleRequest .[[Specifier]].
Assert: url is never failure, because resolving a module specifier must have been previously successful with these same two arguments (either while creating the corresponding module script , or in fetch an import() module script graph ).
Let moduleType be the result of running the module type from module request steps given moduleRequest .
Let resolved module script be moduleMap [( url , moduleType )]. (This entry must exist for us to have gotten to this point.)
Assert:
resolved
module
script
is
a
module
script
(i.e.,
is
not
null
or
"
fetching
").
Assert: resolved module script 's record is not null.
Return resolved module script 's record .
The Import Assertions proposal contains an implementation-defined HostGetSupportedImportAssertions abstract operation. User agents must use the following implementation: [JSIMPORTASSERTIONS]
Return
«
"
type
"
».
To coordinate events, user interaction, scripts, rendering, networking, and so forth, user agents must use event loops as described in this section. Each agent has an associated event loop , which is unique to that agent.
The event loop of a similar-origin window agent is known as a window event loop . The event loop of a dedicated worker agent , shared worker agent , or service worker agent is known as a worker event loop . And the event loop of a worklet agent is known as a worklet event loop .
Event loops do not necessarily correspond to implementation threads. For example, multiple window event loops could be cooperatively scheduled in a single thread.
However, for the various worker agents that are allocated with [[CanBlock]] set to true, the JavaScript specification does place requirements on them regarding forward progress , which effectively amount to requiring dedicated per-agent threads in those cases.
An event loop has one or more task queues . A task queue is a set of tasks .
Task queues are sets , not queues , because the event loop processing model grabs the first runnable task from the chosen queue, instead of dequeuing the first task.
The microtask queue is not a task queue .
Tasks encapsulate algorithms that are responsible for such work as:
Dispatching
an
Event
object
at
a
particular
EventTarget
object
is
often
done
by
a
dedicated
task.
Not all events are dispatched using the task queue ; many are dispatched during other tasks.
The HTML parser tokenizing one or more bytes, and then processing any resulting tokens, is typically a task.
Calling a callback is often done by a dedicated task.
When an algorithm fetches a resource, if the fetching occurs in a non-blocking fashion then the processing of the resource once some or all of the resource is available is performed by a task.
Some elements have tasks that trigger in response to DOM manipulation, e.g. when that element is inserted into the document .
Formally, a task is a struct which has:
Document
associated
with
the
task,
or
null
for
tasks
that
are
not
in
a
window
event
loop
.
A task is runnable if its document is either null or fully active .
Per its source field, each task is defined as coming from a specific task source . For each event loop , every task source must be associated with a specific task queue .
Essentially, task sources are used within standards to separate logically-different types of tasks, which a user agent might wish to distinguish between. Task queues are used by user agents to coalesce task sources within a given event loop .
For example, a user agent could have one task queue for mouse and key events (to which the user interaction task source is associated), and another to which all other task sources are associated. Then, using the freedom granted in the initial step of the event loop processing model , it could give keyboard and mouse events preference over other tasks three-quarters of the time, keeping the interface responsive but not starving other task queues. Note that in this setup, the processing model still enforces that the user agent would never process events from any one task source out of order.
Each event loop has a currently running task , which is either a task or null. Initially, this is null. It is used to handle reentrancy.
Each event loop has a microtask queue , which is a queue of microtasks , initially empty. A microtask is a colloquial way of referring to a task that was created via the queue a microtask algorithm.
Each event loop has a performing a microtask checkpoint boolean, which is initially false. It is used to prevent reentrant invocation of the perform a microtask checkpoint algorithm.
Each
window
event
loop
has
a
DOMHighResTimeStamp
last
render
opportunity
time
,
initially
set
to
zero.
Each
window
event
loop
has
a
DOMHighResTimeStamp
last
idle
period
start
time
,
initially
set
to
zero.
To
get
the
same-loop
windows
for
a
window
event
loop
loop
,
return
all
Window
objects
whose
relevant
agent
's
event
loop
is
loop
.
To queue a task on a task source source , which performs a series of steps steps , optionally given an event loop event loop and a document document :
If event loop was not given, set event loop to the implied event loop .
If document was not given, set document to the implied document .
Let task be a new task .
Set task 's steps to steps .
Set task 's source to source .
Set task 's document to the document .
Set task 's script evaluation environment settings object set to an empty set .
Let queue be the task queue to which source is associated on event loop .
Append task to queue .
Failing to pass an event loop and document to queue a task means relying on the ambiguous and poorly-specified implied event loop and implied document concepts. Specification authors should either always pass these values, or use the wrapper algorithms queue a global task or queue an element task instead. Using the wrapper algorithms is recommended.
To queue a global task on a task source source , with a global object global and a series of steps steps :
Let event loop be global 's relevant agent 's event loop .
Let
document
be
global
's
associated
Document
,
if
global
is
a
Window
object;
otherwise
null.
Queue a task given source , event loop , document , and steps .
To queue an element task on a task source source , with an element element and a series of steps steps :
Let global be element 's relevant global object .
Queue a global task given source , global , and steps .
To queue a microtask which performs a series of steps steps , optionally given an event loop event loop and a document document :
If event loop was not given, set event loop to the implied event loop .
If document was not given, set document to the implied document .
Let microtask be a new task .
Set microtask 's steps to steps .
Set microtask 's source to the microtask task source .
Set microtask 's document to document .
Set microtask 's script evaluation environment settings object set to an empty set .
Enqueue microtask on event loop 's microtask queue .
It is possible for a microtask to be moved to a regular task queue , if, during its initial execution, it spins the event loop . This is the only case in which the source , document , and script evaluation environment settings object set of the microtask are consulted; they are ignored by the perform a microtask checkpoint algorithm.
The implied event loop when queuing a task is the one that can deduced from the context of the calling algorithm. This is generally unambiguous, as most specification algorithms only ever involve a single agent (and thus a single event loop ). The exception is algorithms involving or specifying cross-agent communication (e.g., between a window and a worker); for those cases, the implied event loop concept must not be relied upon and specifications must explicitly provide an event loop when queuing a task or microtask .
The implied document when queuing a task on an event loop event loop is determined as follows:
If event loop is not a window event loop , then return null.
If the task is being queued in the context of an element, then return the element's node document .
If the task is being queued in the context of a browsing context , then return the browsing context's active document .
If
the
task
is
being
queued
by
or
for
a
script
,
then
return
the
script's
settings
object
's
global
object
's
associated
Document
.
Assert: this step is never reached, because one of the previous conditions must be true. Really?
Both implied event loop and implied document are vaguely-defined and have a lot of action-at-a-distance. The hope is to remove these, especially implied document . See issue #4980 .
An event loop must continually run through the following steps for as long as it exists:
Let oldestTask and taskStartTime be null.
If the event loop has a task queue with at least one runnable task , then:
Let taskQueue be one such task queue , chosen in an implementation-defined manner.
Remember that the microtask queue is not a task queue , so it will not be chosen in this step. However, a task queue to which the microtask task source is associated might be chosen in this step. In that case, the task chosen in the next step was originally a microtask , but it got moved as part of spinning the event loop .
Set taskStartTime to the unsafe shared current time .
Set oldestTask to the first runnable task in taskQueue , and remove it from taskQueue .
Set the event loop 's currently running task to oldestTask .
Perform oldestTask 's steps .
Set the event loop 's currently running task back to null.
Let hasARenderingOpportunity be false.
Let now be the unsafe shared current time . [HRT]
If oldestTask is not null, then:
Let top-level browsing contexts be an empty set .
For each environment settings object settings of oldestTask 's script evaluation environment settings object set , append setting 's top-level browsing context to top-level browsing contexts .
Report long tasks , passing in taskStartTime , now (the end time of the task), top-level browsing contexts , and oldestTask .
Update the rendering : if this is a window event loop , then:
Let
docs
be
all
Document
objects
whose
relevant
agent
's
event
loop
is
this
event
loop,
sorted
arbitrarily
except
that
the
following
conditions
must
be
met:
Any
Document
B
whose
browsing
context
's
container
document
is
A
must
be
listed
after
A
in
the
list.
If
there
are
two
documents
A
and
B
whose
browsing
contexts
are
both
child
browsing
contexts
whose
container
documents
are
another
Document
C
,
then
the
order
of
A
and
B
in
the
list
must
match
the
shadow-including
tree
order
of
their
respective
browsing
context
containers
in
C
's
node
tree
.
In
the
steps
below
that
iterate
over
docs
,
each
Document
must
be
processed
in
the
order
it
is
found
in
the
list.
Rendering
opportunities
:
Remove
from
docs
all
Document
objects
whose
browsing
context
do
not
have
a
rendering
opportunity
.
A browsing context has a rendering opportunity if the user agent is currently able to present the contents of the browsing context to the user, accounting for hardware refresh rate constraints and user agent throttling for performance reasons, but considering content presentable even if it's outside the viewport.
A
browsing
context
has
no
rendering
opportunities
if
its
active
document
is
render-blocked
;
otherwise,
rendering
opportunities
are
determined
based
on
hardware
constraints
such
as
display
refresh
rates
and
other
factors
such
as
page
performance
or
whether
the
document's
visibility
state
is
"
visible
".
Rendering
opportunities
typically
occur
at
regular
intervals.
This specification does not mandate any particular model for selecting rendering opportunities. But for example, if the browser is attempting to achieve a 60Hz refresh rate, then rendering opportunities occur at a maximum of every 60th of a second (about 16.7ms). If the browser finds that a browsing context is not able to sustain this rate, it might drop to a more sustainable 30 rendering opportunities per second for that browsing context , rather than occasionally dropping frames. Similarly, if a browsing context is not visible, the user agent might decide to drop that page to a much slower 4 rendering opportunities per second, or even less.
If docs is not empty, then set hasARenderingOpportunity to true and set this event loop 's last render opportunity time to taskStartTime .
Unnecessary
rendering
:
Remove
from
docs
all
Document
objects
which
meet
both
of
the
following
conditions:
Document
's
browsing
context
would
have
no
visible
effect,
and
Document
's
map
of
animation
frame
callbacks
is
empty.
Remove
from
docs
all
Document
objects
for
which
the
user
agent
believes
that
it's
preferable
to
skip
updating
the
rendering
for
other
reasons.
The step labeled Rendering opportunities prevents the user agent from updating the rendering when it is unable to present new content to the user (there's no rendering opportunity ).
The step labeled Unnecessary rendering prevents the user agent from updating the rendering when there's no new content to draw.
This step enables the user agent to prevent the steps below from running for other reasons, for example, to ensure certain tasks are executed immediately after each other, with only microtask checkpoints interleaved (and without, e.g., animation frame callbacks interleaved). Concretely, a user agent might wish to coalesce timer callbacks together, with no intermediate rendering updates.
For
each
fully
active
Document
in
docs
,
flush
autofocus
candidates
for
that
Document
if
its
browsing
context
is
a
top-level
browsing
context
.
For
each
fully
active
Document
in
docs
,
run
the
resize
steps
for
that
Document
,
passing
in
now
as
the
timestamp.
[CSSOMVIEW]
For
each
fully
active
Document
in
docs
,
run
the
scroll
steps
for
that
Document
,
passing
in
now
as
the
timestamp.
[CSSOMVIEW]
For
each
fully
active
Document
in
docs
,
evaluate
media
queries
and
report
changes
for
that
Document
,
passing
in
now
as
the
timestamp.
[CSSOMVIEW]
For
each
fully
active
Document
in
docs
,
update
animations
and
send
events
for
that
Document
,
passing
in
now
as
the
timestamp.
[WEBANIMATIONS]
For
each
fully
active
Document
in
docs
,
run
the
fullscreen
steps
for
that
Document
,
passing
in
now
as
the
timestamp.
[FULLSCREEN]
For
each
fully
active
Document
in
docs
,
if
the
user
agent
detects
that
the
backing
storage
associated
with
a
CanvasRenderingContext2D
or
an
OffscreenCanvasRenderingContext2D
,
context
,
has
been
lost,
then
it
must
run
the
context
lost
steps
for
each
such
context
:
Let
canvas
be
the
value
of
context
's
canvas
attribute,
if
context
is
a
CanvasRenderingContext2D
,
or
the
associated
OffscreenCanvas
object
for
context
otherwise.
Set context 's context lost to true.
Reset the rendering context to its default state given context .
Let
shouldRestore
be
the
result
of
firing
an
event
named
contextlost
at
canvas
,
with
the
cancelable
attribute
initialized
to
true.
If shouldRestore is false, then abort these steps.
Attempt to restore context by creating a backing storage using context 's attributes and associating them with context . If this fails, then abort these steps.
Set context 's context lost to false.
Fire
an
event
named
contextrestored
at
canvas
.
For
each
fully
active
Document
in
docs
,
run
the
animation
frame
callbacks
for
that
Document
,
passing
in
now
as
the
timestamp.
For
each
fully
active
Document
in
docs
,
run
the
update
intersection
observations
steps
for
that
Document
,
passing
in
now
as
the
timestamp.
[INTERSECTIONOBSERVER]
Invoke
the
mark
paint
timing
algorithm
for
each
Document
object
in
docs
.
For
each
fully
active
Document
in
docs
,
update
the
rendering
or
user
interface
of
that
Document
and
its
browsing
context
to
reflect
the
current
state.
If all of the following are true
then:
Set this event loop 's last idle period start time to the unsafe shared current time .
Let computeDeadline be the following steps:
Let deadline be this event loop 's last idle period start time plus 50.
The cap of 50ms in the future is to ensure responsiveness to new user input within the threshold of human perception.
Let hasPendingRenders be false.
For each windowInSameLoop of the same-loop windows for this event loop :
If windowInSameLoop 's map of animation frame callbacks is not empty , or if the user agent believes that the windowInSameLoop might have pending rendering updates, set hasPendingRenders to true.
Let timerCallbackEstimates be the result of getting the values of windowInSameLoop 's map of active timers .
For each timeoutDeadline of timerCallbackEstimates , if timeoutDeadline is less than deadline , set deadline to timeoutDeadline .
If hasPendingRenders is true, then:
Let nextRenderDeadline be this event loop 's last render opportunity time plus (1000 divided by the current refresh rate).
The refresh rate can be hardware- or implementation-specific. For a refresh rate of 60Hz, the nextRenderDeadline would be about 16.67ms after the last render opportunity time .
If nextRenderDeadline is less than deadline , then return nextRenderDeadline .
Return deadline .
For each win of the same-loop windows for this event loop , perform the start an idle period algorithm for win with the following step: return the result of calling computeDeadline , coarsened given win 's relevant settings object 's cross-origin isolated capability . [REQUESTIDLECALLBACK]
If this is a worker event loop , then:
If
this
event
loop
's
agent
's
single
realm
's
global
object
is
a
supported
DedicatedWorkerGlobalScope
and
the
user
agent
believes
that
it
would
benefit
from
having
its
rendering
updated
at
this
time,
then:
Let
now
be
the
current
high
resolution
time
given
the
DedicatedWorkerGlobalScope
.
[HRT]
Run
the
animation
frame
callbacks
for
that
DedicatedWorkerGlobalScope
,
passing
in
now
as
the
timestamp.
Update the rendering of that dedicated worker to reflect the current state.
Similar to the notes for updating the rendering in a window event loop , a user agent can determine the rate of rendering in the dedicated worker.
If
there
are
no
tasks
in
the
event
loop
's
task
queues
and
the
WorkerGlobalScope
object's
closing
flag
is
true,
then
destroy
the
event
loop
,
aborting
these
steps,
resuming
the
run
a
worker
steps
described
in
the
Web
workers
section
below.
When a user agent is to perform a microtask checkpoint :
If the event loop 's performing a microtask checkpoint is true, then return.
Set the event loop 's performing a microtask checkpoint to true.
While the event loop 's microtask queue is not empty :
Let oldestMicrotask be the result of dequeuing from the event loop 's microtask queue .
Set the event loop 's currently running task to oldestMicrotask .
Run oldestMicrotask .
This might involve invoking scripted callbacks, which eventually calls the clean up after running script steps, which call this perform a microtask checkpoint algorithm again, which is why we use the performing a microtask checkpoint flag to avoid reentrancy.
Set the event loop 's currently running task back to null.
For each environment settings object whose responsible event loop is this event loop , notify about rejected promises on that environment settings object .
Perform ClearKeptObjects ().
When
WeakRef.prototype.deref()
returns
an
object,
that
object
is
kept
alive
until
the
next
invocation
of
ClearKeptObjects
(),
after
which
it
is
again
subject
to
garbage
collection.
Set the event loop 's performing a microtask checkpoint to false.
When an algorithm running in parallel is to await a stable state , the user agent must queue a microtask that runs the following steps, and must then stop executing (execution of the algorithm resumes when the microtask is run, as described in the following steps):
Run the algorithm's synchronous section .
Resumes execution of the algorithm in parallel , if appropriate, as described in the algorithm's steps.
Steps in synchronous sections are marked with ⌛.
Algorithm steps that say to spin the event loop until a condition goal is met are equivalent to substituting in the following algorithm steps:
Let task be the event loop 's currently running task .
task could be a microtask .
Let task source be task 's source .
Let old stack be a copy of the JavaScript execution context stack .
Empty the JavaScript execution context stack .
Perform a microtask checkpoint .
If task is a microtask this step will be a no-op due to performing a microtask checkpoint being true.
Wait until the condition goal is met.
Queue a task on task source to:
Replace the JavaScript execution context stack with old stack .
Perform any steps that appear after this spin the event loop instance in the original algorithm.
This resumes task .
Stop task , allowing whatever algorithm that invoked it to resume.
This causes the event loop 's main set of steps or the perform a microtask checkpoint algorithm to continue.
Unlike other algorithms in this and other specifications, which behave similar to programming-language function calls, spin the event loop is more like a macro, which saves typing and indentation at the usage site by expanding into a series of steps and operations.
An algorithm whose steps are:
Do something.
Spin the event loop until awesomeness happens.
Do something else.
is a shorthand which, after "macro expansion", becomes
Do something.
Let old stack be a copy of the JavaScript execution context stack .
Empty the JavaScript execution context stack .
Wait until awesomeness happens.
Queue a task on the task source in which "do something" was done to:
Replace the JavaScript execution context stack with old stack .
Do something else.
Here is a more full example of the substitution, where the event loop is spun from inside a task that is queued from work in parallel. The version using spin the event loop :
Do parallel thing 1.
Queue a task on the DOM manipulation task source to:
Do task thing 1.
Spin the event loop until awesomeness happens.
Do task thing 2.
Do parallel thing 2.
The fully expanded version:
Do parallel thing 1.
Let old stack be null.
Queue a task on the DOM manipulation task source to:
Do task thing 1.
Set old stack to a copy of the JavaScript execution context stack .
Empty the JavaScript execution context stack .
Wait until awesomeness happens.
Queue a task on the DOM manipulation task source to:
Replace the JavaScript execution context stack with old stack .
Do task thing 2.
Do parallel thing 2.
Some of the algorithms in this specification, for historical reasons, require the user agent to pause while running a task until a condition goal is met. This means running the following steps:
If
necessary,
update
the
rendering
or
user
interface
of
any
Document
or
browsing
context
to
reflect
the
current
state.
Wait until the condition goal is met. While a user agent has a paused task , the corresponding event loop must not run further tasks , and any script in the currently running task must block. User agents should remain responsive to user input while paused, however, albeit in a reduced capacity since the event loop will not be doing anything.
Pausing is highly detrimental to the user experience, especially in scenarios where a single event loop is shared among multiple documents. User agents are encouraged to experiment with alternatives to pausing , such as spinning the event loop or even simply proceeding without any kind of suspended execution at all, insofar as it is possible to do so while preserving compatibility with existing content. This specification will happily change if a less-drastic alternative is discovered to be web-compatible.
In the interim, implementers should be aware that the variety of alternatives that user agents might experiment with can change subtle aspects of event loop behavior, including task and microtask timing. Implementations should continue experimenting even if doing so causes them to violate the exact semantics implied by the pause operation.
The following task sources are used by a number of mostly unrelated features in this and other specifications.
This task source is used for features that react to DOM manipulations, such as things that happen in a non-blocking fashion when an element is inserted into the document .
This task source is used for features that react to user interaction, for example keyboard or mouse input.
Events
sent
in
response
to
user
input
(e.g.
click
events)
must
be
fired
using
tasks
queued
with
the
user
interaction
task
source
.
[UIEVENTS]
This task source is used for features that trigger in response to network activity.
This
task
source
is
used
to
queue
calls
to
history.back()
and
similar
APIs.
Writing specifications that correctly interact with the event loop can be tricky. This is compounded by how this specification uses concurrency-model-independent terminology, so we say things like " event loop " and " in parallel " instead of using more familiar model-specific terms like "main thread" or "on a background thread".
By default, specification text generally runs on the event loop . This falls out from the formal event loop processing model , in that you can eventually trace most algorithms back to a task queued there.
The
algorithm
steps
for
any
JavaScript
method
will
be
invoked
by
author
code
calling
that
method.
And
author
code
can
only
be
run
via
queued
tasks,
usually
originating
somewhere
in
the
script
processing
model
.
From this starting point, the overriding guideline is that any work a specification needs to perform that would otherwise block the event loop must instead be performed in parallel with it. This includes (but is not limited to):
performing heavy computation;
displaying a user-facing prompt;
performing operations which could require involving outside systems (i.e. "going out of process").
The next complication is that, in algorithm sections that are in parallel , you must not create or manipulate objects associated to a specific JavaScript realm , global , or environment settings object . (Stated in more familiar terms, you must not directly access main-thread artifacts from a background thread.) Doing so would create data races observable to JavaScript code, since after all, your algorithm steps are running in parallel to the JavaScript code.
You can, however, manipulate specification-level data structures and values from Infra , as those are realm-agnostic. They are never directly exposed to JavaScript without a specific conversion taking place (often via Web IDL ). [INFRA] [WEBIDL]
To affect the world of observable JavaScript objects, then, you must queue a global task to perform any such manipulations. This ensures your steps are properly interleaved with respect to other things happening on the event loop . Furthermore, you must choose a task source when queuing a global task ; this governs the relative order of your steps versus others. If you are unsure which task source to use, pick one of the generic task sources that sounds most applicable. Finally, you must indicate which global object your queued task is associated with; this ensures that if that global object is inactive, the task does not run.
The base primitive, on which queue a global task builds, is the queue a task algorithm. In general, queue a global task is better because it automatically picks the right event loop and, where appropriate, document . Older specifications often use queue a task combined with the implied event loop and implied document concepts, but this is discouraged.
Putting this all together, we can provide a template for a typical algorithm that needs to do work asynchronously:
Do any synchronous setup work, while still on the event loop . This may include converting realm -specific JavaScript values into realm-agnostic specification-level values.
Perform a set of potentially-expensive steps in parallel , operating entirely on realm-agnostic values, and producing a realm-agnostic result.
Queue a global task , on a specified task source and given an appropriate global object , to convert the realm-agnostic result back into observable effects on the observable world of JavaScript objects on the event loop .
The following is an algorithm that "encrypts" a passed-in list of scalar value strings input , after parsing them as URLs:
Let urls be an empty list .
For each string of input :
Let parsed be the result of parsing string relative to the current settings object .
If
parsed
is
failure,
return
a
promise
rejected
with
a
"
SyntaxError
"
DOMException
.
Let serialized be the result of applying the URL serializer to parsed .
Append serialized to urls .
Let realm be the current Realm Record .
Let p be a new promise.
Run the following steps in parallel :
Let encryptedURLs be an empty list .
For each url of urls :
Queue a global task on the networking task source , given realm 's global object , to perform the following steps:
Let array be the result of converting encryptedURLs to a JavaScript array, in realm .
Resolve p with array .
Return p .
Here are several things to notice about this algorithm:
It does its URL parsing up front, on the event loop , before going to the in parallel steps. This is necessary, since parsing depends on the current settings object , which would no longer be current after going in parallel .
Alternately, it could have saved a reference to the current settings object 's API base URL and used it during the in parallel steps; that would have been equivalent. However, we recommend instead doing as much work as possible up front, as this example does. Attempting to save the correct values can be error prone; for example, if we'd saved just the current settings object , instead of its API base URL , there would have been a potential race.
It implicitly passes a list of strings from the initial steps to the in parallel steps. This is OK, as both lists and strings are realm -agnostic.
It performs "expensive computation" (waiting for 100 milliseconds per input URL) during the in parallel steps, thus not blocking the main event loop .
Promises, as observable JavaScript objects, are never created and manipulated during the in parallel steps. p is created before entering those steps, and then is manipulated during a task that is queued specifically for that purpose.
The creation of a JavaScript array object also happens during the queued task, and is careful to specify which realm it creates the array in since that is no longer obvious from context.
(On these last two points, see also whatwg/webidl issue #135 and whatwg/webidl issue #371 , where we are still mulling over the subtleties of the above promise-resolution pattern.)
Another
thing
to
note
is
that,
in
the
event
this
algorithm
was
called
from
a
Web
IDL-specified
operation
taking
a
sequence
<
USVString
>,
there
was
an
automatic
conversion
from
realm
-specific
JavaScript
objects
provided
by
the
author
as
input,
into
the
realm-agnostic
sequence
<
USVString
>
Web
IDL
type,
which
we
then
treat
as
a
list
of
scalar
value
strings
.
So
depending
on
how
your
specification
is
structured,
there
may
be
other
implicit
steps
happening
on
the
main
event
loop
that
play
a
part
in
this
whole
process
of
getting
you
ready
to
go
in
parallel
.
Many objects can have event handlers specified. These act as non-capture event listeners for the object on which they are specified. [DOM]
An event handler is a struct with two items :
a
value
,
which
is
either
null,
a
callback
object,
or
an
internal
raw
uncompiled
handler
.
The
EventHandler
callback
function
type
describes
how
this
is
exposed
to
scripts.
Initially,
an
event
handler
's
value
must
be
set
to
null.
a listener , which is either null or an event listener responsible for running the event handler processing algorithm . Initially, an event handler 's listener must be set to null.
Event handlers are exposed in two ways.
The first way, common to all event handlers, is as an event handler IDL attribute .
The
second
way
is
as
an
event
handler
content
attribute
.
Event
handlers
on
HTML
elements
and
some
of
the
event
handlers
on
Window
objects
are
exposed
in
this
way.
For
both
of
these
two
ways,
the
event
handler
is
exposed
through
a
name
,
which
is
a
string
that
always
starts
with
"
on
"
and
is
followed
by
the
name
of
the
event
for
which
the
handler
is
intended.
Most
of
the
time,
the
object
that
exposes
an
event
handler
is
the
same
as
the
object
on
which
the
corresponding
event
listener
is
added.
However,
the
body
and
frameset
elements
expose
several
event
handlers
that
act
upon
the
element's
Window
object,
if
one
exists.
In
either
case,
we
call
the
object
an
event
handler
acts
upon
the
target
of
that
event
handler
.
To
determine
the
target
of
an
event
handler
,
given
an
EventTarget
object
eventTarget
on
which
the
event
handler
is
exposed,
and
an
event
handler
name
name
,
the
following
steps
are
taken:
If
eventTarget
is
not
a
body
element
or
a
frameset
element,
then
return
eventTarget
.
If
name
is
not
the
name
of
an
attribute
member
of
the
WindowEventHandlers
interface
mixin
and
the
Window
-reflecting
body
element
event
handler
set
does
not
contain
name
,
then
return
eventTarget
.
If eventTarget 's node document is not an active document , then return null.
This
could
happen
if
this
object
is
a
body
element
without
a
corresponding
Window
object,
for
example.
This
check
does
not
necessarily
prevent
body
and
frameset
elements
that
are
not
the
body
element
of
their
node
document
from
reaching
the
next
step.
In
particular,
a
body
element
created
in
an
active
document
(perhaps
with
document.createElement()
)
but
not
connected
will
also
have
its
corresponding
Window
object
as
the
target
of
several
event
handlers
exposed
through
it.
Return eventTarget 's node document 's relevant global object .
Each
EventTarget
object
that
has
one
or
more
event
handlers
specified
has
an
associated
event
handler
map
,
which
is
a
map
of
strings
representing
names
of
event
handlers
to
event
handlers
.
When
an
EventTarget
object
that
has
one
or
more
event
handlers
specified
is
created,
its
event
handler
map
must
be
initialized
such
that
it
contains
an
entry
for
each
event
handler
that
has
that
object
as
target
,
with
items
in
those
event
handlers
set
to
their
initial
values.
The order of the entries of event handler map could be arbitrary. It is not observable through any algorithms that operate on the map.
Entries are not created in the event handler map of an object for event handlers that are merely exposed on that object, but have some other object as their targets .
An event handler IDL attribute is an IDL attribute for a specific event handler . The name of the IDL attribute is the same as the name of the event handler .
The getter of an event handler IDL attribute with name name , when called, must run these steps:
Let eventTarget be the result of determining the target of an event handler given this object and name .
If eventTarget is null, then return null.
Return the result of getting the current value of the event handler given eventTarget and name .
The setter of an event handler IDL attribute with name name , when called, must run these steps:
Let eventTarget be the result of determining the target of an event handler given this object and name .
If eventTarget is null, then return.
If the given value is null, then deactivate an event handler given eventTarget and name .
Otherwise:
Let handlerMap be eventTarget 's event handler map .
Let eventHandler be handlerMap [ name ].
Set eventHandler 's value to the given value.
Activate an event handler given eventTarget and name .
Certain
event
handler
IDL
attributes
have
additional
requirements,
in
particular
the
onmessage
attribute
of
MessagePort
objects.
An event handler content attribute is a content attribute for a specific event handler . The name of the content attribute is the same as the name of the event handler .
Event handler content attributes , when specified, must contain valid JavaScript code which, when parsed, would match the FunctionBody production after automatic semicolon insertion .
The following attribute change steps are used to synchronize between event handler content attributes and event handlers : [DOM]
If namespace is not null, or localName is not the name of an event handler content attribute on element , then return.
Let eventTarget be the result of determining the target of an event handler given element and localName .
If eventTarget is null, then return.
If value is null, then deactivate an event handler given eventTarget and localName .
Otherwise:
If
the
Should
element's
inline
behavior
be
blocked
by
Content
Security
Policy?
algorithm
returns
"
Blocked
"
when
executed
upon
element
,
"
script
attribute
",
and
value
,
then
return.
[CSP]
Let handlerMap be eventTarget 's event handler map .
Let eventHandler be handlerMap [ localName ].
Let location be the script location that triggered the execution of these steps.
Set eventHandler 's value to the internal raw uncompiled handler value / location .
Activate an event handler given eventTarget and localName .
Per the DOM Standard, these steps are run even if oldValue and value are identical (setting an attribute to its current value), but not if oldValue and value are both null (removing an attribute that doesn't currently exist). [DOM]
To
deactivate
an
event
handler
given
an
EventTarget
object
eventTarget
and
a
string
name
that
is
the
name
of
an
event
handler
,
run
these
steps:
Let handlerMap be eventTarget 's event handler map .
Let eventHandler be handlerMap [ name ].
Set eventHandler 's value to null.
Let listener be eventHandler 's listener .
If listener is not null, then remove an event listener with eventTarget and listener .
Set eventHandler 's listener to null.
To
erase
all
event
listeners
and
handlers
given
an
EventTarget
object
eventTarget
,
run
these
steps:
If eventTarget has an associated event handler map , then for each name → eventHandler of eventTarget 's associated event handler map , deactivate an event handler given eventTarget and name .
Remove all event listeners given eventTarget .
This
algorithm
is
used
to
define
document.open()
.
To
activate
an
event
handler
given
an
EventTarget
object
eventTarget
and
a
string
name
that
is
the
name
of
an
event
handler
,
run
these
steps:
Let handlerMap be eventTarget 's event handler map .
Let eventHandler be handlerMap [ name ].
If eventHandler 's listener is not null, then return.
Let
callback
be
the
result
of
creating
a
Web
IDL
EventListener
instance
representing
a
reference
to
a
function
of
one
argument
that
executes
the
steps
of
the
event
handler
processing
algorithm
,
given
eventTarget
,
name
,
and
its
argument.
The
EventListener
's
callback
context
can
be
arbitrary;
it
does
not
impact
the
steps
of
the
event
handler
processing
algorithm
.
[DOM]
The callback is emphatically not the event handler itself. Every event handler ends up registering the same callback, the algorithm defined below, which takes care of invoking the right code, and processing the code's return value.
Let listener be a new event listener whose type is the event handler event type corresponding to eventHandler and callback is callback .
To
be
clear,
an
event
listener
is
different
from
an
EventListener
.
Add an event listener with eventTarget and listener .
Set eventHandler 's listener to listener .
The event listener registration happens only if the event handler 's value is being set to non-null, and the event handler is not already activated. Since listeners are called in the order they were registered, assuming no deactivation occurred, the order of event listeners for a particular event type will always be:
the
event
listeners
registered
with
addEventListener()
before
the
first
time
the
event
handler
's
value
was
set
to
non-null
then the callback to which it is currently set, if any
and
finally
the
event
listeners
registered
with
addEventListener()
after
the
first
time
the
event
handler
's
value
was
set
to
non-null.
This example demonstrates the order in which event listeners are invoked. If the button in this example is clicked by the user, the page will show four alerts, with the text "ONE", "TWO", "THREE", and "FOUR" respectively.
<button id="test">Start Demo</button>
<script>
var button = document.getElementById('test');
button.addEventListener('click', function () { alert('ONE') }, false);
button.setAttribute('onclick', "alert('NOT CALLED')"); // event handler listener is registered here
button.addEventListener('click', function () { alert('THREE') }, false);
button.onclick = function () { alert('TWO'); };
button.addEventListener('click', function () { alert('FOUR') }, false);
</script>
However, in the following example, the event handler is deactivated after its initial activation (and its event listener is removed), before being reactivated at a later time. The page will show five alerts with "ONE", "TWO", "THREE", "FOUR", and "FIVE" respectively, in order.
<button id="test">Start Demo</button>
<script>
var button = document.getElementById('test');
button.addEventListener('click', function () { alert('ONE') }, false);
button.setAttribute('onclick', "alert('NOT CALLED')"); // event handler is activated here
button.addEventListener('click', function () { alert('TWO') }, false);
button.onclick = null; // but deactivated here
button.addEventListener('click', function () { alert('THREE') }, false);
button.onclick = function () { alert('FOUR'); }; // and re-activated here
button.addEventListener('click', function () { alert('FIVE') }, false);
</script>
The interfaces implemented by the event object do not influence whether an event handler is triggered or not.
The
event
handler
processing
algorithm
for
an
EventTarget
object
eventTarget
,
a
string
name
representing
the
name
of
an
event
handler
,
and
an
Event
object
event
is
as
follows:
Let callback be the result of getting the current value of the event handler given eventTarget and name .
If callback is null, then return.
Let
special
error
event
handling
be
true
if
event
is
an
ErrorEvent
object,
event
's
type
is
error
,
and
event
's
currentTarget
implements
the
WindowOrWorkerGlobalScope
mixin.
Otherwise,
let
special
error
event
handling
be
false.
Process
the
Event
object
event
as
follows:
Invoke
callback
with
five
arguments,
the
first
one
having
the
value
of
event
's
message
attribute,
the
second
having
the
value
of
event
's
filename
attribute,
the
third
having
the
value
of
event
's
lineno
attribute,
the
fourth
having
the
value
of
event
's
colno
attribute,
the
fifth
having
the
value
of
event
's
error
attribute,
and
with
the
callback
this
value
set
to
event
's
currentTarget
.
Let
return
value
be
the
callback's
return
value.
[WEBIDL]
Invoke
callback
with
one
argument,
the
value
of
which
is
the
Event
object
event
,
with
the
callback
this
value
set
to
event
's
currentTarget
.
Let
return
value
be
the
callback's
return
value.
[WEBIDL]
If an exception gets thrown by the callback, end these steps and allow the exception to propagate. (It will propagate to the DOM event dispatch logic , which will then report the exception .)
Process return value as follows:
BeforeUnloadEvent
object
and
event
's
type
is
beforeunload
In
this
case,
the
event
handler
IDL
attribute
's
type
will
be
OnBeforeUnloadEventHandler
,
so
return
value
will
have
been
coerced
into
either
null
or
a
DOMString
.
If return value is not null, then:
Set event 's canceled flag .
If
event
's
returnValue
attribute's
value
is
the
empty
string,
then
set
event
's
returnValue
attribute's
value
to
return
value
.
If return value is true, then set event 's canceled flag .
If return value is false, then set event 's canceled flag .
If
we've
gotten
to
this
"Otherwise"
clause
because
event
's
type
is
beforeunload
but
event
is
not
a
BeforeUnloadEvent
object,
then
return
value
will
never
be
false,
since
in
such
cases
return
value
will
have
been
coerced
into
either
null
or
a
DOMString
.
The
EventHandler
callback
function
type
represents
a
callback
used
for
event
handlers.
It
is
represented
in
Web
IDL
as
follows:
[LegacyTreatNonObjectAsNull]
callback EventHandlerNonNull = any (Event event);
typedef
EventHandlerNonNull
?
EventHandler
;
In
JavaScript,
any
Function
object
implements
this
interface.
For example, the following document fragment:
<body
onload="alert(this)"
onclick="alert(this)">
...leads
to
an
alert
saying
"
[object Window]
"
when
the
document
is
loaded,
and
an
alert
saying
"
[object HTMLBodyElement]
"
whenever
the
user
clicks
something
in
the
page.
The return value of the function affects whether the event is canceled or not: as described above, if the return value is false, the event is canceled.
There are two exceptions in the platform, for historical reasons:
The
onerror
handlers
on
global
objects,
where
returning
true
cancels
the
event.
The
onbeforeunload
handler,
where
returning
any
non-null
and
non-undefined
value
will
cancel
the
event.
For
historical
reasons,
the
onerror
handler
has
different
arguments:
[LegacyTreatNonObjectAsNull]
callback OnErrorEventHandlerNonNull = any ((Event or DOMString) event, optional DOMString source, optional unsigned long lineno, optional unsigned long colno, optional any error);
typedef
OnErrorEventHandlerNonNull
?
OnErrorEventHandler
;
window.onerror
=
(message,
source,
lineno,
colno,
error)
=>
{
…
};
Similarly,
the
onbeforeunload
handler
has
a
different
return
value:
[LegacyTreatNonObjectAsNull]
callback OnBeforeUnloadEventHandlerNonNull = DOMString? (Event event);
typedef
OnBeforeUnloadEventHandlerNonNull
?
OnBeforeUnloadEventHandler
;
An internal raw uncompiled handler is a tuple with the following information:
When
the
user
agent
is
to
get
the
current
value
of
the
event
handler
given
an
EventTarget
object
eventTarget
and
a
string
name
that
is
the
name
of
an
event
handler
,
it
must
run
these
steps:
Let handlerMap be eventTarget 's event handler map .
Let eventHandler be handlerMap [ name ].
If eventHandler 's value is an internal raw uncompiled handler , then:
If
eventTarget
is
an
element,
then
let
element
be
eventTarget
,
and
document
be
element
's
node
document
.
Otherwise,
eventTarget
is
a
Window
object,
let
element
be
null,
and
document
be
eventTarget
's
associated
Document
.
If scripting is disabled for document , then return null.
Let body be the uncompiled script body in eventHandler 's value .
Let location be the location where the script body originated, as given by eventHandler 's value .
If element is not null and element has a form owner , let form owner be that form owner . Otherwise, let form owner be null.
Let settings object be the relevant settings object of document .
If body is not parsable as FunctionBody or if parsing detects an early error , then follow these substeps:
Set eventHandler 's value to null.
This does not deactivate the event handler, which additionally removes the event handler's listener (if present).
Report the error for the appropriate script and with the appropriate position (line number and column number) given by location , using settings object 's global object . If the error is still not handled after this, then the error may be reported to a developer console.
Return null.
Push settings object 's realm execution context onto the JavaScript execution context stack ; it is now the running JavaScript execution context .
This is necessary so the subsequent invocation of OrdinaryFunctionCreate takes place in the correct JavaScript Realm .
Let function be the result of calling OrdinaryFunctionCreate , with arguments:
onerror
and
eventTarget
is
a
Window
object
function
",
name
,
"
(event,
source,
lineno,
colno,
error)
{
",
U+000A
LF,
body
,
U+000A
LF,
and
"
}
".
function
",
name
,
"
(event)
{
",
U+000A
LF,
body
,
U+000A
LF,
and
"
}
".
Let realm be settings object 's Realm .
Let scope be realm .[[GlobalEnv]].
If eventHandler is an element's event handler , then set scope to NewObjectEnvironment ( document , true, scope ).
(Otherwise,
eventHandler
is
a
Window
object's
event
handler
.)
If form owner is not null, then set scope to NewObjectEnvironment ( form owner , true, scope ).
If element is not null, then set scope to NewObjectEnvironment ( element , true, scope ).
Return scope .
Remove settings object 's realm execution context from the JavaScript execution context stack .
Set function .[[ScriptOrModule]] to null.
This is done because the default behavior, of associating the created function with the nearest script on the stack, can lead to path-dependent results. For example, an event handler which is first invoked by user interaction would end up with null [[ScriptOrModule]] (since then this algorithm would be first invoked when the active script is null), whereas one that is first invoked by dispatching an event from script would have its [[ScriptOrModule]] set to that script.
Instead, we just always set [[ScriptOrModule]] to null. This is more intuitive anyway; the idea that the first script which dispatches an event is somehow responsible for the event handler code is dubious.
In
practice,
this
only
affects
the
resolution
of
relative
URLs
via
import()
,
which
consult
the
base
URL
of
the
associated
script.
Nulling
out
[[ScriptOrModule]]
means
that
HostResolveImportedModule
and
HostImportModuleDynamically
will
fall
back
to
the
current
settings
object
's
API
base
URL
.
Set
eventHandler
's
value
to
the
result
of
creating
a
Web
IDL
EventHandler
callback
function
object
whose
object
reference
is
function
and
whose
callback
context
is
settings
object
.
Return eventHandler 's value .
Document
objects,
and
Window
objects
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported
by
all
HTML
elements
,
as
both
event
handler
content
attributes
and
event
handler
IDL
attributes
;
and
that
must
be
supported
by
all
Document
and
Window
objects,
as
event
handler
IDL
attributes
:
Event handler | Event handler event type |
---|---|
onabort
|
abort
|
onauxclick
|
auxclick
|
onbeforeinput
|
beforeinput
|
onbeforematch
|
beforematch
|
oncancel
Support in one engine only.
Firefox
No
Safari
No
Chrome
32+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
cancel
|
oncanplay
|
canplay
|
oncanplaythrough
|
canplaythrough
|
onchange
Support in all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera 9+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 10.1+ |
change
|
onclick
Support in all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera 9+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 10.1+ |
click
|
onclose
Firefox
53+
Safari
No
Chrome
32+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
close
|
oncontextlost
|
contextlost
|
oncontextmenu
GlobalEventHandlers/oncontextmenu Support in all current engines.
Firefox
9+
Safari
4+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 5+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 12.1+ |
contextmenu
|
oncontextrestored
|
contextrestored
|
oncuechange
HTMLTrackElement/cuechange_event Support in all current engines.
Firefox
68+
Safari
10+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 14+ Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android 4.4.3+ Samsung Internet ? Opera Android 19+ |
cuechange
|
ondblclick
GlobalEventHandlers/ondblclick Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
dblclick
|
ondrag
|
drag
|
ondragend
|
dragend
|
ondragenter
|
dragenter
|
ondragleave
|
dragleave
|
ondragover
|
dragover
|
ondragstart
|
dragstart
|
ondrop
|
drop
|
ondurationchange
|
durationchange
|
onemptied
Support in all current engines.
Firefox
9+
Safari
9+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 19+ |
emptied
|
onended
Support in all current engines.
Firefox
9+
Safari
9+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 19+ |
ended
|
onformdata
GlobalEventHandlers/onformdata Support in all current engines.
Firefox
72+
Safari
15+
Chrome
77+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS 15+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
formdata
|
oninput
Support in all current engines.
Firefox
9+
Safari
4+
Chrome
1+
Opera 10+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 10.1+ |
input
|
oninvalid
Support in all current engines.
Firefox
9+
Safari
5+
Chrome
4+
Opera 12.1+ Edge 79+ Edge (Legacy) 13+ Internet Explorer No Firefox Android ? Safari iOS 4+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 12.1+ |
invalid
|
onkeydown
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
keydown
|
onkeypress
|
keypress
|
onkeyup
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
keyup
|
onloadeddata
GlobalEventHandlers/onloadeddata Support in all current engines.
Firefox
9+
Safari
9+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 19+ |
loadeddata
|
onloadedmetadata
GlobalEventHandlers/onloadedmetadata Support in all current engines.
Firefox
9+
Safari
9+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 19+ |
loadedmetadata
|
onloadstart
GlobalEventHandlers/onloadstart Support in all current engines.
Firefox
9+
Safari
9+
Chrome
32+
Opera 19+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 19+ |
loadstart
|
onmousedown
GlobalEventHandlers/onmousedown Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
mousedown
|
onmouseenter
GlobalEventHandlers/onmouseenter Support in all current engines.
Firefox
10+
Safari
7+
Chrome
30+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 5.5+ Firefox Android ? Safari iOS 7+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
mouseenter
|
onmouseleave
GlobalEventHandlers/onmouseleave Support in all current engines.
Firefox
10+
Safari
7+
Chrome
30+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 5.5+ Firefox Android ? Safari iOS 7+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
mouseleave
|
onmousemove
GlobalEventHandlers/onmousemove Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
mousemove
|
onmouseout
GlobalEventHandlers/onmouseout Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
mouseout
|
onmouseover
GlobalEventHandlers/onmouseover Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
mouseover
|
onmouseup
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
mouseup
|
onpause
|
pause
|
onplay
|
play
|
onplaying
|
playing
|
onprogress
|
progress
|
onratechange
|
ratechange
|
onreset
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
reset
|
onsecuritypolicyviolation
GlobalEventHandlers/onsecuritypolicyviolation Support in all current engines.
Firefox
93+
Safari
preview+
Chrome
97+
Opera ? Edge 97+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS No Chrome Android ? WebView Android ? Samsung Internet ? Opera Android No |
securitypolicyviolation
|
onseeked
|
seeked
|
onseeking
|
seeking
|
onselect
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
select
|
onslotchange
GlobalEventHandlers/onslotchange Support in all current engines.
Firefox
93+
Safari
preview+
Chrome
97+
Opera ? Edge 97+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS No Chrome Android ? WebView Android ? Samsung Internet ? Opera Android No |
slotchange
|
onstalled
|
stalled
|
onsubmit
Support in all current engines.
Firefox
9+
Safari
1+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
submit
|
onsuspend
|
suspend
|
ontimeupdate
|
timeupdate
|
ontoggle
|
toggle
|
onvolumechange
|
volumechange
|
onwaiting
|
waiting
|
onwebkitanimationend
|
webkitAnimationEnd
|
onwebkitanimationiteration
|
webkitAnimationIteration
|
onwebkitanimationstart
|
webkitAnimationStart
|
onwebkittransitionend
|
webkitTransitionEnd
|
onwheel
Support in all current engines.
Firefox
17+
Safari
7+
Chrome
31+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer No Firefox Android ? Safari iOS 7+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
wheel
|
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported
by
all
HTML
elements
other
than
body
and
frameset
elements,
as
both
event
handler
content
attributes
and
event
handler
IDL
attributes
;
that
must
be
supported
by
all
Document
objects,
as
event
handler
IDL
attributes
;
and
that
must
be
supported
by
all
Window
objects,
as
event
handler
IDL
attributes
on
the
Window
objects
themselves,
and
with
corresponding
event
handler
content
attributes
and
event
handler
IDL
attributes
exposed
on
all
body
and
frameset
elements
that
are
owned
by
that
Window
object's
associated
Document
:
Event handler | Event handler event type |
---|---|
onblur
Support in all current engines.
Firefox
24+
Safari
3.1+
Chrome
1+
Opera 11.6+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ Support in all current engines.
Firefox
6+
Safari
5.1+
Chrome
5+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 11 Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 12.1+ |
blur
|
onerror
Support in all current engines.
Firefox
1+
Safari
6+
Chrome
10+
Opera 11.6+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 12+ |
error
|
onfocus
Support in all current engines.
Firefox
24+
Safari
3.1+
Chrome
1+
Opera 11.6+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ Support in all current engines.
Firefox
6+
Safari
5.1+
Chrome
5+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 11 Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 12.1+ |
focus
|
onload
Support in all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera 9+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 10.1+ |
load
|
onresize
Support in all current engines.
Firefox
38+
Safari
10.1+
Chrome
34+
Opera ? Edge 79+ Edge (Legacy) No Internet Explorer 🔰 4+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
resize
|
onscroll
Support in all current engines.
Firefox
9+
Safari
1.3+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
scroll
|
We
call
the
set
of
the
names
of
the
event
handlers
listed
in
the
first
column
of
this
table
the
Window
-reflecting
body
element
event
handler
set
.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported
by
Window
objects,
as
event
handler
IDL
attributes
on
the
Window
objects
themselves,
and
with
corresponding
event
handler
content
attributes
and
event
handler
IDL
attributes
exposed
on
all
body
and
frameset
elements
that
are
owned
by
that
Window
object's
associated
Document
:
Event handler | Event handler event type |
---|---|
onafterprint
Support in all current engines.
Firefox
6+
Safari
13+
Chrome
63+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
afterprint
|
onbeforeprint
Support in all current engines.
Firefox
6+
Safari
13+
Chrome
63+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
beforeprint
|
onbeforeunload
Support in all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera 12+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12+ |
beforeunload
|
onhashchange
Support in all current engines.
Firefox
3.6+
Safari
5+
Chrome
8+
Opera 10.6+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 8+ Firefox Android ? Safari iOS 5+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 11+ |
hashchange
|
onlanguagechange
Support in all current engines.
Firefox
32+
Safari
10.1+
Chrome
37+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android 4+ Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet 4.0+ Opera Android ? |
languagechange
|
onmessage
Support in all current engines.
Firefox
9+
Safari
4+
Chrome
60+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 8+ Firefox Android ? Safari iOS 4+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 47+ |
message
|
onmessageerror
Firefox
57+
Safari
No
Chrome
60+
Opera ? Edge 79+ Edge (Legacy) 18 Internet Explorer No Firefox Android ? Safari iOS ? Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 47+ |
messageerror
|
onoffline
Support in all current engines.
Firefox
9+
Safari
4+
Chrome
3+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 3+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android ? |
offline
|
ononline
Support in all current engines.
Firefox
9+
Safari
4+
Chrome
3+
Opera ? Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 3+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android ? |
online
|
onpagehide
|
pagehide
|
onpageshow
|
pageshow
|
onpopstate
Support in all current engines.
Firefox
4+
Safari
5+
Chrome
5+
Opera 11.5+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 10+ Firefox Android ? Safari iOS ? Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android 11.5+ |
popstate
|
onrejectionhandled
Support in all current engines.
Firefox
69+
Safari
11+
Chrome
49+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS 11.3+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
rejectionhandled
|
onstorage
Support in all current engines.
Firefox
45+
Safari
4+
Chrome
1+
Opera ? Edge 79+ Edge (Legacy) 15+ Internet Explorer 9+ Firefox Android ? Safari iOS 4+ Chrome Android ? WebView Android 37+ Samsung Internet ? Opera Android ? |
storage
|
onunhandledrejection
Window/unhandledrejection_event Support in all current engines.
Firefox
69+
Safari
11+
Chrome
49+
Opera ? Edge 79+ Edge (Legacy) ? Internet Explorer No Firefox Android ? Safari iOS 11.3+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android ? |
unhandledrejection
|
onunload
Support in all current engines.
Firefox
1+
Safari
3+
Chrome
1+
Opera 4+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 4+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 10.1+ |
unload
|
This
list
of
event
handlers
is
reified
as
event
handler
IDL
attributes
through
the
WindowEventHandlers
interface
mixin.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported
by
all
HTML
elements
,
as
both
event
handler
content
attributes
and
event
handler
IDL
attributes
;
and
that
must
be
supported
by
all
Document
objects,
as
event
handler
IDL
attributes
:
Event handler | Event handler event type |
---|---|
oncut
Support in all current engines.
Firefox
9+
Safari
3+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
cut
|
oncopy
Support in all current engines.
Firefox
3+
Safari
3+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
copy
|
onpaste
Support in all current engines.
Firefox
9+
Safari
3+
Chrome
1+
Opera 12.1+ Edge 79+ Edge (Legacy) 12+ Internet Explorer 9+ Firefox Android ? Safari iOS 1+ Chrome Android ? WebView Android ? Samsung Internet ? Opera Android 12.1+ |
paste
|
This
list
of
event
handlers
is
reified
as
event
handler
IDL
attributes
through
the
DocumentAndElementEventHandlers
interface
mixin.
The
following
are
the
event
handlers
(and
their
corresponding
event
handler
event
types
)
that
must
be
supported
on
Document
objects
as
event
handler
IDL
attributes
:
Event handler | Event handler event type |
---|---|
onreadystatechange
|
readystatechange
|
onvisibilitychange
Document/visibilitychange_event
Firefox
56+
Safari
🔰
14+
Chrome
62+
Opera 49+ Edge 79+ Edge (Legacy) 18 Internet Explorer 🔰 10+ Firefox Android ? Safari iOS 🔰 14+ Chrome Android ? WebView Android 62+ Samsung Internet ? Opera Android 46+ |
visibilitychange
|
Support in all current engines.
interface mixin GlobalEventHandlers {
attribute EventHandler onabort;
attribute EventHandler onauxclick;
attribute EventHandler onbeforeinput;
attribute EventHandler onbeforematch;
attribute EventHandler onblur;
attribute EventHandler oncancel;
attribute EventHandler oncanplay;
attribute EventHandler oncanplaythrough;
attribute EventHandler onchange;
attribute EventHandler onclick;
attribute EventHandler onclose;
attribute EventHandler oncontextlost;
attribute EventHandler oncontextmenu;
attribute EventHandler oncontextrestored;
attribute EventHandler oncuechange;
attribute EventHandler ondblclick;
attribute EventHandler ondrag;
attribute EventHandler ondragend;
attribute EventHandler ondragenter;
attribute EventHandler ondragleave;
attribute EventHandler ondragover;
attribute EventHandler ondragstart;
attribute EventHandler ondrop;
attribute EventHandler ondurationchange;
attribute EventHandler onemptied;
attribute EventHandler onended;
attribute OnErrorEventHandler onerror;
attribute EventHandler onfocus;
attribute EventHandler onformdata;
attribute EventHandler oninput;
attribute EventHandler oninvalid;
attribute EventHandler onkeydown;
attribute EventHandler onkeypress;
attribute EventHandler onkeyup;
attribute EventHandler onload;
attribute EventHandler onloadeddata;
attribute EventHandler onloadedmetadata;
attribute EventHandler onloadstart;
attribute EventHandler onmousedown;
[LegacyLenientThis] attribute EventHandler onmouseenter;
[LegacyLenientThis] attribute EventHandler onmouseleave;
attribute EventHandler onmousemove;
attribute EventHandler onmouseout;
attribute EventHandler onmouseover;
attribute EventHandler onmouseup;
attribute EventHandler onpause;
attribute EventHandler onplay;
attribute EventHandler onplaying;
attribute EventHandler onprogress;
attribute EventHandler onratechange;
attribute EventHandler onreset;
attribute EventHandler onresize;
attribute EventHandler onscroll;
attribute EventHandler onsecuritypolicyviolation;
attribute EventHandler onseeked;
attribute EventHandler onseeking;
attribute EventHandler onselect;
attribute EventHandler onslotchange;
attribute EventHandler onstalled;
attribute EventHandler onsubmit;
attribute EventHandler onsuspend;
attribute EventHandler ontimeupdate;
attribute EventHandler ontoggle;
attribute EventHandler onvolumechange;
attribute EventHandler onwaiting;
attribute EventHandler onwebkitanimationend;
attribute EventHandler onwebkitanimationiteration;
attribute EventHandler onwebkitanimationstart;
attribute EventHandler onwebkittransitionend;
attribute EventHandler onwheel;
};
interface mixin WindowEventHandlers {
attribute EventHandler onafterprint;
attribute EventHandler onbeforeprint;
attribute OnBeforeUnloadEventHandler onbeforeunload;
attribute EventHandler onhashchange;
attribute EventHandler onlanguagechange;
attribute EventHandler onmessage;
attribute EventHandler onmessageerror;
attribute EventHandler onoffline;
attribute EventHandler ononline;
attribute EventHandler onpagehide;
attribute EventHandler onpageshow;
attribute EventHandler onpopstate;
attribute EventHandler onrejectionhandled;
attribute EventHandler onstorage;
attribute EventHandler onunhandledrejection;
attribute EventHandler onunload;
};
interface mixin DocumentAndElementEventHandlers {
attribute EventHandler oncopy;
attribute EventHandler oncut;
attribute EventHandler onpaste;
};
Certain
operations
and
methods
are
defined
as
firing
events
on
elements.
For
example,
the
click()
method
on
the
HTMLElement
interface
is
defined
as
firing
a
click
event
on
the
element.
[UIEVENTS]
Firing a synthetic pointer event named e at target , with an optional not trusted flag , means running these steps:
Let
event
be
the
result
of
creating
an
event
using
PointerEvent
.
Initialize
event
's
type
attribute
to
e
.
Initialize
event
's
bubbles
and
cancelable
attributes
to
true.
Set event 's composed flag .
If
the
not
trusted
flag
is
set,
initialize
event
's
isTrusted
attribute
to
false.
Initialize
event
's
ctrlKey
,
shiftKey
,
altKey
,
and
metaKey
attributes
according
to
the
current
state
of
the
key
input
device,
if
any
(false
for
any
keys
that
are
not
available).
Initialize
event
's
view
attribute
to
target
's
node
document
's
Window
object,
if
any,
and
null
otherwise.
event
's
getModifierState()
method
is
to
return
values
appropriately
describing
the
current
state
of
the
key
input
device.
Return the result of dispatching event at target .
Firing
a
click
event
at
target
means
firing
a
synthetic
pointer
event
named
click
at
target
.
WindowOrWorkerGlobalScope
mixin
The
WindowOrWorkerGlobalScope
mixin
is
for
use
of
APIs
that
are
to
be
exposed
on
Window
and
WorkerGlobalScope
objects.
Other
standards
are
encouraged
to
further
extend
it
using
partial
interface
mixin
WindowOrWorkerGlobalScope
{
…
};
along
with
an
appropriate
reference.
typedef (DOMString or Function) TimerHandler;
interface mixin WindowOrWorkerGlobalScope {
[Replaceable] readonly attribute USVString origin;
readonly attribute boolean isSecureContext;
readonly attribute boolean crossOriginIsolated;
undefined reportError(any e);
// base64 utility methods
DOMString btoa(DOMString data);
ByteString atob(DOMString data);
// timers
long setTimeout(TimerHandler handler, optional long timeout = 0, any... arguments);
undefined clearTimeout(optional long id = 0);
long setInterval(TimerHandler handler, optional long timeout = 0, any... arguments);
undefined clearInterval(optional long id = 0);
// microtask queuing
undefined queueMicrotask(VoidFunction callback);
// ImageBitmap
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, optional ImageBitmapOptions options = {});
Promise<ImageBitmap> createImageBitmap(ImageBitmapSource image, long sx, long sy, long sw, long sh, optional ImageBitmapOptions options = {});
// structured cloning
any structuredClone(any value, optional StructuredSerializeOptions options = {});
};
Window includes WindowOrWorkerGlobalScope;
WorkerGlobalScope
includes
WindowOrWorkerGlobalScope
;
self.
isSecureContext
Support in all current engines.
Returns whether or not this global object represents a secure context . [SECURE-CONTEXTS]
self.
origin
Support in all current engines.
Returns the global object's origin , serialized as string.
self.
crossOriginIsolated
Support in all current engines.
Returns
whether
scripts
running
in
this
global
are
allowed
to
use
APIs
that
require
cross-origin
isolation.
This
depends
on
the
`
Cross-Origin-Opener-Policy
`
and
`
Cross-Origin-Embedder-Policy
`
HTTP
response
headers
and
the
"
cross-origin-isolated
"
feature.
Developers
are
strongly
encouraged
to
use
self.origin
over
location.origin
.
The
former
returns
the
origin
of
the
environment,
the
latter
of
the
URL
of
the
environment.
Imagine
the
following
script
executing
in
a
document
on
https://stargate.example/
:
var frame = document.createElement("iframe")
frame.onload = function() {
var frameWin = frame.contentWindow
console.log(frameWin.location.origin) // "null"
console.log(frameWin.origin) // "https://stargate.example"
}
document.body.appendChild(frame)
self.origin
is
a
more
reliable
security
indicator.
The
isSecureContext
getter
steps
are
to
return
true
if
this
's
relevant
settings
object
is
a
secure
context
,
or
false
otherwise.
The
origin
getter
steps
are
to
return
this
's
relevant
settings
object
's
origin
,
serialized
.
The
crossOriginIsolated
getter
steps
are
to
return
this
's
relevant
settings
object
's
cross-origin
isolated
capability
.
The
atob()
and
btoa()
methods
allow
developers
to
transform
content
to
and
from
the
base64
encoding.
In these APIs, for mnemonic purposes, the "b" can be considered to stand for "binary", and the "a" for "ASCII". In practice, though, for primarily historical reasons, both the input and output of these functions are Unicode strings.
result
=
self.
btoa
(
data
)
Support in all current engines.
Takes the input data, in the form of a Unicode string containing only characters in the range U+0000 to U+00FF, each representing a binary byte with values 0x00 to 0xFF respectively, and converts it to its base64 representation, which it returns.
Throws
an
"
InvalidCharacterError
"
DOMException
exception
if
the
input
string
contains
any
out-of-range
characters.
result
=
self.
atob
(
data
)
Support in all current engines.
Takes the input data, in the form of a Unicode string containing base64-encoded binary data, decodes it, and returns a string consisting of characters in the range U+0000 to U+00FF, each representing a binary byte with values 0x00 to 0xFF respectively, corresponding to that binary data.
Throws
an
"
InvalidCharacterError
"
DOMException
if
the
input
string
is
not
valid
base64
data.
The
btoa(
data
)
method
must
throw
an
"
InvalidCharacterError
"
DOMException
if
data
contains
any
character
whose
code
point
is
greater
than
U+00FF.
Otherwise,
the
user
agent
must
convert
data
to
a
byte
sequence
whose
n
th
byte
is
the
eight-bit
representation
of
the
n
th
code
point
of
data
,
and
then
must
apply
forgiving-base64
encode
to
that
byte
sequence
and
return
the
result.
The
atob(
data
)
method
steps
are:
Let decodedData be the result of running forgiving-base64 decode on data .
If
decodedData
is
failure,
then
throw
an
"
InvalidCharacterError
"
DOMException
.
Return decodedData .