author | Coroiu Cristina <ccoroiu@mozilla.com> |
Thu, 20 Sep 2018 14:22:58 +0300 | |
changeset 437432 | 3dfc23d7f7c0d8b6475fd92636e36207ed07200a |
parent 437431 | 8842e929c30f1b44945f1b58ca1a9777d66ef5eb |
child 437433 | d10273c0ead345543e631bd83fa00ffcbb6d5f15 |
push id | 34683 |
push user | apavel@mozilla.com |
push date | Thu, 20 Sep 2018 21:54:05 +0000 |
treeherder | mozilla-central@4d3cd0ab7277 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
bugs | 1491253 |
milestone | 64.0a1 |
backs out | 261d22d6d396d542f1745d6bcf2222188948c6ac |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -273,20 +273,17 @@ Object.defineProperty(this, "gURLBar", { element.setAttribute("quantumbar", "true"); // Re-focus the input field if it was focused before switching bindings. if (element.hasAttribute("focused")) { element.inputField.focus(); } return this.gURLBar = - new UrlbarInput({ - textbox: element, - panel: document.getElementById("urlbar-results"), - }); + new UrlbarInput(element, document.getElementById("urlbar-results")); }, }); Object.defineProperty(this, "gNavToolbox", { configurable: true, enumerable: true, get() { delete this.gNavToolbox;
--- a/browser/components/urlbar/UrlbarController.jsm +++ b/browser/components/urlbar/UrlbarController.jsm @@ -5,39 +5,24 @@ "use strict"; var EXPORTED_SYMBOLS = ["QueryContext", "UrlbarController"]; ChromeUtils.import("resource://gre/modules/Services.jsm"); // XXX This is a fake manager to provide a basic integration test whilst we // are still constructing the manager. -// eslint-disable-next-line require-jsdoc +/* eslint-disable require-jsdoc */ const ProvidersManager = { queryStart(queryContext, controller) { - queryContext.results = []; - for (let i = 0; i < 12; i++) { - const SWITCH_TO_TAB = Math.random() < .3; - let url = "http://www." + queryContext.searchString; - while (Math.random() < .9) { - url += queryContext.searchString; - } - let title = queryContext.searchString; - while (Math.random() < .5) { - title += queryContext.isPrivate ? " private" : " foo bar"; - } - queryContext.results.push({ - title, - type: SWITCH_TO_TAB ? "switchtotab" : "normal", - url, - }); - } + queryContext.results = [{url: queryContext.searchString}]; controller.receiveResults(queryContext); }, }; +/* eslint-enable require-jsdoc */ /** * 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 { /** @@ -100,37 +85,37 @@ class QueryContext { */ class UrlbarController { /** * Initialises the class. The manager may be overridden here, this is for * test purposes. * * @param {object} [options] * The initial options for UrlbarController. - * @param {object} [options.manager] - * Optional fake providers manager to override the built-in providers manager. - * Intended for use in unit tests only. + * @param {string} [options.manager] + * The string the user entered in autocomplete. Could be the empty string + * in the case of the user opening the popup via the mouse. */ constructor(options = {}) { this.manager = options.manager || ProvidersManager; this._listeners = new Set(); } /** * Takes a query context and starts the query based on the user input. * * @param {QueryContext} queryContext The query details. */ handleQuery(queryContext) { queryContext.autoFill = Services.prefs.getBoolPref("browser.urlbar.autoFill", true); - this._notify("onQueryStarted", queryContext); + this.manager.queryStart(queryContext, this); - this.manager.queryStart(queryContext, this); + this._notify("onQueryStarted", queryContext); } /** * Cancels an in-progress query. * * @param {QueryContext} queryContext The query details. */ cancelQuery(queryContext) {
--- a/browser/components/urlbar/UrlbarInput.jsm +++ b/browser/components/urlbar/UrlbarInput.jsm @@ -4,46 +4,36 @@ "use strict"; var EXPORTED_SYMBOLS = ["UrlbarInput"]; ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetters(this, { - PrivateBrowsingUtils: "resource://gre/modules/PrivateBrowsingUtils.jsm", - QueryContext: "resource:///modules/UrlbarController.jsm", - UrlbarController: "resource:///modules/UrlbarController.jsm", UrlbarView: "resource:///modules/UrlbarView.jsm", }); /** * Represents the urlbar <textbox>. * Also forwards important textbox properties and methods. */ class UrlbarInput { /** - * @param {object} options - * The initial options for UrlbarInput. - * @param {object} options.textbox + * @param {object} textbox * The <textbox> element. - * @param {object} options.panel + * @param {object} panel * The <panel> element. - * @param {UrlbarController} [options.controller] - * Optional fake controller to override the built-in UrlbarController. - * Intended for use in unit tests only. */ - constructor(options = {}) { - this.textbox = options.textbox; - this.panel = options.panel; - this.controller = options.controller || new UrlbarController(); + constructor(textbox, panel) { + this.textbox = textbox; + this.panel = panel; this.view = new UrlbarView(this); this.valueIsTyped = false; this.userInitiatedFocus = false; - this.isPrivate = PrivateBrowsingUtils.isWindowPrivate(this.panel.ownerGlobal); const METHODS = ["addEventListener", "removeEventListener", "setAttribute", "hasAttribute", "removeAttribute", "getAttribute", "focus", "blur", "select"]; const READ_ONLY_PROPERTIES = ["focused", "inputField", "editor"]; const READ_WRITE_PROPERTIES = ["value", "placeholder", "readOnly", "selectionStart", "selectionEnd"]; @@ -98,19 +88,14 @@ class UrlbarInput { if (methodName in this) { this[methodName](event); } else { throw "Unrecognized urlbar event: " + event.type; } } // Private methods below. + /* eslint-disable require-jsdoc */ _oninput(event) { - // XXX Fill in lastKey & maxResults, and add anything else we need. - this.controller.handleQuery(new QueryContext({ - searchString: event.target.value, - lastKey: "", - maxResults: 12, - isPrivate: this.isPrivate, - })); + this.openResults(); } }
--- a/browser/components/urlbar/UrlbarView.jsm +++ b/browser/components/urlbar/UrlbarView.jsm @@ -12,17 +12,16 @@ var EXPORTED_SYMBOLS = ["UrlbarView"]; class UrlbarView { /** * @param {UrlbarInput} urlbar * The UrlbarInput instance belonging to this UrlbarView instance. */ constructor(urlbar) { this.urlbar = urlbar; this.panel = urlbar.panel; - this.controller = urlbar.controller; this.document = urlbar.panel.ownerDocument; this.window = this.document.defaultView; this._mainContainer = this.panel.querySelector(".urlbarView-body-inner"); this._rows = this.panel.querySelector(".urlbarView-results"); // For the horizontal fade-out effect, set the overflow attribute on result // rows when they overflow. @@ -31,18 +30,16 @@ class UrlbarView { event.target.toggleAttribute("overflow", true); } }); this._rows.addEventListener("underflow", event => { if (event.target.classList.contains("urlbarView-row-inner")) { event.target.toggleAttribute("overflow", false); } }); - - this.controller.addQueryListener(this); } /** * Opens the autocomplete results popup. */ open() { this.panel.removeAttribute("hidden"); @@ -58,51 +55,46 @@ class UrlbarView { let width = documentRect.right - documentRect.left; this.panel.setAttribute("width", width); // Subtract two pixels for left and right borders on the panel. this._mainContainer.style.maxWidth = (width - 2) + "px"; this.panel.openPopup(this.urlbar.textbox.closest("toolbar"), "after_end", 0, -1); + this._rows.textContent = ""; + for (let i = 0; i < 12; i++) { + this._addRow(); + } this._rows.firstElementChild.toggleAttribute("selected", true); } /** * Closes the autocomplete results popup. */ close() { } - // UrlbarController listener methods. - onQueryStarted(queryContext) { - this._rows.textContent = ""; - } - - onQueryResults(queryContext) { - for (let result of queryContext.results) { - this._addRow(result); - } - this.open(); - } - // Private methods below. + /* eslint-disable require-jsdoc */ _getBoundsWithoutFlushing(element) { return this.window.windowUtils.getBoundsWithoutFlushing(element); } _createElement(name) { return this.document.createElementNS("http://www.w3.org/1999/xhtml", name); } - _addRow(result) { + _addRow() { + const SWITCH_TO_TAB = Math.random() < .3; + let item = this._createElement("div"); item.className = "urlbarView-row"; - if (result.type == "switchtotab") { + if (SWITCH_TO_TAB) { item.setAttribute("action", "switch-to-tab"); } let content = this._createElement("span"); content.className = "urlbarView-row-inner"; item.appendChild(content); let actionIcon = this._createElement("span"); @@ -110,25 +102,30 @@ class UrlbarView { content.appendChild(actionIcon); let favicon = this._createElement("span"); favicon.className = "urlbarView-favicon"; content.appendChild(favicon); let title = this._createElement("span"); title.className = "urlbarView-title"; - title.textContent = result.title; + do { + title.textContent += "foo bar "; + } while (Math.random() < .5); content.appendChild(title); let secondary = this._createElement("span"); secondary.className = "urlbarView-secondary"; - if (result.type == "switchtotab") { + if (SWITCH_TO_TAB) { secondary.classList.add("urlbarView-action"); secondary.textContent = "Switch to Tab"; } else { secondary.classList.add("urlbarView-url"); - secondary.textContent = result.url; + secondary.textContent = "http://www"; + while (Math.random() < .95) { + secondary.textContent += ".xyz"; + } } content.appendChild(secondary); this._rows.appendChild(item); } }
--- a/browser/components/urlbar/tests/unit/head.js +++ b/browser/components/urlbar/tests/unit/head.js @@ -9,32 +9,21 @@ var commonFile = do_get_file("../../../. if (commonFile) { let uri = Services.io.newFileURI(commonFile); Services.scriptloader.loadSubScript(uri.spec, this); } // Put any other stuff relative to this test folder below. ChromeUtils.import("resource:///modules/UrlbarController.jsm"); -ChromeUtils.defineModuleGetter(this, "UrlbarInput", - "resource:///modules/UrlbarInput.jsm"); ChromeUtils.defineModuleGetter(this, "UrlbarTokenizer", "resource:///modules/UrlbarTokenizer.jsm"); ChromeUtils.defineModuleGetter(this, "PlacesTestUtils", "resource://testing-common/PlacesTestUtils.jsm"); -// ================================================ -// Load mocking/stubbing library, sinon -// docs: http://sinonjs.org/releases/v2.3.2/ -// Sinon needs Timer.jsm for setTimeout etc. -ChromeUtils.import("resource://gre/modules/Timer.jsm"); -Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js", this); -/* globals sinon */ -// ================================================ - /** * @param {string} searchString The search string to insert into the context. * @returns {QueryContext} Creates a dummy query context with pre-filled required options. */ function createContext(searchString = "foo") { return new QueryContext({ searchString, lastKey: searchString ? searchString[searchString.length - 1] : "",
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js +++ b/browser/components/urlbar/tests/unit/test_UrlbarController_integration.js @@ -41,15 +41,12 @@ add_task(async function test_basic_searc controller.handleQuery(context); let params = await startedPromise; Assert.equal(params[0], context); params = await resultsPromise; - Assert.equal(params[0].results.length, 12, - "Should have given the expected amount of results"); - - for (let result of params[0].results) { - Assert.ok(result.url.includes(TEST_URL)); - } + Assert.deepEqual(params[0].results, [{ + url: TEST_URL, + }]); });
--- a/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js +++ b/browser/components/urlbar/tests/unit/test_UrlbarController_unit.js @@ -3,16 +3,25 @@ /** * These tests unit test the functionality of UrlbarController by stubbing out the * model and providing stubs to be called. */ "use strict"; +// ================================================ +// Load mocking/stubbing library, sinon +// docs: http://sinonjs.org/releases/v2.3.2/ +// Sinon needs Timer.jsm for setTimeout etc. +ChromeUtils.import("resource://gre/modules/Timer.jsm"); +Services.scriptloader.loadSubScript("resource://testing-common/sinon-2.3.2.js", this); +/* globals sinon */ +// ================================================ + // A fake ProvidersManager. let fPM; let sandbox; let generalListener; let controller; /** * Asserts that the query context has the expected values.
deleted file mode 100644 --- a/browser/components/urlbar/tests/unit/test_UrlbarInput_unit.js +++ /dev/null @@ -1,129 +0,0 @@ -/* Any copyright is dedicated to the Public Domain. - http://creativecommons.org/publicdomain/zero/1.0/ */ - -/** - * 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://gre/modules/PrivateBrowsingUtils.jsm"); - -/** - * 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, - "Should be a QueryContext"); - - for (let [key, value] of Object.entries(expectedValues)) { - Assert.equal(context[key], value, - `Should have the expected value for ${key} in the QueryContext`); - } -} - -/** - * @returns {object} A fake element with minimal functions for simulating textbox etc. - */ -function createFakeElement() { - return { - addEventListener() {}, - }; -} - -/** - * Checks the result of a handleQuery call on the controller. - * - * @param {object} stub The sinon stub that should have been called with the - * QueryContext. - * @param {object} expectedQueryContextProps - * An object consisting of name/value pairs to check against the - * QueryContext properties. - */ -function checkHandleQueryCall(stub, expectedQueryContextProps) { - Assert.equal(stub.callCount, 1, - "Should have called handleQuery on the controller"); - - let args = stub.args[0]; - Assert.equal(args.length, 1, - "Should have called handleQuery with one argument"); - - let queryContext = args[0]; - Assert.ok(queryContext instanceof QueryContext, - "Should have been passed a QueryContext"); - - for (let [name, value] of Object.entries(expectedQueryContextProps)) { - Assert.deepEqual(queryContext[name], - value, `Should have the correct value for queryContext.${name}`); - } -} - -add_task(function setup() { - sandbox = sinon.sandbox.create(); - - fakeController = new UrlbarController(); - - sandbox.stub(fakeController, "handleQuery"); - sandbox.stub(PrivateBrowsingUtils, "isWindowPrivate").returns(false); - - inputOptions = { - textbox: createFakeElement(), - panel: { - ownerDocument: {}, - querySelector() { - return createFakeElement(); - }, - }, - controller: fakeController, - }; - - input = new UrlbarInput(inputOptions); -}); - -add_task(function test_input_starts_query() { - input.handleEvent({ - target: { - value: "search", - }, - type: "input", - }); - - checkHandleQueryCall(fakeController.handleQuery, { - searchString: "search", - isPrivate: false, - }); - - sandbox.resetHistory(); -}); - -add_task(function test_input_with_private_browsing() { - PrivateBrowsingUtils.isWindowPrivate.returns(true); - - // Rather than using the global input here, we create a new instance which - // will use the updated return value of the private browsing stub. - let privateInput = new UrlbarInput(inputOptions); - - privateInput.handleEvent({ - target: { - value: "search", - }, - type: "input", - }); - - checkHandleQueryCall(fakeController.handleQuery, { - searchString: "search", - isPrivate: true, - }); - - sandbox.resetHistory(); -});
--- a/browser/components/urlbar/tests/unit/xpcshell.ini +++ b/browser/components/urlbar/tests/unit/xpcshell.ini @@ -1,9 +1,8 @@ [DEFAULT] head = head.js firefox-appdir = browser [test_QueryContext.js] [test_tokenizer.js] [test_UrlbarController_unit.js] [test_UrlbarController_integration.js] -[test_UrlbarInput_unit.js]