michael@0: Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); michael@0: Components.utils.import("resource://gre/modules/Services.jsm"); michael@0: michael@0: let Cc = Components.classes; michael@0: let Ci = Components.interfaces; michael@0: michael@0: const PREF_DISABLE_OPEN_NEW_WINDOW = "browser.link.open_newwindow.disabled_in_fullscreen"; michael@0: const isOSX = (Services.appinfo.OS === "Darwin"); michael@0: michael@0: const TEST_FILE = "file_fullscreen-window-open.html"; michael@0: const gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", michael@0: "http://127.0.0.1:8888/"); michael@0: michael@0: function test () { michael@0: waitForExplicitFinish(); michael@0: michael@0: Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, true); michael@0: michael@0: let newTab = gBrowser.addTab(); michael@0: gBrowser.selectedTab = newTab; michael@0: michael@0: let gTestBrowser = gBrowser.selectedBrowser; michael@0: gTestBrowser.addEventListener("load", function onLoad(){ michael@0: gTestBrowser.removeEventListener("load", onLoad, true, true); michael@0: michael@0: // Enter browser fullscreen mode. michael@0: BrowserFullScreen(); michael@0: michael@0: runNextTest(); michael@0: }, true, true); michael@0: gTestBrowser.contentWindow.location.href = gHttpTestRoot + TEST_FILE; michael@0: } michael@0: michael@0: registerCleanupFunction(function(){ michael@0: // Exit browser fullscreen mode. michael@0: BrowserFullScreen(); michael@0: michael@0: gBrowser.removeCurrentTab(); michael@0: michael@0: Services.prefs.clearUserPref(PREF_DISABLE_OPEN_NEW_WINDOW); michael@0: }); michael@0: michael@0: let gTests = [ michael@0: test_open, michael@0: test_open_with_size, michael@0: test_open_with_pos, michael@0: test_open_with_outerSize, michael@0: test_open_with_innerSize, michael@0: test_open_with_dialog, michael@0: test_open_when_open_new_window_by_pref, michael@0: test_open_with_pref_to_disable_in_fullscreen, michael@0: test_open_from_chrome, michael@0: ]; michael@0: michael@0: function runNextTest () { michael@0: let test = gTests.shift(); michael@0: if (test) { michael@0: executeSoon(test); michael@0: } michael@0: else { michael@0: finish(); michael@0: } michael@0: } michael@0: michael@0: michael@0: // Test for window.open() with no feature. michael@0: function test_open() { michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open", michael@0: param: "", michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() with width/height. michael@0: function test_open_with_size() { michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_with_size", michael@0: param: "width=400,height=400", michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() with top/left. michael@0: function test_open_with_pos() { michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_with_pos", michael@0: param: "top=200,left=200", michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() with outerWidth/Height. michael@0: function test_open_with_outerSize() { michael@0: let [outerWidth, outerHeight] = [window.outerWidth, window.outerHeight]; michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_with_outerSize", michael@0: param: "outerWidth=200,outerHeight=200", michael@0: }, michael@0: successFn: function () { michael@0: is(window.outerWidth, outerWidth, "Don't change window.outerWidth."); michael@0: is(window.outerHeight, outerHeight, "Don't change window.outerHeight."); michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() with innerWidth/Height. michael@0: function test_open_with_innerSize() { michael@0: let [innerWidth, innerHeight] = [window.innerWidth, window.innerHeight]; michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_with_innerSize", michael@0: param: "innerWidth=200,innerHeight=200", michael@0: }, michael@0: successFn: function () { michael@0: is(window.innerWidth, innerWidth, "Don't change window.innerWidth."); michael@0: is(window.innerHeight, innerHeight, "Don't change window.innerHeight."); michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() with dialog. michael@0: function test_open_with_dialog() { michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_with_dialog", michael@0: param: "dialog=yes", michael@0: }, michael@0: finalizeFn: function () {}, michael@0: }); michael@0: } michael@0: michael@0: // Test for window.open() michael@0: // when "browser.link.open_newwindow" is nsIBrowserDOMWindow.OPEN_NEWWINDOW michael@0: function test_open_when_open_new_window_by_pref() { michael@0: const PREF_NAME = "browser.link.open_newwindow"; michael@0: Services.prefs.setIntPref(PREF_NAME, Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW); michael@0: is(Services.prefs.getIntPref(PREF_NAME), Ci.nsIBrowserDOMWindow.OPEN_NEWWINDOW, michael@0: PREF_NAME + " is nsIBrowserDOMWindow.OPEN_NEWWINDOW at this time"); michael@0: michael@0: waitForTabOpen({ michael@0: message: { michael@0: title: "test_open_when_open_new_window_by_pref", michael@0: param: "width=400,height=400", michael@0: }, michael@0: finalizeFn: function () { michael@0: Services.prefs.clearUserPref(PREF_NAME); michael@0: }, michael@0: }); michael@0: } michael@0: michael@0: // Test for the pref, "browser.link.open_newwindow.disabled_in_fullscreen" michael@0: function test_open_with_pref_to_disable_in_fullscreen() { michael@0: Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, false); michael@0: michael@0: waitForWindowOpen({ michael@0: message: { michael@0: title: "test_open_with_pref_disabled_in_fullscreen", michael@0: param: "width=400,height=400", michael@0: }, michael@0: finalizeFn: function () { michael@0: Services.prefs.setBoolPref(PREF_DISABLE_OPEN_NEW_WINDOW, true); michael@0: }, michael@0: }); michael@0: } michael@0: michael@0: michael@0: // Test for window.open() called from chrome context. michael@0: function test_open_from_chrome() { michael@0: waitForWindowOpenFromChrome({ michael@0: message: { michael@0: title: "test_open_from_chrome", michael@0: param: "", michael@0: }, michael@0: finalizeFn: function () {}, michael@0: timeout: 10000, michael@0: }); michael@0: } michael@0: michael@0: function waitForTabOpen(aOptions) { michael@0: let start = Date.now(); michael@0: let timeout = aOptions.timeout || 5000; michael@0: let message = aOptions.message; michael@0: michael@0: if (!message.title) { michael@0: ok(false, "Can't get message.title."); michael@0: aOptions.finalizeFn(); michael@0: runNextTest(); michael@0: return; michael@0: } michael@0: michael@0: info("Running test: " + message.title); michael@0: michael@0: let onTabOpen = function onTabOpen(aEvent) { michael@0: gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true); michael@0: michael@0: let tab = aEvent.target; michael@0: tab.linkedBrowser.addEventListener("load", function onLoad(ev){ michael@0: let browser = ev.currentTarget; michael@0: browser.removeEventListener("load", onLoad, true, true); michael@0: clearTimeout(onTimeout); michael@0: michael@0: is(browser.contentWindow.document.title, message.title, michael@0: "Opened Tab is expected: " + message.title); michael@0: michael@0: if (aOptions.successFn) { michael@0: aOptions.successFn(); michael@0: } michael@0: michael@0: gBrowser.removeTab(tab); michael@0: finalize(); michael@0: }, true, true); michael@0: } michael@0: gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, true); michael@0: michael@0: let finalize = function () { michael@0: aOptions.finalizeFn(); michael@0: info("Finished: " + message.title); michael@0: runNextTest(); michael@0: }; michael@0: michael@0: let onTimeout = setTimeout(function(){ michael@0: gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, true); michael@0: michael@0: ok(false, "Timeout: '"+message.title + "'."); michael@0: finalize(); michael@0: }, timeout); michael@0: michael@0: michael@0: const URI = "data:text/html;charset=utf-8,"+ michael@0: message.title + michael@0: "<%2Ftitle><%2Fhead><body><%2Fbody><%2Fhtml>"; michael@0: michael@0: executeWindowOpenInContent({ michael@0: uri: URI, michael@0: title: message.title, michael@0: option: message.param, michael@0: }); michael@0: } michael@0: michael@0: michael@0: function waitForWindowOpen(aOptions) { michael@0: let start = Date.now(); michael@0: let timeout = aOptions.timeout || 10000; michael@0: let message = aOptions.message; michael@0: let url = aOptions.url || getBrowserURL(); michael@0: michael@0: if (!message.title) { michael@0: ok(false, "Can't get message.title"); michael@0: aOptions.finalizeFn(); michael@0: runNextTest(); michael@0: return; michael@0: } michael@0: michael@0: info("Running test: " + message.title); michael@0: michael@0: let onFinalize = function () { michael@0: aOptions.finalizeFn(); michael@0: michael@0: info("Finished: " + message.title); michael@0: runNextTest(); michael@0: }; michael@0: michael@0: let onTimeout = setTimeout(function(){ michael@0: Services.wm.removeListener(listener); michael@0: ok(false, "Fail: '"+message.title + "'."); michael@0: michael@0: onFinalize(); michael@0: }, timeout); michael@0: michael@0: let listener = new WindowListener(message.title, url, { michael@0: onSuccess: aOptions.successFn, michael@0: onTimeout: onTimeout, michael@0: onFinalize: onFinalize, michael@0: }); michael@0: Services.wm.addListener(listener); michael@0: michael@0: const URI = aOptions.url || "about:blank"; michael@0: michael@0: executeWindowOpenInContent({ michael@0: uri: URI, michael@0: title: message.title, michael@0: option: message.param, michael@0: }); michael@0: } michael@0: michael@0: function executeWindowOpenInContent(aParam) { michael@0: var testWindow = gBrowser.selectedBrowser.contentWindow; michael@0: var testElm = testWindow.document.getElementById("test"); michael@0: michael@0: testElm.setAttribute("data-test-param", JSON.stringify(aParam)); michael@0: EventUtils.synthesizeMouseAtCenter(testElm, {}, testWindow); michael@0: } michael@0: michael@0: function waitForWindowOpenFromChrome(aOptions) { michael@0: let start = Date.now(); michael@0: let timeout = aOptions.timeout || 10000; michael@0: let message = aOptions.message; michael@0: let url = aOptions.url || getBrowserURL(); michael@0: michael@0: if (!message.title) { michael@0: ok(false, "Can't get message.title"); michael@0: aOptions.finalizeFn(); michael@0: runNextTest(); michael@0: return; michael@0: } michael@0: michael@0: info("Running test: " + message.title); michael@0: michael@0: let onFinalize = function () { michael@0: aOptions.finalizeFn(); michael@0: michael@0: info("Finished: " + message.title); michael@0: runNextTest(); michael@0: }; michael@0: michael@0: let onTimeout = setTimeout(function(){ michael@0: Services.wm.removeListener(listener); michael@0: ok(false, "Fail: '"+message.title + "'."); michael@0: michael@0: testWindow.close(); michael@0: onFinalize(); michael@0: }, timeout); michael@0: michael@0: let listener = new WindowListener(message.title, url, { michael@0: onSuccess: aOptions.successFn, michael@0: onTimeout: onTimeout, michael@0: onFinalize: onFinalize, michael@0: }); michael@0: Services.wm.addListener(listener); michael@0: michael@0: michael@0: const URI = aOptions.url || "about:blank"; michael@0: michael@0: let testWindow = window.open(URI, message.title, message.option); michael@0: } michael@0: michael@0: function WindowListener(aTitle, aUrl, aCallBackObj) { michael@0: this.test_title = aTitle; michael@0: this.test_url = aUrl; michael@0: this.callback_onSuccess = aCallBackObj.onSuccess; michael@0: this.callBack_onTimeout = aCallBackObj.onTimeout; michael@0: this.callBack_onFinalize = aCallBackObj.onFinalize; michael@0: } michael@0: WindowListener.prototype = { michael@0: michael@0: test_title: null, michael@0: test_url: null, michael@0: callback_onSuccess: null, michael@0: callBack_onTimeout: null, michael@0: callBack_onFinalize: null, michael@0: michael@0: onOpenWindow: function(aXULWindow) { michael@0: Services.wm.removeListener(this); michael@0: michael@0: let domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor) michael@0: .getInterface(Ci.nsIDOMWindow); michael@0: domwindow.addEventListener("load", function onLoad(aEvent) { michael@0: is(domwindow.document.location.href, this.test_url, michael@0: "Opened Window is expected: "+ this.test_title); michael@0: if (this.callback_onSuccess) { michael@0: this.callback_onSuccess(); michael@0: } michael@0: michael@0: domwindow.removeEventListener("load", onLoad, true); michael@0: clearTimeout(this.callBack_onTimeout); michael@0: michael@0: // wait for trasition to fullscreen on OSX Lion later michael@0: if (isOSX) { michael@0: setTimeout(function(){ michael@0: domwindow.close(); michael@0: executeSoon(this.callBack_onFinalize); michael@0: }.bind(this), 3000); michael@0: } michael@0: else { michael@0: domwindow.close(); michael@0: executeSoon(this.callBack_onFinalize); michael@0: } michael@0: }.bind(this), true); michael@0: }, michael@0: onCloseWindow: function(aXULWindow) {}, michael@0: onWindowTitleChange: function(aXULWindow, aNewTitle) {}, michael@0: QueryInterface: XPCOMUtils.generateQI([Ci.nsIWindowMediatorListener, michael@0: Ci.nsISupports]), michael@0: };