summaryrefslogtreecommitdiffstats
path: root/toolkit/components/windowcreator
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/components/windowcreator')
-rw-r--r--toolkit/components/windowcreator/moz.build20
-rw-r--r--toolkit/components/windowcreator/nsIWindowCreator.idl52
-rw-r--r--toolkit/components/windowcreator/nsIWindowProvider.idl109
-rw-r--r--toolkit/components/windowcreator/test/320x240.ogvbin0 -> 28942 bytes
-rw-r--r--toolkit/components/windowcreator/test/browser.ini13
-rw-r--r--toolkit/components/windowcreator/test/browser_bug1204626.js88
-rw-r--r--toolkit/components/windowcreator/test/browser_persist.js105
-rw-r--r--toolkit/components/windowcreator/test/browser_save_form_input_state.js131
-rw-r--r--toolkit/components/windowcreator/test/bug1170334_iframe.xml3
-rw-r--r--toolkit/components/windowcreator/test/bug1170334_style.css1
-rw-r--r--toolkit/components/windowcreator/test/bug1204626_doc0.html3
-rw-r--r--toolkit/components/windowcreator/test/bug1204626_doc1.html5
-rw-r--r--toolkit/components/windowcreator/test/bug449141_page.html11
-rw-r--r--toolkit/components/windowcreator/test/chrome.ini11
-rw-r--r--toolkit/components/windowcreator/test/file_form_state.html25
-rw-r--r--toolkit/components/windowcreator/test/file_persist_image.pngbin0 -> 1010 bytes
-rw-r--r--toolkit/components/windowcreator/test/file_persist_picture_source.html5
-rw-r--r--toolkit/components/windowcreator/test/file_persist_srcset.html3
-rw-r--r--toolkit/components/windowcreator/test/file_persist_svg.html5
-rw-r--r--toolkit/components/windowcreator/test/mochitest.ini5
-rw-r--r--toolkit/components/windowcreator/test/moz.build9
-rw-r--r--toolkit/components/windowcreator/test/test_bug1170334_wbp_xmlstyle.html77
-rw-r--r--toolkit/components/windowcreator/test/test_bug1192654.html77
-rw-r--r--toolkit/components/windowcreator/test/test_bug449141.html96
-rw-r--r--toolkit/components/windowcreator/test/test_private_window_from_content.html12
-rw-r--r--toolkit/components/windowcreator/test/test_window_open_position_constraint.html56
-rw-r--r--toolkit/components/windowcreator/test/test_window_open_units.html36
-rw-r--r--toolkit/components/windowcreator/tests/unit/test_wwauthpromptfactory.js55
-rw-r--r--toolkit/components/windowcreator/tests/unit/test_wwpromptfactory.js20
-rw-r--r--toolkit/components/windowcreator/tests/unit/xpcshell.ini5
30 files changed, 1038 insertions, 0 deletions
diff --git a/toolkit/components/windowcreator/moz.build b/toolkit/components/windowcreator/moz.build
new file mode 100644
index 0000000000..66b328cc79
--- /dev/null
+++ b/toolkit/components/windowcreator/moz.build
@@ -0,0 +1,20 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Core", "Window Management")
+
+TEST_DIRS += ["test"]
+
+if CONFIG["ENABLE_TESTS"]:
+ XPCSHELL_TESTS_MANIFESTS += ["tests/unit/xpcshell.ini"]
+
+XPIDL_SOURCES += [
+ "nsIWindowCreator.idl",
+ "nsIWindowProvider.idl",
+]
+
+XPIDL_MODULE = "windowcreator"
diff --git a/toolkit/components/windowcreator/nsIWindowCreator.idl b/toolkit/components/windowcreator/nsIWindowCreator.idl
new file mode 100644
index 0000000000..b03ec11448
--- /dev/null
+++ b/toolkit/components/windowcreator/nsIWindowCreator.idl
@@ -0,0 +1,52 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * nsIWindowCreator is a callback interface used by Gecko to create
+ * new browser windows. The application, either Mozilla or an embedding app,
+ * must provide an implementation of the Window Watcher component and
+ * notify the WindowWatcher during application initialization.
+ *
+ * @see nsIWindowWatcher
+ */
+
+#include "nsISupports.idl"
+
+interface nsIOpenWindowInfo;
+interface nsIRemoteTab;
+interface nsIURI;
+interface nsIWebBrowserChrome;
+interface mozIDOMWindowProxy;
+
+[scriptable, uuid(30465632-A777-44cc-90F9-8145475EF999)]
+interface nsIWindowCreator : nsISupports {
+
+ /** Create a new window. Gecko will/may call this method, if made
+ available to it, to create new windows.
+ @param parent Parent window, if any. Null if not. The newly created
+ window should be made a child/dependent window of
+ the parent, if any (and if the concept applies
+ to the underlying OS).
+ @param chromeFlags Chrome features from nsIWebBrowserChrome
+ @param aOpenWindowInfo Information used to open initial content in
+ the new chrome window. Can be nullptr.
+ @param cancel Return |true| to reject window creation. If true the
+ implementation has determined the window should not
+ be created at all. The caller should not default
+ to any possible backup scheme for creating the window.
+ @return the new window. Will be null if canceled or an error occurred.
+ */
+ nsIWebBrowserChrome createChromeWindow(in nsIWebBrowserChrome parent,
+ in uint32_t chromeFlags,
+ in nsIOpenWindowInfo aOpenWindowInfo,
+ out boolean cancel);
+};
+
+%{C++
+// {30465632-A777-44cc-90F9-8145475EF999}
+#define NS_WINDOWCREATOR_IID \
+ {0x30465632, 0xa777, 0x44cc, {0x90, 0xf9, 0x81, 0x45, 0x47, 0x5e, 0xf9, 0x99}}
+%}
diff --git a/toolkit/components/windowcreator/nsIWindowProvider.idl b/toolkit/components/windowcreator/nsIWindowProvider.idl
new file mode 100644
index 0000000000..a51b5689ee
--- /dev/null
+++ b/toolkit/components/windowcreator/nsIWindowProvider.idl
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * nsIWindowProvider is a callback interface used by Gecko when it needs to
+ * open a new window. This interface can be implemented by Gecko consumers who
+ * wish to provide a custom "new window" of their own (for example by returning
+ * a new tab, an existing window, etc) instead of just having a real new
+ * toplevel window open.
+ */
+
+#include "nsISupports.idl"
+
+%{ C++
+class nsDocShellLoadState;
+%}
+
+webidl BrowsingContext;
+interface mozIDOMWindowProxy;
+interface nsIURI;
+interface nsIOpenWindowInfo;
+native nsDocShellLoadStatePtr(nsDocShellLoadState*);
+
+/**
+ * The nsIWindowProvider interface exists so that the window watcher's default
+ * behavior of opening a new window can be easly modified. When the window
+ * watcher needs to open a new window, it will first check with the
+ * nsIWindowProvider it gets from the parent window. If there is no provider
+ * or the provider does not provide a window, the window watcher will proceed
+ * to actually open a new window.
+ */
+[scriptable, uuid(e97a3830-15ef-499b-8372-c22d128091c1)]
+interface nsIWindowProvider : nsISupports
+{
+ /**
+ * A method to request that this provider provide a window. The window
+ * returned need not to have the right name or parent set on it; setting
+ * those is the caller's responsibility. The provider can always return null
+ * to have the caller create a brand-new window.
+ *
+ * @param aOpenWindowInfo Must not be null. This is the information the
+ * caller wants to be used to construct the new window.
+ *
+ * @param aChromeFlags The chrome flags the caller will use to create a new
+ * window if this provider returns null. See nsIWebBrowserChrome for
+ * the possible values of this field.
+ *
+ * @param aURI The URI to be loaded in the new window (may be NULL). The
+ * nsIWindowProvider implementation must not load this URI into the
+ * window it returns. This URI is provided solely to help the
+ * nsIWindowProvider implementation make decisions; the caller will
+ * handle loading the URI in the window returned if provideWindow
+ * returns a window.
+ *
+ * When making decisions based on aURI, note that even when it's not
+ * null, aURI may not represent all relevant information about the
+ * load. For example, the load may have extra load flags, POST data,
+ * etc.
+ *
+ * @param aName The name of the window being opened. Setting the name on the
+ * return value of provideWindow will be handled by the caller; aName
+ * is provided solely to help the nsIWindowProvider implementation
+ * make decisions.
+ *
+ * @param aFeatures The feature string for the window being opened. This may
+ * be empty. The nsIWindowProvider implementation is allowed to apply
+ * the feature string to the window it returns in any way it sees fit.
+ * See the nsIWindowWatcher interface for details on feature strings.
+ *
+ * @param aIsPopupRequested True if this window is opened by window.open
+ * with requesting a popup window. This doesn't necessarily mean
+ * whether the actual window is shown as minimal popup or not.
+ *
+ * @param aLoadState Specify setup information of the load in the new window
+ *
+ * @param aWindowIsNew [out] Whether the window being returned was just
+ * created by the window provider implementation. This can be used by
+ * callers to keep track of which windows were opened by the user as
+ * opposed to being opened programmatically. This should be set to
+ * false if the window being returned existed before the
+ * provideWindow() call. The value of this out parameter is
+ * meaningless if provideWindow() returns null.
+ *
+ * @return A window the caller should use or null if the caller should just
+ * create a new window. The returned window may be newly opened by
+ * the nsIWindowProvider implementation or may be a window that
+ * already existed.
+ *
+ * @throw NS_ERROR_ABORT if the caller should cease its attempt to open a new
+ * window.
+ *
+ * @see nsIWindowWatcher for more information on aFeatures.
+ * @see nsIWebBrowserChrome for more information on aChromeFlags.
+ */
+ [noscript]
+ BrowsingContext provideWindow(in nsIOpenWindowInfo aOpenWindowInfo,
+ in unsigned long aChromeFlags,
+ in boolean aCalledFromJS,
+ in nsIURI aURI,
+ in AString aName,
+ in AUTF8String aFeatures,
+ in boolean aForceNoOpener,
+ in boolean aForceNoReferrer,
+ in boolean aIsPopupRequested,
+ in nsDocShellLoadStatePtr aLoadState,
+ out boolean aWindowIsNew);
+};
diff --git a/toolkit/components/windowcreator/test/320x240.ogv b/toolkit/components/windowcreator/test/320x240.ogv
new file mode 100644
index 0000000000..093158432a
--- /dev/null
+++ b/toolkit/components/windowcreator/test/320x240.ogv
Binary files differ
diff --git a/toolkit/components/windowcreator/test/browser.ini b/toolkit/components/windowcreator/test/browser.ini
new file mode 100644
index 0000000000..53f53c0d61
--- /dev/null
+++ b/toolkit/components/windowcreator/test/browser.ini
@@ -0,0 +1,13 @@
+[browser_bug1204626.js]
+support-files =
+ bug1204626_doc0.html
+ bug1204626_doc1.html
+[browser_save_form_input_state.js]
+support-files =
+ file_form_state.html
+[browser_persist.js]
+support-files =
+ file_persist_srcset.html
+ file_persist_svg.html
+ file_persist_picture_source.html
+ file_persist_image.png
diff --git a/toolkit/components/windowcreator/test/browser_bug1204626.js b/toolkit/components/windowcreator/test/browser_bug1204626.js
new file mode 100644
index 0000000000..84dbf5080a
--- /dev/null
+++ b/toolkit/components/windowcreator/test/browser_bug1204626.js
@@ -0,0 +1,88 @@
+/* eslint-disable mozilla/no-arbitrary-setTimeout */
+"use strict"; // -*- js-indent-level: 2; indent-tabs-mode: nil -*-
+const contentBase =
+ "https://example.com/browser/toolkit/components/windowcreator/test/";
+const chromeBase =
+ "chrome://mochitests/content/browser/toolkit/components/windowcreator/test/";
+const testPageURL = contentBase + "bug1204626_doc0.html";
+
+function one_test(delay, continuation) {
+ let delayStr = delay === null ? "no delay" : "delay = " + delay + "ms";
+ let browser;
+
+ BrowserTestUtils.openNewForegroundTab(gBrowser, testPageURL).then(tab => {
+ browser = tab.linkedBrowser;
+ let persistable = browser.frameLoader;
+ persistable.startPersistence(null, {
+ onDocumentReady,
+ onError(status) {
+ ok(false, new Components.Exception("startPersistence failed", status));
+ continuation();
+ },
+ });
+ });
+
+ function onDocumentReady(doc) {
+ const nameStem = "test_bug1204626_" + Date.now();
+ let wbp = Cc[
+ "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
+ ].createInstance(Ci.nsIWebBrowserPersist);
+ let tmp = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let tmpFile = tmp.clone();
+ tmpFile.append(nameStem + "_saved.html");
+ let tmpDir = tmp.clone();
+ tmpDir.append(nameStem + "_files");
+
+ registerCleanupFunction(function cleanUp() {
+ if (tmpFile.exists()) {
+ tmpFile.remove(/* recursive: */ false);
+ }
+ if (tmpDir.exists()) {
+ tmpDir.remove(/* recursive: */ true);
+ }
+ });
+
+ wbp.progressListener = {
+ onProgressChange() {},
+ onLocationChange() {},
+ onStatusChange() {},
+ onSecurityChange() {},
+ onContentBlockingEvent() {},
+ onStateChange(_wbp, _req, state, _status) {
+ if ((state & Ci.nsIWebProgressListener.STATE_STOP) == 0) {
+ return;
+ }
+ ok(true, "Finished save (" + delayStr + ") but might have crashed.");
+ continuation();
+ },
+ };
+
+ function doSave() {
+ wbp.saveDocument(doc, tmpFile, tmpDir, null, 0, 0);
+ }
+ if (delay === null) {
+ doSave();
+ } else {
+ setTimeout(doSave, delay);
+ }
+ SpecialPowers.spawn(browser, [], () => {
+ content.window.close();
+ });
+ }
+}
+
+function test() {
+ waitForExplicitFinish();
+ // 0ms breaks having the actor under PBrowser, but not 10ms.
+ // 10ms provokes the double-__delete__, but not 0ms.
+ // And a few others, just in case.
+ const testRuns = [null, 0, 10, 0, 10, 20, 50, 100];
+ let i = 0;
+ (function next_test() {
+ if (i < testRuns.length) {
+ one_test(testRuns[i++], next_test);
+ } else {
+ finish();
+ }
+ })();
+}
diff --git a/toolkit/components/windowcreator/test/browser_persist.js b/toolkit/components/windowcreator/test/browser_persist.js
new file mode 100644
index 0000000000..54ab889aac
--- /dev/null
+++ b/toolkit/components/windowcreator/test/browser_persist.js
@@ -0,0 +1,105 @@
+"use strict"; // -*- js-indent-level: 2; indent-tabs-mode: nil -*-
+
+Services.scriptloader.loadSubScript(
+ "chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js",
+ this
+);
+
+const contentBase =
+ "https://example.com/browser/toolkit/components/windowcreator/test/";
+const chromeBase =
+ "chrome://mochitests/content/browser/toolkit/components/windowcreator/test/";
+
+// Checks that the source and target documents are the same.
+const REFTESTS = [
+ "file_persist_srcset.html",
+ "file_persist_picture_source.html",
+ "file_persist_svg.html",
+ // ...
+];
+
+async function persist(name, uri) {
+ return BrowserTestUtils.withNewTab(uri, async function (browser) {
+ // Snapshot the doc as loaded, this is our reference.
+ info("snapshotting reference");
+ let reference = await snapshotWindow(browser);
+
+ info("starting persistence");
+ let doc = await new Promise(function (resolve) {
+ browser.frameLoader.startPersistence(null, {
+ onDocumentReady(d) {
+ resolve(d);
+ },
+ onError(e) {
+ ok(false, "startPersistence failed: " + e);
+ },
+ });
+ });
+
+ let wbp = Cc[
+ "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
+ ].createInstance(Ci.nsIWebBrowserPersist);
+ let tmp = Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let tmpFile = tmp.clone();
+ tmpFile.append(name + "_saved.html");
+ let tmpDir = tmp.clone();
+ tmpDir.append(name + "_files");
+
+ registerCleanupFunction(function cleanUp() {
+ if (tmpFile.exists()) {
+ tmpFile.remove(/* recursive = */ false);
+ }
+ if (tmpDir.exists()) {
+ tmpDir.remove(/* recursive = */ true);
+ }
+ });
+
+ info("persisting document");
+ // Wait for the persisted document.
+ await new Promise(function (resolve) {
+ wbp.progressListener = {
+ onProgressChange() {},
+ onLocationChange() {},
+ onStatusChange() {},
+ onSecurityChange() {},
+ onContentBlockingEvent() {},
+ onStateChange(_wbp, _req, state, _status) {
+ if (state & Ci.nsIWebProgressListener.STATE_STOP) {
+ resolve();
+ }
+ },
+ };
+
+ wbp.saveDocument(doc, tmpFile, tmpDir, null, 0, 0);
+ });
+
+ info("load done, loading persisted document");
+ let fileUri = Services.io.newFileURI(tmpFile).spec;
+ let test = await BrowserTestUtils.withNewTab(
+ fileUri,
+ async function (persistedBrowser) {
+ info("snapshotting persisted document");
+ return snapshotWindow(persistedBrowser);
+ }
+ );
+ return { test, reference };
+ });
+}
+
+add_task(async function () {
+ for (let filename of REFTESTS) {
+ let uri = contentBase + filename;
+ let { test, reference } = await persist(filename, uri);
+ let expectEqual = true;
+ let [same, testUri, refUri] = compareSnapshots(
+ test,
+ reference,
+ expectEqual
+ );
+ ok(same, "test and references should match");
+ if (!same) {
+ info(testUri);
+ info(refUri);
+ }
+ }
+});
diff --git a/toolkit/components/windowcreator/test/browser_save_form_input_state.js b/toolkit/components/windowcreator/test/browser_save_form_input_state.js
new file mode 100644
index 0000000000..6992c29c85
--- /dev/null
+++ b/toolkit/components/windowcreator/test/browser_save_form_input_state.js
@@ -0,0 +1,131 @@
+/* Any copyright is dedicated to the Public Domain.
+ * https://creativecommons.org/publicdomain/zero/1.0/ */
+
+"use strict";
+
+const TEST_PATH = getRootDirectory(gTestPath).replace(
+ "chrome://mochitests/content",
+ "http://example.com"
+);
+
+var textareas = ["a-textbox", "a-prefilled-textbox"];
+var textboxes = ["a-text", "a-prefilled-text"];
+
+/**
+ * Ported from mochitest, this test verifies that form state is saved by our
+ * webbrowserpersist code. See bug 293834 for context.
+ */
+add_task(async function checkFormStateSaved() {
+ await BrowserTestUtils.withNewTab(
+ TEST_PATH + "file_form_state.html",
+ async browser => {
+ await SpecialPowers.spawn(browser, [{ textareas, textboxes }], fillform);
+ let fileURISpec = await new Promise((resolve, reject) => {
+ let stack = Components.stack.caller;
+ browser.frameLoader.startPersistence(null, {
+ onDocumentReady(document) {
+ // Note that 'document' here is going to be an nsIWebBrowserPersistDocument,
+ // not a regular DOM document.
+ resolve(persistDocument(document));
+ },
+ onError(status) {
+ reject(
+ Components.Exception(
+ "saveBrowser failed asynchronously in startPersistence",
+ status,
+ stack
+ )
+ );
+ },
+ });
+ });
+ await BrowserTestUtils.withNewTab(fileURISpec, async otherBrowser => {
+ await SpecialPowers.spawn(
+ otherBrowser,
+ [{ textareas, textboxes }],
+ checkform
+ );
+ });
+ }
+ );
+});
+
+// eslint-disable-next-line no-shadow
+function fillform({ textareas, textboxes }) {
+ let doc = content.document;
+ for (let i in textareas) {
+ doc.getElementById(textareas[i]).textContent += "form state";
+ }
+ for (let i in textboxes) {
+ doc.getElementById(textboxes[i]).value += "form state";
+ }
+ doc.getElementById("a-checkbox").checked = true;
+ doc.getElementById("radioa").checked = true;
+ doc.getElementById("aselect").selectedIndex = 0;
+}
+
+// eslint-disable-next-line no-shadow
+function checkform({ textareas, textboxes }) {
+ let doc = content.document;
+ for (let i in textareas) {
+ var textContent = doc.getElementById(textareas[i]).textContent;
+ Assert.ok(
+ /form\s+state/m.test(textContent),
+ "Modified textarea " + textareas[i] + " form state should be preserved!"
+ );
+ }
+ for (let i in textboxes) {
+ var value = doc.getElementById(textboxes[i]).value;
+ Assert.ok(
+ /form\s+state/m.test(value),
+ "Modified textbox " + textboxes[i] + " form state should be preserved!"
+ );
+ }
+ Assert.ok(
+ doc.getElementById("a-checkbox").checked,
+ "Modified checkbox checked state should be preserved!"
+ );
+ Assert.ok(
+ doc.getElementById("radioa").checked,
+ "Modified radio checked state should be preserved!"
+ );
+ Assert.equal(
+ doc.getElementById("aselect").selectedIndex,
+ 0,
+ "Modified select selected index should be preserved"
+ );
+}
+
+function getTempDir() {
+ return Services.dirsvc.get("TmpD", Ci.nsIFile);
+}
+
+function persistDocument(aDoc) {
+ const nsIWBP = Ci.nsIWebBrowserPersist;
+ const persistFlags =
+ nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES |
+ nsIWBP.PERSIST_FLAGS_FROM_CACHE |
+ nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+ const encodingFlags = nsIWBP.ENCODE_FLAGS_ENCODE_BASIC_ENTITIES;
+
+ var file = getTempDir();
+ file.append("bug293834-serialized.html");
+
+ var persist = Cc[
+ "@mozilla.org/embedding/browser/nsWebBrowserPersist;1"
+ ].createInstance(Ci.nsIWebBrowserPersist);
+ persist.progressListener = null;
+ persist.persistFlags = persistFlags;
+ const kWrapColumn = 80;
+ var folder = getTempDir();
+ folder.append("bug293834-serialized");
+ persist.saveDocument(
+ aDoc,
+ file,
+ folder,
+ "text/html",
+ encodingFlags,
+ kWrapColumn
+ );
+ return Services.io.newFileURI(file).spec;
+}
diff --git a/toolkit/components/windowcreator/test/bug1170334_iframe.xml b/toolkit/components/windowcreator/test/bug1170334_iframe.xml
new file mode 100644
index 0000000000..1821e07f96
--- /dev/null
+++ b/toolkit/components/windowcreator/test/bug1170334_iframe.xml
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<?xml-stylesheet href="bug1170334_style.css" type="text/css" title="&quot;?&gt;FAIL"?>
+<thing/>
diff --git a/toolkit/components/windowcreator/test/bug1170334_style.css b/toolkit/components/windowcreator/test/bug1170334_style.css
new file mode 100644
index 0000000000..476c22b695
--- /dev/null
+++ b/toolkit/components/windowcreator/test/bug1170334_style.css
@@ -0,0 +1 @@
+/* This stylesheet intentionally left blank. */
diff --git a/toolkit/components/windowcreator/test/bug1204626_doc0.html b/toolkit/components/windowcreator/test/bug1204626_doc0.html
new file mode 100644
index 0000000000..cbced762c3
--- /dev/null
+++ b/toolkit/components/windowcreator/test/bug1204626_doc0.html
@@ -0,0 +1,3 @@
+<!DOCTYPE html>
+<p>This is a document, and it contains an iframe:</p>
+<iframe src="bug1204626_doc1.html"></iframe>
diff --git a/toolkit/components/windowcreator/test/bug1204626_doc1.html b/toolkit/components/windowcreator/test/bug1204626_doc1.html
new file mode 100644
index 0000000000..cffc283d2c
--- /dev/null
+++ b/toolkit/components/windowcreator/test/bug1204626_doc1.html
@@ -0,0 +1,5 @@
+<!DOCTYPE html>
+<p>This is the document inside the iframe. <small>(Currently this
+document doesn't even need to exist in order to reproduce the bug in
+question, as long as the parent contains a frame, but it's probably
+best not to depend on that.)</small></p>
diff --git a/toolkit/components/windowcreator/test/bug449141_page.html b/toolkit/components/windowcreator/test/bug449141_page.html
new file mode 100644
index 0000000000..3b8e3f550a
--- /dev/null
+++ b/toolkit/components/windowcreator/test/bug449141_page.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+
+<html>
+ <head>
+ <title>Nested iframe for bug 449141</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ </head>
+ <body>
+ <video src='320x240.ogv'></video>
+ </body>
+</html>
diff --git a/toolkit/components/windowcreator/test/chrome.ini b/toolkit/components/windowcreator/test/chrome.ini
new file mode 100644
index 0000000000..9954dde591
--- /dev/null
+++ b/toolkit/components/windowcreator/test/chrome.ini
@@ -0,0 +1,11 @@
+[DEFAULT]
+support-files =
+ 320x240.ogv
+ bug449141_page.html
+ bug1170334_iframe.xml
+ bug1170334_style.css
+
+[test_bug449141.html]
+skip-if = toolkit == 'android'
+[test_bug1170334_wbp_xmlstyle.html]
+[test_bug1192654.html]
diff --git a/toolkit/components/windowcreator/test/file_form_state.html b/toolkit/components/windowcreator/test/file_form_state.html
new file mode 100644
index 0000000000..b5e4cd4ada
--- /dev/null
+++ b/toolkit/components/windowcreator/test/file_form_state.html
@@ -0,0 +1,25 @@
+<!DOCTYPE html>
+
+<html>
+ <head>
+ <title>Nested iframe for bug 293834</title>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ </head>
+ <body>
+ <form>
+ not prefilled: <input id="a-text" type="text"></input><br>
+ prefilled: <input id="a-prefilled-text" type="text" value="prefill "></input><br>
+
+ <input name="a-radio" id="radioa" value="radio-a" type="radio">Should be saved checked</input><br>
+ <input name="a-radio" value="radio-c" type="radio" checked="true">Initially checked</input><br>
+ <select id="aselect">
+ <option value="target">Should be saved selected</option>
+ <option value="default" selected="selected">Default Selected</option>
+ </select><br>
+ not prefilled: <textarea id="a-textbox"></textarea><br>
+ prefilled: <textarea id="a-prefilled-textbox">prefill </textarea><br>
+ <input id="a-checkbox" type="checkbox">Should be saved checked</input><br>
+ <input id="a-prefilled-checkbox" type="checkbox" checked="true">Initiallly checked</input><br>
+ </form>
+ </body>
+</html>
diff --git a/toolkit/components/windowcreator/test/file_persist_image.png b/toolkit/components/windowcreator/test/file_persist_image.png
new file mode 100644
index 0000000000..820f8cace2
--- /dev/null
+++ b/toolkit/components/windowcreator/test/file_persist_image.png
Binary files differ
diff --git a/toolkit/components/windowcreator/test/file_persist_picture_source.html b/toolkit/components/windowcreator/test/file_persist_picture_source.html
new file mode 100644
index 0000000000..26988cbf78
--- /dev/null
+++ b/toolkit/components/windowcreator/test/file_persist_picture_source.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<picture>
+ <source srcset="file_persist_image.png">
+ <img width=100 height=100>
+</picture>
diff --git a/toolkit/components/windowcreator/test/file_persist_srcset.html b/toolkit/components/windowcreator/test/file_persist_srcset.html
new file mode 100644
index 0000000000..46f9318ad9
--- /dev/null
+++ b/toolkit/components/windowcreator/test/file_persist_srcset.html
@@ -0,0 +1,3 @@
+<!doctype html>
+<img width=100 height=100 srcset="file_persist_image.png" onerror="this.alt = location.href;" alt="FAIL">
+<img width=100 height=100 srcset="file_persist_image.png 1x, file_persist_image.png 2x, file_persist_image.png 100w, file_persist_image_bad.png">
diff --git a/toolkit/components/windowcreator/test/file_persist_svg.html b/toolkit/components/windowcreator/test/file_persist_svg.html
new file mode 100644
index 0000000000..55de728352
--- /dev/null
+++ b/toolkit/components/windowcreator/test/file_persist_svg.html
@@ -0,0 +1,5 @@
+<!doctype html>
+<svg>
+ <image href="file_persist_image.png"/>
+ <image x="100" xlink:href="file_persist_image.png"/>
+</svg>
diff --git a/toolkit/components/windowcreator/test/mochitest.ini b/toolkit/components/windowcreator/test/mochitest.ini
new file mode 100644
index 0000000000..f90d819f5d
--- /dev/null
+++ b/toolkit/components/windowcreator/test/mochitest.ini
@@ -0,0 +1,5 @@
+[test_private_window_from_content.html]
+[test_window_open_position_constraint.html]
+skip-if = toolkit == 'android'
+[test_window_open_units.html]
+skip-if = toolkit == 'android' || (devedition && os == 'win' && bits == 32) # Windows: bug 1540566
diff --git a/toolkit/components/windowcreator/test/moz.build b/toolkit/components/windowcreator/test/moz.build
new file mode 100644
index 0000000000..bef136aaef
--- /dev/null
+++ b/toolkit/components/windowcreator/test/moz.build
@@ -0,0 +1,9 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOCHITEST_MANIFESTS += ["mochitest.ini"]
+MOCHITEST_CHROME_MANIFESTS += ["chrome.ini"]
+BROWSER_CHROME_MANIFESTS += ["browser.ini"]
diff --git a/toolkit/components/windowcreator/test/test_bug1170334_wbp_xmlstyle.html b/toolkit/components/windowcreator/test/test_bug1170334_wbp_xmlstyle.html
new file mode 100644
index 0000000000..89c160a50f
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_bug1170334_wbp_xmlstyle.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1170334
+-->
+<head>
+ <title>Test for Bug 1170334 (nsWebBrowserPersist vs. XML stylesheets)</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1170334">Mozilla Bug 1170334</a>
+<p id="display"></p>
+<pre id="results"></pre>
+<div id="content">
+ <iframe src="bug1170334_iframe.xml" id="iframe"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+const nameStem = "test_bug1170334_" + Date.now();
+const { Ci, Cc, Cu, Cr } = SpecialPowers;
+let iframe = document.getElementById("iframe");
+
+SimpleTest.waitForExplicitFinish();
+
+iframe.onload = function iframe_onload1() {
+ let doc = iframe.contentDocument;
+ ok(doc, "iframe content document exists");
+
+ let wbp = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+ .createInstance(Ci.nsIWebBrowserPersist);
+ let tmp = SpecialPowers.Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let tmpFile = tmp.clone();
+ tmpFile.append(nameStem + "_iframe.xml");
+ let tmpDir = tmp.clone();
+ tmpDir.append(nameStem + "_files");
+
+ // When the document in the iframe is saved, try to load the result.
+ wbp.progressListener = {
+ onProgressChange() {},
+ onLocationChange() {},
+ onStatusChange() {},
+ onSecurityChange() {},
+ onContentBlockingEvent() {},
+ onStateChange: function wbp_stateChange(_wbp, _req, state, status) {
+ if ((state & Ci.nsIWebProgressListener.STATE_STOP) == 0) {
+ return;
+ }
+ is(status, Cr.NS_OK, "nsWebBrowserPersist status");
+ iframe.onload = function iframe_onload2() {
+ let elem = iframe.contentDocument.documentElement;
+ is(elem && elem.tagName, "thing", "document element tag");
+ if (elem && elem.tagName == "parsererror") {
+ ok(false, "Parser error: " + elem.textContent);
+ }
+
+ cleanUp();
+ SimpleTest.finish();
+ };
+ iframe.src = SpecialPowers.Services.io.newFileURI(tmpFile).spec;
+ },
+ };
+ wbp.saveDocument(doc, tmpFile, tmpDir, null, 0, 0);
+
+ function cleanUp() {
+ if (tmpFile.exists()) {
+ tmpFile.remove(/* recursive: */ false);
+ }
+ if (tmpDir.exists()) {
+ tmpDir.remove(/* recursive: */ true);
+ }
+ }
+};
+</script>
+</pre>
+</body>
+</html>
diff --git a/toolkit/components/windowcreator/test/test_bug1192654.html b/toolkit/components/windowcreator/test/test_bug1192654.html
new file mode 100644
index 0000000000..8ec01630ff
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_bug1192654.html
@@ -0,0 +1,77 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=1192654
+-->
+<head>
+ <title>Test for Bug 1192654 (nsWebBrowser vs. nonpersistable subdocuments)</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1192654">Mozilla Bug 1192654</a>
+<p id="display"></p>
+<pre id="results"></pre>
+<div id="content">
+ <!-- The outer iframe uses a data URI for simplicity; this would
+ also work if it were loaded from a support file by relative
+ URI. The inner iframe (the one nsWebBrowserPersist traverses)
+ uses a data URI because data: is a non-persistable scheme and
+ thus triggers the bug.
+ -->
+ <iframe src="data:text/html,<iframe%20src=%22data:text/plain,Example%22>"
+ id="iframe"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+const nameStem = "test_bug1192654_" + Date.now();
+const { Ci, Cc, Cu, Cr } = SpecialPowers;
+let iframe = document.getElementById("iframe");
+
+SimpleTest.waitForExplicitFinish();
+
+iframe.onload = function iframe_onload1() {
+ let doc = iframe.contentDocument;
+ ok(doc, "iframe content document exists");
+
+ let wbp = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+ .createInstance(Ci.nsIWebBrowserPersist);
+ let tmp = SpecialPowers.Services.dirsvc.get("TmpD", Ci.nsIFile);
+ let tmpFile = tmp.clone();
+ tmpFile.append(nameStem + "_iframe.xml");
+ let tmpDir = tmp.clone();
+ tmpDir.append(nameStem + "_files");
+
+ wbp.progressListener = {
+ onProgressChange() {},
+ onLocationChange() {},
+ onStatusChange() {},
+ onSecurityChange() {},
+ onContentBlockingEvent() {},
+ onStateChange: wbp_stateChange,
+ };
+ SimpleTest.registerCleanupFunction(cleanUp);
+
+ wbp.saveDocument(doc, tmpFile, tmpDir, null, 0, 0);
+
+ function wbp_stateChange(_wbp, _req, state, status) {
+ if ((state & Ci.nsIWebProgressListener.STATE_STOP) == 0) {
+ return;
+ }
+ is(status, Cr.NS_OK, "nsWebBrowserPersist status");
+ SimpleTest.finish();
+ }
+
+ function cleanUp() {
+ if (tmpFile.exists()) {
+ tmpFile.remove(/* recursive: */ false);
+ }
+ if (tmpDir.exists()) {
+ tmpDir.remove(/* recursive: */ true);
+ }
+ }
+};
+</script>
+</pre>
+</body>
+</html>
diff --git a/toolkit/components/windowcreator/test/test_bug449141.html b/toolkit/components/windowcreator/test/test_bug449141.html
new file mode 100644
index 0000000000..f178689599
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_bug449141.html
@@ -0,0 +1,96 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=449141
+-->
+<head>
+ <title>Test for Bug 449141</title>
+ <script src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=449141">Mozilla Bug 449141</a>
+<p id="display">
+
+</p>
+<pre id="results"></pre>
+<div id="content" style="display: none">
+ <iframe src="bug449141_page.html" id="source"></iframe>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+/** Test for Bug 449141 */
+
+const Cc = SpecialPowers.Cc;
+const Ci = SpecialPowers.Ci;
+
+function getTempDir() {
+ return SpecialPowers.Services.dirsvc.get("TmpD", Ci.nsIFile);
+}
+
+// STATE_STOP from nsIWebProgressListener.idl
+const STATE_STOP = 0x00000010;
+
+var progressListener = {
+ onProgressChange() {
+ /* Ignore progress callback */
+ },
+ onStateChange(aProgress, aRequest, aStateFlag, aStatus) {
+ if (aStateFlag & STATE_STOP) {
+ var dirExists = false;
+ var videoExists = false;
+
+ var videoFile = getTempDir();
+ videoFile.append(this.dirName);
+ dirExists = videoFile.exists();
+ videoFile.append("320x240.ogv");
+ videoExists = videoFile.exists();
+ this.folder.remove(true);
+ this.file.remove(false);
+ ok(dirExists, "Directory containing video file should be created");
+ ok(videoExists, "Video should be persisted with document");
+ SimpleTest.finish();
+ }
+ },
+};
+
+function persistDocument(aDoc) {
+ const nsIWBP = Ci.nsIWebBrowserPersist;
+ const persistFlags =
+ nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES
+ | nsIWBP.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;
+ const encodingFlags =
+ nsIWBP.ENCODE_FLAGS_ENCODE_BASIC_ENTITIES;
+
+ var id = Math.round(Math.random() * 10000);
+ var dirName = "bug449141_serialized" + id;
+ progressListener.dirName = dirName;
+
+ var file = getTempDir();
+ file.append("bug449141-serialized" + id + ".html");
+
+ var persist = Cc["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
+ .createInstance(Ci.nsIWebBrowserPersist);
+ persist.progressListener = progressListener;
+ persist.persistFlags = persistFlags;
+ const kWrapColumn = 80;
+ var folder = getTempDir();
+ folder.append(dirName);
+ progressListener.folder = folder;
+ progressListener.file = file;
+ persist.saveDocument(aDoc, SpecialPowers.Services.io.newFileURI(file),
+ folder,
+ aDoc.contentType,
+ encodingFlags, kWrapColumn);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+addLoadEvent(function() {
+ var srcDoc = document.getElementById("source").contentDocument;
+ persistDocument(srcDoc);
+});
+</script>
+</pre>
+</body>
+</html>
diff --git a/toolkit/components/windowcreator/test/test_private_window_from_content.html b/toolkit/components/windowcreator/test/test_private_window_from_content.html
new file mode 100644
index 0000000000..82ba0d9388
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_private_window_from_content.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<script src="/tests/SimpleTest/SimpleTest.js"></script>
+<script>
+ // Make sure that we cannot open private browsing windows from unprivileged content
+ var win = window.open("about:blank", "_blank", "private");
+ ok(!SpecialPowers.isContentWindowPrivate(win));
+ win.close();
+ // Also, make sure that passing non-private doesn't make any difference either
+ win = window.open("about:blank", "_blank", "non-private");
+ ok(!SpecialPowers.isContentWindowPrivate(win));
+ win.close();
+</script>
diff --git a/toolkit/components/windowcreator/test/test_window_open_position_constraint.html b/toolkit/components/windowcreator/test/test_window_open_position_constraint.html
new file mode 100644
index 0000000000..80e2371ed1
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_window_open_position_constraint.html
@@ -0,0 +1,56 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 978847</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=978847">Mozilla Bug 978847</a>
+<p id="display"></p>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ var x;
+ var y;
+
+ // window should be constrained to the screen rect,
+ // which we assume is less than 10000px square
+ var w1 = window.open("about:blank", "", "left=16000,top=16000,width=100,height=100");
+ SimpleTest.waitForFocus(function() {
+ ok(w1.screenX < 10000 && w1.screenY < 10000,
+ "window should not be opened off-screen: got location " +
+ w1.screenX + "," + w1.screenY);
+ x = w1.screenX;
+ y = w1.screenY;
+ w1.close();
+
+ // larger window dimensions should result in a shift of the constrained location
+ var w2 = window.open("about:blank", "", "left=16000,top=16000,width=150,height=150");
+ SimpleTest.waitForFocus(function() {
+ ok(w2.screenX == x - 50 && w2.screenY == y - 50,
+ "constrained window position did not depend on size as expected: got " +
+ w2.screenX + "," + w2.screenY + ", expected " + (x - 50) + "," + (y - 50));
+ w2.close();
+
+ // now try with coordinates that are close to MAXINT,
+ // so adding width/height risks 32-bit integer overflow
+ var w3 = window.open("about:blank", "", "left=2147483600,top=2147483600,width=100,height=100");
+ SimpleTest.waitForFocus(function() {
+ ok(w3.screenX < 10000 && w3.screenY < 10000,
+ "window should not be opened off-screen: got location " +
+ w3.screenX + "," + w3.screenY);
+ w3.close();
+ SimpleTest.finish();
+ }, w3, true);
+ }, w2, true);
+ }, w1, true);
+}, window, false);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/toolkit/components/windowcreator/test/test_window_open_units.html b/toolkit/components/windowcreator/test/test_window_open_units.html
new file mode 100644
index 0000000000..b6f75b7fe9
--- /dev/null
+++ b/toolkit/components/windowcreator/test/test_window_open_units.html
@@ -0,0 +1,36 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+ <title>Test for Bug 594140</title>
+ <script src="/tests/SimpleTest/SimpleTest.js"></script>
+ <script src="/tests/SimpleTest/WindowSnapshot.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=594140">Mozilla Bug 594140</a>
+<p id="display"></p>
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+SimpleTest.waitForExplicitFinish();
+
+SimpleTest.waitForFocus(function() {
+ SpecialPowers.setFullZoom(window, 2);
+
+ var w = window.open("about:blank", "", "width=200,height=100");
+ SimpleTest.waitForFocus(function() {
+ ok(w.innerWidth <= 402 && w.innerWidth >= 398,
+ "width (" + w.innerWidth + ") should be around twice what was requested (200)");
+ ok(w.innerHeight <= 202 && w.innerHeight >= 198,
+ "height (" + w.innerHeight + ") should be around twice what was requested (100)");
+
+ SpecialPowers.setFullZoom(window, 1);
+ w.close();
+ SimpleTest.finish();
+ }, w, true);
+}, window, false);
+
+</script>
+</pre>
+</body>
+</html>
diff --git a/toolkit/components/windowcreator/tests/unit/test_wwauthpromptfactory.js b/toolkit/components/windowcreator/tests/unit/test_wwauthpromptfactory.js
new file mode 100644
index 0000000000..ba4d4b8f9b
--- /dev/null
+++ b/toolkit/components/windowcreator/tests/unit/test_wwauthpromptfactory.js
@@ -0,0 +1,55 @@
+var authPromptRequestReceived;
+
+const tPFCID = Components.ID("{749e62f4-60ae-4569-a8a2-de78b649660f}");
+const tPFContract = "@mozilla.org/passwordmanager/authpromptfactory;1";
+
+/*
+ * TestPromptFactory
+ *
+ * Implements nsIPromptFactory
+ */
+var TestPromptFactory = {
+ QueryInterface: ChromeUtils.generateQI(["nsIFactory", "nsIPromptFactory"]),
+
+ createInstance: function tPF_ci(iid) {
+ return this.QueryInterface(iid);
+ },
+
+ getPrompt: function tPF_getPrompt(aWindow, aIID) {
+ if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) {
+ authPromptRequestReceived = true;
+ return {};
+ }
+
+ throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE);
+ },
+}; // end of TestPromptFactory implementation
+
+/*
+ * The tests
+ */
+function run_test() {
+ Components.manager.nsIComponentRegistrar.registerFactory(
+ tPFCID,
+ "TestPromptFactory",
+ tPFContract,
+ TestPromptFactory
+ );
+
+ // Make sure that getting both nsIAuthPrompt and nsIAuthPrompt2 works
+ // (these should work independently of whether the application has
+ // nsIPromptService)
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService();
+
+ authPromptRequestReceived = false;
+
+ Assert.notEqual(ww.nsIPromptFactory.getPrompt(null, Ci.nsIAuthPrompt), null);
+
+ Assert.ok(authPromptRequestReceived);
+
+ authPromptRequestReceived = false;
+
+ Assert.notEqual(ww.nsIPromptFactory.getPrompt(null, Ci.nsIAuthPrompt2), null);
+
+ Assert.ok(authPromptRequestReceived);
+}
diff --git a/toolkit/components/windowcreator/tests/unit/test_wwpromptfactory.js b/toolkit/components/windowcreator/tests/unit/test_wwpromptfactory.js
new file mode 100644
index 0000000000..92c8d90c1f
--- /dev/null
+++ b/toolkit/components/windowcreator/tests/unit/test_wwpromptfactory.js
@@ -0,0 +1,20 @@
+function run_test() {
+ // Make sure that getting both nsIAuthPrompt and nsIAuthPrompt2 works
+ // (these should work independently of whether the application has
+ // nsIPromptService)
+ var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].getService();
+
+ var prompt;
+
+ prompt = ww.nsIWindowWatcher.getNewPrompter(null);
+ Assert.notEqual(prompt, null);
+ prompt = ww.nsIWindowWatcher.getNewAuthPrompter(null);
+ Assert.notEqual(prompt, null);
+
+ prompt = ww.nsIPromptFactory.getPrompt(null, Ci.nsIPrompt);
+ Assert.notEqual(prompt, null);
+ prompt = ww.nsIPromptFactory.getPrompt(null, Ci.nsIAuthPrompt);
+ Assert.notEqual(prompt, null);
+ prompt = ww.nsIPromptFactory.getPrompt(null, Ci.nsIAuthPrompt2);
+ Assert.notEqual(prompt, null);
+}
diff --git a/toolkit/components/windowcreator/tests/unit/xpcshell.ini b/toolkit/components/windowcreator/tests/unit/xpcshell.ini
new file mode 100644
index 0000000000..bd6eb7a043
--- /dev/null
+++ b/toolkit/components/windowcreator/tests/unit/xpcshell.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+head =
+
+[test_wwauthpromptfactory.js]
+[test_wwpromptfactory.js]