DOM Range and HTML5 Selection

We’ve written a lot about the support we’re building in Internet Explorer 9 to allow developers to write the same markup and get the same results across browsers. IE9 includes two new features that are great for web developers writing same markup: DOM Range and the HTML5 Text Selection APIs. DOM Range provides a simple, consistent way to extract and manipulate a piece of a document. It’s also the underlying unit of the HTML5 Text Selection APIs, which help you connect with one of the common ways that users interact with the browser – selecting text.

As a developer, HTML5 Selection gives you a way to programmatically get and set the pieces of a page your users select, as seen in this code snippet:

 var selection = window.getSelection();
var range = selection.getRangeAt(0);

As you might guess from the names used in the snippet, the slice of the document you get back is defined in terms of DOM Range. A Range is really just a way of describing a piece of a document, enabling you to operate on it as you see fit. For example, if I want to edit the inline style of all the elements in the Range:

 var contents = range.extractContents();
var childNodes = contents.childNodes;

for (var i = 0; i < childNodes.length; i++)
{
     if (childNodes[i].nodeName != "#text")
        childNodes[i].style.color = "red";

    range.insertNode(childNodes[i].cloneNode(true));
}

Internet Explorer has long had similar functionality to Range, via the proprietary TextRange and HTMLDocument.selection objects. TextRanges were created and manipulated in terms of characters, words, and lines. These were useful abstractions, but they could potentially lead to some ambiguity, and didn’t lend themselves to easy manipulation by DOM APIs.

To see some of the advantages of DOM Range and HTML5 Selection, we’ll use a demo I created in the test drive site that relies on them. In the demo, there is a text editor that receives the user selection, extracts the nodes inside, applies arbitrary operations to them, and then re-inserts them where they came from. This allows a caller to set an inline style on each of the elements in a selection to make its text color green, for example.

Setting text color is an example of functionality you can easily achieve with TextRange’s execCommand method, which has a set of predefined operations. But what about operations that fall outside this scope, like translating a piece of text?

To see an example in action, try using the ‘Translate’ command in the demo. This command makes an AJAX call to Bing Translate, passing off each of the elements in the user selection for translation. Because a Range operates in terms of nodes and offsets, this is just another operation; the operation receives some nodes, performs the operation, and then puts them back. This pattern allows the code to be generalized for other operations..

If I try to do the same thing with TextRange, I cannot use execCommand. To do this I have to extract the text content, pass it off for translation, then delete the old text and re-insert the new. In the process, I lose previous operations like text or size changes, because the lack of node-awareness doesn’t provide enough information to extract individual pieces, modify them, and then put them back in their original containers.

As Dean mentioned in a recent post, one of our goals for this release is enabling developers to write the same markup for all browsers. During our planning research, we collected usage data showing that DOM Range and the HTML5 Selection APIs were among the most-used on the Web. Supporting widely-used APIs is a big part of achieving the “same markup” ideal, so these APIs are a high priority.

However, it’s worth pointing out that if you have an application that depends on the old APIs, they continue to work as before in the latest mode, making your upgrade path to IE9 easier. Wherever possible, we recommend using techniques Tony Ross wrote about to send IE9 the same markup for Range as you send other browsers

We hope the end result of supporting these APIs is a better experience for you, the developer. As a reflection of the work we’ve done here to improve interoperability, the IE9 Acid3 score increases. The current Platform Preview now passes tests 7, 9, 12, and 13.

It’s been a lot of fun working on this, and I can’t wait to see what other developers do with it.

Thanks!

Jon Seitel

Program Manager

Comments

  • Anonymous
    January 01, 2003
    achter grond met tijgers en angels

  • Anonymous
    May 11, 2010
    i can't wait the IE9 release! =) keep the good work!

  • Anonymous
    May 11, 2010
    I don't care how long it takes for Microsoft to release IE9, just do a good job of it.

  • Anonymous
    May 11, 2010
    In order to avoid misusing the term "markup", you could simply say "code".

  • Anonymous
    May 11, 2010
    Will document.implementation.hasFeature() be updated to convey the fact that IE supports DOM Range and others? See for example the W3C's "What does your user agent claim to support?" page -- http://www.w3.org/2003/02/06-dom-support.html All the best, Dave

  • Anonymous
    May 11, 2010
    The comment has been removed

  • Anonymous
    May 12, 2010
    @Brian LePore Totally agree, why is HTML5 being thrown in front of standards that have been around for a long time. But I am looking forward to IE9 and finally it seems the IE team have realised what developers want.

  • Anonymous
    May 12, 2010
    <<why is HTML5 being thrown in front of standards that have been around for a long time.>> Because HTML5 usually makes small tweaks to those standards, and/or clarifies ambiguities in those standards. HTML5 is about creating interoperability of implementations.

  • Anonymous
    May 12, 2010
    @Brian: HTML5 defines the Selection object as part of the specification, and this was the basis of our implementation. Please see: http://dev.w3.org/html5/spec/Overview.html#documentSelection Thanks for the feedback!

  • Anonymous
    May 12, 2010
    @Jonathan Seitel [MSFT] var range = selection.getRangeAt(0); is HTML5 Does second IE9 platform preview support createRange() ? as defined in http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Creating If not, what are the plans to support DOM 2 Range interface? regards, Gérard

  • Anonymous
    May 12, 2010
    As someone that had to deal with this before in IE6, IE7 & IE8 where IE's own proprietary text range functions changed (without notice) while not updating to the standard that other browsers had implemented I am glad to finally see that MSFT is fixing this. Fingers-Crossed that IE9 really is the major release we're hoping for to help push users off IE6, IE7 and IE8.

  • Anonymous
    May 12, 2010
    Great post, thanks. Any news about Canvas implementation? How are you doing with SVG? Last check showed IE implementing 29% of SVG, do you plan to increment this figure?

  • Anonymous
    May 13, 2010
    Stop with the "same markup" lies until you have Canvas support.

  • Anonymous
    May 13, 2010
    Can the developer community get tools to find and simplify duplicate code (e.g., 'childnodes[i]') which seem to exist to a much greater extent in web pages. if (childNodes[i].nodeName != "#text")        childNodes[i].style.color = "red";    range.insertNode(childNodes[i].cloneNode(true)); This type of code seems to be more widespread in web pages.

  • Anonymous
    May 14, 2010
    Canvas isn't really markup though. The old school graphics programmer in me wants Canvas, but I don't think immediate mode raster graphics makes much sense on the web.