Open Bug 361453 Opened 18 years ago Updated 2 years ago

data loss when navigating back from editable iframe

Categories

(Core :: DOM: Navigation, defect)

defect

Tracking

()

People

(Reporter: ratan.work, Unassigned)

References

()

Details

(Keywords: dataloss, helpwanted)

Attachments

(2 files)

User-Agent:       Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0
Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1) Gecko/20061010 Firefox/2.0

The content typed in an editable iframe are lost when using browser back button (or ALT + Back Arrow)

Reproducible: Always

Steps to Reproduce:
In the example URL do following:
1. Go to url http://web38401.mail.mud.yahoo.com/dc/historytest.html
   OR download attached html and open historytest.html in FF
2. Click on button 'Compose (Add History After compose frame)'
3. Type some content in editable iframe
4. Click browser back button
5. Reload current page (click browser refresh button)
6. Click on button 'Compose (Add History Before compose frame)'
7. Type some content in editable iframe
8. Click browser back button
   
Actual Results:  
Notice that the content you typed in editable iframe (step 7) are gone.


Expected Results:  
Browser should maintain content typed in editable iframe.
Component: General → Editor
Product: Firefox → Core
Version: unspecified → 1.0 Branch
product=core  not sure if we have a real good match for component..
QA Contact: general
Session history, I guess.  Though there's just no provision for saving editor state, and it's not entirely clear to me how one would go about doing it anyway.  Certainly not without using up a heck of a lot of memory.

Not critical, though.  In fact more of an enhancement request for the Midas stuff.
Severity: critical → normal
Status: UNCONFIRMED → NEW
Component: Editor → History: Session
Ever confirmed: true
Keywords: helpwanted
OS: Windows XP → All
QA Contact: history.session
Hardware: PC → All
Version: 1.0 Branch → Trunk
Keywords: dataloss
Boris,
After step 4 in my test case, editable iframe maintains the content I typed
So I expect FF to behave similar after step 8.
In both the cases (step 4 & step 8), FF should navigate back in the history iframe rather than wiping out content from compose iframe (editable iframe). It does behave correctly after step 4 but not after step 8.

I'm not sure what do you mean by "Certainly not without using up a heck of a lot of memory." It seems to me FF is doing either of following:
1. navigating back twice (first in history iframe and second in compose iframe) on one Back action
2. it is saving the whole page state when iframe navigation is happening in history iframe so navigating back is restoring the whole page state (page without compose iframe). Compose iframe is added dynamically after history iframe navigation in step 6. Hitting back in step 8 shows the content wiped out compose iframe that is no more editable. However, browser correctly navigates back in history iframe and back button shows it correctly.


"Not critical, though.  In fact more of an enhancement request for the Midas
stuff."
This is critical to us (Yahoo Mail). if user types a long email and hit browser back button then in certain situations they may loose data. I clearly sees that it can happen in other DHTML applications too as dynamic iframe creation and iframe navigations are common. It is a release blocker for us or we have to disable certain feature as I don't see a work around for it. It happen both in FF 1.5.0.2 and FF 2.0 that we discovered recently.
Severity: normal → critical
> After step 4 in my test case, editable iframe maintains the content I typed

Oh, I see.   You're messing around with multiple racing iframes...

So at a guess, you're starting a load in the "history" iframe, then starting a load in the "compose" iframe.  When we do "back", we unwind the last load, and that's in the "compose" iframe.

Why exactly do you expect what you're doing to work, and what effect are you trying to achieve?

As for the severity field measures how severe the bug is in general, not how important it is to the reporter.  This bug is just not critical -- not a crash, not serious permanent data loss of data users expect never to lose, not a security exploit.  I'm not going to fight over the field with you, but I think you're abusing it.
"So at a guess, you're starting a load in the "history" iframe, then starting a
load in the "compose" iframe.  When we do "back", we unwind the last load, and
that's in the "compose" iframe."

Just to make it more clear:
1. history iframe is to control browser navigation. Everytime user clicks on compose button then a history entry is added in browser.
   The code that adds to browser history is:
   location.href = url //adds a history entry.

2. Compose iframe doesn't add history entry as there is no navigation in compose frame: 
   frameBody.innerHTML = text;

3. That means if user clicks on browser back button then navigation should happen in history iframe only. I see the correct behavior in 4th step in my test case. In 8th step, navigation seems to happen in both history iframe as well as compose iframe and that causes data loss. It shouldn't navigate in compose iframe as compose iframe didn't add a history entry.

I changed the severity of bug because it is permanent data loss and it seemed to me from your comment that you didn't quiet get it what was I trying to communicate.
Anyway, thanks for your comments.
Component: History: Session → General
OS: All → Windows XP
Product: Core → Firefox
Hardware: All → PC
Version: Trunk → 1.0 Branch
"So at a guess, you're starting a load in the "history" iframe, then starting a
load in the "compose" iframe.  When we do "back", we unwind the last load, and
that's in the "compose" iframe."

It is true that I'm starting a load in history iframe but there is no load in compose iframe. so, when I click back button then it should unwind only history iframe.
It works as expected when you follow these steps:
1. Go to url http://web38401.mail.mud.yahoo.com/dc/historytest.html
   OR download attached html and open historytest.html in FF
2. Click on button 'Compose (Add History Before compose frame)'
3. Type some content in editable iframe
4. Click browser back button
See it works fine (maintains compose iframe content and unwind history iframe )

