Bug 1955066 - Enter search mode after adding an HTML form as a search engine. r=urlbar-reviewers,search-reviewers,scunnane,daisuke
Differential Revision: https://phabricator.services.mozilla.com/D242187
This commit is contained in:
@@ -222,7 +222,7 @@ document.addEventListener(
|
|||||||
if (!gContextMenu) {
|
if (!gContextMenu) {
|
||||||
throw new Error("Context menu doesn't seem to be open.");
|
throw new Error("Context menu doesn't seem to be open.");
|
||||||
}
|
}
|
||||||
gContextMenu.addSearchFieldAsEngine();
|
gContextMenu.addSearchFieldAsEngine().catch(console.error);
|
||||||
break;
|
break;
|
||||||
case "context-searchselect": {
|
case "context-searchselect": {
|
||||||
let { searchTerms, usePrivate, principal, csp } = event.target;
|
let { searchTerms, usePrivate, principal, csp } = event.target;
|
||||||
|
|||||||
@@ -2346,18 +2346,34 @@ export class nsContextMenu {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
addSearchFieldAsEngine() {
|
async addSearchFieldAsEngine() {
|
||||||
this.actor
|
let { url, formData, charset, method } =
|
||||||
.getSearchFieldEngineData(this.targetIdentifier)
|
await this.actor.getSearchFieldEngineData(this.targetIdentifier);
|
||||||
.then(async ({ url, formData, charset, method }) => {
|
|
||||||
let icon = this.browser.mIconURL;
|
let { engineInfo } = await this.window.gDialogBox.open(
|
||||||
let uri = Services.io.newURI(url);
|
|
||||||
await this.window.gDialogBox.open(
|
|
||||||
"chrome://browser/content/search/addEngine.xhtml",
|
"chrome://browser/content/search/addEngine.xhtml",
|
||||||
{ uri, formData, charset, method, icon, mode: "FORM", title: true }
|
{
|
||||||
|
mode: "FORM",
|
||||||
|
title: true,
|
||||||
|
nameTemplate: Services.io.newURI(url).host,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
})
|
|
||||||
.catch(console.error);
|
// If the user saved, engineInfo contains `name` and `alias`.
|
||||||
|
// Otherwise, it's undefined.
|
||||||
|
if (engineInfo) {
|
||||||
|
let searchEngine = await Services.search.addUserEngine({
|
||||||
|
name: engineInfo.name,
|
||||||
|
alias: engineInfo.alias,
|
||||||
|
url,
|
||||||
|
formData,
|
||||||
|
charset,
|
||||||
|
method,
|
||||||
|
icon: this.browser.mIconURL,
|
||||||
|
});
|
||||||
|
|
||||||
|
this.window.gURLBar.search("", { searchEngine });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -8,8 +8,8 @@
|
|||||||
// in about:preferences, or when adding a search engine via the context menu of
|
// in about:preferences, or when adding a search engine via the context menu of
|
||||||
// an HTML form. Depending on the scenario where it is used, different arguments
|
// an HTML form. Depending on the scenario where it is used, different arguments
|
||||||
// must be supplied in an object in `window.arguments[0]`:
|
// must be supplied in an object in `window.arguments[0]`:
|
||||||
// - `mode` (required)
|
// - `mode` [required] - The type of dialog: NEW, EDIT or FORM.
|
||||||
// - `title` (optional, to display a title in the window element)
|
// - `title` [optional] - To display a title in the window element.
|
||||||
// - all arguments required by the constructor of the dialog class
|
// - all arguments required by the constructor of the dialog class
|
||||||
|
|
||||||
const lazy = {};
|
const lazy = {};
|
||||||
@@ -117,10 +117,12 @@ class EditEngineDialog extends EngineDialog {
|
|||||||
/**
|
/**
|
||||||
* Initializes the dialog with information from a user search engine.
|
* Initializes the dialog with information from a user search engine.
|
||||||
*
|
*
|
||||||
* @param {nsISearchEngine} engine
|
* @param {object} args
|
||||||
|
* The arguments.
|
||||||
|
* @param {nsISearchEngine} args.engine
|
||||||
* The search engine to edit. Must be a UserSearchEngine.
|
* The search engine to edit. Must be a UserSearchEngine.
|
||||||
*/
|
*/
|
||||||
constructor(engine) {
|
constructor({ engine }) {
|
||||||
super();
|
super();
|
||||||
this._postData = document.getElementById("enginePostData");
|
this._postData = document.getElementById("enginePostData");
|
||||||
|
|
||||||
@@ -228,48 +230,33 @@ class EditEngineDialog extends EngineDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This dialog is opened via the context menu of an input and
|
* This dialog is opened via the context menu of an input and lets the
|
||||||
* will add a search engine based on the input's form.
|
* user choose a name and an alias for an engine. Unlike the other two
|
||||||
|
* dialogs, it does not add or change an engine in the search service,
|
||||||
|
* and instead returns the user input to the caller.
|
||||||
|
*
|
||||||
|
* The chosen name and alias are returned via `window.arguments[0].engineInfo`.
|
||||||
|
* If the user chooses to not save the engine, it's undefined.
|
||||||
*/
|
*/
|
||||||
class NewEngineFromFormDialog extends EngineDialog {
|
class NewEngineFromFormDialog extends EngineDialog {
|
||||||
#formData;
|
|
||||||
#charset;
|
|
||||||
#method;
|
|
||||||
#icon;
|
|
||||||
#uri;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the dialog with data from an HTML form. The search input's
|
* Initializes the dialog.
|
||||||
* formData value should be "{searchTerms}".
|
|
||||||
*
|
*
|
||||||
* @param {object} args
|
* @param {object} args
|
||||||
* The arguments.
|
* The arguments.
|
||||||
* @param {nsIURI} args.uri
|
* @param {string} args.nameTemplate
|
||||||
* The full action url of the form.
|
* The initial value of the name input.
|
||||||
* @param {FormData} args.formData
|
|
||||||
* The FormData of the form.
|
|
||||||
* @param {string} args.charset
|
|
||||||
* The character encoding of the form's page.
|
|
||||||
* @param {string} args.method
|
|
||||||
* The HTTP method used to submit the form.
|
|
||||||
* @param {string} args.icon
|
|
||||||
* Url of the page's favicon.
|
|
||||||
*/
|
*/
|
||||||
constructor({ uri, formData, charset, method, icon }) {
|
constructor({ nameTemplate }) {
|
||||||
super();
|
super();
|
||||||
this.#formData = formData;
|
this._name.value = nameTemplate;
|
||||||
this.#charset = charset;
|
|
||||||
this.#method = method;
|
|
||||||
this.#icon = icon;
|
|
||||||
this.#uri = uri.spec;
|
|
||||||
|
|
||||||
this._name.value = uri.host;
|
|
||||||
this.onNameInput();
|
this.onNameInput();
|
||||||
this.onAliasInput();
|
this.onAliasInput();
|
||||||
|
|
||||||
document.getElementById("engineUrlRow").remove();
|
document.getElementById("engineUrlRow").remove();
|
||||||
document.getElementById("suggestUrlRow").remove();
|
|
||||||
this._url = null;
|
this._url = null;
|
||||||
|
document.getElementById("suggestUrlRow").remove();
|
||||||
|
this._suggestUrl = null;
|
||||||
|
|
||||||
let title = { raw: document.title };
|
let title = { raw: document.title };
|
||||||
document.documentElement.setAttribute("headertitle", JSON.stringify(title));
|
document.documentElement.setAttribute("headertitle", JSON.stringify(title));
|
||||||
@@ -280,15 +267,11 @@ class NewEngineFromFormDialog extends EngineDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onAddEngine() {
|
onAddEngine() {
|
||||||
Services.search.addUserEngine({
|
window.arguments[0].engineInfo = {
|
||||||
url: this.#uri,
|
|
||||||
name: this._name.value.trim(),
|
name: this._name.value.trim(),
|
||||||
|
// Empty string means no alias.
|
||||||
alias: this._alias.value.trim(),
|
alias: this._alias.value.trim(),
|
||||||
formData: this.#formData,
|
};
|
||||||
charset: this.#charset,
|
|
||||||
method: this.#method,
|
|
||||||
icon: this.#icon,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,7 +290,7 @@ window.addEventListener("DOMContentLoaded", () => {
|
|||||||
gAddEngineDialog = new NewEngineDialog();
|
gAddEngineDialog = new NewEngineDialog();
|
||||||
break;
|
break;
|
||||||
case "EDIT":
|
case "EDIT":
|
||||||
gAddEngineDialog = new EditEngineDialog(window.arguments[0].engine);
|
gAddEngineDialog = new EditEngineDialog(window.arguments[0]);
|
||||||
break;
|
break;
|
||||||
case "FORM":
|
case "FORM":
|
||||||
gAddEngineDialog = new NewEngineFromFormDialog(window.arguments[0]);
|
gAddEngineDialog = new NewEngineFromFormDialog(window.arguments[0]);
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
|
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
ChromeUtils.defineLazyGetter(this, "UrlbarTestUtils", () => {
|
||||||
|
const { UrlbarTestUtils: module } = ChromeUtils.importESModule(
|
||||||
|
"resource://testing-common/UrlbarTestUtils.sys.mjs"
|
||||||
|
);
|
||||||
|
module.init(this);
|
||||||
|
return module;
|
||||||
|
});
|
||||||
|
|
||||||
const TESTS = [
|
const TESTS = [
|
||||||
{
|
{
|
||||||
action: "/search",
|
action: "/search",
|
||||||
@@ -95,13 +103,13 @@ async function addEngine(browser, selector, name, alias) {
|
|||||||
fillTextField("engineAlias", alias, dialogWin);
|
fillTextField("engineAlias", alias, dialogWin);
|
||||||
|
|
||||||
info("Saving engine.");
|
info("Saving engine.");
|
||||||
let promiseAdded = SearchTestUtils.promiseSearchNotification(
|
|
||||||
SearchUtils.MODIFIED_TYPE.ADDED,
|
|
||||||
SearchUtils.TOPIC_ENGINE_MODIFIED
|
|
||||||
);
|
|
||||||
EventUtils.synthesizeKey("VK_RETURN", {}, dialogWin);
|
EventUtils.synthesizeKey("VK_RETURN", {}, dialogWin);
|
||||||
await window.gDialogBox.dialog._closingPromise;
|
await TestUtils.waitForCondition(
|
||||||
await promiseAdded;
|
() => gURLBar.searchMode?.engineName == name
|
||||||
|
);
|
||||||
|
Assert.ok(true, "Went into search mode.");
|
||||||
|
|
||||||
|
await UrlbarTestUtils.exitSearchMode(window);
|
||||||
return Services.search.getEngineByName(name);
|
return Services.search.getEngineByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -217,7 +217,11 @@ export class SearchModeSwitcher {
|
|||||||
|
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
case "browser-search-engine-modified": {
|
case "browser-search-engine-modified": {
|
||||||
if (data === "engine-default" || data === "engine-default-private") {
|
if (
|
||||||
|
data === "engine-default" ||
|
||||||
|
data === "engine-default-private" ||
|
||||||
|
data === "engine-icon-changed"
|
||||||
|
) {
|
||||||
this.updateSearchIcon();
|
this.updateSearchIcon();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user