forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			251 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			251 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* Any copyright is dedicated to the Public Domain.
 | 
						|
 * http://creativecommons.org/publicdomain/zero/1.0/ */
 | 
						|
 | 
						|
const ACTOR = "Bug422543";
 | 
						|
 | 
						|
let getActor = browser => {
 | 
						|
  return browser.browsingContext.currentWindowGlobal.getActor(ACTOR);
 | 
						|
};
 | 
						|
 | 
						|
add_task(async function runTests() {
 | 
						|
  if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
 | 
						|
    await setupAsync();
 | 
						|
    let browser = gBrowser.selectedBrowser;
 | 
						|
    // Now that we're set up, initialize our frame script.
 | 
						|
    await checkListenersAsync("initial", "listeners initialized");
 | 
						|
 | 
						|
    // Check if all history listeners are always notified.
 | 
						|
    info("# part 1");
 | 
						|
    await whenPageShown(browser, () =>
 | 
						|
      BrowserTestUtils.loadURI(browser, "http://www.example.com/")
 | 
						|
    );
 | 
						|
    await checkListenersAsync("newentry", "shistory has a new entry");
 | 
						|
    ok(browser.canGoBack, "we can go back");
 | 
						|
 | 
						|
    await whenPageShown(browser, () => browser.goBack());
 | 
						|
    await checkListenersAsync("gotoindex", "back to the first shentry");
 | 
						|
    ok(browser.canGoForward, "we can go forward");
 | 
						|
 | 
						|
    await whenPageShown(browser, () => browser.goForward());
 | 
						|
    await checkListenersAsync("gotoindex", "forward to the second shentry");
 | 
						|
 | 
						|
    await whenPageShown(browser, () => browser.reload());
 | 
						|
    await checkListenersAsync("reload", "current shentry reloaded");
 | 
						|
 | 
						|
    await whenPageShown(browser, () => browser.gotoIndex(0));
 | 
						|
    await checkListenersAsync("gotoindex", "back to the first index");
 | 
						|
 | 
						|
    // Check nsISHistory.notifyOnHistoryReload
 | 
						|
    info("# part 2");
 | 
						|
    ok(await notifyReloadAsync(), "reloading has not been canceled");
 | 
						|
    await checkListenersAsync("reload", "saw the reload notification");
 | 
						|
 | 
						|
    // Let the first listener cancel the reload action.
 | 
						|
    info("# part 3");
 | 
						|
    await resetListenersAsync();
 | 
						|
    await setListenerRetvalAsync(0, false);
 | 
						|
    ok(!(await notifyReloadAsync()), "reloading has been canceled");
 | 
						|
    await checkListenersAsync("reload", "saw the reload notification");
 | 
						|
 | 
						|
    // Let both listeners cancel the reload action.
 | 
						|
    info("# part 4");
 | 
						|
    await resetListenersAsync();
 | 
						|
    await setListenerRetvalAsync(1, false);
 | 
						|
    ok(!(await notifyReloadAsync()), "reloading has been canceled");
 | 
						|
    await checkListenersAsync("reload", "saw the reload notification");
 | 
						|
 | 
						|
    // Let the second listener cancel the reload action.
 | 
						|
    info("# part 5");
 | 
						|
    await resetListenersAsync();
 | 
						|
    await setListenerRetvalAsync(0, true);
 | 
						|
    ok(!(await notifyReloadAsync()), "reloading has been canceled");
 | 
						|
    await checkListenersAsync("reload", "saw the reload notification");
 | 
						|
 | 
						|
    function sendQuery(message, arg = {}) {
 | 
						|
      return getActor(gBrowser.selectedBrowser).sendQuery(message, arg);
 | 
						|
    }
 | 
						|
 | 
						|
    function checkListenersAsync(aLast, aMessage) {
 | 
						|
      return sendQuery("getListenerStatus").then(listenerStatuses => {
 | 
						|
        is(listenerStatuses[0], aLast, aMessage);
 | 
						|
        is(listenerStatuses[1], aLast, aMessage);
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    function resetListenersAsync() {
 | 
						|
      return sendQuery("resetListeners");
 | 
						|
    }
 | 
						|
 | 
						|
    function notifyReloadAsync() {
 | 
						|
      return sendQuery("notifyReload").then(({ rval }) => {
 | 
						|
        return rval;
 | 
						|
      });
 | 
						|
    }
 | 
						|
 | 
						|
    function setListenerRetvalAsync(num, val) {
 | 
						|
      return sendQuery("setRetval", { num, val });
 | 
						|
    }
 | 
						|
 | 
						|
    async function setupAsync() {
 | 
						|
      let tab = await BrowserTestUtils.openNewForegroundTab(
 | 
						|
        gBrowser,
 | 
						|
        "http://mochi.test:8888"
 | 
						|
      );
 | 
						|
 | 
						|
      let base = getRootDirectory(gTestPath).slice(0, -1);
 | 
						|
      ChromeUtils.registerWindowActor(ACTOR, {
 | 
						|
        child: {
 | 
						|
          moduleURI: `${base}/Bug422543Child.jsm`,
 | 
						|
        },
 | 
						|
      });
 | 
						|
 | 
						|
      registerCleanupFunction(async () => {
 | 
						|
        await sendQuery("cleanup");
 | 
						|
        gBrowser.removeTab(tab);
 | 
						|
 | 
						|
        ChromeUtils.unregisterWindowActor(ACTOR);
 | 
						|
      });
 | 
						|
 | 
						|
      await sendQuery("init");
 | 
						|
    }
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  await setup();
 | 
						|
  let browser = gBrowser.selectedBrowser;
 | 
						|
  // Now that we're set up, initialize our frame script.
 | 
						|
  checkListeners("initial", "listeners initialized");
 | 
						|
 | 
						|
  // Check if all history listeners are always notified.
 | 
						|
  info("# part 1");
 | 
						|
  await whenPageShown(browser, () =>
 | 
						|
    BrowserTestUtils.loadURI(browser, "http://www.example.com/")
 | 
						|
  );
 | 
						|
  checkListeners("newentry", "shistory has a new entry");
 | 
						|
  ok(browser.canGoBack, "we can go back");
 | 
						|
 | 
						|
  await whenPageShown(browser, () => browser.goBack());
 | 
						|
  checkListeners("gotoindex", "back to the first shentry");
 | 
						|
  ok(browser.canGoForward, "we can go forward");
 | 
						|
 | 
						|
  await whenPageShown(browser, () => browser.goForward());
 | 
						|
  checkListeners("gotoindex", "forward to the second shentry");
 | 
						|
 | 
						|
  await whenPageShown(browser, () => browser.reload());
 | 
						|
  checkListeners("reload", "current shentry reloaded");
 | 
						|
 | 
						|
  await whenPageShown(browser, () => browser.gotoIndex(0));
 | 
						|
  checkListeners("gotoindex", "back to the first index");
 | 
						|
 | 
						|
  // Check nsISHistory.notifyOnHistoryReload
 | 
						|
  info("# part 2");
 | 
						|
  ok(notifyReload(browser), "reloading has not been canceled");
 | 
						|
  checkListeners("reload", "saw the reload notification");
 | 
						|
 | 
						|
  // Let the first listener cancel the reload action.
 | 
						|
  info("# part 3");
 | 
						|
  resetListeners();
 | 
						|
  setListenerRetval(0, false);
 | 
						|
  ok(!notifyReload(browser), "reloading has been canceled");
 | 
						|
  checkListeners("reload", "saw the reload notification");
 | 
						|
 | 
						|
  // Let both listeners cancel the reload action.
 | 
						|
  info("# part 4");
 | 
						|
  resetListeners();
 | 
						|
  setListenerRetval(1, false);
 | 
						|
  ok(!notifyReload(browser), "reloading has been canceled");
 | 
						|
  checkListeners("reload", "saw the reload notification");
 | 
						|
 | 
						|
  // Let the second listener cancel the reload action.
 | 
						|
  info("# part 5");
 | 
						|
  resetListeners();
 | 
						|
  setListenerRetval(0, true);
 | 
						|
  ok(!notifyReload(browser), "reloading has been canceled");
 | 
						|
  checkListeners("reload", "saw the reload notification");
 | 
						|
});
 | 
						|
 | 
						|
class SHistoryListener {
 | 
						|
  constructor() {
 | 
						|
    this.retval = true;
 | 
						|
    this.last = "initial";
 | 
						|
  }
 | 
						|
 | 
						|
  OnHistoryNewEntry(aNewURI) {
 | 
						|
    this.last = "newentry";
 | 
						|
  }
 | 
						|
 | 
						|
  OnHistoryGotoIndex() {
 | 
						|
    this.last = "gotoindex";
 | 
						|
  }
 | 
						|
 | 
						|
  OnHistoryPurge() {
 | 
						|
    this.last = "purge";
 | 
						|
  }
 | 
						|
 | 
						|
  OnHistoryReload() {
 | 
						|
    this.last = "reload";
 | 
						|
    return this.retval;
 | 
						|
  }
 | 
						|
 | 
						|
  OnHistoryReplaceEntry() {}
 | 
						|
}
 | 
						|
SHistoryListener.prototype.QueryInterface = ChromeUtils.generateQI([
 | 
						|
  "nsISHistoryListener",
 | 
						|
  "nsISupportsWeakReference",
 | 
						|
]);
 | 
						|
 | 
						|
let listeners = [new SHistoryListener(), new SHistoryListener()];
 | 
						|
 | 
						|
function checkListeners(aLast, aMessage) {
 | 
						|
  is(listeners[0].last, aLast, aMessage);
 | 
						|
  is(listeners[1].last, aLast, aMessage);
 | 
						|
}
 | 
						|
 | 
						|
function resetListeners() {
 | 
						|
  for (let listener of listeners) {
 | 
						|
    listener.last = "initial";
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function notifyReload(browser) {
 | 
						|
  return browser.browsingContext.sessionHistory.notifyOnHistoryReload();
 | 
						|
}
 | 
						|
 | 
						|
function setListenerRetval(num, val) {
 | 
						|
  listeners[num].retval = val;
 | 
						|
}
 | 
						|
 | 
						|
async function setup() {
 | 
						|
  let tab = await BrowserTestUtils.openNewForegroundTab(
 | 
						|
    gBrowser,
 | 
						|
    "http://mochi.test:8888"
 | 
						|
  );
 | 
						|
 | 
						|
  let browser = tab.linkedBrowser;
 | 
						|
  registerCleanupFunction(async function() {
 | 
						|
    for (let listener of listeners) {
 | 
						|
      browser.browsingContext.sessionHistory.removeSHistoryListener(listener);
 | 
						|
    }
 | 
						|
    gBrowser.removeTab(tab);
 | 
						|
  });
 | 
						|
  for (let listener of listeners) {
 | 
						|
    browser.browsingContext.sessionHistory.addSHistoryListener(listener);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function whenPageShown(aBrowser, aNavigation) {
 | 
						|
  let promise = new Promise(resolve => {
 | 
						|
    let unregister = BrowserTestUtils.addContentEventListener(
 | 
						|
      aBrowser,
 | 
						|
      "pageshow",
 | 
						|
      () => {
 | 
						|
        unregister();
 | 
						|
        resolve();
 | 
						|
      },
 | 
						|
      { capture: true }
 | 
						|
    );
 | 
						|
  });
 | 
						|
 | 
						|
  aNavigation();
 | 
						|
  return promise;
 | 
						|
}
 |