Bubbling/Capturing for XHR + other non-DOM objects

Hi webapps and DOM events folks!

(Cross-posting this)

This topic came up internally on the IE team, and we thought it would be noteworthy to put this question before the working groups in hopes of getting a spec clarification made.

The question is: for XHR and other non-DOM related objects that support the EventTarget interface, meaning objects that will be surfaced off of "window" but aren't really a part of the markup tree, how should event propagation be handled?

There is some good language in the current DOM Level 3 events spec, although in the context of this question it reads somewhat ambiguously. First, in section 3.1 Event dispatch and DOM event flow [1], the spec hints that any phase of the event flow may be skipped if it is "not supported":

   A phase shall be skipped if it is not supported, or if the event object's propagation has been stopped.

Then, later in the same section, the spec states that the model "defined above" _must_ be followed regardless of the specific event flow associated with the target. Naturally, the model is the capture-target-bubble phase, but the previous section also describes how the defaultView is handled in the propagation path:

   In the production of the propagation path, if the defaultView implements the EventTarget interface, the event propagates from defaultView to the document object during the capture phase, and from the document object to the defaultView during the bubble phase. Note: for legacy reasons, the load event does not propagate to the defaultView in HTML implementations.

In browsers, the defaultView (window) does support the EventTarget interface.

So given all of that background, one of the key questions for XHR is if an XHR instance belongs to a defaultView or not. One might ask the same thing of localStorage (though storage events fire on the window, not the Storage instance), indexDB, Workers, Notifications, FileAPI etc. where the API is not really related to the DOM tree (I'll call these non-DOM objects).

In each of these cases (or is it the same for all cases?) should we expect events to *capture* through the defaultView to the XHR (indexDB, FileAPI, etc.) instance, and then optionally bubble back to it, or are these objects just islands unto themselves, where there is only an *at_target* phase for events the fire on them?

My recommendation: exempt these non-DOM objects from requiring strict adherence to the DOM event flow. In a simple test [2], I show that all major browsers (except Opera) fire 'readystatechange' directly on the XHR instance and do not capture the event through the window object (Opera did not appear to support addEventListener on the XHR instance when I tried).

[1] http://dev.w3.org/2006/webapi/DOM-Level-3-Events/html/DOM3-Events.html#event-flow
[2]

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>Capture testing</title>
    <style>input[type="text"] { width: 400px; }</style>
</head>
<body>
  <script>
      function testXHR() {
         window.xhrEventCaptures = false;
         window.xhrEventTarget = false;

         window.addEventListener('readystatechange', function () { window.xhrEventCaptures = true; }, true);
         var xhr = new XMLHttpRequest();
         xhr.addEventListener('readystatechange', function () { window.xhrEventTarget = true; }, true);
         xhr.open("GET", "http://www.bing.com/");
         xhr.send();
         setTimeout(function () {
             document.querySelectorAll('input[type="text"]')[0].value = (window.xhrEventCaptures ? "window captured XHR events" : (window.xhrEventTarget ? "window DID NOT capture XHR events" : "test error: no events fired"));
         }, 500);
      }
  </script>
  <p><input type="button" onclick="testXHR()" value="Test XHR"/><input type="text" /></p>
</body>
</html>

Received on Tuesday, 22 June 2010 23:54:28 UTC