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>

Reply via email to