However, the following steps wipes out compose iframe content:
1. Go to url http://web38401.mail.mud.yahoo.com/dc/historytest.html
   OR download attached html and open historytest.html in FF
2. Click on button 'Compose (Add History After compose frame)'
3. Type some content in editable iframe
4. Click browser back button
5. Reload current page (click browser refresh button)
6. Click on button 'Compose (Add History Before compose frame)'
7. Type some content in editable iframe
8. Click browser back button
See compose iframe contents are wiped out and history iframe unwinds (look at back button history)

"Why exactly do you expect what you're doing to work, and what effect are you
trying to achieve?"

User is composing a message in Yahoo Mail and hits back button in the browser then we take user to previous Mail Tab (not firefox tab) user visited. User can have multiple tabs in Yahoo Mail Beta to read and compose messages. We navigate user's back action in the history frame. There is no navigation due to compose frame so there shouldn't be any navigation in compose frame. On investigating user complains on compose data loss at time while composing a message and hitting back button revealed flow of navigations that caused data loss in FF and that is the attached test case I have come up with. Hope it helps you guys to fix it.
Severity: critical → normal
Component: General → History: Session
OS: Windows XP → All
Product: Firefox → Core
Hardware: PC → All
Version: 1.0 Branch → Trunk
I noticed today that data loss occurs even if iframe is not editable. FF navigates back to "about:blank" that I have specified while creating iframe tag dynamically.
I followed same step as in bug description except that I didn't turn on designMode for compose iframe.
OK, I finally got time to debug this a bit.  Sorry about the delay.  :(

First of all, on trunk the problem seems to have disappeared between the 2006-10-16-01 and 2006-10-17-01 builds.  Most likely due to bug 351633 getting fixed.

Still looking at the branch situation.
Oh, just to check.  Ratan Hudda, does the trunk also fix your original problem, or just this testcase?
OK. So this testcase is basically tickling all the design issues in session history... ;)

The way session history works is by maintaining a list of trees of session history entries -- one tree for each "state" of a page.  On back/forward, the two relevant trees are compared and any frames that changed between the two states (that is, that have nodes in both trees that are not flagges as clones of each other) are navigated as needed.

A salient "feature" of this setup is that it does not deal well with dynamic modifications to the frame tree, because it doesn't really modify the session history entry tree to be in sync with it.

So in this case, here's what happens, pegged to the steps in comment 0:

Step 2:

  The page adds an iframe and then sets the src of the existing iframe to a
  javascript: URI.  Adding the iframe is treated as a frame addition, so it does
  not create a new session history tree, but just adds a new node to the
  existing tree.  So the existing tree now has three nodes (one for toplevel
  page, and one for each of the subframes).  Then the javascript: URI load
  happens, which clones the existing three-node tree, and replaces the node for
  the frame in which the javascript: load happened with a new node.  Then the
  location set in javascript in that document happens, and since it's happening
  during document load is treated as a replace load and replaces the relevant
  session history entry with a new entry.

Step 4:

  The two trees are compared.  The only different node is the one for the iframe
  that the javascript: load happened in, so that's the only frame that's
  navigated.

Step 5:

  The session history tree is unaffected, but there are now fewer frames in the
  page (!).

Step 6:

  This time, the javascript: load happens first.  javascript: URI loads are
  synchronous on the branch, so the frame tree is immediately cloned, and
  the entry the javascript: load is happening in is replaced by a new entry. 
  Then an iframe is added to the document.  It creates a session history entry
  in the tree based on how many frames are there before it.  But there's already
  an entry in the tree at that spot!  So it gets replaced with the one for the
  iframe's about:blank document.  In a debug build this actually asserts:
  "Adding child where we already have a child?  This will likely misbehave."

Step 8:

  The two trees are compared.  The "old" (one we're starting from) tree has an
  entry for the javascript: URI document (or rather for whatever that set the
  location to), and an entry for the about:blank of the iframe we added in step
  6.  The "new" (one we're going to) tree has an entry for whatever the location
  was set to in step 2 and an entry for the about:blank of the iframe we added
  in step 2(!).  Both are mis-matches, so loads happen in both frames, leading
  to this bug.

On trunk, step 6 is different because javascript: execution is async while adding a new frame to the tree is still sync, so the steps get reversed to be the same order as in step 2 and everything is fine.

To be honest, I don't really see a branch-safe way of fixing this.  We _might_ be able to work around this issue by reusing the id of the existing entry when we would hit the assert above.  But that would cause problems in other cases (specifically, not navigating frames in some cases that should be navigated)...

What we really need to do is to redesign session history to work with AJAX-y stuff like this, but it's not clear what the "right" behavior would be.

In the meantime, is there a way you can guarantee that the javascript: execution will happen _after_ the new frames have been added to the document?  As long as you do that, there should be no problems, I'd think.
I tested it on Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9a2pre) Gecko/20070205 Minefield/3.0a2pre

It continue to happen in the mail but somehow FF 3.0 seems to have fixed the testcase case I attached. I worked it around earlier by detecting the iframe unload and then saving the content and restoring it later.
I think now I understand it better so I will give it a try by adding iframe first (compose iframe) and then executing javascript (set src of the existing iframe to a javascript: URI).
Thanks for your long explanation.
related to bug 191176?
Does this still happen? Checking in bug 430624 may have fixed this...
Component: History: Session → Document Navigation
QA Contact: history.session → docshell
This problem is very annoying on Mac OX X, where Command+Left is supposed to navigate to the beginning of a line.  Users will frequently encounter this problem.
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: