Open Bug 638493 Opened 13 years ago Updated 2 years ago

Calling window.close() from inside a chromeTab should close the tab

Categories

(Thunderbird :: Toolbars and Tabs, defect)

defect

Tracking

(Not tracked)

ASSIGNED

People

(Reporter: protz, Assigned: protz)

Details

Running window.close() from inside a chromeTab doesn't close the tab anymore. I just tested with a contentTab and it doesn't work anymore as well.

The code is here http://mxr.mozilla.org/comm-central/source/mail/base/content/specialTabs.js#965

sid, while I was writing the tests for the spellchecker context menu in content tabs, there was at the bottom of test-content-tabs.js a comment saying:

// TODO
// - window.close() from contentTab

which is why I wrote the extra test, but your told me in https://bugzilla.mozilla.org/show_bug.cgi?id=626076#c4 that you thought we had "plenty of tests for this". Actually, I don't think we have any tests or that would've been spotted before. I'd like to be proved wrong, though :-).

The test I initially wrote fired window.close through "the outside", by accessing the content tab's inner window object through the tabmail. I could not get it to work by inserting a fake <a onclick="window.close();"> inside the content tab and then clicking on it through mozmill. There's probably something going wrong with the event.isTrusted check we make before actually closing the tab.

I'm taking this, but any comments/thoughts would be highly appreciated :-), especially on the rationale for isTrusted.

CCing relevant people who seem to have been working on this.
(In reply to comment #0)
> 
> which is why I wrote the extra test, but your told me in
> https://bugzilla.mozilla.org/show_bug.cgi?id=626076#c4 that you thought we had
> "plenty of tests for this". Actually, I don't think we have any tests or that
> would've been spotted before.

Hahaha, ouch, you're right -- I was probably thinking of window.close tests in general.
Heh no problem. It's just clear now I'll have to write tests for that :-). Right now I'm kind of confused as to why the DOMWindowClose event does not fire...
So the thing is, Firefox has a policy for *content* that says: « if page A is calling window.close(), unless page A has been opened by a call to window.open("pageA"), calling window.close() will do nothing ». That seems alright.

However, *chrome* code should be able to close itself, i.e. running window.close() from chrome://myext/content/myChromePage.html should actually close the tab. It does not, and the DOMWindowClose event is not even fired.

You can try this out in your Thunderbird by running the line below:

Components.classes['@mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator).getMostRecentWindow("mail:3pane").document.getElementById("tabmail").openTab("chromeTab", {chromePage: 'data:text/html,<a href="http://" onclick="dump(\'xxxxx\\n\'); window.close(); return false">hello</a>'});

This opens a new chrome tab with a link inside. The link, when clicked, will dump (to check that it actually does something) then run window.close(). Nothing will happen.

:asuth, any ideas about that?
Summary: Calling window.close() from inside a chromeTab or a contentTab is broken → Calling window.close() from inside a chromeTab should close the tab
Using the test command in comment 3,

Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1pre) Gecko/20090928 Shredder/3.1a1pre

Nothing happens when "Evaluate" is pressed

Miramar 3.3 Alpha 2 as well as:
Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.3a1pre) Gecko/20090929 Shredder/3.1a1pre

Dumped: (Tab is not closed when link is clicked)
[object Object]

May be related to bug 519041?

http://hg.mozilla.org/comm-central/pushloghtml?startdate=2009-09-28+03%3A00&enddate=2009-09-29+03%3A00
http://hg.mozilla.org/mozilla-central/pushloghtml?startdate=2009-09-28+03%3A00&enddate=2009-09-29+03%3A00
Gary, I think 20090928 is around the time the tabbrowser first started to work properly in Thunderbird. So it looks like this never actually worked in the first place, this being "a chrome tab should be able to close itself by calling window.close()".
function closeTab() {
  let browser = window.frameElement;
  let tabmail = window.top.document.getElementById("tabmail");
  let tabs = tabmail.tabInfo;
  let candidates = tabs.filter(function (x) x.browser == browser);
  if (candidates.length == 1) {
    tabmail.closeTab(candidates[0]);
  } else {
    Log.error("Couldn't find a tab to close...");
  }
}

Now I'm using the function above to efficiently close myself from inside a chrome tab. Maybe we could just add a line into specialTabs.js that injects this function into the freshly loaded chrome tab, in lieu of the default close action? That seems like a huge hack, but I'm afraid I have no better solution to offer, and I'm not skilled enough to determine why the DOMWindowClose event should fail to propagate.
Boris, do you have any hint as to why this might be failing? It sounds to me like this is related to the docshell, but I'm not very familiar with that area of the code. Thanks!
> Boris, do you have any hint as to why this might be failing?

I'm missing a lot of context here, but window.close() on an nsGlobalWindow can be a no-op for the following reasons:

1)  The window is already closed or is in the middle of being closed.
2)  The window has a modal dialog parented to it
3)  The window is a subframe (this includes any <iframe> or <browser> in chrome
    that does not have a type equal to "content" or starting with "content-").
4)  The window did not have an opener and the caller is not trusted for write.
5)  An onbeforeunload event handler prevents the close.

My best guess based on the bug summary is that you're hitting item 3 above.  Is that the case?  If not, the next most likely one is probably item 5 if the caller is chrome....
Thanks for your input. This is indeed a chrome <browser> inside the main (chrome) Thunderbird window. Any ideas how to properly solve the issue, or should we stick with the workaround I described in comment #6?
> Any ideas how to properly solve the issue

The cleanest way is probably to have a way in chrome to flag chrome sub-docshells as "not actually a subframe".
This seems to be out of my expertise area, so I'll stick with the workaround. I may look into it one day, though... thanks for the guidance Boris.
At least file a bug on making that happen?  Seems like it would matter to others too (esp. as we move to having real chrome tabs in tabbrowser).
in fact, type="chrome-tab" might be one way to expose the XUL interface to it....

Was such a bug filed?
Is this something other add-ons would be keen to utilize?

(In reply to Jonathan Protzenko [:protz] from comment #11)

This seems to be out of my expertise area, so I'll stick with the
workaround. I may look into it one day, though... thanks for the guidance
Boris.

(In reply to Boris Zbarsky [:bzbarsky, bz on IRC] from comment #12)

At least file a bug on making that happen? Seems like it would matter to
others too (esp. as we move to having real chrome tabs in tabbrowser).

Flags: needinfo?(jonathan.protzenko)

I have absolutely no recollection of this, sorry, but I don't think I filed a fresh bug.

Flags: needinfo?(jonathan.protzenko)
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.