Page MenuHomePhabricator

Vector EditWarning breaks page caching. Edits get erased when navigating back and forth
Closed, DeclinedPublic

Description

Navigable TOC / Wiki-Editor break page caching, probably by using an "unload" event, in Firefox (and probably other browsers too).

For details please see https://developer.mozilla.org/En/Using_Firefox_1.5_caching

Essentially, page caching saves javascript states and iframe contents so that accidentally navigating away from a page and coming back does not erase the edits by reloading the page.

Unfortunately, registering an unload event handler breaks this caching. The "pagehide" should be used in browsers that support caching instead of the "unload" event.

If page caching is used when leaving a page can be tested in the "pagehide" event handler with "event.persisted == true".


Version: 1.17.x
Severity: major

Details

Reference
bz22680

Event Timeline

bzimport raised the priority of this task from to High.Nov 21 2014, 11:09 PM
bzimport set Reference to bz22680.

This is actually to do with the Vector/EditWarning extension's use of the onbeforeunload handler.

What is the use-case where users loose information by leaving the page and returning without being warned? The Vector/EditWarning extension is designed to provide notice that you will loose changes if you leave.

Ironically, it seems to be the message that warns about the caching problems which breaks the page caching ;-)

wikEd users complain that they lose their edit page state upon navigating back and forth (or forth and back), i.e. when you come back, the editor completely reloads from scratch with the original text and all edits are lost. Without cache breaking you simply continue editing where you left the page.

Also, all dynamically loaded images and scripts seem to get lost regularly and will then be reloaded from the server which takes a while.

I think it should be possible to use the pagehide event instead of the onbeforeunload for your purposes if it is available.

And you might not need the message at all if the caching works.

For details please see https://developer.mozilla.org/En/Using_Firefox_1.5_caching

Pagehide fires before unload, like the beforeunload event, and allows you to stop the page leave.

In the pagehide handler you can test if the page will not be cached with "event.persisted != true", e.g. to display the warning.

(In reply to comment #4)

For details please see
https://developer.mozilla.org/En/Using_Firefox_1.5_caching

Pagehide fires before unload, like the beforeunload event, and allows you to
stop the page leave.

Actually, no, it doesn't allow you to stop anything. I've tried using event.preventDefault() and return false in a pagehide handler in Firefox 3.6, and they don't have any effect. The HTML 5 spec draft that includes the pagehide event also explicitly says it's uncancelable.

Also, the documentation you link to says hooking the unload event breaks caching, but we only use the *before*unload event, which isn't mentioned. In fact, page caching seems to work fine for me: on a regular edit page, the content of the textarea is restored after clicking OK in the edit warning and going back.

If wikEd has issues with this despite all that, it should probably disable EditWarning. This is not cleanly possible just yet, but will be soon per bug 23807.

I just found this tweet https://twitter.com/kangax/status/4057887867:

onbeforeunload invalidates page cache in FF3.5, BUT null'ing onbeforeunload in handler itself turns page cache back on. Nice... 9:49 AM Sep 17th, 2009 via Twitterrific kangax

(In reply to comment #6)

I just found this tweet https://twitter.com/kangax/status/4057887867:

onbeforeunload invalidates page cache in FF3.5, BUT null'ing onbeforeunload
in handler itself turns page cache back on. Nice... 9:49 AM Sep 17th, 2009 via
Twitterrific kangax

Thank God for Twitter :)

I will implement this tomorrow.

Created attachment 7434
Testcase for cache breaking by onbeforeunload

The tweet was right, removeEventListener in the handler prevents the cache invalidation. Here is simple test case for experimenting.

Attached:

Just be creative in finding a way to reinstate your onbeforeunload handler when you come back to that page :-)

Created attachment 7435
Fixed testcase for cache breaking by onbeforeunload

You can use the pageshow event to reinstate the beforeunload event, see for the working testcase for details.

Attached:

Thank you for digging up this trick. Fixed in r68229.

Cache invalidation happens again, leading to lost edits on page navigation and time consuming reloads of images and other elements with every page load. Therefore I have reopened this bug.

This time it happens on en-WP under vector but with all beta features and obviously script-related preference settings including gadgets disabled.

Maybe it is this one?

Line 3022 in http://bits.wikimedia.org/w/extensions/UsabilityInitiative/js/plugins.combined.js?283 (code after "// Attach our own handler for onbeforeunload which respects the current one").

