mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
249 lines
8.9 KiB
JavaScript
249 lines
8.9 KiB
JavaScript
|
// Test for bug 343515 - Need API for tabbrowsers to tell docshells they're visible/hidden
|
||
|
|
||
|
// Globals
|
||
|
var testPath = "http://mochi.test:8888/browser/docshell/test/navigation/";
|
||
|
var Ci = Components.interfaces;
|
||
|
var Cc = Components.classes;
|
||
|
var ctx = {};
|
||
|
|
||
|
// Helper function to check if a window is active
|
||
|
function isActive(aWindow) {
|
||
|
var docshell = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||
|
.getInterface(Ci.nsIWebNavigation)
|
||
|
.QueryInterface(Ci.nsIDocShell);
|
||
|
return docshell.isActive;
|
||
|
}
|
||
|
|
||
|
// Returns a closure that will remove itself as a listener from
|
||
|
// aElem and then call aCallback. aCallback is executed asynchronously,
|
||
|
// which is handy because load events fire before mIsDocumentLoaded is actually
|
||
|
// set to true. :(
|
||
|
function autoRemovedListener(aElem, aType, aCallback) {
|
||
|
|
||
|
var elem = aElem;
|
||
|
var type = aType;
|
||
|
var callback = aCallback;
|
||
|
|
||
|
function remover() {
|
||
|
elem.removeEventListener(type, remover, true);
|
||
|
executeSoon(callback);
|
||
|
}
|
||
|
|
||
|
return remover;
|
||
|
}
|
||
|
|
||
|
// Returns a closure that iteratively (BFS) waits for all
|
||
|
// of the descendant frames of aInitialWindow to finish loading,
|
||
|
// then calls aFinalCallback.
|
||
|
function frameLoadWaiter(aInitialWindow, aFinalCallback) {
|
||
|
|
||
|
// The window we're currently waiting on
|
||
|
var curr = aInitialWindow;
|
||
|
|
||
|
// The windows we need to wait for
|
||
|
var waitQueue = [];
|
||
|
|
||
|
// The callback to call when we're all done
|
||
|
var finalCallback = aFinalCallback;
|
||
|
|
||
|
function frameLoadCallback() {
|
||
|
|
||
|
// Push any subframes of what we just got
|
||
|
for (var i = 0; i < curr.frames.length; ++i)
|
||
|
waitQueue.push(curr.frames[i]);
|
||
|
|
||
|
// Handle the next window in the queue
|
||
|
if (waitQueue.length >= 1) {
|
||
|
curr = waitQueue.shift();
|
||
|
if (curr.document.readyState == "complete")
|
||
|
frameLoadCallback();
|
||
|
else
|
||
|
curr.addEventListener("load", autoRemovedListener(curr, "load", frameLoadCallback), true);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// Otherwise, we're all done. Call the final callback
|
||
|
finalCallback();
|
||
|
}
|
||
|
|
||
|
return frameLoadCallback;
|
||
|
}
|
||
|
|
||
|
// Entry point from Mochikit
|
||
|
function test() {
|
||
|
|
||
|
// Lots of callbacks going on here
|
||
|
waitForExplicitFinish();
|
||
|
|
||
|
// Begin the test
|
||
|
step1();
|
||
|
}
|
||
|
|
||
|
function step1() {
|
||
|
|
||
|
// Get a handle on the initial tab
|
||
|
ctx.tab0 = gBrowser.selectedTab;
|
||
|
ctx.tab0Browser = gBrowser.getBrowserForTab(ctx.tab0);
|
||
|
ctx.tab0Window = ctx.tab0Browser.contentWindow;
|
||
|
|
||
|
// Our current tab should be active
|
||
|
ok(isActive(ctx.tab0Window), "Tab 0 should be active at test start");
|
||
|
|
||
|
// Open a New Tab
|
||
|
ctx.tab1 = gBrowser.addTab(testPath + "bug343515_pg1.html");
|
||
|
ctx.tab1Browser = gBrowser.getBrowserForTab(ctx.tab1);
|
||
|
ctx.tab1Window = ctx.tab1Browser.contentWindow;
|
||
|
ctx.tab1Browser.addEventListener("load",
|
||
|
autoRemovedListener(ctx.tab1Browser, "load", step2),
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
function step2() {
|
||
|
|
||
|
// Our current tab should still be active
|
||
|
ok(isActive(ctx.tab0Window), "Tab 0 should still be active");
|
||
|
ok(!isActive(ctx.tab1Window), "Tab 1 should not be active");
|
||
|
|
||
|
// Switch to tab 1
|
||
|
gBrowser.selectedTab = ctx.tab1;
|
||
|
|
||
|
// Tab 1 should now be active
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(isActive(ctx.tab1Window), "Tab 1 should be active");
|
||
|
|
||
|
// Open another tab
|
||
|
ctx.tab2 = gBrowser.addTab(testPath + "bug343515_pg2.html");
|
||
|
ctx.tab2Browser = gBrowser.getBrowserForTab(ctx.tab2);
|
||
|
ctx.tab2Window = ctx.tab2Browser.contentWindow;
|
||
|
ctx.tab2Browser.addEventListener("load",
|
||
|
autoRemovedListener(ctx.tab2Browser, "load",
|
||
|
frameLoadWaiter(ctx.tab2Window, step3)),
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
function step3() {
|
||
|
|
||
|
// Tab 0 should be inactive, Tab 1 should be active
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(isActive(ctx.tab1Window), "Tab 1 should be active");
|
||
|
|
||
|
// Tab 2's window _and_ its iframes should be inactive
|
||
|
ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive");
|
||
|
is(ctx.tab2Window.frames.length, 2, "Tab 2 should have 2 iframes");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive");
|
||
|
|
||
|
// Navigate tab 2 to a different page
|
||
|
ctx.tab2Window.location = testPath + "bug343515_pg3.html";
|
||
|
ctx.tab2Browser.addEventListener("load",
|
||
|
autoRemovedListener(ctx.tab2Browser, "load",
|
||
|
frameLoadWaiter(ctx.tab2Window, step4)),
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
function step4() {
|
||
|
|
||
|
// Tab 0 should be inactive, Tab 1 should be active
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(isActive(ctx.tab1Window), "Tab 1 should be active");
|
||
|
|
||
|
// Tab2 and all descendants should be inactive
|
||
|
ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive");
|
||
|
is(ctx.tab2Window.frames.length, 2, "Tab 2 should have 2 iframes");
|
||
|
is(ctx.tab2Window.frames[0].frames.length, 1, "Tab 2 iframe 0 should have 1 iframes");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive");
|
||
|
|
||
|
// Switch to Tab 2
|
||
|
gBrowser.selectedTab = ctx.tab2;
|
||
|
|
||
|
// Check everything
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab1Window), "Tab 1 should be inactive");
|
||
|
ok(isActive(ctx.tab2Window), "Tab 2 should be active");
|
||
|
ok(isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be active");
|
||
|
ok(isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be active");
|
||
|
ok(isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be active");
|
||
|
|
||
|
// Go back
|
||
|
ctx.tab2Browser.addEventListener("pageshow",
|
||
|
autoRemovedListener(ctx.tab2Browser, "pageshow",
|
||
|
frameLoadWaiter(ctx.tab2Window, step5)),
|
||
|
true);
|
||
|
ctx.tab2Browser.goBack();
|
||
|
|
||
|
}
|
||
|
|
||
|
function step5() {
|
||
|
|
||
|
// Check everything
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab1Window), "Tab 1 should be inactive");
|
||
|
ok(isActive(ctx.tab2Window), "Tab 2 should be active");
|
||
|
ok(isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be active");
|
||
|
ok(isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be active");
|
||
|
|
||
|
// Switch to tab 1
|
||
|
gBrowser.selectedTab = ctx.tab1;
|
||
|
|
||
|
// Navigate to page 3
|
||
|
ctx.tab1Window.location = testPath + "bug343515_pg3.html";
|
||
|
ctx.tab1Browser.addEventListener("load",
|
||
|
autoRemovedListener(ctx.tab1Browser, "load",
|
||
|
frameLoadWaiter(ctx.tab1Window, step6)),
|
||
|
true);
|
||
|
}
|
||
|
|
||
|
function step6() {
|
||
|
|
||
|
// Check everything
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(isActive(ctx.tab1Window), "Tab 1 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[0]), "Tab1 iframe 0 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[1]), "Tab1 iframe 1 should be active");
|
||
|
ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive");
|
||
|
|
||
|
// Go forward on tab 2
|
||
|
ctx.tab2Browser.addEventListener("pageshow",
|
||
|
autoRemovedListener(ctx.tab2Browser, "pageshow",
|
||
|
frameLoadWaiter(ctx.tab2Window, step7)),
|
||
|
true);
|
||
|
var tab2docshell = ctx.tab2Window.QueryInterface(Ci.nsIInterfaceRequestor)
|
||
|
.getInterface(Ci.nsIWebNavigation);
|
||
|
tab2docshell.goForward();
|
||
|
}
|
||
|
|
||
|
function step7() {
|
||
|
|
||
|
ctx.tab2Window = ctx.tab2Browser.contentWindow;
|
||
|
|
||
|
// Check everything
|
||
|
ok(!isActive(ctx.tab0Window), "Tab 0 should be inactive");
|
||
|
ok(isActive(ctx.tab1Window), "Tab 1 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[0]), "Tab1 iframe 0 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[0].frames[0]), "Tab1 iframe 0 subiframe 0 should be active");
|
||
|
ok(isActive(ctx.tab1Window.frames[1]), "Tab1 iframe 1 should be active");
|
||
|
ok(!isActive(ctx.tab2Window), "Tab 2 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0]), "Tab2 iframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[0].frames[0]), "Tab2 iframe 0 subiframe 0 should be inactive");
|
||
|
ok(!isActive(ctx.tab2Window.frames[1]), "Tab2 iframe 1 should be inactive");
|
||
|
|
||
|
// That's probably enough
|
||
|
allDone();
|
||
|
}
|
||
|
|
||
|
function allDone() {
|
||
|
|
||
|
// Close the tabs we made
|
||
|
gBrowser.removeCurrentTab();
|
||
|
gBrowser.tabContainer.advanceSelectedTab(1, true);
|
||
|
gBrowser.removeCurrentTab();
|
||
|
|
||
|
// Tell the framework we're done
|
||
|
finish();
|
||
|
}
|