4.12. Scripting
Scripts allow authors to add interactivity to their documents.
Authors are encouraged to use declarative alternatives to scripting where possible, as declarative mechanisms are often more maintainable, and many users disable scripting.
details
element could be used. Authors are also encouraged to make their applications degrade gracefully in the absence of scripting support.
4.12.1. The script
element
- Categories:
- Metadata content.
- Flow content.
- Phrasing content.
- Script-supporting element.
- Contexts in which this element can be used:
- Where metadata content is expected.
- Where phrasing content is expected.
- Where script-supporting elements are expected.
- Content model:
- If there is no
src
attribute, depends on the value of thetype
attribute, but must match script content restrictions. - If there is a
src
attribute, the element must be either empty or contain only script documentation that also matches script content restrictions. - Tag omission in text/html:
- Neither tag is omissible
- Content attributes:
- Global attributes
src
- Address of the resourcetype
- Type of embedded resourcecharset
- Character encoding of the external script resourceasync
- Execute script in paralleldefer
- Defer script executioncrossorigin
- How the element handles crossorigin requestsnonce
- Cryptographic nonce used in Content Security Policy checks [CSP3]- Allowed ARIA role attribute values:
- None
- Allowed ARIA state and property attributes:
- None
- DOM interface:
-
interface
HTMLScriptElement
: HTMLElement { attribute DOMString src; attribute DOMString type; attribute DOMString charset; attribute boolean async; attribute boolean defer; attribute DOMString? crossOrigin; attribute DOMString text; attribute DOMString nonce; };
The script
element allows authors to include dynamic script and data blocks in
their documents. The element does not represent content for the
user.
The type
attribute allows customization of the
type of script represented:
-
Omitting the attribute, or setting it to a JavaScript MIME type, means that the script is a classic script, to be interpreted according to the JavaScript Script top-level production. Classic scripts are affected by the
charset
,async
, anddefer
attributes. Authors should omit the attribute, instead of redundantly giving a JavaScript MIME type. -
Setting the attribute to an ASCII case-insensitive match for the string "
module
" means that the script is a module script, to be interpreted according to the JavaScript Module top-level production. Module scripts are not affected by thecharset
anddefer
attributes. -
Setting the attribute to any other value means that the script is a data block, which is not processed. None of the
script
attributes (excepttype
itself) have any effect on data blocks. Authors must use a valid MIME type that is not a JavaScript MIME type to denote data blocks.
The requirement that data blocks must be denoted using a valid MIME type is in place to avoid potential future collisions. If this specification
ever adds additional types of script, they will be triggered by setting the type
attribute to something which is not a MIME type, like how the "module
"
value denotes module scripts. By using a valid MIME type now, you ensure that your data block
will not ever be reinterpreted as a different script type, even in future user agents.
Classic scripts and module scripts may either be embedded inline or may be imported
from an external file using the src
attribute,
which if specified gives the URL of the external script resource to use. If src
is specified, it must be a valid non-empty URL potentially surrounded by spaces. The
contents of inline script
elements, or the external script resource, must conform with the
requirements of the JavaScript specification’s Script or Module productions, for classic scripts and module scripts respectively. [ECMA-262]
When used to include data blocks, the data must be embedded inline, the format of the data
must be given using the type
attribute, and the contents of the script
element must
conform to the requirements defined for the format used. The src
, charset
, async
, defer
, crossorigin
, and nonce
attributes must
not be specified.
The charset
attribute gives the character
encoding of the external script resource. The attribute must not be specified if the src
attribute is not present, or if the script is not a classic script.
(Module scripts are always interpreted as UTF-8.) If the attribute is set, its value
must be an ASCII case-insensitive match for one of the labels of an encoding, and must specify the same encoding as the charset
parameter of the Content-Type metadata of the external
file, if any. [ENCODING]
The async
and defer
attributes are boolean attributes that indicate how the script should be executed. Classic scripts may specify defer
or async
; module scripts may specify async
.
There are several possible modes that can be selected using these attributes, and depending on the
script’s type
.
For classic scripts, if the async
attribute is present, then the classic script
will be fetched in parallel to parsing and evaluated as soon as it is available
(potentially before parsing completes). If the async
attribute is not present but the defer
attribute is present, then the classic script will be fetched in parallel and evaluated when the page has finished parsing. If neither attribute is
present, then the script is fetched and evaluated immediately, blocking parsing until these are
both complete.
For module scripts, if the async
attribute is present, then the module script
and all its dependencies will be fetched in parallel to parsing, and the module script will
be evaluated as soon as it is available (potentially before parsing completes). Otherwise, the
module script and its dependencies will be fetched in parallel to parsing and evaluated
when the page has finished parsing. (The defer
attribute has no effect on module
scripts.)
This is all summarized in the following schematic diagram:
The exact processing details for these attributes are, for mostly historical
reasons, somewhat non-trivial, involving a number of aspects of HTML. The implementation
requirements are therefore by necessity scattered throughout the specification. The algorithms
below (in this section) describe the core of this processing, but these algorithms reference and
are referenced by the parsing rules for script
start and end tags in HTML, in foreign content, and in XML, the rules for the document.write()
method, the handling of scripting, etc.
The defer
attribute may be specified even if the async
attribute is
specified, to cause legacy Web browsers that only support defer
(and not async
) to fall back to the defer
behavior instead of the blocking behavior
that is the default.
The crossorigin
attribute is a CORS settings attribute. For classic scripts, it controls whether error information
will be exposed, when the script is obtained from other origins. For module scripts, it controls the credentials mode used for cross-origin requests.
Unlike classic scripts, module scripts require the use of the CORS protocol for cross-origin fetching.
The nonce
attribute represents a
cryptographic nonce ("number used once") which can be used by Content Security Policy to
determine whether or not the script specified by an element will be executed. The value is text. [CSP3]
Changing the src
, type
, charset
, async
, defer
, crossorigin
, and nonce
attributes dynamically has no
direct effect; these attributes are only used at specific times described below.
The IDL attributes src
, type
, charset
, defer
, and nonce
, must each reflect the
respective content attributes of the same name.
The crossOrigin
IDL attribute must reflect the crossorigin
content attribute.
The async
IDL attribute controls whether
the element will execute in parallel or not. If the element’s "non-blocking" flag is
set, then, on getting, the async
IDL attribute must return true, and on
setting, the "non-blocking" flag must first be unset, and then the content attribute must
be removed if the IDL attribute’s new value is false, and must be set to the empty string if the
IDL attribute’s new value is true. If the element’s "non-blocking" flag is not set, the IDL attribute must reflect the async
content attribute.
- script .
text
[ = value ] -
Returns the child text content of the element.
Can be set, to replace the element’s children with the given value.
The IDL attribute text
must return the child text content of the script
element. On setting, it must act the same way as the textContent
IDL attribute.
When inserted using the document.write()
method, script
elements execute (typically blocking further script execution or HTML parsing),
but when inserted using innerHTML
and outerHTML
attributes, they do not
execute at all.
script
elements are used. One embeds an external classic script,
and the other includes some data as a data block.
<script src="game-engine.js"></script> <script type="text/x-game-map"> ........U.........e o............A....e .....A.....AAA....e .A..AAA...AAAAA...e </script>
The data in this case might be used by the script to generate the map of a video game. The data doesn’t have to be used that way, though; maybe the map data is actually embedded in other parts of the page’s markup, and the data block here is just used by the site’s search engine to help users who are looking for particular features in their game maps.
script
element can be used to define a function that is
then used by other parts of the document, as part of a classic script. It also shows how
a script
element can be used to invoke script while the document is being parsed, in this
case to initialize the form’s output.
<script> function calculate(form) { var price = 52000; if (form.elements.brakes.checked) price += 1000; if (form.elements.radio.checked) price += 2500; if (form.elements.turbo.checked) price += 5000; if (form.elements.sticker.checked) price += 250; form.elements.result.value = price; } </script> <form name="pricecalc" onsubmit="return false" onchange="calculate(this)"> <fieldset> <legend>Work out the price of your car</legend> <p>Base cost: £52000.</p> <p>Select additional options:</p> <ul> <li><label><input type=checkbox name=brakes> Ceramic brakes (£1000)</label></li> <li><label><input type=checkbox name=radio> Satellite radio (£2500)</label></li> <li><label><input type=checkbox name=turbo> Turbo charger (£5000)</label></li> <li><label><input type=checkbox name=sticker> "XZ" sticker (£250)</label></li> </ul> <p>Total: £<output name=result></output></p> </fieldset> <script> calculate(document.forms.pricecalc); </script> </form>
script
element can be used to include an external module script.
<script type="module" src="app.js"></script>
This module, and all its dependencies (expressed through JavaScript import
statements in the
source file), will be fetched. Once the entire resulting module tree has been imported, and the
document has finished parsing, the contents of app.js
will be evaluated.
script
element can be used to write an inline module script that performs a number of substitutions on the document’s text, in order to
make for a more interesting reading experience (e.g. on a news site): [XKCD-1288]
<script type="module">
import { walkAllTextNodeDescendants } from "./dom-utils.js";
const substitutions = new Map([
["witnesses", "these dudes I know"]
["allegedly", "kinda probably"]
["new study", "Tumblr post"]
["rebuild", "avenge"]
["space", "spaaace"]
["Google glass", "Virtual Boy"]
["smartphone", "Pokédex"]
["electric", "atomic"]
["Senator", "Elf-Lord"]
["car", "cat"]
["election", "eating contest"]
["Congressional leaders", "river spirits"]
["homeland security", "Homestar Runner"]
["could not be reached for comment", "is guilty and everyone knows it"]
]);
function substitute(textNode) {
for (const [before, after] of substitutions.entries()) {
textNode.data = textNode.data.replace(new RegExp(\\b${before}\\b
, "ig"), after);
}
}
walkAllTextNodeDescendants(document.body, substitute);
</script>
Some notable features gained by using a module script include the ability to import
functions from other JavaScript modules, strict mode by default, and how top-level declarations
do not introduce new properties onto the global object. Also note that no matter where
this script
element appears in the document, it will not be evaluated until both document
parsing has complete and its dependency (dom-utils.js
) has been fetched and evaluated.
4.12.1.1. Processing model
A script
element has several associated pieces of state.
The first is a flag indicating whether or not the script block has been
"already started". Initially, script
elements must have this flag unset (script
blocks, when created, are not "already started"). The cloning steps for script
elements
must set the "already started" flag on the copy if it is set on the element being cloned.
The second is a flag indicating whether the element was "parser-inserted".
Initially, script
elements must have this flag unset. It is set by the HTML parser and the XML parser on script
elements they insert and affects the processing of those
elements.
The third is a flag indicating whether the element will "non-blocking". Initially, script
elements must have this flag set. It is unset by the HTML parser and the XML parser on script
elements they insert. In addition, whenever
a script
element whose "non-blocking" flag is set has an async
content
attribute added, the element’s "non-blocking" flag must be unset.
The fourth is a flag indicating whether or not the script block is
"ready to be parser-executed". Initially, script
elements must have this flag unset
(script blocks, when created, are not "ready to be parser-executed"). This flag is used only for
elements that are also "parser-inserted", to let the parser know when to execute the
script.
The fifth is the script’s type, which is either "classic
" or
"module
". It is determined when the script is prepared, based on the type
attribute of the element at that time. Initially, script
elements must have
this flag unset.
The sixth is a flag indicating whether or not the script is from an external file. It
is determined when the script is prepared, based on the src
attribute of the
element at that time.
Finally, a script
element has the script’s script, which is a script
resulting from preparing the element. This is set asynchronously after the classic script or module tree is fetched. Once it is set, either to a script
in the
case of success or to null in the case of failure, the fetching algorithms will note that the script is ready, which can trigger other actions. The user agent must delay the load event of the element’s node document until the script is ready.
When a script
element that is not marked as being "parser-inserted" experiences one of
the events listed in the following list, the user agent must immediately prepare the script
element:
-
The
script
element gets inserted into a document, at the time the node is inserted according to the DOM, after any otherscript
elements inserted at the same time that are earlier in theDocument
in tree order. -
The
script
element is in aDocument
and a node or document fragment is inserted into thescript
element, after anyscript
elements inserted at that time. -
The
script
element is in aDocument
and has asrc
attribute set where previously the element had no such attribute.
To prepare a script, the user agent must act as follows:
-
If the
script
element is marked as having "already started", then the user agent must abort these steps at this point. The script is not executed. -
If the element has its "parser-inserted" flag set, then set was-parser-inserted to true and unset the element’s "parser-inserted" flag. Otherwise, set was-parser-inserted to false.
This is done so that if parser-inserted
script
elements fail to run when the parser tries to run them, e.g., because they are empty or specify an unsupported scripting language, another script can later mutate them and cause them to run again. -
If was-parser-inserted is true and the element does not have an
async
attribute, then set the element’s "non-blocking" flag to true.This is done so that if a parser-inserted
script
element fails to run when the parser tries to run it, but it is later executed after a script dynamically updates it, it will execute in a non-blocking fashion even if theasync
attribute isn’t set. -
If the element has no
src
attribute, and its child nodes, if any, consist only of comment nodes and emptyText
nodes, then abort these steps at this point. The script is not executed. -
If the element is not in a
Document
, then the user agent must abort these steps at this point. The script is not executed. -
If either:
-
the
script
element has atype
attribute and its value is the empty string, or -
the
script
element has notype
attribute but it has alanguage
attribute and that attribute’s value is the empty string, or -
the
script
element has neither atype
attribute nor alanguage
attribute, then
...let the script block’s type string for this
script
element be "text/javascript
".Otherwise, if the
script
element has atype
attribute, let the script block’s type string for thisscript
element be the value of that attribute with any leading or trailing sequences of space characters removed.Otherwise, the element has a non-empty
language
attribute; let the script block’s type string for thisscript
element be the child text content of thelanguage
attribute.The
language
attribute is never conforming, and is always ignored if there is atype
attribute present.Determine the script’s type as follows:
-
If the script block’s type string is an ASCII case-insensitive match for any JavaScript MIME type, the script’s type is "
classic
". -
If the script block’s type string is an ASCII case-insensitive match for the string "
module
", the script’s type is "module
". -
If neither of the above conditions are true, then abort these steps at this point. No script is executed.
-
-
If was-parser-inserted is true, then flag the element as "parser-inserted" again, and set the element’s "non-blocking" flag to false.
-
The user agent must set the element’s "already started" flag.
-
If the element is flagged as "parser-inserted", but the element’s node document is not the
Document
of the parser that created the element, then abort these steps. -
If scripting is disabled for the
script
element, then abort these steps at this point. The script is not executed.The definition of scripting is disabled means that, amongst others, the following scripts will not execute: scripts in
XMLHttpRequest
'sresponseXML
documents, scripts inDOMParser
-created documents, scripts in documents created byXSLTProcessor
’stransformToDocument
feature, and scripts that are first inserted by a script into aDocument
that was created using thecreateDocument()
API. [XHR] [DOM-PARSING] [XSLTP] [DOM41] -
If the
script
element does not have asrc
content attribute, and the Should element’s inline behavior be blocked by Content Security Policy? algorithm returns "Blocked
" when executed upon thescript
element, "script
", and thescript
element’s child text content, then abort these steps. The script is not executed. [CSP3] -
If the
script
element has anevent
attribute and afor
attribute, and the script’s type is "classic
", then run these substeps:-
Let for be the value of the
for
attribute. -
Let event be the value of the
event
attribute. -
Strip leading and trailing white space from event and for.
-
If for is not an ASCII case-insensitive match for the string "
window
", then the user agent must abort these steps at this point. The script is not executed. -
If event is not an ASCII case-insensitive match for either the string "
onload
" or the string "onload()
", then the user agent must abort these steps at this point. The script is not executed.
-
-
If the
script
element has acharset
attribute, then let encoding be the result of getting an encoding from the value of thecharset
attribute.If the
script
element does not have acharset
attribute, or if getting an encoding failed, let encoding be the same as the encoding of the document itself.If the script’s type is "
module
", this encoding will be ignored. -
Let CORS setting be the current state of the element’s
crossorigin
content attribute. -
If the
script
element has anonce
attribute, then let cryptographic nonce be that attribute’s value.Otherwise, let cryptographic nonce be the empty string.
-
Let parser state be "
parser-inserted
" if thescript
element has been flagged as "parser-inserted", and "not parser-inserted
" otherwise. -
Let settings be the element’s node document’s
Window
object’s environment settings object. -
If the element has a
src
content attribute, run these substeps:-
Let src be the value of the element’s
src
attribute. -
If src is the empty string, queue a task to fire a simple event named
error
at the element, and abort these steps. -
Set the element’s from an external file flag.
-
Parse src relative to the element’s node document.
-
If the previous step failed, queue a task to fire a simple event named
error
at the element, and abort these steps.Otherwise, let url be the resulting URL record.
-
Switch on the script’s type:
"classic"
- Fetch a classic script given url, CORS setting, cryptographic nonce, parser state, settings, and encoding.
"module"
-
-
Let credentials mode be determined by switching on CORS setting:
- No CORS
"omit"
- Anonymous
"same-origin"
- Use Credentials
"include"
-
Fetch a module script tree given url, credentials mode, cryptographic nonce, parser state, "
script
", and settings.
-
For performance reasons, user agents may start fetching the classic script or module tree (as defined above) as the
src
attribute is set, instead, in the hope that the element will be inserted into the document (and that thecrossorigin
attribute won’t change value in the meantime). Either way, once the element is inserted into the document, the load must have started as described in this step. If the UA performs such prefetching, but the element is never inserted in the document, or thesrc
attribute is dynamically changed, or thecrossorigin
attribute is dynamically changed, then the user agent will not execute the script so obtained, and the fetching process will have been effectively wasted.
-
-
If the element does not have a
src
content attribute, run these substeps:-
Let source text be the value of the
text
IDL attribute. -
Switch on the script’s type:
"classic"
-
-
Let script be the result of creating a classic script using source text and settings.
-
Set the script’s script to script.
-
"module"
-
-
Let base URL be the
script
element’s node document’s document base URL. -
Let script be the result of creating a module script using source text, settings, base URL, and CORS setting.
-
If this returns null, set the script’s script to null and abort these substeps; the script is ready.
-
Fetch the descendants of script. When this asynchronously completes, set the script’s script to the result. At that time, the script is ready.
-
-
-
Then, follow the first of the following options that describes the situation:
-
the script’s type src
present?defer
present?async
present?other conditions "classic"
yes yes no element flagged as "parser-inserted" "module"
yes or no n/a no element flagged as "parser-inserted" Document
of the parser that created the element.When the the script is ready, set the element’s "ready to be parser-executed" flag. The parser will handle executing the script.
-
the script’s type src
present?defer
present?async
present?other conditions "classic"
yes no no element flagged as "parser-inserted" Document
of the parser that created the element. (There can only be one such script perDocument
at a time.)When the script is ready, set the element’s "ready to be parser-executed" flag. The parser will handle executing the script.
-
the script’s type src
present?defer
present?async
present?other conditions "classic"
yes yes or no no "non-blocking" flag not set on element "module"
yes or no n/a no "non-blocking" flag not set on element script
element at the time the prepare a script algorithm started.When the script is ready, run the following steps:
-
If the element is not now the first element in the list of scripts that will execute in order as soon as possible to which it was added above, then mark the element as ready but abort these steps without executing the script yet.
-
Execution: Execute the script block corresponding to the first script element in this list of scripts that will execute in order as soon as possible.
-
Remove the first element from this list of scripts that will execute in order as soon as possible.
-
If this list of scripts that will execute in order as soon as possible is still not empty and the first entry has already been marked as ready, then jump back to the step labeled Execution.
-
-
the script’s type src
present?defer
present?async
present?other conditions "classic"
yes yes or no yes or no n/a "module"
yes or no n/a yes or no n/a script
element at the time the prepare a script algorithm started.When the script is ready, execute the script block and then remove the element from the set of scripts that will execute as soon as possible.
-
the script’s type src
present?defer
present?async
present?other conditions "classic"
or"module"
no yes or no yes or no All of the following: -
element flagged as "parser-inserted"
-
an XML parser or an HTML parser whose script nesting level is not greater than one created the
script
-
the
Document
of the XML parser or HTML parser that created thescript
has a style sheet that is blocking scripts
Document
of the parser that created the element. (There can only be one such script perDocument
at a time.)Set the element’s "ready to be parser-executed" flag. The parser will handle executing the script.
-
- Otherwise
- Immediately execute the script block, even if other scripts are already executing.
The pending parsing-blocking script of a Document
is used by the Document
's
parser(s).
If a script
element that blocks a parser gets moved to another Document
before it would normally have stopped blocking that parser, it nonetheless continues blocking that
parser until the condition that causes it to be blocking the parser no longer applies (e.g., if
the script is a pending parsing-blocking script because there was a style sheet that is blocking scripts when it was parsed, but then the script is moved to
another Document
before the style sheet loads, the script still blocks the parser until the
style sheets are all loaded, at which time the script executes and the parser is unblocked).
When the user agent is required to execute a script block, it must run the following steps:
-
If the element is flagged as "parser-inserted", but the element’s node document is not the
Document
of the parser that created the element, then abort these steps. -
If the script’s script is null, fire a simple event named
error
at the element, and abort these steps. -
If the script is from an external file, or the script’s type is "
module
", then increment the ignore-destructive-writes counter of thescript
element’s node document. Let neutralized doc be thatDocument
. -
Let old script element be the value to which the
script
element’s node document’scurrentScript
object was most recently set. -
Switch on the script’s type:
"classic"
-
-
Set the
script
element’s node document’scurrentScript
attribute to thescript
element.This does not use the in a document check, as the
script
element could have been removed from the document prior to execution, and in that scenariocurrentScript
still needs to point to it. -
Run the classic script given by the script’s script.
-
"module"
-
-
Set the
script
element’s node document’scurrentScript
attribute to null. -
Run the module script given by the script’s script.
-
-
Set the
script
element’s node document’scurrentScript
object to old script element. -
Decrement the ignore-destructive-writes counter of neutralized doc, if it was incremented in the earlier step.
-
If the script’s type is "
classic
" and the script is from an external file, fire a simple event namedload
at thescript
element.Otherwise queue a task to fire a simple event named
load
at thescript
element.
4.12.1.2. Scripting languages
A JavaScript MIME type is a MIME type string that is one of the following and refers to JavaScript: [ECMA-262]
application/ecmascript
application/javascript
application/x-ecmascript
application/x-javascript
text/ecmascript
text/javascript
text/javascript1.0
text/javascript1.1
text/javascript1.2
text/javascript1.3
text/javascript1.4
text/javascript1.5
text/jscript
text/livescript
text/x-ecmascript
text/x-javascript
User agents must recognize all JavaScript MIME types.
User agents may support other MIME types for other languages, but must not support other MIME types for the languages in the list above. User agents are not required to support JavaScript. The processing model for languages other than JavaScript is outside the scope of this specification.
The following MIME types (with or without parameters) must not be interpreted as scripting languages:
-
text/plain
-
text/xml
-
application/octet-stream
-
application/xml
These types are explicitly listed here because they are poorly-defined types that are nonetheless likely to be used as formats for data blocks, and it would be problematic if they were suddenly to be interpreted as script by a user agent.
When examining types to determine if they represent supported languages, user agents must not ignore MIME parameters. Types are to be compared including all parameters.
For example, types that include the charset
parameter will not be
recognized as referencing any of the scripting languages listed above.
4.12.1.3. Restrictions for contents of script
elements
The easiest and safest way to avoid the rather strange restrictions described in
this section is to always escape "<!--
" as "<\!--
", "<script
" as "<\script
",
and "</script
" as "<\/script
" when these sequences appear in literals in scripts (e.g.,
in strings, regular expressions, or comments), and to avoid writing code that uses such constructs
in expressions. Doing so avoids the pitfalls that the restrictions in this section are prone to
triggering: namely, that, for historical reasons, parsing of script
blocks in HTML is a
strange and exotic practice that acts unintuitively in the face of these sequences.
The textContent
of a script
element must match the script
production in
the following ABNF, the character set for which is Unicode. [ABNF]
script = outer *( comment-open inner comment-close outer ) outer = < any string that doesn’t contain a substring that matches not-in-outer > not-in-outer = comment-open inner = < any string that doesn’t contain a substring that matches not-in-inner > not-in-inner = comment-close / script-open comment-open = "<!--" comment-close = "-->" script-open = "<" s c r i p t tag-end s = %x0053 ; U+0053 LATIN CAPITAL LETTER S s =/ %x0073 ; U+0073 LATIN SMALL LETTER S c = %x0043 ; U+0043 LATIN CAPITAL LETTER C c =/ %x0063 ; U+0063 LATIN SMALL LETTER C r = %x0052 ; U+0052 LATIN CAPITAL LETTER R r =/ %x0072 ; U+0072 LATIN SMALL LETTER R i = %x0049 ; U+0049 LATIN CAPITAL LETTER I i =/ %x0069 ; U+0069 LATIN SMALL LETTER I p = %x0050 ; U+0050 LATIN CAPITAL LETTER P p =/ %x0070 ; U+0070 LATIN SMALL LETTER P t = %x0054 ; U+0054 LATIN CAPITAL LETTER T t =/ %x0074 ; U+0074 LATIN SMALL LETTER T tag-end = %x0009 ; U+0009 CHARACTER TABULATION (tab) tag-end =/ %x000A ; U+000A LINE FEED (LF) tag-end =/ %x000C ; U+000C FORM FEED (FF) tag-end =/ %x0020 ; U+0020 SPACE tag-end =/ %x002F ; U+002F SOLIDUS (/) tag-end =/ %x003E ; U+003E GREATER-THAN SIGN (>)
When a script
element contains script documentation, there are further restrictions on
the contents of the element, as described in the section below.
var example = 'Consider this string: <!-- <script>'; console.log(example);
If one were to put this string directly in a script
block, it would violate the
restrictions above:
<script> var example = 'Consider this string: <!-- <script>'; console.log(example); </script>
The bigger problem, though, and the reason why it would violate those restrictions, is that
actually the script would get parsed weirdly: the script block above is not terminated.
That is, what looks like a "</script>
" end tag in this snippet is actually still part of
the script
block. The script doesn’t execute (since it’s not terminated); if it somehow were
to execute, as it might if the markup looked as follows, it would fail because the script is not
valid JavaScript:
<script> var example = 'Consider this string: <!-- <script>'; console.log(example); </script> <!-- despite appearances, this is actually part of the script still! --> <script> ... // this is the same script block still... </script>
What is going on here is that for legacy reasons, "<!--
" and "<script
" strings in script
elements in HTML need to be balanced in order for the parser to consider closing the
block.
By escaping the problematic strings as mentioned at the top of this section, the problem is avoided entirely:
<script> var example = 'Consider this string: <\!-- <\script>'; console.log(example); </script> <!-- this is just a comment between script blocks --> <script> ... // this is a new script block </script>
It is possible for these sequences to naturally occur in script expressions, as in the following examples:
if (x<!--y) { ... } if ( player<script ) { ... }
In such cases the characters cannot be escaped, but the expressions can be rewritten so that the sequences don’t occur, as in:
if (x < !--y) { ... } if (!--y > x) { ... } if (!(--y) > x) { ... } if (player < script) { ... } if (script > player) { ... }
Doing this also avoids a different pitfall as well: for related historical reasons, the string
"<!--
" in classic scripts is actually treated as a line comment start, just like
"//
".
4.12.1.4. Inline documentation for external scripts
If a script
element’s src
attribute is specified, then the contents of the script
element, if any, must be such that the value of the text
IDL
attribute, which is derived from the element’s contents, matches the documentation
production in
the following ABNF, the character set for which is Unicode. [ABNF]
documentation = *( *( space / tab / comment ) [ line-comment ] newline ) comment = slash star *( not-star / star not-slash ) 1*star slash line-comment = slash slash *not-newline ; characters tab = %x0009 ; U+0009 CHARACTER TABULATION (tab) newline = %x000A ; U+000A LINE FEED (LF) space = %x0020 ; U+0020 SPACE star = %x002A ; U+002A ASTERISK (*) slash = %x002F ; U+002F SOLIDUS (/) not-newline = %x0000-0009 / %x000B-10FFFF ; a Unicode character other than U+000A LINE FEED (LF) not-star = %x0000-0029 / %x002B-10FFFF ; a Unicode character other than U+002A ASTERISK (*) not-slash = %x0000-002E / %x0030-10FFFF ; a Unicode character other than U+002F SOLIDUS (/)
This corresponds to putting the contents of the element in JavaScript comments.
This requirement is in addition to the earlier restrictions on the syntax of
contents of script
elements.
src
attribute.
<script src="cool-effects.js"> // create new instances using: // var e = new Effect(); // start the effect using .play, stop using .stop: // e.play(); // e.stop(); </script>
4.12.1.5. Interaction of script
elements and XSLT
This section is non-normative.
This specification does not define how XSLT interacts with the script
element.
However, in the absence of another specification actually defining this, here are some guidelines
for implementors, based on existing implementations:
-
When an XSLT transformation program is triggered by an
<?xml-stylesheet?>
processing instruction and the browser implements a direct-to-DOM transformation,script
elements created by the XSLT processor need to be marked "parser-inserted" and run in document order (modulo scripts markeddefer
orasync
), immediately, as the transformation is occurring. -
The
XSLTProcessor.transformToDocument()
method [XSLTP] adds elements to aDocument
that is not in a browsing context, and, accordingly, anyscript
elements they create need to have their "already started" flag set in the prepare a script algorithm and never get executed (scripting is disabled). Suchscript
elements still need to be marked "parser-inserted", though, such that theirasync
IDL attribute will return false in the absence of anasync
content attribute. -
The
XSLTProcessor.transformToFragment()
method needs to create a fragment that is equivalent to one built manually by creating the elements usingdocument.createElementNS()
. For instance, it needs to createscript
elements that aren’t "parser-inserted" and that don’t have their "already started" flag set, so that they will execute when the fragment is inserted into a document.
The main distinction between the first two cases and the last case is that the first two
operate on Document
s and the last operates on a fragment.
4.12.2. The noscript
element
- Categories:
- Metadata content.
- Flow content.
- Phrasing content.
- Contexts in which this element can be used:
- In a
head
element of an HTML document, if there are no ancestornoscript
elements. - Where phrasing content is expected in HTML documents, if there are no ancestor
noscript
elements. - Content model:
- When scripting is disabled, in a
head
element: in any order, zero or morelink
elements, zero or morestyle
elements, and zero or moremeta
elements. - When scripting is disabled, not in a
head
element: transparent, but there must be nonoscript
element descendants. - Otherwise: text that conforms to the requirements given in the prose.
- Tag omission in text/html:
- Neither tag is omissible
- Content attributes:
- Global attributes
- Allowed ARIA role attribute values:
- None
- Allowed ARIA state and property attributes:
- Global aria-* attributes
- DOM interface:
- Uses
HTMLElement
.
The noscript
element represents nothing if scripting is enabled, and represents its children if scripting is disabled. It is used to present different
markup to user agents that support scripting and those that don’t support scripting, by affecting
how the document is parsed.
When used in HTML documents, the allowed content model is as follows:
- In a
head
element, if scripting is disabled for thenoscript
element -
The
noscript
element must contain onlylink
,style
, andmeta
elements. - In a
head
element, if scripting is enabled for thenoscript
element -
The
noscript
element must contain only text, except that invoking the HTML fragment parsing algorithm with thenoscript
element as the context element and the text contents as the input must result in a list of nodes that consists only oflink
,style
, andmeta
elements that would be conforming if they were children of thenoscript
element, and no parse errors. - Outside of
head
elements, if scripting is disabled for thenoscript
element -
The
noscript
element’s content model is transparent, with the additional restriction that anoscript
element must not have anoscript
element as an ancestor (that is,noscript
can’t be nested). - Outside of
head
elements, if scripting is enabled for thenoscript
element -
The
noscript
element must contain only text, except that the text must be such that running the following algorithm results in a conforming document with nonoscript
elements and noscript
elements, and such that no step in the algorithm throws an exception or causes an HTML parser to flag a parse error:-
Remove every
script
element from the document. -
Make a list of every
noscript
element in the document. For everynoscript
element in that list, perform the following steps:-
Let s be the child text content of the
noscript
element. -
Set the
outerHTML
attribute of thenoscript
element to the value of s. (This, as a side-effect, causes thenoscript
element to be removed from the document.) [DOM-PARSING]
-
-
All these contortions are required because, for historical reasons, the noscript
element is handled differently by the HTML parser based on whether scripting was enabled or not when the parser was invoked.
The noscript
element must not be used in XML documents.
The noscript
element is only effective in the HTML syntax, it has no effect in the XHTML syntax.
This is because the way it works is by essentially "turning off" the parser when scripts are
enabled, so that the contents of the element are treated as pure text and not as real elements.
XML does not define a mechanism by which to do this.
The noscript
element has no other requirements. In particular, children of the noscript
element are not exempt from §4.10.21 Form submission, scripting, and so forth, even when scripting is enabled for the element.
noscript
element is used to provide fallback for a script.
<form action="calcSquare.php"> <p> <label for=x>Number</label>: <input id="x" name="x" type="number"> </p> <script> var x = document.getElementById('x'); var output = document.createElement('p'); output.textContent = 'Type a number; it will be squared right then!'; x.form.appendChild(output); x.form.onsubmit = function () { return false; } x.oninput = function () { var v = x.valueAsNumber; output.textContent = v + ' squared is ' + v * v; }; </script> <noscript> <input type=submit value="Calculate Square"> </noscript> </form>
When script is disabled, a button appears to do the calculation on the server side. When script is enabled, the value is computed on-the-fly instead.
The noscript
element is a blunt instrument. Sometimes, scripts might be enabled,
but for some reason the page’s script might fail. For this reason, it’s generally better to avoid
using noscript
, and to instead design the script to change the page from being a
scriptless page to a scripted page on the fly, as in the next example:
<form action="calcSquare.php"> <p> <label for=x>Number</label>: <input id="x" name="x" type="number"> </p> <input id="submit" type=submit value="Calculate Square"> <script> var x = document.getElementById('x'); var output = document.createElement('p'); output.textContent = 'Type a number; it will be squared right then!'; x.form.appendChild(output); x.form.onsubmit = function () { return false; } x.oninput = function () { var v = x.valueAsNumber; output.textContent = v + ' squared is ' + v * v; }; var submit = document.getElementById('submit'); submit.parentNode.removeChild(submit); </script> </form>
The above technique is also useful in XHTML, since noscript
is not supported in the XHTML syntax.
4.12.3. The template
element
- Categories:
- Metadata content.
- Flow content.
- Phrasing content.
- Script-supporting element.
- Contexts in which this element can be used:
- Where metadata content is expected.
- Where phrasing content is expected.
- Where script-supporting elements are expected.
- As a child of a
colgroup
element that doesn’t have aspan
attribute. - Content model:
- Nothing (for clarification, see example).
- Tag omission in text/html:
- Neither tag is omissible.
- Content attributes:
- Global attributes
- Allowed ARIA role attribute values:
- None
- Allowed ARIA state and property attributes:
- None
- DOM interface:
-
[Exposed=Window, HTMLConstructor] interface
HTMLTemplateElement
: HTMLElement { readonly attribute DocumentFragment content; };
The template
element is used to declare fragments of HTML that can be cloned and
inserted in the document by script.
In a rendering, the template
element represents nothing.
The template contents of a template
element are not children of the element itself.
It is also possible, as a result of DOM manipulation, for a template
element to contain Text
nodes and element nodes; however, having any is a violation of the template
element’s content model, since its content model is defined as nothing.
For example, consider the following document:
<!DOCTYPE html> <html lang="en"> <head> <title>Homework</title> <body> <template id="template"><p>Smile!</p></template> <script> let num = 3; const fragment = document.getElementById('template').content.cloneNode(true); while (num-- > 1) { fragment.firstChild.before(fragment.firstChild.cloneNode(true)); fragment.firstChild.textContent += fragment.lastChild.textContent; } document.body.appendChild(fragment); </script> </html>
The p
element in the template
is not a child of the template
in the DOM; it is a child of the DocumentFragment
returned by the template
element’s content
IDL
attribute.
If the script were to call appendChild()
on the template
element, that would add a child to the template
element (as for any other element); however, doing so is a violation of the template
element’s content model.
- template .
content
-
Returns the template contents (a
DocumentFragment
).
Each template
element has an associated DocumentFragment
object that is its template contents. The template contents have no conformance requirements. When a template
element is created, the user agent must run the following steps to establish the template contents:
-
Let doc be the
template
element’s node document’s appropriate template contents owner document. -
Create a
DocumentFragment
object whose node document is doc and host is thetemplate
element. -
Set the
template
element’s template contents to the newly createdDocumentFragment
object.
A Document
doc’s appropriate template contents owner document is the Document
returned by the following algorithm:
-
If doc is not a
Document
created by this algorithm, then:-
If doc does not yet have an associated inert template document, then:
- Let new doc be a new
Document
(that does not have a browsing context). This is "aDocument
created by this algorithm" for the purposes of the step above. - If doc is an HTML document, mark new doc as an HTML document also.
- Let doc’s associated inert template document be new doc.
- Let new doc be a new
- Set doc to doc’s associated inert template document.
Each
Document
not created by this algorithm thus gets a singleDocument
to act as its proxy for owning the template contents of all itstemplate
elements, so that they aren’t in a browsing context and thus remain inert (e.g., scripts do not run). Meanwhile,template
elements insideDocument
objects that are created by this algorithm just reuse the sameDocument
owner for their contents. -
- Return doc.
The adopting steps (with node and oldDocument as parameters) for template
elements
are the following:
-
Let doc be node’s node document’s appropriate template contents owner document.
node’s node document is the
Document
object that node was just adopted into. - Adopt node’s template contents (a
DocumentFragment
object) into doc.
The content
IDL attribute must return
the template
element’s template contents.
The cloning steps for a template
element node being cloned to a copy copy must run the
following steps:
- If the clone children flag is not set in the calling clone algorithm, abort these steps.
- Let copied contents be the result of cloning all the children of node’s template contents, with document set to copy’s template contents’s node document, and with the clone children flag set.
- Append copied contents to copy’s template contents.
template
to provide the element structure instead of manually generating the
structure from markup.
<!DOCTYPE html> <html lang="en"> <title>Cat data</title> <script> // Data is hard-coded here, but could come from the server var data = [ { name: 'Pillar', color: 'Ticked Tabby', sex: 'Female (neutered)', legs: 3 }, { name: 'Hedral', color: 'Tuxedo', sex: 'Male (neutered)', legs: 4 }, ]; </script> <table> <thead> <tr> <th>Name <th>Color <th>Sex <th>Legs <tbody> <template id="row"> <tr><td><td><td><td> </template> </table> <script> var template = document.querySelector('#row'); for (var i = 0; i < data.length; i += 1) { var cat = data[i]; var clone = template.content.cloneNode(true); var cells = clone.querySelectorAll('td'); cells[0].textContent = cat.name; cells[1].textContent = cat.color; cells[2].textContent = cat.sex; cells[3].textContent = cat.legs; template.parentNode.appendChild(clone); } </script>
This example uses cloneNode()
on the template
’s contents; it could
equivalently have used document.importNode()
, which does the same thing. The only
difference between these two APIs is when the node document is updated: with cloneNode()
it is updated when the nodes are appended with appendChild()
, with document.importNode()
it is updated when the nodes
are cloned.
4.12.3.1. Interaction of template
elements with XSLT and XPath
This section is non-normative.
This specification does not define how XSLT and XPath interact with the template
element. However, in the absence of another specification actually defining this, here are some
guidelines for implementors, which are intended to be consistent with other processing described
in this specification:
- An XSLT processor based on an XML parser that acts as described
in this specification needs to act as if
template
elements contain as descendants their template contents for the purposes of the transform. - An XSLT processor that outputs a DOM needs to ensure that nodes that would go into a
template
element are instead placed into the element’s template contents. - XPath evaluation using the XPath DOM API when applied to a
Document
parsed using the HTML parser or the XML parser described in this specification needs to ignore template contents.
4.12.4. The canvas
element
- Categories:
- Flow content.
- Phrasing content.
- Embedded content.
- Palpable content.
- Contexts in which this element can be used:
- Where embedded content is expected.
- Content model:
- Transparent.
- Tag omission in text/html:
- Neither tag is omissible
- Content attributes:
- Global attributes
width
- Horizontal dimensionheight
- Vertical dimension- Allowed ARIA role attribute values:
- Any role value.
- Allowed ARIA state and property attributes:
- Global aria-* attributes
- Any
aria-*
attributes applicable to the allowed roles. - DOM interface:
-
typedef (CanvasRenderingContext2D or WebGLRenderingContext)
RenderingContext
; interfaceHTMLCanvasElement
: HTMLElement { attribute unsigned long width; attribute unsigned long height; RenderingContext?getContext
(DOMStringcontextId
, any...arguments
); booleanprobablySupportsContext
(DOMStringcontextId
, any...arguments
); DOMString toDataURL(optional DOMStringtype
, any...arguments
); voidtoBlob
(BlobCallback_callback
, optional DOMStringtype
, any...arguments
); }; callbackBlobCallback
= void (Blob?blob
);
The canvas
element provides scripts with a resolution-dependent bitmap canvas,
which can be used for rendering graphs, game graphics, art, or other visual images on the fly.
Authors should not use the canvas
element in a document when a more suitable
element is available. For example, it is inappropriate to use a canvas
element to
render a page heading: if the desired presentation of the heading is graphically intense, it
should be marked up using appropriate elements (typically h1
) and then styled using
CSS and supporting technologies such as Web Components.
When authors use the canvas
element, they must also provide content that, when
presented to the user, conveys essentially the same function or purpose as the canvas
's bitmap. This content may be placed as content of the canvas
element. The contents of the canvas
element, if any, are the element’s fallback
content.
In interactive visual media, if scripting is enabled for
the canvas
element, and if support for canvas
elements has been enabled,
the canvas
element represents embedded content consisting
of a dynamically created image, the element’s bitmap.
In non-interactive, static, visual media, if the canvas
element has been
previously associated with a rendering context (e.g., if the page was viewed in an interactive
visual medium and is now being printed, or if some script that ran during the page layout process
painted on the element), then the canvas
element represents embedded content with the element’s current bitmap and size. Otherwise, the element
represents its fallback content instead.
In non-visual media, and in visual media if scripting is
disabled for the canvas
element or if support for canvas
elements
has been disabled, the canvas
element represents its fallback
content instead.
When a canvas
element represents embedded content, the
user can still focus descendants of the canvas
element (in the fallback
content). When an element is focused, it is the target of keyboard interaction
events (even though the element itself is not visible). This allows authors to make an interactive
canvas keyboard-accessible: authors should have a one-to-one mapping of interactive regions to focusable areas in the fallback content. (Focus has no
effect on mouse interaction events.) [UIEVENTS]
An element whose nearest canvas
element ancestor is being rendered and represents embedded content is an element that is being used as
relevant canvas fallback content.
The canvas
element has two attributes to control the size of the element’s bitmap: width
and height
. These attributes, when specified, must have
values that are valid non-negative integers.
The rules for parsing non-negative integers must be used to obtain their
numeric values. If an attribute is missing, or if parsing its value returns an error, then the
default value must be used instead. The width
attribute defaults to 300, and the height
attribute
defaults to 150.
The intrinsic dimensions of the canvas
element when it represents embedded content are equal to the dimensions of the
element’s bitmap.
The user agent must use a square pixel density consisting of one pixel of image data per
coordinate space unit for the bitmaps of a canvas
and its rendering contexts.
A canvas
element can be sized arbitrarily by a style sheet, its
bitmap is then subject to the object-fit CSS property. [CSS3-IMAGES]
The bitmaps of canvas
elements, the bitmaps of ImageBitmap
objects,
as well as some of the bitmaps of rendering contexts, such as those described in the section on
the CanvasRenderingContext2D
object below, have an origin-clean flag, which can be set to true or false.
Initially, when the canvas
element or ImageBitmap
object is created,
its bitmap’s origin-clean flag must be set to
true.
A canvas
bitmap can also have a hit region list, as described in the CanvasRenderingContext2D
section below.
A canvas
element can have a rendering context bound to it. Initially, it does not
have a bound rendering context. To keep track of whether it has a rendering context or not, and
what kind of rendering context it is, a canvas
also has a canvas context mode,
which is initially none but can be changed to either 2d, webgl by algorithms
defined in this specification.
When its canvas context mode is none, a canvas
element has no rendering context,
and its bitmap must be fully transparent black with an intrinsic width equal to the numeric value
of the element’s width
attribute and an intrinsic height equal to the numeric value of the element’s height
attribute, those values being interpreted in CSS pixels, and being updated as the attributes are
set, changed, or removed.
When a canvas
element represents embedded content, it provides
a paint source whose width is the element’s intrinsic width, whose height is
the element’s intrinsic height, and whose appearance is the element’s bitmap.
Whenever the width
and height
content attributes are set, removed, changed, or
redundantly set to the value they already have, if the canvas context mode is 2d, the user agent must set bitmap dimensions to the numeric values of
the width
and height
content attributes.
The width
and height
IDL attributes must reflect the
respective content attributes of the same name, with the same defaults.
- context = canvas .
getContext
(contextId [, ... ] ) -
Returns an object that exposes an API for drawing on the canvas. The first argument specifies the desired API, either "
2d
" or "webgl
". Subsequent arguments are handled by that API.The list of defined contexts is given on the WHATWG Wiki CanvasContexts page. [WHATWGWIKI]
Example contexts are the "
2d
" [CANVAS-2D] and the "webgl
" context [WEBGL].Returns null if the given context ID is not supported or if the canvas has already been initialized with some other (incompatible) context type (e.g., trying to get a "
2d
" context after getting a "webgl
" context). - supported = canvas .
probablySupportsContext
(contextId [, ... ] ) -
Returns false if calling
getContext()
with the same arguments would definitely return null, and true otherwise.This return value is not a guarantee that
getContext()
will or will not return an object, as conditions (e.g., availability of system resources) can vary over time.
The getContext(contextId, arguments...)
method of the canvas
element, when invoked,
must run the steps in the cell of the following table whose column header describes the canvas
element’s canvas context mode and whose row header describes the method’s first argument.
none | 2d | webgl | |
---|---|---|---|
"2d "
|
Set the | Return the same object as was return the last time the method was invoked with this same first argument. | Return null. |
"webgl ", if the user agent supports the WebGL feature in its current configuration
| Follow the instructions given in the WebGL specification’s Context Creation section to
obtain either a WebGLRenderingContext or null; if the returned value is null,
then return null and abort these steps, otherwise, set the canvas element’s context mode to webgl, set the new WebGLRenderingContext object’s context mode to webgl, and return the WebGLRenderingContext object‡ [WEBGL]
| Return null. | Return the same object as was return the last time the method was invoked with this same first argument. |
A vendor-specific extension* | Behave as defined for the extension. | Behave as defined for the extension. | Behave as defined for the extension. |
An unsupported value† | Return null. | Return null. | Return null. |
* Vendors may define experimental contexts using the syntax vendorname-context
, for example, moz-3d
.
† For example, the "webgl
" value in the case of a user agent having exhausted the
graphics hardware’s abilities and having no software fallback implementation.
‡ The second (and subsequent) argument(s) to the method, if any, are ignored in all cases except this one. See the WebGL specification for details.
The probablySupportsContext(contextId, arguments...)
method of the canvas
element, when
invoked, must return false if calling getContext()
on
the same object and with the same arguments would definitely return null at this time, and true
otherwise.
- url = canvas .
toDataURL
( [ type, ... ] ) -
Returns a
data:
URL for the image in the canvas.The first argument, if provided, controls the type of the image to be returned (e.g., PNG or JPEG). The default is
image/png
; that type is also used if the given type isn’t supported. The other arguments are specific to the type, and control the way that the image is generated, as given in the table below.When trying to use types other than "
image/png
", authors can check if the image was really returned in the requested format by checking to see if the returned string starts with one of the exact strings "data:image/png,
" or "data:image/png;
". If it does, the image is PNG, and thus the requested type was not supported. (The one exception to this is if the canvas has either no height or no width, in which case the result might simply be "data:,
".) - canvas .
toBlob
(callback [, type, ... ] ) -
Creates a
Blob
object representing a file containing the image in the canvas, and invokes a callback with a handle to that object.The second argument, if provided, controls the type of the image to be returned (e.g., PNG or JPEG). The default is
image/png
; that type is also used if the given type isn’t supported. The other arguments are specific to the type, and control the way that the image is generated, as given in the table below.
The toDataURL()
method must run the
following steps:
- If the
canvas
element’s bitmap’s origin-clean flag is set to false, throw a "SecurityError
"DOMException
and abort these steps. - If the
canvas
element’s bitmap has no pixels (i.e., either its horizontal dimension or its vertical dimension is zero) then return the string "data:,
" and abort these steps. (This is the shortestdata:
URL; it represents the empty string in atext/plain
resource.) - Let file be a serialization of the
canvas
element’s bitmap as a file, using the method’s arguments (if any) as the arguments. - Return a
data:
URL representing file. [RFC2397]
The toBlob()
method must run the following
steps:
- If the
canvas
element’s bitmap’s origin-clean flag is set to false, throw a "SecurityError
"DOMException
and abort these steps. - Let callback be the first argument.
- Let arguments be the second and subsequent arguments to the method, if any.
-
If the
canvas
element’s bitmap has no pixels (i.e., either its horizontal dimension or its vertical dimension is zero) then let result be null.Otherwise, let result be a
Blob
object representing a serialization of thecanvas
element’s bitmap as a file, using arguments. [FILEAPI] - Return, but continue running these steps in parallel.
- Queue a task to invoke the
BlobCallback
callback with result as its argument. The task source for this task is the canvas blob serialization task source.
4.12.4.1. Color spaces and color correction
The canvas
APIs must perform color correction at only two points: when rendering
images with their own gamma correction and color space information onto a bitmap, to convert the
image to the color space used by the bitmaps (e.g., using the 2D Context’s drawImage()
method with an HTMLImageElement
object), and when rendering the actual canvas bitmap to the output device.
Thus, in the 2D context, colors used to draw shapes onto the canvas will exactly
match colors obtained through the getImageData()
method.
The toDataURL()
method must not include color space
information in the resources they return. Where the output format allows it, the color of pixels
in resources created by toDataURL()
must match those
returned by the getImageData()
method.
In user agents that support CSS, the color space used by a canvas
element must
match the color space used for processing any colors for that element in CSS.
The gamma correction and color space information of images must be handled in such a way that
an image rendered directly using an img
element would use the same colors as one
painted on a canvas
element that is then itself rendered. Furthermore, the rendering
of images that have no color correction information (such as those returned by the toDataURL()
method) must be rendered with no color
correction.
Thus, in the 2D context, calling the drawImage()
method to render the output of the toDataURL()
method to the canvas, given the appropriate
dimensions, has no visible effect.
4.12.4.2. Serializing bitmaps to a file
When a user agent is to create a serialization of the bitmap as a file, optionally with some given arguments, and optionally with a native flag set, it must create an image file in the format given by the first value of arguments, or, if there are no arguments, in the PNG format. [PNG]
If the native flag is set, or if the bitmap has one pixel per coordinate space unit, then the image file must have the same pixel data (before compression, if applicable) as the bitmap, and if the file format used supports encoding resolution metadata, the resolution of that bitmap (device pixels per coordinate space units being interpreted as image pixels per CSS pixel) must be given as well.
Otherwise, the image file’s pixel data must be the bitmap’s pixel data scaled to one image pixel per coordinate space unit, and if the file format used supports encoding resolution metadata, the resolution must be given as 96dpi (one image pixel per CSS pixel).
If arguments is not empty, the first value must be interpreted as a MIME type giving the format to use. If the type has any parameters, it must be treated as not supported.
For example, the value "image/png
" would mean to generate a PNG
image, the value "image/jpeg
" would mean to generate a JPEG image, and the value
"image/svg+xml
" would mean to generate an SVG image (which would require that the
user agent track how the bitmap was generated, an unlikely, though potentially awesome,
feature).
User agents must support PNG ("image/png
"). User agents may support other types.
If the user agent does not support the requested type, it must create the file using the PNG
format. [PNG]
User agents must convert the provided type to ASCII lowercase before establishing if they support that type.
For image types that do not support an alpha channel, the serialized image must be the bitmap image composited onto a solid black background using the source-over operator.
If the first argument in arguments gives a type corresponding to one of the types given in the first column of the following table, and the user agent supports that type, then the subsequent arguments, if any, must be treated as described in the second cell of that row.
Type | Other arguments | Reference |
---|---|---|
image/jpeg
| The second argument, if it is a number in the range 0.0 to 1.0 inclusive, must be treated as the desired quality level. If it is not a number or is outside that range, the user agent must use its default value, as if the argument had been omitted. | [JPEG] |
For the purposes of these rules, an argument is considered to be a number if it is converted to
an IDL double value by the rules for handling arguments of type any
in the
Web IDL specification. [WEBIDL]
Other arguments must be ignored and must not cause the user agent to throw an exception. A future version of this specification will probably define other parameters to be passed to these methods to allow authors to more carefully control compression settings, image metadata, etc.
4.12.4.3. Security with canvas
elements
This section is non-normative.
Information leakage can occur if scripts from one origin can access information (e.g., read pixels) from images from another origin (one that isn’t the same).
To mitigate this, bitmaps used with canvas
elements and ImageBitmap
objects are defined to have a flag indicating whether they are origin-clean. All bitmaps start with their origin-clean set to true. The flag is set to
false when cross-origin images or fonts are used.
The toDataURL()
, toBlob()
, and getImageData()
methods check the flag and will
throw a "SecurityError
" DOMException
rather than leak cross-origin data.
The value of the origin-clean flag is
propagated from a source canvas
element’s bitmap to a new ImageBitmap
object by createImageBitmap()
. Conversely, a
destination canvas
element’s bitmap will have its origin-clean flags set to false by drawImage
if the source image is an ImageBitmap
object whose bitmap has its origin-clean flag set to false.
The flag can be reset in certain situations; for example, when a CanvasRenderingContext2D
is bound to a new canvas
, the bitmap is cleared
and its flag reset.