Open Bug 698360 Opened 13 years ago Updated 2 years ago

on back, "load" event fires for a bfcached doc and persisted state is misreported in the "pageshow" event

Categories

(Core :: DOM: Navigation, defect)

x86
Windows XP
defect

Tracking

()

People

(Reporter: al_9x, Unassigned)

Details

Please use Fx8.0b5 to repro. The problem exists on trunk, but it's not as clear that the dom is cached because the image I am inserting onload does not show (maybe something is wrong with my error console code, what?).

1. start with new profile, one window, one tab
2. open the error console, show only errors
3. eval the following code:
___________________________________________________
var tb = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser').gBrowser; tb.addEventListener('DOMContentLoaded', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type);}, true); tb.addEventListener('load', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type); var doc = e.target; document.body.insertBefore(document.createElement('IMG'), document.body.firstChild).src = 'http://www.google.com/images/nav_logo91.png';}, true); tb.addEventListener('pageshow', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type + (e.persisted ? ' : cached' : ' : uncached'));}, true);
___________________________________________________

4. load http://www.google.com/search?q=whatever
5. click on maps
6. go back, the first time you go back, just "pageshow" fires
7. go forward and quickly back again.  When the maps page loads, the progress spinner stops, then briefly restarts again as something on the page updates.  To repro this, it's essential to go back immediately after the maps page appears, don't wait till the spinner restart.
8. now when you go back, both "load" and "pageshow" fire, and persisted is false, however the DOM is bfcached, you can see another image added and DOMContentLoaded does not fire, so load should not fire and persisted should be true
There is a mistake in my load handler, I declare a doc var (var doc = e.target) but insert the img via "document."  With this corrected, it highlights the problem as intended (Fx8 and trunk).  I think I used correct code with Fx8, but somehow introduced the problem and pasted it here with the error.  Here is the corrected code, please try it:

___________________________________________________
var tb = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser').gBrowser; tb.addEventListener('DOMContentLoaded', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type);}, true); tb.addEventListener('load', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type); var doc = e.target; doc.body.insertBefore(doc.createElement('IMG'), doc.body.firstChild).src = 'http://www.google.com/images/nav_logo91.png';}, true); tb.addEventListener('pageshow', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type + (e.persisted ? ' : cached' : ' : uncached'));}, true);
___________________________________________________
Boris, Olli,

Are you able to repro this with code from comment 1?
I can reproduce the log entries, but I haven't had a chance to look into what the long script there is doing and hence what the expected behavior is.
 (In reply to Boris Zbarsky (:bz) from comment #3)
> I can reproduce the log entries

To clarify, reproducing the bug would mean seeing 2 things when going back (quickly) from the maps page:

1. two events logged:
load
pageshow : uncached

2. two inserted images, which demonstrates that the DOM was bfcached when the second image was added

Are you seeing that?
(In reply to Boris Zbarsky (:bz) from comment #5)
> Yep.

What is you assessment, is it a bug?  The page is bfcached, so load shouldn't fire and persisted should be true in pageshow?
At first glance, something is wrong, yes.  The big question is whether it's web-visible.
(In reply to Boris Zbarsky (:bz) from comment #7)
> At first glance, something is wrong, yes.  The big question is whether it's
> web-visible.

If you're asking what happens when the load and pageshow listeners are attached to the content window (as opposed to chrome), the answer is, the same thing.  I first noticed this problem with a NoScript surrogate script, which did just that.  Here's a modified error console script which attaches load and pageshow to the content window in DOMContentLoaded:

Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser').gBrowser.addEventListener('DOMContentLoaded', function(e) {var win = e.target.defaultView; win.addEventListener('load', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type); var doc = e.target; doc.body.insertBefore(doc.createElement('IMG'), doc.body.firstChild).src = 'http://www.google.com/images/nav_logo91.png';}, false); win.addEventListener('pageshow', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type + (e.persisted ? ' : cached' : ' : uncached'));}, false); var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type);}, true);
I'm asking what happens if that script runs in the page itself, not from chrome.
a bit simplified:

Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow('navigator:browser').gBrowser.addEventListener('DOMContentLoaded', function(e) {var url = e.target.location.href; if (url !== 'http://www.google.com/search?q=whatever') return; Components.utils.reportError(e.type); var win = e.target.defaultView; win.addEventListener('load', function(e) {Components.utils.reportError(e.type); var doc = e.target; doc.body.insertBefore(doc.createElement('IMG'), doc.body.firstChild).src = 'http://www.google.com/images/nav_logo91.png';}, false); win.addEventListener('pageshow', function(e) {Components.utils.reportError(e.type + (e.persisted ? ' : cached' : ' : uncached'));}, false); }, true);
(In reply to Boris Zbarsky (:bz) from comment #9)
> I'm asking what happens if that script runs in the page itself, not from
> chrome.

NoScript has a pref to force surrogate script execution via dom based <script> element with text insertion, if it isn't that already.  So that is the page itself.

However, if you want more evidence, I've used Fiddler (proxy) to add load and pageshow handlers to the google page.  Same results.

Does that answer your question?
Yep, thanks.
So this happens only within ***.google.com ?
The key here is the page from which you go back (maps) and the timing of the back navigation, from the description:  

"When the maps page loads, the progress spinner stops, then briefly restarts again as something on the page updates.  To repro this, it's essential to go back immediately after the maps page appears, don't wait till the spinner restart."

The following local page also repros:
__________________________
<script>
addEventListener('load', function(e) {
	console.log(e.type + ' : ' + e.target.location);
	document.body.insertBefore(document.createElement('IMG'), document.body.firstChild).src = 'http://www.google.com/images/nav_logo91.png'
}, false);
addEventListener('pageshow', function(e) console.log(e.type + (e.persisted ? ' : cached : ' : ' : uncached : ') + e.target.location), false);
</script>

<a href="http://maps.google.com/maps?q=Mozilla">maps</a>
______________________________________________________________

I have not investigate what exactly the maps page is doing that helps reveal this bug, regardless, the initial page is bfcached, the timing of back should not matter.
this has been confirmed, please NEW it
Status: UNCONFIRMED → NEW
Ever confirmed: true
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.