Bug 1194897 - [e10s] window.[location|menu|personal|status|tool]bar.visible is always false
Interesting...
Alice0775 White has attached a test case from digg. Let me see if I can reduce this down even further.
Here's the (unminimized) event handler on the link that's causing the issue:
function v(e) {
var r = 'http://api.digg.com/api/v3/redirect',
i = $(this).closest(a),
s = i.data('contentId'),
o = i.data('position'),
u = t.user.get('user_id'),
f = n.get('frontend.auid'),
l = i.data('source'),
c = {
url: this.href
};
s && (c.content_id = s),
u ? c.user_id = u : f && (c.auid = f),
l && (c.source = l),
o != null && (c.position = o),
navigator.mozApps && window.locationbar.visible === !1 && (c.platform = 1005, window.open([r,
$.param(c)].join('?')));
if (p === 'mobile') c.platform = 1005,
window.location.href = [
r,
$.param(c)
].join('?');
else {
if (this.target !== '_blank') return;
window.open([r,
$.param(c)].join('?'))
}
return !1
}
So I think I can probably reduce this even further - add an event
handler to a link, call window.open twice in it, and stopPropagation /
preventDefault the event.
Let's test.
Ahhhh - I see what's going on. In e10s, a content window gets
window.locationbar.visible as false, so we do that first window.open, as
well as the later window.open (since we're not on mobile).
Huh… for some reason, on digg, window.locationbar.visible is false… on other sites it's true. What?
So with e10s, in the content process, the chrome flags on the
nsIWebBrowserChrome that's retrieved in the LocationBar props thing are:
0b00000000000001000000000000000000 = 262144
Whoa, what? Where are the default chrome flags here?
Uhhh...
What's the normal return value?
0b10000000000000000000111111111110 = 2147487742
Well shit, there's your problem right there.
So where are we getting this chrome flags from?
Uh… interesting. So the mChromeFlags on the TabChild are:
0b00000000000000000111111111111111 = 32767
And that IS where we're supposed to be getting the chrome flags from.
So somehow, we're getting broken when attempting to get the chromeFlags
from the TabChild. Whoaaaa...
I wonder where I got that 32767 from the TabChild from, because running
with a debug build, I get 262144 constantly. Spooky. Probably some kind
of weird optimization confused lldb?
Anyhow, I see what's gone wrong now. Here's the code that spawns the
TabParent / TabChild when I open a new tab from the parent process:
if
(constructorSender) {
uint32_t chromeFlags = 0 ;
nsCOMPtr < nsILoadContext > loadContext = do_QueryInterface(docShell);
if (loadContext && loadContext -> UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome :: CHROME_PRIVATE_WINDOW;
}
bool affectLifetime;
docShell -> GetAffectPrivateSessionLifetime( & affectLifetime);
if (affectLifetime) {
chromeFlags |= nsIWebBrowserChrome :: CHROME_PRIVATE_LIFETIME;
}
if (tabId == 0 ) {
return nullptr;
}
nsRefPtr < TabParent > tp( new TabParent(constructorSender, tabId,
aContext, chromeFlags));
tp -> SetInitedByParent();
tp -> SetOwnerElement(aFrameElement);
PBrowserParent * browser = constructorSender -> SendPBrowserConstructor(
// DeallocPBrowserParent() releases this ref.
tp.forget().take(),
tabId,
aContext.AsIPCTabContext(),
chromeFlags,
constructorSender -> ChildID(),
constructorSender -> IsForApp(),
constructorSender -> IsForBrowser());
uint32_t chromeFlags = 0 ;
nsCOMPtr < nsILoadContext > loadContext = do_QueryInterface(docShell);
if (loadContext && loadContext -> UsePrivateBrowsing()) {
chromeFlags |= nsIWebBrowserChrome :: CHROME_PRIVATE_WINDOW;
}
bool affectLifetime;
docShell -> GetAffectPrivateSessionLifetime( & affectLifetime);
if (affectLifetime) {
chromeFlags |= nsIWebBrowserChrome :: CHROME_PRIVATE_LIFETIME;
}
if (tabId == 0 ) {
return nullptr;
}
nsRefPtr < TabParent > tp( new TabParent(constructorSender, tabId,
aContext, chromeFlags));
tp -> SetInitedByParent();
tp -> SetOwnerElement(aFrameElement);
PBrowserParent * browser = constructorSender -> SendPBrowserConstructor(
// DeallocPBrowserParent() releases this ref.
tp.forget().take(),
tabId,
aContext.AsIPCTabContext(),
chromeFlags,
constructorSender -> ChildID(),
constructorSender -> IsForApp(),
constructorSender -> IsForBrowser());
return
TabParent
::
GetFrom(browser);
And notice that I start with blank chromeFlags and only flip the
CHROME_PRIVATE_WINDOW and CHROME_PRIVATE_LIFETIME bits. Ah hah...
4:41 PM
<
mconley
> smaug: I'm working on bug 1194897. It looks like when we
create new remote browsers, we pass down an extremely minimal
chromeFlags that doesn't include information on what toolbars are
visible
4:41 PM
<
mconley
> smaug: the solution I'm considering is somehow grabbing the
root docshell, GetInterface'ing the nsIWebBrowserChrome, getting at the
chrome flags, and copying the chromeFlags over
4:42 PM
<
mconley
> however, I'm wary of doing that in
ContentParent::CreateBrowserOrApp, since my approach is pretty Firefox
Desktop specific
4:42 PM
<
mconley
> and from what I'm reading here,
ContentParent::CreateBrowserOrApp is used by B2G and probably other
stuff that doesn't necessarily know or care about nsIWebBrowserChrome
4:42 PM
<
mconley
> any advice on how best to proceed?
4:45 PM
<
smaug
> ...back
4:47 PM
<
smaug
> mconley: so, there sure should be nsIWebBrowserChrome available in b2g too
4:47 PM
<
mconley
> oh! That's interesting
4:47 PM
<
smaug
> given that nsContentTreeOwner inherits it
4:47 PM
<
mconley
> and the root docshell will be able to GetInterface to it?
4:49 PM
<
smaug
> mconley: or get treeowner from any docshell
4:50 PM
<
smaug
> and QI that
4:50 PM
<
mconley
> ah hah
4:50 PM
<
mconley
> smaug: so is my plan advisable - to get at the nsIWebBrowserChrome and copy its chromeFlags?
4:50 PM
<
smaug
> hmm, does only nsContentTreeOwner extend nsIWebBrowserChrome
4:50 PM
<
smaug
> sounds ok
4:51 PM
<
mconley
> smaug: both nsChrome/nsContentTreeOwner know how to GetInterface to an nsIWebBrowserChrome, so I think I'm okay
4:51 PM
<
mconley
> smaug: thanks!
Renamed bug
from Bug 1194897 - [e10s] Clicking a link on digg.com with e10s enabled yields two tabs
to Bug 1194897 - [e10s] window.[location|menu|personal|status|tool]bar.visible is always false.
File a bug to add some tests for this. Filed
https://bugzilla.mozilla.org/show_bug.cgi?id=1210482