--- a/browser/components/urlbar/UrlbarController.jsm
+++ b/browser/components/urlbar/UrlbarController.jsm
@@ -1,18 +1,24 @@
/* 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/. */
"use strict";
var EXPORTED_SYMBOLS = ["QueryContext", "UrlbarController"];
-ChromeUtils.import("resource://gre/modules/Services.jsm");
-ChromeUtils.import("resource:///modules/UrlbarProvidersManager.jsm");
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetters(this, {
+ // BrowserUsageTelemetry: "resource:///modules/BrowserUsageTelemetry.jsm",
+ Services: "resource://gre/modules/Services.jsm",
+ UrlbarPrefs: "resource:///modules/UrlbarPrefs.jsm",
+ UrlbarProvidersManager: "resource:///modules/UrlbarProvidersManager.jsm",
+ UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
+});
/**
* QueryContext defines a user's autocomplete input from within the Address Bar.
* It supplements it with details of how the search results should be obtained
* and what they consist of.
*/
class QueryContext {
/**
@@ -73,24 +79,31 @@ class QueryContext {
* - onQueryResults(queryContext)
* - onQueryCancelled(queryContext)
*/
class UrlbarController {
/**
* Initialises the class. The manager may be overridden here, this is for
* test purposes.
*
- * @param {object} [options]
+ * @param {object} options
* The initial options for UrlbarController.
+ * @param {object} options.window
+ * The window this controller is operating within.
* @param {object} [options.manager]
* Optional fake providers manager to override the built-in providers manager.
* Intended for use in unit tests only.
*/
constructor(options = {}) {
+ if (!options.window) {
+ throw new Error("Missing options: window");
+ }
+
this.manager = options.manager || UrlbarProvidersManager;
+ this.window = options.window;
this._listeners = new Set();
}
/**
* Takes a query context and starts the query based on the user input.
*
* @param {QueryContext} queryContext The query details.
@@ -120,16 +133,114 @@ class UrlbarController {
*
* @param {QueryContext} queryContext The query details.
*/
receiveResults(queryContext) {
this._notify("onQueryResults", queryContext);
}
/**
+ * Handles the case where a url or other text has been entered into the
+ * urlbar. This will either load the URL, or some text that could be a keyword
+ * or a simple value to load via the default search engine.
+ *
+ * @param {Event} event The event that triggered this.
+ * @param {string} text The text that was entered into the urlbar.
+ * @param {string} [openWhere] Where we expect the result to be opened.
+ * @param {object} [openParams]
+ * The parameters related to how and where the result will be opened.
+ * For possible properties @see {_loadURL}
+ */
+ handleEnteredText(event, text, openWhere, openParams = {}) {
+ let browser = this.window.gBrowser.selectedBrowser;
+ let where = openWhere || this._whereToOpen(event);
+
+ openParams.postData = null;
+ openParams.allowInheritPrincipal = false;
+
+ // TODO: Work out how we get the user selection behavior, probably via passing
+ // it in, since we don't have the old autocomplete controller to work with.
+ // BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
+ // event, this.userSelectionBehavior);
+
+ text = text.trim();
+
+ try {
+ new URL(text);
+ } catch (ex) {
+ // TODO: Figure out why we need lastLocationChange here.
+ // TODO: Possibly move getShortcutOrURIAndPostData into a utility function
+ // in a jsm (there's nothing window specific about it).
+ // let lastLocationChange = browser.lastLocationChange;
+ // getShortcutOrURIAndPostData(text).then(data => {
+ // if (where != "current" ||
+ // browser.lastLocationChange == lastLocationChange) {
+ // params.postData = data.postData;
+ // params.allowInheritPrincipal = data.mayInheritPrincipal;
+ // this._loadURL(data.url, browser, where,
+ // openUILinkParams);
+ // }
+ // });
+ return;
+ }
+
+ this._loadURL(text, browser, where, openParams);
+ }
+
+ /**
+ * Opens a specific result that has been selected.
+ *
+ * @param {Event} event The event that triggered this.
+ * @param {UrlbarMatch} result The result that was selected.
+ * @param {string} [openWhere] Where we expect the result to be opened.
+ * @param {object} [openParams]
+ * The parameters related to how and where the result will be opened.
+ * For possible properties @see {_loadURL}
+ */
+ resultSelected(event, result, openWhere, openParams = {}) {
+ // TODO: Work out how we get the user selection behavior, probably via passing
+ // it in, since we don't have the old autocomplete controller to work with.
+ // BrowserUsageTelemetry.recordUrlbarSelectedResultMethod(
+ // event, this.userSelectionBehavior);
+
+ let where = openWhere || this._whereToOpen(event);
+ openParams.postData = null;
+ openParams.allowInheritPrincipal = false;
+ let browser = this.window.gBrowser.selectedBrowser;
+ let url = result.url;
+
+ switch (result.type) {
+ case UrlbarUtils.MATCH_TYPE.TAB_SWITCH: {
+ // TODO: Implement handleRevert or equivalent on the input.
+ // this.input.handleRevert();
+ let prevTab = this.window.gBrowser.selectedTab;
+ let loadOpts = {
+ adoptIntoActiveWindow: UrlbarPrefs.get("switchTabs.adoptIntoActiveWindow"),
+ };
+
+ if (this.window.switchToTabHavingURI(url, false, loadOpts) &&
+ this.window.isTabEmpty(prevTab)) {
+ this.window.gBrowser.removeTab(prevTab);
+ }
+ return;
+
+ // TODO: How to handle meta chars?
+ // Once we get here, we got a TAB_SWITCH match but the user
+ // bypassed it by pressing shift/meta/ctrl. Those modifiers
+ // might otherwise affect where we open - we always want to
+ // open in the current tab.
+ // where = "current";
+
+ }
+ }
+
+ this._loadURL(url, browser, where, openParams);
+ }
+
+ /**
* Adds a listener for query actions and results.
*
* @param {object} listener The listener to add.
* @throws {TypeError} Throws if the listener is not an object.
*/
addQueryListener(listener) {
if (!listener || typeof listener != "object") {
throw new TypeError("Expected listener to be an object");
@@ -164,9 +275,118 @@ class UrlbarController {
for (let listener of this._listeners) {
try {
listener[name](...params);
} catch (ex) {
Cu.reportError(ex);
}
}
}
+
+ /**
+ * Loads the url in the appropriate place.
+ *
+ * @param {string} url
+ * The URL to open.
+ * @param {object} browser
+ * The browser to open it in.
+ * @param {string} openUILinkWhere
+ * Where we expect the result to be opened.
+ * @param {object} params
+ * The parameters related to how and where the result will be opened.
+ * Further supported paramters are listed in utilityOverlay.js#openUILinkIn.
+ * @param {object} params.triggeringPrincipal
+ * The principal that the action was triggered from.
+ * @param {nsIInputStream} [params.postData]
+ * The POST data associated with a search submission.
+ * @param {boolean} [params.allowInheritPrincipal]
+ * If the principal may be inherited
+ */
+ _loadURL(url, browser, openUILinkWhere, params) {
+ // TODO: These should probably be set by the input field.
+ // this.value = url;
+ // browser.userTypedValue = url;
+ if (this.window.gInitialPages.includes(url)) {
+ browser.initialPageLoadedFromURLBar = url;
+ }
+ try {
+ // TODO: Move function to PlacesUIUtils.
+ this.window.addToUrlbarHistory(url);
+ } catch (ex) {
+ // Things may go wrong when adding url to session history,
+ // but don't let that interfere with the loading of the url.
+ Cu.reportError(ex);
+ }
+
+ params.allowThirdPartyFixup = true;
+
+ if (openUILinkWhere == "current") {
+ params.targetBrowser = browser;
+ params.indicateErrorPageLoad = true;
+ params.allowPinnedTabHostChange = true;
+ params.allowPopups = url.startsWith("javascript:");
+ } else {
+ params.initiatingDoc = this.window.document;
+ }
+
+ // Focus the content area before triggering loads, since if the load
+ // occurs in a new tab, we want focus to be restored to the content
+ // area when the current tab is re-selected.
+ browser.focus();
+
+ if (openUILinkWhere != "current") {
+ // TODO: Implement handleRevert or equivalent on the input.
+ // this.input.handleRevert();
+ }
+
+ try {
+ this.window.openTrustedLinkIn(url, openUILinkWhere, params);
+ } catch (ex) {
+ // This load can throw an exception in certain cases, which means
+ // we'll want to replace the URL with the loaded URL:
+ if (ex.result != Cr.NS_ERROR_LOAD_SHOWED_ERRORPAGE) {
+ // TODO: Implement handleRevert or equivalent on the input.
+ // this.input.handleRevert();
+ }
+ }
+
+ // TODO This should probably be handed via input.
+ // Ensure the start of the URL is visible for usability reasons.
+ // this.selectionStart = this.selectionEnd = 0;
+ }
+
+ /**
+ * Determines where a URL/page should be opened.
+ *
+ * @param {Event} event the event triggering the opening.
+ * @returns {"current" | "tabshifted" | "tab" | "save" | "window"}
+ */
+ _whereToOpen(event) {
+ let isMouseEvent = event instanceof this.window.MouseEvent;
+ let reuseEmpty = !isMouseEvent;
+ let where = undefined;
+ if (!isMouseEvent && event && event.altKey) {
+ // We support using 'alt' to open in a tab, because ctrl/shift
+ // might be used for canonizing URLs:
+ where = event.shiftKey ? "tabshifted" : "tab";
+ } else if (!isMouseEvent && this._ctrlCanonizesURLs && event && event.ctrlKey) {
+ // If we're allowing canonization, and this is a key event with ctrl
+ // pressed, open in current tab to allow ctrl-enter to canonize URL.
+ where = "current";
+ } else {
+ where = this.window.whereToOpenLink(event, false, false);
+ }
+ if (this.openInTab) {
+ if (where == "current") {
+ where = "tab";
+ } else if (where == "tab") {
+ where = "current";
+ }
+ reuseEmpty = true;
+ }
+ if (where == "tab" &&
+ reuseEmpty &&
+ this.window.isTabEmpty(this.window.gBrowser.selectedTab)) {
+ where = "current";
+ }
+ return where;
+ }
}
--- a/browser/components/urlbar/UrlbarInput.jsm
+++ b/browser/components/urlbar/UrlbarInput.jsm
@@ -39,17 +39,19 @@ class UrlbarInput {
* Intended for use in unit tests only.
*/
constructor(options = {}) {
this.textbox = options.textbox;
this.textbox.clickSelectsAll = UrlbarPrefs.get("clickSelectsAll");
this.panel = options.panel;
this.window = this.textbox.ownerGlobal;
- this.controller = options.controller || new UrlbarController();
+ this.controller = options.controller || new UrlbarController({
+ window: this.window,
+ });
this.view = new UrlbarView(this);
this.valueIsTyped = false;
this.userInitiatedFocus = false;
this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.window);
// Forward textbox methods and properties.
const METHODS = ["addEventListener", "removeEventListener",
"setAttribute", "hasAttribute", "removeAttribute", "getAttribute",
@@ -93,16 +95,17 @@ class UrlbarInput {
this.inputField.addEventListener("blur", this);
this.inputField.addEventListener("focus", this);
this.inputField.addEventListener("mousedown", this);
this.inputField.addEventListener("mouseover", this);
this.inputField.addEventListener("overflow", this);
this.inputField.addEventListener("underflow", this);
this.inputField.addEventListener("scrollend", this);
this.inputField.addEventListener("select", this);
+ this.inputField.addEventListener("keyup", this);
this.inputField.controllers.insertControllerAt(0, new CopyCutController(this));
}
/**
* Shortens the given value, usually by removing http:// and trailing slashes,
* such that calling nsIURIFixup::createFixupURI with the result will produce
* the same URI.
@@ -151,29 +154,89 @@ class UrlbarInput {
try {
return Services.uriFixup.createExposableURI(uri);
} catch (ex) {}
return uri;
}
/**
- * Passes DOM events for the textbox to the _on<event type> methods.
+ * Passes DOM events for the textbox to the _on_<event type> methods.
* @param {Event} event
* DOM event from the <textbox>.
*/
handleEvent(event) {
let methodName = "_on_" + event.type;
if (methodName in this) {
this[methodName](event);
} else {
throw "Unrecognized urlbar event: " + event.type;
}
}
+ /**
+ * Handles an event which would cause a url or text to be opened.
+ * XXX the name is currently handleCommand which is compatible with
+ * urlbarBindings. However, it is no longer called automatically by autocomplete,
+ * See _on_keyup.
+ *
+ * @param {Event} event The event triggering the open.
+ * @param {string} [openWhere] Where we expect the result to be opened.
+ * @param {object} [openParams]
+ * The parameters related to where the result will be opened.
+ * @param {object} [triggeringPrincipal]
+ * The principal that the action was triggered from.
+ */
+ handleCommand(event, openWhere, openParams, triggeringPrincipal) {
+ let isMouseEvent = event instanceof this.window.MouseEvent;
+ if (isMouseEvent && event.button == 2) {
+ // Do nothing for right clicks.
+ return;
+ }
+
+ // TODO: Hook up one-off button handling.
+ // Determine whether to use the selected one-off search button. In
+ // one-off search buttons parlance, "selected" means that the button
+ // has been navigated to via the keyboard. So we want to use it if
+ // the triggering event is not a mouse click -- i.e., it's a Return
+ // key -- or if the one-off was mouse-clicked.
+ // let selectedOneOff = this.popup.oneOffSearchButtons.selectedButton;
+ // if (selectedOneOff &&
+ // isMouseEvent &&
+ // event.originalTarget != selectedOneOff) {
+ // selectedOneOff = null;
+ // }
+ //
+ // // Do the command of the selected one-off if it's not an engine.
+ // if (selectedOneOff && !selectedOneOff.engine) {
+ // selectedOneOff.doCommand();
+ // return;
+ // }
+
+ let url = this.value;
+ if (!url) {
+ return;
+ }
+
+ this.controller.handleEnteredText(event, url);
+
+ this.view.close();
+ }
+
+ /**
+ * Called by the view when a result is selected.
+ *
+ * @param {Event} event The event that selected the result.
+ * @param {UrlbarMatch} result The result that was selected.
+ */
+ resultSelected(event, result) {
+ // TODO: Set the input value to the target url.
+ this.controller.resultSelected(event, result);
+ }
+
// Getters and Setters below.
get focused() {
return this.textbox.getAttribute("focused") == "true";
}
get value() {
return this.inputField.value;
@@ -410,16 +473,25 @@ class UrlbarInput {
_on_scrollend(event) {
this._updateTextOverflow();
}
_on_TabSelect(event) {
this.controller.tabContextChanged();
}
+
+ _on_keyup(event) {
+ // TODO: We may have an autoFill entry, so we should use that instead.
+ // TODO: We should have an input bufferrer so that we can use search results
+ // if appropriate.
+ if (event.key == "Enter") {
+ this.handleCommand(event);
+ }
+ }
}
/**
* Handles copy and cut commands for the urlbar.
*/
class CopyCutController {
/**
* @param {UrlbarInput} urlbar
--- a/browser/components/urlbar/UrlbarPrefs.jsm
+++ b/browser/components/urlbar/UrlbarPrefs.jsm
@@ -103,16 +103,20 @@ const PREF_URLBAR_DEFAULTS = new Map([
["suggest.history.onlyTyped", false],
// Results will include switch-to-tab results when this is true.
["suggest.openpage", true],
// Results will include search suggestions when this is true.
["suggest.searches", false],
+ // When using switch to tabs, if set to true this will move the tab into the
+ // active window.
+ ["switchTabs.adoptIntoActiveWindow", false],
+
// Remove redundant portions from URLs.
["trimURLs", true],
// Results will include a built-in set of popular domains when this is true.
["usepreloadedtopurls.enabled", true],
// After this many days from the profile creation date, the built-in set of
// popular domains will no longer be included in the results.
--- a/browser/components/urlbar/UrlbarView.jsm
+++ b/browser/components/urlbar/UrlbarView.jsm
@@ -70,46 +70,51 @@ class UrlbarView {
this._rows.firstElementChild.toggleAttribute("selected", true);
}
/**
* Closes the autocomplete results popup.
*/
close() {
+ this.panel.hidePopup();
}
// UrlbarController listener methods.
onQueryStarted(queryContext) {
this._rows.textContent = "";
}
onQueryResults(queryContext) {
// XXX For now, clear the results for each set received. We should really
// be updating the existing list.
this._rows.textContent = "";
- for (let result of queryContext.results) {
- this._addRow(result);
+ this._queryContext = queryContext;
+ for (let resultIndex in queryContext.results) {
+ this._addRow(resultIndex);
}
this.open();
}
// Private methods below.
_getBoundsWithoutFlushing(element) {
return this.window.windowUtils.getBoundsWithoutFlushing(element);
}
_createElement(name) {
return this.document.createElementNS("http://www.w3.org/1999/xhtml", name);
}
- _addRow(result) {
+ _addRow(resultIndex) {
+ let result = this._queryContext.results[resultIndex];
let item = this._createElement("div");
item.className = "urlbarView-row";
+ item.addEventListener("click", this);
+ item.setAttribute("resultIndex", resultIndex);
if (result.type == UrlbarUtils.MATCH_TYPE.TAB_SWITCH) {
item.setAttribute("action", "switch-to-tab");
}
let content = this._createElement("span");
content.className = "urlbarView-row-inner";
item.appendChild(content);
@@ -134,9 +139,36 @@ class UrlbarView {
} else {
secondary.classList.add("urlbarView-url");
secondary.textContent = result.url;
}
content.appendChild(secondary);
this._rows.appendChild(item);
}
+
+ /**
+ * Passes DOM events for the view to the _on_<event type> methods.
+ * @param {Event} event
+ * DOM event from the <view>.
+ */
+ handleEvent(event) {
+ let methodName = "_on_" + event.type;
+ if (methodName in this) {
+ this[methodName](event);
+ } else {
+ throw "Unrecognized urlbar event: " + event.type;
+ }
+ }
+
+ _on_click(event) {
+ let row = event.target;
+ while (!row.classList.contains("urlbarView-row")) {
+ row = row.parentNode;
+ }
+ let resultIndex = row.getAttribute("resultIndex");
+ let result = this._queryContext.results[resultIndex];
+ if (result) {
+ this.urlbar.resultSelected(event, result);
+ }
+ this.close();
+ }
}
--- a/browser/components/urlbar/tests/browser/browser.ini
+++ b/browser/components/urlbar/tests/browser/browser.ini
@@ -1,8 +1,11 @@
# 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/.
[DEFAULT]
+support-files =
+ head.js
+[browser_UrlbarController_resultOpening.js]
[browser_UrlbarInput_unit.js]
support-files = empty.xul
new file mode 100644
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/browser_UrlbarController_resultOpening.js
@@ -0,0 +1,76 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * These tests unit test the result/url loading functionality of UrlbarController.
+ */
+
+"use strict";
+
+let controller;
+
+add_task(async function setup() {
+ sandbox = sinon.sandbox.create();
+
+ controller = new UrlbarController({
+ window,
+ });
+
+ registerCleanupFunction(async () => {
+ sandbox.restore();
+ });
+});
+
+add_task(function test_handleEnteredText_url() {
+ sandbox.stub(window, "openTrustedLinkIn");
+
+ const event = new KeyboardEvent("keyup", {key: "Enter"});
+ // Additional spaces in the url to check that we trim correctly.
+ controller.handleEnteredText(event, " https://example.com ");
+
+ Assert.ok(window.openTrustedLinkIn.calledOnce,
+ "Should have triggered opening the url.");
+
+ let args = window.openTrustedLinkIn.args[0];
+
+ Assert.equal(args[0], "https://example.com",
+ "Should have triggered opening with the correct url");
+ Assert.equal(args[1], "current",
+ "Should be opening in the current browser");
+ Assert.deepEqual(args[2], {
+ allowInheritPrincipal: false,
+ allowPinnedTabHostChange: true,
+ allowPopups: false,
+ allowThirdPartyFixup: true,
+ indicateErrorPageLoad: true,
+ postData: null,
+ targetBrowser: gBrowser.selectedBrowser,
+ }, "Should have the correct additional parameters for opening");
+
+ sandbox.restore();
+});
+
+add_task(function test_resultSelected_switchtab() {
+ sandbox.stub(window, "switchToTabHavingURI").returns(true);
+ sandbox.stub(window, "isTabEmpty").returns(false);
+ sandbox.stub(window.gBrowser, "removeTab");
+
+ const event = new MouseEvent("click", {button: 0});
+ const url = "https://example.com/1";
+ const result = new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH, {url});
+
+ controller.resultSelected(event, result);
+
+ Assert.ok(window.switchToTabHavingURI.calledOnce,
+ "Should have triggered switching to the tab");
+
+ let args = window.switchToTabHavingURI.args[0];
+
+ Assert.equal(args[0], url, "Should have passed the expected url");
+ Assert.ok(!args[1], "Should not attempt to open a new tab");
+ Assert.deepEqual(args[2], {
+ adoptIntoActiveWindow: UrlbarPrefs.get("switchTabs.adoptIntoActiveWindow"),
+ }, "Should have the correct additional parameters for opening");
+
+ sandbox.restore();
+});
--- a/browser/components/urlbar/tests/browser/browser_UrlbarInput_unit.js
+++ b/browser/components/urlbar/tests/browser/browser_UrlbarInput_unit.js
@@ -4,30 +4,20 @@
/**
* These tests unit test the functionality of UrlbarController by stubbing out the
* model and providing stubs to be called.
*/
"use strict";
let fakeController;
-let sandbox;
let generalListener;
let input;
let inputOptions;
-ChromeUtils.import("resource:///modules/UrlbarController.jsm", this);
-
-/* global sinon */
-Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
-
-registerCleanupFunction(function() {
- delete window.sinon;
-});
-
/**
* Asserts that the query context has the expected values.
*
* @param {QueryContext} context
* @param {object} expectedValues The expected values for the QueryContext.
*/
function assertContextMatches(context, expectedValues) {
Assert.ok(context instanceof QueryContext,
@@ -64,17 +54,19 @@ function checkStartQueryCall(stub, expec
Assert.deepEqual(queryContext[name],
value, `Should have the correct value for queryContext.${name}`);
}
}
add_task(async function setup() {
sandbox = sinon.sandbox.create();
- fakeController = new UrlbarController();
+ fakeController = new UrlbarController({
+ window,
+ });
sandbox.stub(fakeController, "startQuery");
sandbox.stub(PrivateBrowsingUtils, "isWindowPrivate").returns(false);
// Open a new window, so we don't affect other tests by adding extra
// UrbarInput wrappers around the urlbar.
let gTestRoot = getRootDirectory(gTestPath);
new file mode 100644
--- /dev/null
+++ b/browser/components/urlbar/tests/browser/head.js
@@ -0,0 +1,26 @@
+/* Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/**
+ * These tests unit test the result/url loading functionality of UrlbarController.
+ */
+
+"use strict";
+
+let sandbox;
+
+ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
+XPCOMUtils.defineLazyModuleGetters(this, {
+ Services: "resource://gre/modules/Services.jsm",
+ QueryContext: "resource:///modules/UrlbarController.jsm",
+ UrlbarController: "resource:///modules/UrlbarController.jsm",
+ UrlbarMatch: "resource:///modules/UrlbarMatch.jsm",
+ UrlbarUtils: "resource:///modules/UrlbarUtils.jsm",
+});
+
+/* global sinon */
+Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js");
+
+registerCleanupFunction(function() {
+ delete window.sinon;
+});
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js
+++ b/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js
@@ -25,17 +25,19 @@ function assertContextMatches(context, e
for (let [key, value] of Object.entries(expectedValues)) {
Assert.equal(context[key], value,
`Should have the expected value for ${key} in the QueryContext`);
}
}
add_task(async function setup() {
- controller = new UrlbarController();
+ controller = new UrlbarController({
+ window: {},
+ });
});
add_task(async function test_basic_search() {
const context = createContext(TEST_URL);
registerBasicTestProvider([match]);
let startedPromise = promiseControllerNotification(controller, "onQueryStarted");
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js
+++ b/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js
@@ -41,16 +41,17 @@ add_task(function setup() {
generalListener = {
onQueryStarted: sandbox.stub(),
onQueryResults: sandbox.stub(),
onQueryCancelled: sandbox.stub(),
};
controller = new UrlbarController({
manager: fPM,
+ window: {},
});
controller.addQueryListener(generalListener);
});
add_task(function test_add_and_remove_listeners() {
Assert.throws(() => controller.addQueryListener(null),
/Expected listener to be an object/,
"Should throw for a null listener");
--- a/browser/components/urlbar/tests/unit/test_providersManager.js
+++ b/browser/components/urlbar/tests/unit/test_providersManager.js
@@ -3,17 +3,19 @@
"use strict";
add_task(async function test_providers() {
let match = new UrlbarMatch(UrlbarUtils.MATCH_TYPE.TAB_SWITCH, { url: "http://mozilla.org/foo/" });
registerBasicTestProvider([match]);
let context = createContext();
- let controller = new UrlbarController();
+ let controller = new UrlbarController({
+ window: {},
+ });
let resultsPromise = promiseControllerNotification(controller, "onQueryResults");
await UrlbarProvidersManager.startQuery(context, controller);
// Sanity check that this doesn't throw. It should be a no-op since we await
// for startQuery.
UrlbarProvidersManager.cancelQuery(context);
let params = await resultsPromise;