This is a snapshot of an early working draft and has therefore been superseded by the HTML standard.

This document will not be further updated.

HTML 5

Call For Comments — 27 October 2007

4.3. Scripting

4.3.1. Running executable code

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:

User agents may provide a mechanism to enable or disable the execution of author-provided code. When the user agent is configured such that author-provided code does not execute, or if the user agent is implemented so as to never execute author-provided code, it is said that scripting is disabled. When author-provided code does execute, scripting is enabled. A user agent with scripting disabled is a user agent with no scripting support for the purposes of conformance.

4.3.2. Origin

Access to certain APIs is granted or denied to scripts based on the origin of the script and the API being accessed.

The origin of a script depends on the context of that script:

If a script is in a script element
The origin of the script is the origin of the Document to which the script element belongs.
If a script is a function or other code reference created by another script
The origin of the script is the origin of the script that created it.
If a script is a javascript: URI in an attribute
The origin is the origin of the Document of the element on which the attribute is found.
If a script is a javascript: URI in a style sheet
The origin is the origin of the Document to which the style sheet applies.
If a script is a javascript: URI to which a browsing context is being navigated, the URI having been provided by the user (e.g. by using a bookmarklet)
The origin is the origin of the Document of the browsing context's active document.
If a script is a javascript: URI to which a browsing context is being navigated, the URI having been declared in markup
The origin is the origin of the Document of the element (e.g. an a or area element) that declared the URI.
If a script is a javascript: URI to which a browsing context is being navigated, the URI having been provided by script
The origin is the origin of the script that provided the URI.

The origin of scripts thus comes down to finding the origin of Document objects.

The origin of a Document or image that was served over the network and whose address uses a URI scheme with a server-based naming authority is the tuple consisting of the <scheme>, <host>/<ihost>, and <port> parts of the Document's full URI. [RFC3986] [RFC3987]

The origin of a Document or image that was generated from a data: URI found in another Document or in a script is the origin of the Document or script.

The origin of a Document or image that was generated from a data: URI from another source is a globally unique identifier assigned when the document is created.

The origin of a Document or image that was generated from a javascript: URI is the same as the origin of that javascript: URI.

The string representing the script's domain in IDNA format is obtained as follows: take the domain part of the script's origin tuple and apply the IDNA ToASCII algorithm and then the IDNA ToUnicode algorithm to each component of the domain name (with both the AllowUnassigned and UseSTD3ASCIIRules flags set both times). [RFC3490]

If ToASCII fails to convert one of the components of the string, e.g. because it is too long or because it contains invalid characters, or if the origin of the script has no domain part, then the string representing the script's domain in IDNA format cannot be obtained. (ToUnicode is defined to never fail.)

It's been suggested that we should put IP addresses into the origin tuple, to mitigate DNS rebinding attacks. However that would kill multi-homed systems like GMail. Should we do something like have a DNS record say whether or not to include the IP in the origin for a host?

4.3.3. Unscripted same-origin checks

When two URIs are to be compared to determine if they have the same scheme/host/port, it means that the following algorithm must be invoked, where uri1 and uri2 are the two URIs.

  1. First, both uri1 and uri2 must be normalized to obtain the two tuples (scheme1, host1, port1) and (scheme2, host2, port2), by applying the following subalgorithm to each URI:

    1. Let uri be the URI being normalized.

    2. Parse uri according to the rules described in RFC 3986 and RFC 3987. [RFC3986] [RFC3987]

    3. If uri does not use a server-based naming authority, then fail the overall algorithm — the two URIs do not have the same scheme/host/port.

    4. Let scheme be the <scheme> component of the URI. If the UA doesn't support the given protocol, then fail the overall algorithm — the two URIs do not have the same scheme/host/port.

    5. Let host be the <host>/<ihost> component of the URI.

    6. Apply the IDNA ToASCII algorithm to host, with both the AllowUnassigned and UseSTD3ASCIIRules flags set. Let host be the result of the ToASCII algorithm.

      If ToASCII fails to convert one of the components of the string, e.g. because it is too long or because it contains invalid characters, then fail the overall algorithm — the two URIs do not have the same scheme/host/port. [RFC3490]

    7. If no port is explicitly listed, then let port be the default port for the protocol given by scheme. Otherwise, let port be the <port> component of the URI.

    8. Return the tuple (scheme, host, port).

  2. If scheme1 is not case-insensitively identical to scheme2, or if host1 is not case-insensitively identical to host2, or if port1 is not identical to port2, then fail the overall algorithm — the two URIs do not have the same scheme/host/port.

  3. Otherwise, the two URIs do have the same scheme/host/port.

4.3.4. Security exceptions

Define security exception.

4.3.5. The javascript: protocol

A URI using the javascript: protocol must, if evaluated, be evaluated using the in-context evaluation operation defined for javascript: URIs. [JSURI]

When a browsing context is navigated to a javascript: URI, and the active document of that browsing context has the same origin as the URI, the dereference context must be the browsing context being navigated.

When a browsing context is navigated to a javascript: URI, and the active document of that browsing context has a different origin than the URI, the dereference context must be an empty object.

Otherwise, the dereference context must the browsing context of the Document to which belongs the element for which the URI is being dereferenced, or to which the style sheet for which the URI is being dereferenced applies, whichever is appropriate.

URIs using the javascript: protocol should be evaluated when the resource for that URI is needed, unless scripting is disabled or the Document corresponding to the dereference context (as defined above), if any, has designMode enabled.

If the dereference by-product is void (there is no return value), then the URI must be treated in a manner equivalent to an HTTP resource with an HTTP 204 No Content response.

Otherwise, the URI must be treated in a manner equivalent to an HTTP resource with a 200 OK response whose Content-Type metadata is text/html and whose response body is the dereference by-product, converted to a string value.

Certain contexts, in particular img elements, ignore the Content-Type metadata.

So for example a javascript: URI for a src attribute of an img element would be evaluated in the context of the page as soon as the attribute is set; it would then be sniffed to determine the image type and decoded as an image.

A javascript: URI in an href attribute of an a element would only be evaluated when the link was followed.

The src attribute of an iframe element would be evaluated in the context of the iframe's own browsing context; once evaluated, its return value (if it was not void) would replace that browsing context's document, thus changing the variables visible in that browsing context.

4.3.6. Events

We need to define how to handle events that are to be fired on a Document that is no longer the active document of its browsing context, and for Documents that have no browsing context. Do the events fire? Do the handlers in that document not fire? Do we just define scripting to be disabled when the document isn't active, with events still running as is? See also the script element section, which says scripts don't run when the document isn't active.

4.3.6.1. Event handler attributes

HTML elements can have event handler attributes specified. These act as bubbling event listeners for the element on which they are specified.

Each event handler attribute has two parts, an event handler content attribute and an event handler DOM attribute. Event handler attributes must initially be set to null. When their value changes (through the changing of their event handler content attribute or their event handler DOM attribute), they will either be null, or have an EventListener object assigned to them.

Objects other than Element objects, in particular Window, only have event handler DOM attribute (since they have no content attributes).

Event handler content attributes, when specified, must contain valid ECMAScript code matching the ECMAScript FunctionBody production. [ECMA262]

When an event handler content attribute is set, its new value must be interpreted as the body of an anonymous function with a single argument called event, with the new function's scope chain being linked from the activation object of the handler, to the element, to the element's form element if it is a form control, to the Document object, to the browsing context of that Document. The function's this parameter must be the Element object representing the element. The resulting function must then be set as the value of the corresponding event handler attribute, and the new value must be set as the value of the content attribute. If the given function body fails to compile, then the corresponding event handler attribute must be set to null instead (the content attribute must still be updated to the new value, though).

See ECMA262 Edition 3, sections 10.1.6 and 10.2.3, for more details on activation objects. [ECMA262]

How do we allow non-JS event handlers?

Event handler DOM attributes, on setting, must set the corresponding event handler attribute to their new value, and on getting, must return whatever the current value of the corresponding event handler attribute is (possibly null).

The following are the event handler attributes that must be supported by all HTML elements, as both content attributes and DOM attributes, and on Window objects, as DOM attributes:

onabort

Must be invoked whenever an abort event is targeted at or bubbles through the element.

onbeforeunload

Must be invoked whenever a beforeunload event is targeted at or bubbles through the element.

onblur

Must be invoked whenever a blur event is targeted at or bubbles through the element.

onchange

Must be invoked whenever a change event is targeted at or bubbles through the element.

onclick

Must be invoked whenever a click event is targeted at or bubbles through the element.

oncontextmenu

Must be invoked whenever a contextmenu event is targeted at or bubbles through the element.

ondblclick

Must be invoked whenever a dblclick event is targeted at or bubbles through the element.

ondrag

Must be invoked whenever a drag event is targeted at or bubbles through the element.

ondragend

Must be invoked whenever a dragend event is targeted at or bubbles through the element.

ondragenter

Must be invoked whenever a dragenter event is targeted at or bubbles through the element.

ondragleave

Must be invoked whenever a dragleave event is targeted at or bubbles through the element.

ondragover

Must be invoked whenever a dragover event is targeted at or bubbles through the element.

ondragstart

Must be invoked whenever a dragstart event is targeted at or bubbles through the element.

ondrop

Must be invoked whenever a drop event is targeted at or bubbles through the element.

onerror

Must be invoked whenever an error event is targeted at or bubbles through the element.

The onerror handler is also used for reporting script errors.

onfocus

Must be invoked whenever a focus event is targeted at or bubbles through the element.

onkeydown

Must be invoked whenever a keydown event is targeted at or bubbles through the element.

onkeypress

Must be invoked whenever a keypress event is targeted at or bubbles through the element.

onkeyup

Must be invoked whenever a keyup event is targeted at or bubbles through the element.

onload

Must be invoked whenever a load event is targeted at or bubbles through the element.

onmessage

Must be invoked whenever a message event is targeted at or bubbles through the element.

onmousedown