Also happens under monobook. There seem to be unload events in jquery.js?283s.

Happens on all pages, including those that neither Vector nor UsabilityInitiative is on. Could be a bug in jQuery I guess.

I recall this had to do with the fact that we were wrapping the textarea, which essentially removes/adds it.

(In reply to comment #16)

I recall this had to do with the fact that we were wrapping the textarea, which
essentially removes/adds it.

No, that's not the same issue, as this bug occurs with WikiEditor disabled as well.

What's happening is that something, somewhere is either setting an onunload, which will disable bfcache no matter what, or setting an unbeforeunload without cleaning up after themselves properly (which is what EditWarning used to do before I fixed it).

jQuery(window).bind('unload',function(){for(var id in jQuery.cache) etc

sounds like a candidate to me.

Still happening on Wikipedia. This causes big problem for editors (lost edits) and low-bandwidth users (probably lots of extra traffic).

(In reply to comment #18)

jQuery(window).bind('unload',function(){for(var id in jQuery.cache) etc

sounds like a candidate to me.

That one did turn out to be one of the culprits, yes. The code inside the unload handler is only needed in IE, and jQuery 1.4 is smart enough to actually only bind the handler in IE. There was a second such occurrence in jquery.stars.js from the ArticleAssessmentPilot extension, which I fixed in r74267.

The fix for jquery.stars went live just now. I will migrate Wikimedia to jQuery 1.4.2 on Monday Oct 11 per bug 25419.

Migrating to 1.4.2 seems to have fixed the issue for me (Firefox 3.6.10) in most cases. Going back and forth between normal pages as well as unchanged edit pages uses bfcache just fine.

The only case in which bfcache still breaks (due to a bug in EditWarning that's gonna be hard to fix) is when the edit warning pops up and you click OK. However, bfcache only breaks in the sense that the page is reloaded; the edited text is stil there. This is not totally ideal, but I seriously don't know how we could do better. The bug as filed has been fixed (reloading of pages only occurs in one specific case, and edits don't get erased anymore), so I'm closing this bug.

Once again, this problem is back and presents a major problem: the complete edit gets lost when (accidentally) navigating away and back to an edit page.

(In reply to comment #22)

Once again, this problem is back and presents a major problem: the complete
edit gets lost when (accidentally) navigating away and back to an edit page.

This problem appears on all pages, not just edit pages. It also only appears on enwiki but not on mediawikiwiki or nlwiki, so it's probably a local JS issue. I'll try to see if I can discover what's causing it.

I've nailed it down to the WikiMiniAtlas script.

One of the criteria for disabling bfcache that's mentioned in the documentation is "the top-level page contains frames that are not cacheable". WMA inserts an invisible, empty <iframe> on every page view, and I've confirmed that removing the iframe in Firebug fixes the bfcache problem.

I'm not sure how WMA can insert the iframe in a way that won't break bfcache (maybe remove it in an onbeforeunload hook?), but inserting it when needed instead of inserting an empty, invisible one unconditionally on page load would go a long way.

Re-closing as FIXED because this incarnation of the bug is not in MediaWiki, but in WikiMiniAtlas.

Oh, and thanks for figuring this out!

Once again, this problem is back and presents a major problem: the complete
edit gets lost when (accidentally) navigating away and back to an edit page. WMA has been fixed April 2011 as far as I can tell.

(In reply to comment #27)

Once again, this problem is back and presents a major problem: the complete
edit gets lost when (accidentally) navigating away and back to an edit page.
WMA has been fixed April 2011 as far as I can tell.

I can't reproduce this in Firefox 11.0. Can you reproduce this when logged out? If not, it's very probably another Gadget or user script causing this.

This bug is still there. I can reproduce it with all gadgets disabled and when being logged out (running wikEd from Greasemonkey). It does, however, not happen when using the standard textarea.

I am wondering if there is a textarea recovering script running in Mediawiki that masks the bug. Any idea?

Actually, this seems to be a Firefox bug. I will keep you updated.

That report was closed as WFM, linking to http://support.ant.com/requests/6520 as the culprit, but that's behind a login-wall for me. What's the status of this?

It is a bug in the Firefox addon Ant downloader and they are still working on a fix. Changed Status to Resolved, Worksforme