W3C home > Mailing lists > Public > whatwg@whatwg.org > August 2010

[whatwg] Should events be paused on detached iframes?

From: Ben Lerner <blerner@cs.washington.edu>
Date: Tue, 24 Aug 2010 16:09:12 -0700
Message-ID: <4C745118.3040105@cs.washington.edu>
  The history navigation analogy is a good one: pages presumably already 
have to handle the pageshow event to deal with being revived from the 
history, and the browser already needs to know how to fire that event.  
Why not reuse those mechanisms?  A strawman claim: Nothing may be 
changing from the perspective of the iframe, but it certainly is 
changing from the perspective of the container or the user: detaching an 
iframe from a page is like navigating a browsing context away from a 
page, putting it into hibernation until it's reattached to an active 
document/browsing context.  What subtle or important facet of the web am 
I missing that breaks this analogy? (It wouldn't surprise me if I missed 
something obvious, either... :)

Another reason to consider suspending detached iframes: suppose that in 
the chat window example below, the iframe wasn't just a same-origin 
place to store global state, but also had its own UI, with callbacks and 
event handlers and whatnot.  If, during the interim while the iframe was 
being detached, adopted and reattached, that frame executed a timer that 
popped up a modal alert or prompt to the user, how would the user 
reasonably know where that alert came from?  And what document(s?) 
should be paused while the alert is shown?

To stretch an analogy a bit: detaching an iframe, saving a reference to 
it, and then attaching it/adopting it later to another document is a bit 
like using DVR to record the rest of a TV show to watch later: I should 
get the same show, paused wherever I left off watching it, on whatever 
TV is convenient for me to watch it on.  I shouldn't have to immediately 
start watching on the second screen in order to preserve state, and it 
shouldn't keep playing while I move from one screen to the other :)

Regarding XHR and such -- I guess what I'm suggesting is suspending the 
event loop, but not necessarily suspending asynch processes.  So XHR can 
continue to queue tasks; media can continue to buffer; resources can 
continue to load.  When the document is reattached, it finds itself with 
a backlog of events to handle, which is the exact same situation as a 
very bursty network connection :)

On 8/24/2010 3:42 PM, Dirk Pranke wrote:
> On a related note, the behavior of onUnload in this situation is quite
> unclear. Should onUnload() fire if an iframe is detached from the DOM?
Indeed -- it seems to me from the spec that it should not fire, until 
(following the snippet Dmitry quoted below) the last reference to the 
iframe is dropped and therefore the browsing context can be discarded.

I'm not sure the adoptNode workaround mentioned in the bugs below is a 
full fix.  It gets us from behavior #1 to behavior #3, but doesn't 
consider #2 as a possibility.  Certainly some loose ends to think about...

~ben

