michael@0: /* Any copyright is dedicated to the Public Domain. michael@0: * http://creativecommons.org/publicdomain/zero/1.0/ */ michael@0: michael@0: Cu.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: michael@0: function SHistoryListener() { michael@0: } michael@0: michael@0: SHistoryListener.prototype = { michael@0: retval: true, michael@0: last: "initial", michael@0: michael@0: OnHistoryNewEntry: function (aNewURI) { michael@0: this.last = "newentry"; michael@0: }, michael@0: michael@0: OnHistoryGoBack: function (aBackURI) { michael@0: this.last = "goback"; michael@0: return this.retval; michael@0: }, michael@0: michael@0: OnHistoryGoForward: function (aForwardURI) { michael@0: this.last = "goforward"; michael@0: return this.retval; michael@0: }, michael@0: michael@0: OnHistoryGotoIndex: function (aIndex, aGotoURI) { michael@0: this.last = "gotoindex"; michael@0: return this.retval; michael@0: }, michael@0: michael@0: OnHistoryPurge: function (aNumEntries) { michael@0: this.last = "purge"; michael@0: return this.retval; michael@0: }, michael@0: michael@0: OnHistoryReload: function (aReloadURI, aReloadFlags) { michael@0: this.last = "reload"; michael@0: return this.retval; michael@0: }, michael@0: michael@0: OnHistoryReplaceEntry: function (aIndex) {}, michael@0: michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsISHistoryListener, michael@0: Ci.nsISupportsWeakReference]) michael@0: }; michael@0: michael@0: let gFirstListener = new SHistoryListener(); michael@0: let gSecondListener = new SHistoryListener(); michael@0: michael@0: function test() { michael@0: TestRunner.run(); michael@0: } michael@0: michael@0: function runTests() { michael@0: yield setup(); michael@0: let browser = gBrowser.selectedBrowser; michael@0: checkListeners("initial", "listeners initialized"); michael@0: michael@0: // Check if all history listeners are always notified. michael@0: info("# part 1"); michael@0: browser.loadURI("http://www.example.com/"); michael@0: yield whenPageShown(browser); michael@0: checkListeners("newentry", "shistory has a new entry"); michael@0: ok(browser.canGoBack, "we can go back"); michael@0: michael@0: browser.goBack(); michael@0: yield whenPageShown(browser); michael@0: checkListeners("goback", "back to the first shentry"); michael@0: ok(browser.canGoForward, "we can go forward"); michael@0: michael@0: browser.goForward(); michael@0: yield whenPageShown(browser); michael@0: checkListeners("goforward", "forward to the second shentry"); michael@0: michael@0: browser.reload(); michael@0: yield whenPageShown(browser); michael@0: checkListeners("reload", "current shentry reloaded"); michael@0: michael@0: browser.gotoIndex(0); michael@0: yield whenPageShown(browser); michael@0: checkListeners("gotoindex", "back to the first index"); michael@0: michael@0: // Check nsISHistoryInternal.notifyOnHistoryReload michael@0: info("# part 2"); michael@0: ok(notifyReload(), "reloading has not been canceled"); michael@0: checkListeners("reload", "saw the reload notification"); michael@0: michael@0: // Let the first listener cancel the reload action. michael@0: info("# part 3"); michael@0: resetListeners(); michael@0: gFirstListener.retval = false; michael@0: ok(!notifyReload(), "reloading has been canceled"); michael@0: checkListeners("reload", "saw the reload notification"); michael@0: michael@0: // Let both listeners cancel the reload action. michael@0: info("# part 4"); michael@0: resetListeners(); michael@0: gSecondListener.retval = false; michael@0: ok(!notifyReload(), "reloading has been canceled"); michael@0: checkListeners("reload", "saw the reload notification"); michael@0: michael@0: // Let the second listener cancel the reload action. michael@0: info("# part 5"); michael@0: resetListeners(); michael@0: gFirstListener.retval = true; michael@0: ok(!notifyReload(), "reloading has been canceled"); michael@0: checkListeners("reload", "saw the reload notification"); michael@0: } michael@0: michael@0: function checkListeners(aLast, aMessage) { michael@0: is(gFirstListener.last, aLast, aMessage); michael@0: is(gSecondListener.last, aLast, aMessage); michael@0: } michael@0: michael@0: function resetListeners() { michael@0: gFirstListener.last = gSecondListener.last = "initial"; michael@0: } michael@0: michael@0: function notifyReload() { michael@0: let browser = gBrowser.selectedBrowser; michael@0: let shistory = browser.docShell.sessionHistory; michael@0: shistory.QueryInterface(Ci.nsISHistoryInternal); michael@0: return shistory.notifyOnHistoryReload(browser.currentURI, 0); michael@0: } michael@0: michael@0: function setup(aCallback) { michael@0: let tab = gBrowser.selectedTab = gBrowser.addTab("about:mozilla"); michael@0: let browser = tab.linkedBrowser; michael@0: registerCleanupFunction(function () gBrowser.removeTab(tab)); michael@0: michael@0: whenPageShown(browser, function () { michael@0: gFirstListener = new SHistoryListener(); michael@0: gSecondListener = new SHistoryListener(); michael@0: michael@0: let shistory = browser.docShell.sessionHistory; michael@0: shistory.addSHistoryListener(gFirstListener); michael@0: shistory.addSHistoryListener(gSecondListener); michael@0: michael@0: registerCleanupFunction(function () { michael@0: shistory.removeSHistoryListener(gFirstListener); michael@0: shistory.removeSHistoryListener(gSecondListener); michael@0: }); michael@0: michael@0: (aCallback || TestRunner.next)(); michael@0: }); michael@0: } michael@0: michael@0: function whenPageShown(aBrowser, aCallback) { michael@0: aBrowser.addEventListener("pageshow", function onLoad() { michael@0: aBrowser.removeEventListener("pageshow", onLoad, true); michael@0: executeSoon(aCallback || TestRunner.next); michael@0: }, true); michael@0: } michael@0: michael@0: let TestRunner = { michael@0: run: function () { michael@0: waitForExplicitFinish(); michael@0: this._iter = runTests(); michael@0: this.next(); michael@0: }, michael@0: michael@0: next: function () { michael@0: try { michael@0: TestRunner._iter.next(); michael@0: } catch (e if e instanceof StopIteration) { michael@0: TestRunner.finish(); michael@0: } michael@0: }, michael@0: michael@0: finish: function () { michael@0: finish(); michael@0: } michael@0: };