3

Disclaimer before the uppity types start in: This is not to be deployed "in the wild". This is for local, personal use by a Chrome add-on only. I am not trying trick visitors to my sites or do anything else unsavory. I've seen a bit of chastising of those wanting to hook onbeforeunload.

Some Background

Far and away my biggest gripe with Chrome (at least on Mac OS) is its tab close buttons which, when I have several tabs open (as I usually do), results in my frequently closing tabs unintentionally as the tabs themselves become fairly small and thus the click target area that isn't covered by the tab close button is very small. On certain tabs with news stories, blog posts, documentation, etc. it's annoying but not a huge inconvenience. I just CMD+T to reopen the tab and there's no real harm done. However, certain tabs, in particular Gmail, have definite downsides to being closed. I frequently have one or more chat dialogs with coworkers open and reopening a tab does not restore the chat dialog, and initiating a new chat loses me the current chat history (yes, it's saved, but it's not conveniently accessible by scrolling backwards in context). There are a handful of requests for Google to add the option to simply remove tab close buttons (I prefer to use CMD+W myself), but I'm not holding my breath on that.

A Partial Solution

A while back a friend pointed me towards the dotJS Chrome add-on which allows per-domain custom JavaScript execution, akin to GreaseMonkey, but slightly different. At any rate, it gave me a means to "fix" issues/wants on a number of sites I visit regularly, and I've found it to be very helpful thus far. The other day it occurred to me that I could probably keep my Gmail, et al tab(s) open with a bit of JavaScript. I threw together a small script that based on a regular expression would prompt you before closing a tab. The gist of the code is as follows:

var unloadHandler = function(e) {
    if (/(mail.google.com|google.com\/reader|gmail.com)/.test(location)) {
        return 'Are you sure you want to close: ' + location.host;
    }
};

window.onbeforeunload = unloadHandler;

Lo and behold, this did the trick for most of the sites I tried it on; except one: Gmail. Let me correct that: it worked, insofar as it prompted me to confirm the closing of the Gmail tab, and if I opted to not close it, it would keep the tab open, but before the dialog prompted me, the page had gone completely white. Element inspector shows that the markup is all still there (so far as I can tell), and the styles on the elements shouldn't be hiding things (i.e. display: none; visibility: hidden; etc) and the elements' positioning is still correct (e.g. they're within the viewable area). I went through one-by-one removing elements to see if anything was obscuring the Gmail interface, but was never able to reveal it on screen. I cannot for the life of me figure out what's going on. I'm not sure if Gmail is hooked into some event I'm unaware of (an on*before*beforeunload?), or if Google's browser is doing something special with their Gmail page, or what is causing the strange behavior. Google Reader is unaffected by this oddity (I can prevent close and retain the contents of the page) as are all of the other sites I've tested with.

Does anyone know what might be causing this issue?

For the record, I am running the following: Mac OS X 10.6.5, Google Chrome 10.0.648.205, and dotJS 1.3.

I appreciate any feedback, but I am not looking for solutions that involve: pinning tabs, changing my workflow/usage (e.g. not selecting tabs with the mouse), etc. I really want to figure out what, specifically, Gmail (or perhaps Chrome?) is doing that is sabotaging my efforts here. Thanks in advance.

Ben
  • 51,770
  • 36
  • 127
  • 149
theraccoonbear
  • 4,283
  • 3
  • 33
  • 41
  • It is possible that gmail hooks into onbeforeunload. Even if you hook into the same event, gmail's handler will still be called, especially if it is first in the list. I'm not sure if it is possible to guarantee that your handler will be called first, and if so, if you can stop the event. onbeforeunload tends to be handled differently than other events. Not sure if you can try to remove existing onbeforeunload handlers on the page so only yours is executed. – ewh Apr 30 '11 at 16:58

1 Answers1

2

I think Gmail's own code causes this behavior. I can reproduce your problem (on linux machine) with subscribing for this event from the console with this function

window.onbeforeunload = function(e) {
    return "Hey what\'s wrong with you?!";
};

After it I've started the developer tool profiler, the last call after closing the window (and choose the 'stay on this page' answer for the question) is a removeChild function call, which removes some content from the <iframe id="canvas_frame" />. So the content elements are not there anymore.

function Fc(b) {
    return b && b.parentNode ? b.parentNode.removeChild(b) : m
}

I've found some 'traces' in the obfuscated code for subscribing for the beforeunload event, but it's hard to be sure :)

function It(b, a) {
    this.Qc = jCa++;
    this.ea = b;
    this.ka = new J(this);
    this.Qa = a;
    this.Ka = [];
    this.Za = !1;
    this.ka.ya(this.ea, "unload", this.Da);
    this.ka.ya(this.ea, "beforeunload", this.ab);
    Ypa(Zd(a), this);
    this.ia()
}

I tried to reproduce this behavior in Firefox but I think google ships different javascript codes for different browsers so I can't reproduce it.

szaboat
  • 593
  • 3
  • 11