Closed Bug 237717 Opened 21 years ago Closed 21 years ago

[FIXr]loading iframe or object with html file inta a positioned div causes extra entries of current document in history

Categories

(Core :: DOM: Navigation, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.8alpha1

People

(Reporter: fotemac, Assigned: bzbarsky)

References

()

Details

Attachments

(3 files, 1 obsolete file)

User-Agent: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.6) Gecko/20040113 Build Identifier: Mozilla/5.0 (Windows; U; Win95; en-US; rv:1.6) Gecko/20040113 If an ifame element which has a text/html file as its src, or an object element which has a type="text/html" file as its data, is loaded dynamically into a positioned div (layer), the current document is reiterated inappropriately in the history. The consequence is that one must hit the back button multiple times to actually get back to the previous document. Reproducible: Always Steps to Reproduce: 1.use createRange() ... appendChild() to load <iframe src="foo.html" ...></iframe> or <object data="foo.html" type="text/html"...></object> into a div with position:absolute. 2.check the history list (down-arrow button beside the back button) and you will see that every time you do 1. another entry of the current document is added inappropriately to the list. 3. Actual Results: Because of the inappropriate reiterations of the current document in the history, one must hit the back button multiple times (or jump over those reiterations in the dropdown with the history list) to actually get back to the previous document. Expected Results: Neither IE nor Opera have this bug. Their back buttons take you back properly to the previous document. So should Mozilla'a.
When I searched for this bug with "iframe object history" as keywords I did find 148794 and some others which seemed related, but not quite the same. Those involved writing content into an iframe, and none mentioned object. The bug I'm reporting involves writing an iframe or object element into a positioned div. In any case, hold on to my URL to check when you folks think you might have fixed the bug.
*** Bug 237723 has been marked as a duplicate of this bug. ***
Consider the following scenario: 1) You have an iframe on the page 2) I click a link in the iframe, which loads a new URL in the iframe Under those conditions, we need to add an entry to session history so that you can go back. This is the code that is getting triggered by that testcase (which you should attach to the bug, by the way). It's not quite clear to me how the two cases may easily be disambiguated; right now I suspect that we treat any frame load that happens while the toplevel document is not loading as a page traversal like above.
Keywords: helpwanted
No. You appear to be mixing apples with oranges, and that appears to be the kind of thing that's behind the jam Mozilla finds itself in with regard to this matter. The W3C DTDs define iframe and object as inline elements. Their content should NOT be associated with the session history for the current "full" window, any more than should the content of other elements within the overall document being displayed in that window. The iframe and object with type="text/html" do have a similarity to new windows like those created via window.open(). Also, an iframe can be a target, like a bona fide frame. And so it is understandable that one would instinctively expect an iframe or a object with type="text/html" to have an accessible history, but if so, it should be independent of the current window's session history. The way IE handles the history issue for iframe (doesn't handle it for object with type="text/html") is that if you follow links within the iframe and then right-click WITHIN the iframe, the back and forward buttons of the resultant menu apply to those links travered within the iframe. But, again, one should not muddle such an "sub-history" if one sets that up (it's not necessary based on the DTDs, but also not precluded), with the session history for the current "full" window's documents.
> You appear to be mixing apples with oranges _I_ am merely describing what the code currently does so that whoever comes along and tries to fix this bug will know where to look. > but if so, it should be independent of the current window's session history Why? Why is an iframe any different from a frame in this regard? From a user's perspective it's not -- a user doesn't care whether you use a frame, iframe, object, or some other method because they all look and act the same in the end. That's not changing. The IE method was considered, but there was wide agreement that it's incredibly painful and counterintuitive (and that there is no strong motivation for it). Note that this behavior is not incompatible with fixing this bug; it's just that fixing this bug must not break this behavior.
I am unclear about what you are referring to with the terms "the IE behavior" and "this behavior". In any case, I did some more exploring and here's what I found. IE, Opera and Mozilla all behave essentially the same when the iframe or object with type="text/html" are encased in a p or an ordinary div. They indeed are treated "like a frame" -- with the session history listing only the URLs, but keeping track of whether they should be placed in the iframe (or object) versus the overall window as one presses the back and forward buttons. However, if the iframe or object with type="text/html" is encased in a positioned div (layer), IE and Opera continue to treat them "like a frame" whereas Mozilla starts reiterating the URL of the overall document in the session history instead of the URLs being loaded into the iframe or object, and so the back and forward buttons appear to be doing nothing as you cycle through those reiterations of the same (and wrong) URL.
Attached file Testcase
Attached patch Partial fix (not quite right) (obsolete) — Splinter Review
This fixes the original problem reported by not adding to session history when we're doing the initial load in an iframe. Really, though, this is wallpaper over a bug (in nsDocShell::CloneAndReplace, probably). With this patch, we don't store the right history state for the iframe (since we're in fact not storing its history state at all), so appending it to the document, following a link, then going back breaks. What _should_ be happening is that when we append the iframe its history state is attached to the current page history state (instead of creating a new one as we do now). Like the "replace" part of CloneAndReplace needs to work.
Attached patch Slightly betterSplinter Review
OK, so the old behavior is: When a subframe loads, grab the current history entry of the subframe, walk to the root docshell, get the current toplevel history entry, clone it, recursively, except replace the current history entry of the subframe (when we get to it) with the new entry we are loading. This behavior makes perfect sense _except_ when the subframe has no current history entry. This is what happens when we have an initial load in a subframe (as in this bug). In this case, there is nothing to replace, so we end up constructing an exact clone of the toplevel history entry, which is sorta bad. The old behavior is: Just like the old behavior, except if the subframe has no current history entry, append its new history entry to the current history entry of its parent. This is exactly what we would do if the parent were still loading (well, we'd append to the loading history entry, but if we're done loading the current one is the one to use), and to me it makes sense to treat the two cases the same way.
Attachment #144102 - Attachment is obsolete: true
Comment on attachment 144103 [details] [diff] [review] Slightly better Adam, could you review? I've done the following tests (and this patch passes): 1) Load page with static iframe, click link in iframe, test that back works correctly. 2) Load page with dynamic iframe created via button. Click the button. Click a link in the iframe. Test that back works correctly (btw, without this patch it doesn't in this case). 3) The original testcase in this bug (the bogus history entries no longer appear). 4) As test 2, but the dynamically created iframe shows a page with a link to another page as in test 2. Click that link. Then click the button in the iframe, which creates an iframe within the iframe. Follow a link in that innermost iframe. Click back -- this should go one page back in the innermost iframe. Click back again -- this should go one page back in the outer iframe.
Attachment #144103 - Flags: review?(adamlock)
Taking...
Assignee: nobody → bzbarsky
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: helpwanted
OS: Windows 95 → All
Priority: -- → P1
Hardware: PC → All
Summary: loading iframe or object with html file inta a positioned div causes extra entries of current document in history → [FIX]loading iframe or object with html file inta a positioned div causes extra entries of current document in history
Target Milestone: --- → mozilla1.8alpha
Attached file Reporter's testcase
Creating a "Reporter's testcase" attachment for the document at the Reporter's URL to help ensure that the patch for this bug also is tested for objects with type-"text/html" and not just iframes.
Ugh. the links in the "Reporter's testcase" do not work because the base is changed to http://bugzilla.mozilla.org/ and I didn't include a base tag to keep it http://www.macridesweb.com/oltest/ Here is a URL for the document I intended to be used: http://www.macridesweb.com/oltest/Bug237717.html#iframecontent including a fragment to get you to the relevant section of the document. I also edited the input field for the URL: above to this URL plus fragment, but I am relatively new to Bugzilla and don't know if that will work. The patch as described seems appropriate, but what about this scenario (which my testcase was intended to help test): You dynamically load an iframe or an object with data="foo.html" and type="text/html" into a positioned div and make the div visible. You follow links within that iframe or object thus extending the session history. While the positioned div stays visible your back and forward buttons can load appropriately. However, at some point your DHTML restores the positioned div to hidden. You now have entries in the session history which can't be displayed. What happens when you proceed to those entries via the back or forward buttons, or history list dropdown menu?
Let me amplify that last question. In Boris' testcase the "Add ifraame" and "Remove iframe" buttons use createElement() ... appendChild() to add, and then removeChild() to remove, an iframe element into the document's body, with reformatting of the entire decument each time the respective buttons are hit, and with the same foo.html docuement (the Mozilla home page) being used as the iframe src each time the "Add iframe" button is used. In my testcase, I lnstead load iframe or object elements dynamically into a pre-defined positioned div (with an id of "overDiv" and initially hidden) in conjunction with onmouseover events for a number of different links. I also always use the same foo.html file as the src for the iframe or data for the objects in my testcase, but normally the different links would use different HTML files. Thus once the positioned div is hidden again, one normally would not be interested in the history for any links followed from within, and displayed within the iframe or object. Whenever the positioned div is dynamically loaded and made visible via one or another event, the sub-history for that content (an iframe or object in these cases) should again start from scratch, as one expects for a dynamically loaded positioned div which normally gets HTML fragments (rather than a complete HTML file via the trick of making an iframe or object the dynamically loaded content). That is why my initial orientation was not to treat the iframe or object "like a frame" when it ls dynamically loaded into a positioned div such that the sub-history survives beyond the point when the positioned div is again hidden. Here's another way to phrase the issue. Should the handling (persistence) of such "sub-menus" be different when the iframe or object with data="foo.html" and type="text/html" is loaded dynamically into (is made the child of) a positioned div versus the body element? Furthermore, should it matter whether the src or data value for an iframe or object currently being loaded into the positioned div or body element is the same or a different HTML file from that which was previously loaded and had accumulated a sub-history? But for now, the patch for not adding to session history when doing the initial load of an html file for the subframe, and then appending the subframe's history to the parent's (if I'm interpreting Boris' comments correctly)should take care of the most serious bug issue.
> tested for objects with type-"text/html" and not just iframes. Mozilla uses the same exact code for both, so testing one is sufficient, actaully. ;) (In reply to comment #14) > What happens when you proceed to those entries via the back or forward > buttons, or history list dropdown menu? From the user's point of view, nothing changes. In my testcase, nothing changes, in fact. In your testcase, since the frame still exists, the document loaded in the frame actually changes (though the user can't see that). It's not completely clear what should happen here, if only because there are so many ways to hide a frame that it's not really possible to determine whether one is hidden... and since unhiding iframes is also possible, changing the state of history depending on the hidden state of the frame could be very confusing to the user, just like the "nothing happens" behavior. We'd need to come up with a decent description of what _should_ happen, methinks (and perhaps we should file a separate bug on this issue). (In reply to comment #15) > Should the handling (persistence) of such "sub-menus" be different No. A lot of pages put _all_ their content in a positioned div, and we don't want to break iframe history on those pages. > should it matter whether the src or [....] is the same or a different HTML > file This should be treated as it normally would be in history. That is, it depends on the type of load being done (eg if the load is done with location.replace(), there should be no new history entry, but if the load is done normally there should be).
Your reasoning seems sound, even though the patch will yield some seemingly strange (but "explainable") history historesis for my DHTML popup library. I looked at other browsers in this context, and Opera 7.23 is behaving for both iframe and object with data="foo.html" and type="text/html" as Mozilla will do with your patch. IE behaves that way only for iframe. For object with data="foo.html" and type="text/html" it actually has the current Mozilla bug, i.e., when you activate links within the object, it clones the parent's URL in the session history instead of appending the URL for the subframe link. You can see that most easily via the onmouseover popup for the "With object scrollbar, caption and Close link" anchor in my testcase.
Comment on attachment 144103 [details] [diff] [review] Slightly better r=adamlock
Attachment #144103 - Flags: review?(adamlock) → review+
Comment on attachment 144103 [details] [diff] [review] Slightly better darin, could you sr?
Attachment #144103 - Flags: superreview?(darin)
Attachment #144103 - Flags: superreview?(darin) → superreview+
Summary: [FIX]loading iframe or object with html file inta a positioned div causes extra entries of current document in history → [FIXr]loading iframe or object with html file inta a positioned div causes extra entries of current document in history
Checekd in for 1.8a.
Status: NEW → RESOLVED
Closed: 21 years ago
Resolution: --- → FIXED
Would it be possible to include this in 1.7branch? Apparently, this fix fixed a 'back-button issue' in bug 235398
Blocks: 235398
Session history code is notoriously fragile; changes to it are very dangerous and often lead to regressions in bizarre circumstances. As a result, I'm absolutely opposed to landing this on any branches until it's baked on the trunk for a good long time (preferably through an alpha milestone release and ensuing bug reporting); even then I would be wary of doing so on a long-lived branch unless some exhaustive regression testing has been done (I'm talking along the lines of testing every single resolved session history bug in bugzilla to make sure it didn't regress). In addition to those concerns, see bug 235398 comment 9.
*** Bug 235398 has been marked as a duplicate of this bug. ***
*** Bug 211457 has been marked as a duplicate of this bug. ***
*** Bug 129590 has been marked as a duplicate of this bug. ***
(In reply to comment #22) > As a result, I'm absolutely opposed to landing this on any branches until it's > baked on the trunk for a good long time (preferably through an alpha milestone > release and ensuing bug reporting); It seems like this criterion is now satisfied (of course, it is not if there's a regression reported during 1.8alpha-cycle). > even then I would be wary of doing so on a > long-lived branch unless some exhaustive regression testing has been done (I'm > talking along the lines of testing every single resolved session history > bug in bugzilla to make sure it didn't regress). This is certainly not. I'll try to do this.
*** Bug 248204 has been marked as a duplicate of this bug. ***
I completely forgot about this bug because I've been using 1.7.x with libdocshell.so built with the patch applied. As a result, ff 1.0 was released with this problem, which is rather unfortunate for Korean users (one of top sites is rendered very hard to navigate due to this bug). I wanted to put up a 'hot fix' for them (i.e. docshell so/dll/dylib), but firefox distribution has that dll/so/dylib along with many other dll/so/dylib's folded into the main firefox binary (firefox-bin on linux) making it impossible(?)/hard to replace only docshell. I'm wondering if any session history regression has been reported since the patch went into the trunk.If not, one of two bz's conditions for branch landing would be met.
I'm not actually aware of any regressions that have been reported since this was checked in. I'm not sure how far that carries given the ridiculously low amount of testing trunk has been getting (major and obvious regression issues have been taking weeks to report...)
*** Bug 292881 has been marked as a duplicate of this bug. ***
Component: History: Session → Document Navigation
QA Contact: history.session → docshell
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: