This week in HTML 5 - Episode 16

December 18th, 2008 by Mark Pilgrim, Google

Welcome back to "This Week in HTML 5," where I'll try to summarize the major activity in the ongoing standards process in the WHATWG and W3C HTML Working Group.

The big news this week is r2529, which makes so many changes that I had to ask Ian to explain it to me. This is what he said:

Someone asked for onbeforeunload, so I started fixing it. Then I found that there was some rot in the drywall. So I took down the drywall. Then I found a rat infestation. So I killed all the rats. Then I found that the reason for the rot was a slow leak in the plumbing. So I tried fixing the plumbing, but it turned out the whole building used lead pipes. So I had to redo all the plumbing. But then I found that the town's water system wasn't quite compatible with modern plumbing techniques, and I had to dig up the entire town. And that's basically it.

"Amusing, in a quiet way," said Eeyore, "but not really helpful."

Basically, the way that scripts are defined has changed dramatically. Not in an terribly incompatible way, just a clearer definition that paves the way for better specification of certain properties of script (and noscript). Let's start with the new definition of a script:

A script has:

A script execution environment

The characteristics of the script execution environment depend on the language, and are not defined by this specification.

In JavaScript, the script execution environment consists of the interpreter, the stack of execution contexts, the global code and function code and the Function objects resulting, and so forth.

A list of code entry-points

Each code entry-point represents a block of executable code that the script exposes to other scripts and to the user agent.

Each Function object in a JavaScript script execution environment has a corresponding code entry-point, for instance.

The main program code of the script, if any, is the initial code entry-point. Typically, the code corresponding to this entry-point is executed immediately after the script is parsed.

In JavaScript, this corresponds to the execution context of the global code.

A relationship with the script's global object

An object that provides the APIs that the code can use.

This is typically a Window object. In JavaScript, this corresponds to the global object.

When a script's global object is an empty object, it can't do anything that interacts with the environment.

A relationship with the script's browsing context

A browsing context that is assigned responsibility for actions taken by the script.

When a script creates and navigates a new top-level browsing context, the opener attribute of the new browsing context's Window object will be set to the script's browsing context's Window object.

A character encoding

A character encoding, set when the script is created, used to encode URLs. If the character encoding is set from another source, e.g. a document's character encoding, then the script's character encoding must follow the source, so that if the source's changes, so does the script's.

A base URL

A URL, set when the script is created, used to resolve relative URLs. If the base URL is set from another source, e.g. a document base URL, then the script's base URL must follow the source, so that if the source's changes, so does the script's.

Membership in a script group

A group of one or more scripts that are loaded in the same context, which are always disabled as a group. Scripts in a script group all have the same global object and browsing context.

A script group can be frozen. When a script group is frozen, any code defined in that script group will throw an exception when invoked. A frozen script group can be unfrozen, allowing scripts in that script group to run normally again.

The most interesting part of this new definition is the script group, a new concept which now governs all scripts. When a Document is created, it gets a fresh script group, which contains all the scripts that are defined (or are later created somehow) in the document. When the user navigates away from the document, the entire script group is frozen, and browsers should not execute those scripts anymore. This sounds like an obvious statement if you think of documents as individual browser windows (or tabs), but consider the case of a document with multiple frames, or one with an embedded iframe. Suppose that the user clicks some link within the iframe that only navigates to a new URL within the iframe (i.e. the parent document stays the same). The parent document may have some reference to functions defined in the old iframe. Should it still be able to call these functions? IE says no; other browsers say yes. HTML 5 now says no, because when the iframe navigates to a new URL, the old iframes script group is frozen -- even if there are active references to those scripts (say, from the parent document), browsers shouldn't allow the page to execute them.

The main benefit of this new concept of script groups is that it removes a number of complications faced by the non-IE browsers. For example, it prevents the problem of scripts suddenly discovering that their global object is no longer the object that they think of as the Window object. Script groups are also frozen when calling document.open(). Freezing script groups also defines the point at which timers and other callbacks are reset, which is something that previous versions of HTML had never defined.

And after all of this ripping up and redefining, HTML 5 now defines the onbeforeunload event, which is already supported by major browsers.

Other interesting tidbits this week:

Tune in next week for another exciting episode of "This Week in HTML 5."

This Week in HTML 5 - Episode 15

December 10th, 2008 by Mark Pilgrim, Google

Welcome back to "This Week in HTML 5," where I'll try to summarize the major activity in the ongoing standards process in the WHATWG and W3C HTML Working Group.

The big news this week is the disintegration of HTTP authentication from HTML forms (which was last week's big news). As I predicted, the proposal generated a healthy discussion, but a combination of security concerns and concerns about tight coupling ultimately did in the proposal.

In its place, r2470 includes the following conformance requirement to allow for the possibility of someone specifying such a scheme in the future (hat tip: Robert Sayre):

HTTP 401 responses that do not include a challenge recognised by the user agent must be processed as if they had no challenge, e.g. rendering the entity body as if the response had been 200 OK.

User agents may show the entity body of an HTTP 401 response even when the response do include a recognised challenge, with the option to login being included in a non-modal fashion, to enable the information provided by the server to be used by the user before authenticating. Similarly, user agents should allow the user to authenticate (in a non-modal fashion) against authentication challenges included in other responses such as HTTP 200 OK responses, effectively allowing resources to present HTTP login forms without requiring their use.

Continuing with the web forms work, the <input> element has gained a new type: a color picker, marked up as <input type=color>. Browser vendors are encouraged to integrate this field with platform-native color pickers, as appropriate. As with all new input types, browsers that do not explicitly recognize the new type will default to a simple text field.

The <audio> and <video> API continues to churn rapidly. Implementors should probably ignore it altogether until it's been stable for two consecutive weeks. To wit: r2493 removes the pixelratio attribute, originally proposed to allow authors to override the display of videos known to be encoded with incorrect an aspect ratio. r2498 adds the playing event, fired when playback as started. r2489 drops the HAVE_SOME_DATA readyState. I will try to write up a comprehensive summary of this API once its stabilizes.

Other interesting tidbits this week:

Tune in next week for another exciting episode of "This Week in HTML 5."

This Week in HTML 5 - Episode 14

November 25th, 2008 by Mark Pilgrim, Google

Welcome back to "This Week in HTML 5," where I'll try to summarize the major activity in the ongoing standards process in the WHATWG and W3C HTML Working Group.

The big news this week is a radical proposal for integrating HTTP authentication with HTML forms. r2432 defines a new token for the WWW-Authenticate header: "HTML".

A common use for forms is user authentication. To indicate that an HTTP URL requires authentication through such a form before use, the HTTP 401 response code with a WWW-Authenticate challenge "HTML" may be used.

For this authentication scheme, the framework defined in RFC2617 is used as follows. [RFC2617]

challenge = "HTML" [ form ]
form      = "form" "=" form-name 
form-name = quoted-string

The form parameter, if present, indicates that the first form element in the entity body whose name is the specified string, in tree order, if any, is the login form. If the parameter is omitted, then the first form element in the entity body, in tree order, if any, is the login form.

There is no credentials production for this scheme because the login information is to be sent as a normal form submission and not using the Authorization HTTP header.

This idea has been kicked around for more than a decade. Microsoft wrote User Agent Authentication Forms in 1999. Mark Nottingham asked the WHATWG to investigate the idea in 2004. Better late than never, Ian Hickson summarizes the feedback to date. No doubt this new proposal will generate further discussion. No browsers currently support this proposal.

Other interesting tidbits this week:

  • r2429 adds the <input type=search> form field. [<input type=search> discussion]
  • r2440 allows the multiple attribute to appear on <input type=email> and <input type=file>. [<input type=email multiple> discussion]
  • r2423 specifies how <object> elements are submitted in forms. Unbeknownst to me, this feature was present in HTML 4 and is supported across multiple browsers. If a plugin exposes a value getter, the name of the <object> element is submitted with the value exposed by the plugin. [<object> form submission example, Mozilla bug 188938]
  • r2434 seriously revamps the concept of "vaguer moments in time." r2433 notes, correctly, that there is no year zero in the Gregorian calendar. r2437 further refines the calculation of dates before 1582. [date and time discussion]
  • r2426 clarifies the fallback behavior of the <object> element.
  • r2427 documents existing browser behavior in sending all attributes and attribute values to a plugin invoked from an <object> element. Previously, HTML 5 has specified that only specific parameters were sent, but browsers consistently send all attributes, so there it is.
  • r2424 explains the intended audience of the HTML 5 specification itself.

Tune in next week for another exciting episode of "This Week in HTML 5."

This Week in HTML 5 - Episode 13

November 18th, 2008 by Mark Pilgrim, Google

Welcome back to "This Week in HTML 5," where I'll try to summarize the major activity in the ongoing standards process in the WHATWG and W3C HTML Working Group.

The big news this week is a major revamping of how browsers should process multimedia in the <audio> and <video> elements.

r2404 makes a number of important changes. First, the canPlayType() method has moved from the navigator object to HTMLMediaElement (i.e. a specific <audio> or <video> element), and it now returns a string rather than an integer. [canPlayType() discussion]

The canPlayType(type) method must return the string "no" if type is a type that the user agent knows it cannot render; it must return "probably" if the user agent is confident that the type represents a media resource that it can render if used in with this audio or video element; and it must return "maybe" otherwise. Implementors are encouraged to return "maybe" unless the type can be confidently established as being supported or not. Generally, a user agent should never return "probably" if the type doesn't have a codecs parameter.

Wait, what codecs parameter? That's the second major change: the <source type> attribute (which previously could only contain a MIME type like "video/mp4", which is insufficient to determine playability) can now contain a MIME type and a codecs parameter. As specified in RFC 4281, the codecs parameter specifies the specific codecs used by the individual streams within the audio/video container. The section on the type attribute contains several examples of using the codecs parameter.

Third, the <source type> attribute is now optional. If you aren't sure what kind of video you're serving, you can just throw one or more <source> elements into a <video> element and the browser will try each of them in the order specified [r2403] until it finds something it can play. [load() algorithm discussion] Of course, if you include a type attribute (and codecs parameter within it), the browser may use it to determine playability without loading multiple resources, but this is no longer required.

The final change (this week) to multimedia elements is the elimination of the start, end, loopstart, loopend, and playcount attributes. They are all replaced by a single attribute, loop, which takes a boolean. To handle initially seeking to a specific timecode (like the now-eliminated start attribute), the HTML 5 spec vaguely declares, "For example, a fragment identifier could be used to indicate a start position." This obviously needs further specification.

One multimedia-related issue that did not change in the spec this week is same-origin checking for media elements. Robert O'Callahan asked whether video should be allowed to load from another domain, noting (correctly) that it could lead to information leakage about files posted on private intranets. Chris Double outlines the issues and some proposed solutions. However, contrary to Chris' expectation, HTML 5 will not (yet) mandate cross-site restrictions for audio/video files. This is an ongoing discussion. [WHATWG discussion thread, Theora discussion thread]

In other news, Ian Hickson summarized the discussion around the <input placeholder> attribute (which I first mentioned in This Week in HTML 5 Episode 8) and committed r2409 that defines the new attribute:

The placeholder attribute represents a short hint (a word or short phrase) intended to aid the user with data entry. A hint could be a sample value or a brief description of the expected format.

For a longer hint or other advisory text, the title attribute is more appropriate.

The placeholder attribute should not be used as an alternative to a label.

User agents should present this hint to the user only when the element's value is the empty string and the control is not focused (e.g. by displaying it inside a blank unfocused control).

Read the section on the placeholder attribute for an example of its proper use.

Other interesting tidbits this week:

Around the web:

Tune in next week for another exciting episode of "This Week in HTML 5."

The Road to HTML 5: getElementsByClassName()

November 11th, 2008 by Mark Pilgrim, Google

Welcome back to my semi-regular column, "The Road to HTML 5," where I'll try to explain some of the new elements, attributes, and other features in the upcoming HTML 5 specification.

The feature of the day is getElementsByClassName(). Long desired by web developers and implemented in Javascript libraries like Prototype, this function does exactly what it says on the tin: it returns a list of elements in the DOM that define one or more classnames in the class attribute. getElementsByClassName() exists as a method of the document object (for searching the entire DOM), as well as on each HTMLElement object (for searching the children of an element).

The HTML 5 specification defines getElementsByClassName():

The getElementsByClassName(classNames) method takes a string that contains an unordered set of unique space-separated tokens representing classes. When called, the method must return a live NodeList object containing all the elements in the document, in tree order, that have all the classes specified in that argument, having obtained the classes by splitting a string on spaces. If there are no tokens specified in the argument, then the method must return an empty NodeList. If the document is in quirks mode, then the comparisons for the classes must be done in an ASCII case-insensitive manner, otherwise, the comparisons must be done in a case-sensitive manner.

A Brief History of getElementsByClassName()

Can We Use It?

Yes We Can! As you can tell from the timeline, getElementsByClassName() is supported natively in Firefox 3, Opera 9.5, Safari 3.1, and all versions of Google Chrome. It is not available in any version of Microsoft Internet Explorer. (IE 8 beta 2 is the latest version as of this writing.) To use it in browsers that do not support it natively, you will need a wrapper script. There are many such scripts; I myself am partial to Robert Nyman's Ultimate GetElementsByClassName. It uses the native getElementsByClassName() method in modern browsers that support it, then falls back to the little-known document.evaluate() method, which is supported by older versions of Firefox (since at least 1.5) and Opera (since at least 9.27). If all else fails, Robert's script falls back to recursively traversing the DOM and collecting elements that match the given classnames.

And in conclusion

getElementsByClassName() is well-supported across all modern browsers except IE, and a performance-optimized open source wrapper script can cover IE and older browsers.