Must be invoked whenever a mousedown event is targeted at or bubbles through the element.

onmousemove

Must be invoked whenever a mousemove event is targeted at or bubbles through the element.

onmouseout

Must be invoked whenever a mouseout event is targeted at or bubbles through the element.

onmouseover

Must be invoked whenever a mouseover event is targeted at or bubbles through the element.

onmouseup

Must be invoked whenever a mouseup event is targeted at or bubbles through the element.

onmousewheel

Must be invoked whenever a mousewheel event is targeted at or bubbles through the element.

onresize

Must be invoked whenever a resize event is targeted at or bubbles through the element.

onscroll

Must be invoked whenever a scroll event is targeted at or bubbles through the element.

onselect

Must be invoked whenever a select event is targeted at or bubbles through the element.

onsubmit

Must be invoked whenever a submit event is targeted at or bubbles through the element.

onunload

Must be invoked whenever an unload event is targeted at or bubbles through the element.

When an event handler attribute is invoked, its argument must be set to the Event object of the event in question. If the function returns the exact boolean value false, the event's preventDefault() method must then invoked. Exception: for historical reasons, for the HTML mouseover event, the preventDefault() method must be called when the function returns true instead.

When scripting is disabled, event handler attributes must do nothing.

When scripting is enabled, all event handler attributes on an element, whether set to null or to a function, must be registered as event listeners on the element, as if the addEventListenerNS() method on the Element object's EventTarget interface had been invoked when the element was created, with the event type (type argument) equal to the type described for the event handler attribute in the list above, the namespace (namespaceURI argument) set to null, the listener set to be a target and bubbling phase listener (useCapture argument set to false), the event group set to the default group (evtGroup argument set to null), and the event listener itself (listener argument) set to do nothing while the event handler attribute is null, and set to invoke the function associated with the event handler attribute otherwise.

4.3.6.2. Event firing

maybe this should be moved higher up (terminology? conformance? DOM?) Also, the whole terminology thing should be changed so that we don't define any specific events here, we only define 'simple event', 'progress event', 'mouse event', 'key event', and the like, and have the actual dispatch use those generic terms when firing events.

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. [DOM3EVENTS]

Firing a click event means that a click event with no namespace, which bubbles and is cancelable, and which uses the MouseEvent interface, must be dispatched at the given element. The event object must have its screenX, screenY, clientX, clientY, and button attributes set to 0, its ctrlKey, shiftKey, altKey, and metaKey attributes set according to the current state of the key input device, if any (false for any keys that are not available), its detail attribute set to 1, and its relatedTarget attribute set to null. The getModifierState() method on the object must return values appropriately describing the state of the key input device at the time the event is created.

Firing a change event means that a change event with no namespace, which bubbles but is not cancelable, and which uses the Event interface, must be dispatched at the given element. The event object must have its detail attribute set to 0.

Firing a contextmenu event means that a contextmenu event with no namespace, which bubbles and is cancelable, and which uses the Event interface, must be dispatched at the given element. The event object must have its detail attribute set to 0.

Firing a simple event called e means that an event with the name e, with no namespace, which does not bubble but is cancelable, and which uses the Event interface, must be dispatched at the given element.

Firing a show event means firing a simple event called show. Actually this should fire an event that has modifier information (shift/ctrl etc).

Firing a load event means firing a simple event called load. Firing an error event means firing a simple event called error.

Firing a progress event called e means something that hasn't yet been defined, in the [PROGRESS] spec.

The default action of these event is to do nothing unless otherwise stated.

If you dispatch a custom "click" event at an element that would normally have default actions, should they get triggered? If so, we need to go through the entire spec and make sure that any default actions are defined in terms of any event of the right type on that element, not those that are dispatched in expected ways.

4.3.6.3. Events and the Window object

When an event is dispatched at a DOM node in a Document in a browsing context, if the event is not a load event, the user agent must also dispatch the event to the Window, as follows:

  1. In the capture phase, the event must be dispatched to the Window object before being dispatched to any of the nodes.
  2. In the bubble phase, the event must be dispatched to the Window object at the end of the phase, unless bubbling has been prevented.
4.3.6.4. Runtime script errors

This section only applies to user agents that support scripting in general and ECMAScript in particular.

Whenever a runtime script error occurs in one of the scripts associated with the document, the value of the onerror event handler DOM attribute of the Window object must be processed, as follows:

If the value is a function

The function referenced by the onerror attribute must be invoked with three arguments, before notifying the user of the error.

The three arguments passed to the function are all DOMStrings; the first must give the message that the UA is considering reporting, the second must give the URI to the resource in which the error occured, and the third must give the line number in that resource on which the error occured.

If the function returns false, then the error should not be reported to the user. Otherwise, if the function returns another value (or does not return at all), the error should be reported to the user.

Any exceptions thrown or errors caused by this function must be reported to the user immediately after the error that the function was called for, without calling the function again.

If the value is null

The error should not reported to the user.

If the value is anything else

The error should be reported to the user.

The initial value of onerror must be undefined.