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 (15)

  1. Anonymous says:

    achter grond met tijgers en angels

  2. DavidPaulo says:

    i can’t wait the IE9 release! =) keep the good work!

  3. Andrew says:

    I don’t care how long it takes for Microsoft to release IE9, just do a good job of it.

  4. Stifu says:

    In order to avoid misusing the term "markup", you could simply say "code".

  5. Dave Hodder says:

    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

  6. Brian LePore says:

    Er, what exactly is different about this Selection object from the one that has existed for years in other browsers. Why is this HTML5 Selection and not DOM/W3C Selection like it has been referred to in the past?

    BTW, THANK YOU FOR THIS. As someone that has worked on a WYSIWYG editor (before giving up and switching to TinyMCE). Let me tell you that it was a pain in the butt branching off in various places, detecting which features were available, etc. And heck, many of the other browsers had issues too (this was prior to Acid3 coming out). Fixes for Gecko screwed up stuff for Webkit. I swore at the time that Ranges/Selection had the most browser incompatibilities since the 4.0 days.

  7. Mike says:

    @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.

  8. ERic says:

    <<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.

  9. Jonathan Seitel [MSFT] says:

    @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!

  10. @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

  11. steve says:

    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.

  12. carlos says:

    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?

  13. Canvas says:

    Stop with the "same markup" lies until you have Canvas support.

  14. Greg says:

    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.

  15. raffi12 says:

    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.