On 8/24/2010 3:27 PM, Dmitry Titov wrote:
> Indeed, in WebKit you normally see #1 (iframe unloads). We have added 
> the ability to move 'live' iframe, as Adam mentions, potentially 
> across documents, while keeping it completely alive, with XHRs 
> loading, events firing etc (aka 'magic iframe' feature). One would 
> need to use adoptNode() API to do that, something like:
>
> var iframe = document.getElementById("test");
> other_document.adoptNode(iframe);
> other_document.getElementById("newParent").attachChild(iframe);
>
> WebKit has a bug (https://bugs.webkit.org/show_bug.cgi?id=13574) to 
> enable moving iframes w/o reloading. FF has a bug on that as well 
> (https://bugzilla.mozilla.org/show_bug.cgi?id=254144) but it's hard to 
> say when exactly those will be fixed. I hope to fix WebKit issue at 
> some point.
>
> While discussing 'magic iframe', Ian Hickson pointed out that nothing 
> in the spec actually mandates discarding the live document inside 
> iframe simply because it's iframe element is connected/disconnected to 
> DOM of the parent document. Here is a note from the HTML5 spec about 
> that:
> Removing 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#remove-an-element-from-a-document> an 
> |iframe 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-iframe-element>| from 
> a |Document 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#document>| does 
> not cause its browsing context 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context> to 
> be discarded. Indeed, an |iframe 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-iframe-element>|'s 
> browsing context 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context> can 
> survive its original parent |Document 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#document>| if 
> its |iframe 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/the-iframe-element.html#the-iframe-element>| is 
> moved to another |Document 
> <http://www.whatwg.org/specs/web-apps/current-work/multipage/infrastructure.html#document>|.
>
> So it seems the right behavior is to keep the content alive. It's not 
> clear why the events would not fire during DOM operations though. 
> Perhaps they should, since nothing is changing from the perspective of 
> the document loaded into iframe - for example, XHR probably should 
> continue loading content if it was doing so before iframe was 
> disconnected from its parent node. Doing some suspension (as for 
> example is done when a page goes into back-forward cache?) would be 
> way more complex mechanism to have, with necessary events on 
> pause/unpause so the live document could re-start async operations 
> correctly.
>
> Dmitry
>
> On Tue, Aug 24, 2010 at 1:38 PM, Adam Barth <w3c at adambarth.com 
> <mailto:w3c at adambarth.com>> wrote:
>
>     This seems related to the "magic iframe" concept that was recently
>     added in WebKit.  Basically, magic iframe lets you move an iframe from
>     one document to another without blowing away the JavaScript/DOM state
>     of the iframe.  The way this works is that the iframe remains "alive"
>     until the browser returns to the main event loop.  If a living iframe
>     gets added to a document, then it keeps all it's state.  This feature
>     is useful for sites like Gmail that have chat windows that can be
>     opened from the main document.  If the user closes the main document,
>     the chat windows can adopt some iframe that keeps the proper state.
>
>     Adam
>
>
>     On Tue, Aug 24, 2010 at 1:30 PM, Ben Lerner
>     <blerner at cs.washington.edu <mailto:blerner at cs.washington.edu>> wrote:
>     >  There seems to be a bit of disagreement among browsers about
>     how event
>     > loops and iframes interact when an iframe is removed and then
>     reinserted
>     > into its parent document.  Consider the following two documents:
>     the parent
>     > document has a button that removes or reattaches an iframe to
>     the document,
>     > while the second simply sets an interval to update the page content.
>     >
>     > Page1.html:
>     > <!DOCTYPE HTML>
>     > <html>
>     > <body>
>     > <p><button onclick="toggleInDoc();">Show/hide</button></p>
>     > <iframe id="test" src="page2.html"></iframe>
>     > <script>
>     >    var test = document.getElementById("test");
>     >    function toggleInDoc() {
>     >      if (test.parentNode == null)
>     >        document.body.appendChild(test);
>     >      else
>     >        document.body.removeChild(test);
>     >    }
>     > </script>
>     > </body>
>     > </html>
>     >
>     >
>     > Page2.html:
>     > <!DOCTYPE HTML>
>     > <html>
>     > <body>
>     > <p id="test"></p>
>     > <script>
>     >    window.setInterval(function() {
>     document.getElementById("test").innerHTML
>     > += "."; }, 500);
>     > </script>
>     > </body>
>     > </html>
>     >
>     >
>     > Assume the user waits until the interval has fired several
>     times, then
>     > presses the button, waits a while, and presses it again.  There
>     are three
>     > possible outcomes:
>     > 1. When the iframe is reattached, the inner page reloads.  This
>     seems to go
>     > beyond the wording of the spec, which says only "When an iframe
>     element is
>     > first inserted into a document, the user agent must create a
>     nested browsing
>     > context, and then process the iframe attributes for the first
>     time."  (This
>     > isn't the first time the iframe is inserted into the document, so we
>     > shouldn't process the iframe attributes again.)
>     >
>     > 2. The interval (and presumably, all events) in the iframe is
>     paused while
>     > it's been detached (since the document is no longer fully
>     active, but it
>     > also has not been discarded because of the global reference to
>     its container
>     > element).
>     >
>     > 3. The interval (and presumably, all events) continues to fire
>     while it's
>     > been detached, and the content of page2 will have changed while
>     it's been
>     > detached from page1.
>     >
>     > So far, Chrome 6, Opera 10.6 and Firefox 3.6 follow #1, and IE 8
>     follows #3.
>     >  My reading of the "fully active" clause of the spec leads me to
>     expect #2.
>     >  Which of these behaviors is the desired one?  And/or, would it
>     be desirable
>     > to permit authors to specify which behavior they intend?
>     >
>     > Thanks,
>     > ~ben
>     >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.whatwg.org/pipermail/whatwg-whatwg.org/attachments/20100824/d5ecc3ff/attachment-0001.htm>
Received on Tuesday, 24 August 2010 16:09:12 UTC

This archive was generated by hypermail 2.3.1 : Monday, 13 April 2015 23:09:00 UTC