Bug 959576 - Create a component to get the list of priority domains. r=gavin

This commit is contained in:
Marco Bonardo 2014-03-22 14:24:36 +01:00
Родитель b4496f7882
Коммит fb58538bf3
16 изменённых файлов: 367 добавлений и 19 удалений

Просмотреть файл

@ -7,7 +7,7 @@
<Description>Find photos, movies, music, and text to rip, sample, mash, and share.</Description>
<InputEncoding>utf-8</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAJUSURBVDiNjZO9S1thGMXPvTfJFbnkipNkLLS0ksFg0M0lf4CboNCEgIIg/RiKtEOn0qGWTtbVoBYcIji10I9J0ApWCjp0kRaXdhHjTW4+uGnur4NJ8GOwZ3nf4TnnfZ5z3scAdBGGYdyVdN+yrGHTNNOtVqsVhuG+pO+S3gE/LtV3BIxzPDJNc8FxHGN0dNRKpVIGoJ2dndr+/r5Vr9cl6bmkN0AoSQIEyHXdj5KYnZ3F932uolKpkM/nK5KQ9FmSCZwLOI7zQBLr6+vXiFdRLBaDtsiTTve3YrFYkM/nbyR3MDU1dSKpLumO+vr6Xruui+d5AFSrVVZWVtjY2KDRaABwdHTE4uIie3t7AJTLZaLRaFXSCyUSid1MJgOA53n09/eTTqdJJpPMzc2xurqKbduMj48Tj8fZ3d0FYHBw8FjSezmOU56fnwdgeXkZ27ap1WpUKhWazSZjY2Nks1kASqVSd4zp6eljSX/MtiHdRDpnEATyfb+bkiSVSqXu3TCM8xgHBga+dkY4OzvDdV2GhoZIJBLMzMxQKBSIRqNkMhlisRhbW1sAJJPJn5I+KB6Pv7poou/7rK2tsbm5SRAEXROXlpY4ODgAoFarYdu2J+llN8ZcLvffMeZyud+SGpLuCVBPT89jSRQKhRvJxWKxISmU9JTOT5Rk9Pb2fpHE5OQkJycn14inp6dMTEx4bdM/SbKAy8sk6WEkElmwLCuSSqUYGRmxgHB7e7t+eHgYazabgaRnkt7SeZnr63xbUtYwjGHTNNNhGP4F9iR9a6/zr4v1/wDE1D9XlC4rrAAAAABJRU5ErkJggg==</Image>
<Url type="text/html" method="GET" template="http://search.creativecommons.org/">
<Url type="text/html" method="GET" template="http://search.creativecommons.org/" resultdomain="creativecommons.org">
<Param name="q" value="{searchTerms}"/>
<Param name="sourceid" value="Mozilla-search"/>
</Url>

Просмотреть файл

@ -11,7 +11,7 @@
<Param name="s" value="0"/>
<Param name="q" value="{searchTerms}"/>
</Url>
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4">
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4" resultdomain="ebay.com">
<Param name="mpre" value="http://shop.ebay.com/?_nkw={searchTerms}"/>
</Url>
<SearchForm>http://search.ebay.com/</SearchForm>

Просмотреть файл

@ -11,7 +11,7 @@
<Param name="action" value="opensearch"/>
<Param name="search" value="{searchTerms}"/>
</Url>
<Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search">
<Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search" resultdomain="wikipedia.org">
<Param name="search" value="{searchTerms}"/>
<Param name="sourceid" value="Mozilla-search"/>
</Url>

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Просмотреть файл

@ -22,7 +22,7 @@ interface nsISearchSubmission : nsISupports
readonly attribute nsIURI uri;
};
[scriptable, uuid(7914c4b8-f05b-40c9-a982-38a058cd1769)]
[scriptable, uuid(77de6680-57ec-4105-a183-cc7cf7e84b09)]
interface nsISearchEngine : nsISupports
{
/**
@ -157,6 +157,18 @@ interface nsISearchEngine : nsISupports
*/
readonly attribute AString identifier;
/**
* Gets a string representing the hostname from which search results for a
* given responseType are returned, minus the leading "www." (if present).
* This can be specified as an url attribute in the engine description file,
* but will default to host from the <Url>'s template otherwise.
*
* @param responseType [optional]
* The MIME type to get resultDomain for. Defaults to "text/html".
*
* @return the resultDomain for the given responseType.
*/
AString getResultDomain([optional] in AString responseType);
};
[scriptable, uuid(9fc39136-f08b-46d3-b232-96f4b7b0e235)]

Просмотреть файл

@ -0,0 +1,142 @@
/* 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";
this.EXPORTED_SYMBOLS = [ "PriorityUrlProvider" ];
const Ci = Components.interfaces;
const Cc = Components.classes;
const Cu = Components.utils;
const Cr = Components.results;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/Task.jsm");
/**
* Provides search engines matches to the PriorityUrlProvider through the
* search engines definitions handled by the Search Service.
*/
const SEARCH_ENGINE_TOPIC = "browser-search-engine-modified";
let SearchEnginesProvider = {
init: function () {
this._engines = new Map();
let deferred = Promise.defer();
Services.search.init(rv => {
if (Components.isSuccessCode(rv)) {
Services.search.getVisibleEngines().forEach(this._addEngine, this);
deferred.resolve();
} else {
deferred.reject(new Error("Unable to initialize search service."));
}
});
Services.obs.addObserver(this, SEARCH_ENGINE_TOPIC, true);
return deferred.promise;
},
observe: function (engine, topic, verb) {
let engine = engine.QueryInterface(Ci.nsISearchEngine);
switch (verb) {
case "engine-added":
this._addEngine(engine);
break;
case "engine-changed":
if (engine.hidden) {
this._removeEngine(engine);
} else {
this._addEngine(engine);
}
break;
case "engine-removed":
this._removeEngine(engine);
break;
}
},
_addEngine: function (engine) {
if (this._engines.has(engine.name)) {
return;
}
let token = engine.getResultDomain();
if (!token) {
return;
}
let match = { token: token,
// TODO (bug 557665): searchForm should provide an usable
// url with affiliate code, if available.
url: engine.searchForm,
title: engine.name,
iconUrl: engine.iconURI ? engine.iconURI.spec : null,
reason: "search" }
this._engines.set(engine.name, match);
PriorityUrlProvider.addMatch(match);
},
_removeEngine: function (engine) {
if (!this._engines.has(engine.name)) {
return;
}
this._engines.delete(engine.name);
PriorityUrlProvider.removeMatchByToken(engine.getResultDomain());
},
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference])
}
/**
* The PriorityUrlProvider allows to match a given string to a list of
* urls that should have priority in url search components, like autocomplete.
* Each returned match is an object with the following properties:
* - token: string used to match the search term to the url
* - url: url string represented by the match
* - title: title describing the match, or an empty string if not available
* - iconUrl: url of the icon associated to the match, or null if not available
* - reason: a string describing the origin of the match, for example if it
* represents a search engine, it will be "search".
*/
let matches = new Map();
let initialized = false;
function promiseInitialized() {
if (initialized) {
return Promise.resolve();
}
return Task.spawn(function* () {
try {
yield SearchEnginesProvider.init();
} catch (ex) {
Cu.reportError(ex);
}
initialized = true;
});
}
this.PriorityUrlProvider = Object.freeze({
addMatch: function (match) {
matches.set(match.token, match);
},
removeMatchByToken: function (token) {
matches.delete(token);
},
getMatchingSpec: function (searchToken) {
return Task.spawn(function* () {
yield promiseInitialized();
for (let [token, match] of matches.entries()) {
// Match at the beginning for now. In future an aOptions argument may
// allow to control the matching behavior.
if (token.startsWith(searchToken)) {
return match;
}
}
return null;
}.bind(this));
}
});

Просмотреть файл

@ -68,6 +68,7 @@ if CONFIG['MOZ_PLACES']:
'PlacesBackups.jsm',
'PlacesDBUtils.jsm',
'PlacesTransactions.jsm',
'PriorityUrlProvider.jsm'
]
EXTRA_PP_JS_MODULES += [

Просмотреть файл

@ -0,0 +1,74 @@
/* 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/. */
Cu.import("resource://gre/modules/PriorityUrlProvider.jsm");
function run_test() {
run_next_test();
}
add_task(function* search_engine_match() {
let engine = yield promiseDefaultSearchEngine();
let token = engine.getResultDomain();
let match = yield PriorityUrlProvider.getMatchingSpec(token.substr(0, 1));
do_check_eq(match.url, engine.searchForm);
do_check_eq(match.title, engine.name);
do_check_eq(match.iconUrl, engine.iconURI ? engine.iconURI.spec : null);
do_check_eq(match.reason, "search");
});
add_task(function* no_match() {
do_check_eq(null, yield PriorityUrlProvider.getMatchingSpec("test"));
});
add_task(function* hide_search_engine_nomatch() {
let engine = yield promiseDefaultSearchEngine();
let token = engine.getResultDomain();
let promiseTopic = promiseSearchTopic("engine-changed");
Services.search.removeEngine(engine);
yield promiseTopic;
do_check_true(engine.hidden);
do_check_eq(null, yield PriorityUrlProvider.getMatchingSpec(token.substr(0, 1)));
});
add_task(function* add_search_engine_match() {
let promiseTopic = promiseSearchTopic("engine-added");
do_check_eq(null, yield PriorityUrlProvider.getMatchingSpec("bacon"));
Services.search.addEngineWithDetails("bacon", "", "bacon", "Search Bacon",
"GET", "http://www.bacon.moz/?search={searchTerms}");
yield promiseSearchTopic;
let match = yield PriorityUrlProvider.getMatchingSpec("bacon");
do_check_eq(match.url, "http://www.bacon.moz");
do_check_eq(match.title, "bacon");
do_check_eq(match.iconUrl, null);
do_check_eq(match.reason, "search");
});
add_task(function* remove_search_engine_nomatch() {
let engine = Services.search.getEngineByName("bacon");
let promiseTopic = promiseSearchTopic("engine-removed");
Services.search.removeEngine(engine);
yield promiseTopic;
do_check_eq(null, yield PriorityUrlProvider.getMatchingSpec("bacon"));
});
function promiseDefaultSearchEngine() {
let deferred = Promise.defer();
Services.search.init( () => {
deferred.resolve(Services.search.defaultEngine);
});
return deferred.promise;
}
function promiseSearchTopic(expectedVerb) {
let deferred = Promise.defer();
Services.obs.addObserver( function observe(subject, topic, verb) {
do_log_info("browser-search-engine-modified: " + verb);
if (verb == expectedVerb) {
Services.obs.removeObserver(observe, "browser-search-engine-modified");
deferred.resolve();
}
}, "browser-search-engine-modified", false);
return deferred.promise;
}

Просмотреть файл

@ -64,6 +64,7 @@ skip-if = os == "android"
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
[test_async_history_api.js]
[test_async_transactions.js]
[test_autocomplete_stopSearch_no_throw.js]
[test_bookmark_catobs.js]
[test_bookmarks_json.js]
@ -86,6 +87,7 @@ fail-if = os == "android"
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
[test_getChildIndex.js]
[test_getPlacesInfo.js]
[test_history.js]
[test_history_autocomplete_tags.js]
[test_history_catobs.js]
@ -110,7 +112,11 @@ fail-if = os == "android"
skip-if = true
[test_null_interfaces.js]
[test_onItemChanged_tags.js]
[test_pageGuid_bookmarkGuid.js]
[test_placeURIs.js]
[test_PlacesUtils_asyncGetBookmarkIds.js]
[test_PlacesUtils_lazyobservers.js]
[test_placesTxn.js]
[test_preventive_maintenance.js]
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
@ -118,6 +124,7 @@ skip-if = os == "android"
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
[test_preventive_maintenance_runTasks.js]
[test_priorityUrlProvider.js]
[test_removeVisitsByTimeframe.js]
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
@ -126,16 +133,10 @@ skip-if = os == "android"
[test_sql_guid_functions.js]
[test_tag_autocomplete_search.js]
[test_tagging.js]
[test_telemetry.js]
[test_update_frecency_after_delete.js]
# Bug 676989: test hangs consistently on Android
skip-if = os == "android"
[test_utils_backups_create.js]
[test_utils_getURLsForContainerNode.js]
[test_utils_setAnnotationsFor.js]
[test_PlacesUtils_asyncGetBookmarkIds.js]
[test_PlacesUtils_lazyobservers.js]
[test_placesTxn.js]
[test_telemetry.js]
[test_getPlacesInfo.js]
[test_pageGuid_bookmarkGuid.js]
[test_async_transactions.js]

Просмотреть файл

@ -861,12 +861,14 @@ function ParamSubstitution(aParamValue, aSearchTerms, aEngine) {
* The URL to which search queries should be sent. For GET requests,
* must contain the string "{searchTerms}", to indicate where the user
* entered search terms should be inserted.
* @param aResultDomain
* The root domain for this URL. Defaults to the template's host.
*
* @see http://opensearch.a9.com/spec/1.1/querysyntax/#urltag
*
* @throws NS_ERROR_NOT_IMPLEMENTED if aType is unsupported.
*/
function EngineURL(aType, aMethod, aTemplate) {
function EngineURL(aType, aMethod, aTemplate, aResultDomain) {
if (!aType || !aMethod || !aTemplate)
FAIL("missing type, method or template for EngineURL!");
@ -898,6 +900,14 @@ function EngineURL(aType, aMethod, aTemplate) {
default:
FAIL("new EngineURL: template uses invalid scheme!", Cr.NS_ERROR_FAILURE);
}
// If no resultDomain was specified in the engine definition file, use the
// host from the template.
this.resultDomain = aResultDomain || templateURI.host;
// We never want to return a "www." prefix, so eventually strip it.
if (this.resultDomain.startsWith("www.")) {
this.resultDomain = this.resultDomain.substr(4);
}
}
EngineURL.prototype = {
@ -1018,7 +1028,8 @@ EngineURL.prototype = {
_serializeToJSON: function SRCH_EURL__serializeToJSON() {
var json = {
template: this.template,
rels: this.rels
rels: this.rels,
resultDomain: this.resultDomain
};
if (this.type != URLTYPE_SEARCH_HTML)
@ -1049,6 +1060,8 @@ EngineURL.prototype = {
url.setAttribute("template", this.template);
if (this.rels.length)
url.setAttribute("rel", this.rels.join(" "));
if (this.resultDomain)
url.setAttribute("resultDomain", this.resultDomain);
for (var i = 0; i < this.params.length; ++i) {
var param = aDoc.createElementNS(OPENSEARCH_NS_11, "Param");
@ -1770,9 +1783,10 @@ Engine.prototype = {
// specified
var method = aElement.getAttribute("method") || "GET";
var template = aElement.getAttribute("template");
var resultDomain = aElement.getAttribute("resultdomain");
try {
var url = new EngineURL(type, method, template);
var url = new EngineURL(type, method, template, resultDomain);
} catch (ex) {
FAIL("_parseURL: failed to add " + template + " as a URL",
Cr.NS_ERROR_FAILURE);
@ -2271,7 +2285,8 @@ Engine.prototype = {
for (let i = 0; i < aJson._urls.length; ++i) {
let url = aJson._urls[i];
let engineURL = new EngineURL(url.type || URLTYPE_SEARCH_HTML,
url.method || "GET", url.template);
url.method || "GET", url.template,
url.resultDomain);
engineURL._initWithJSON(url, this);
this._urls.push(engineURL);
}
@ -2719,6 +2734,25 @@ Engine.prototype = {
return (this._getURLOfType(type) != null);
},
// from nsISearchEngine
getResultDomain: function SRCH_ENG_getResultDomain(aResponseType) {
#ifdef ANDROID
if (!aResponseType) {
aResponseType = this._defaultMobileResponseType;
}
#endif
if (!aResponseType) {
aResponseType = URLTYPE_SEARCH_HTML;
}
LOG("getResultDomain: responseType: \"" + aResponseType + "\"");
let url = this._getURLOfType(aResponseType);
if (url)
return url.resultDomain;
return "";
},
// nsISupports
QueryInterface: function SRCH_ENG_QI(aIID) {
if (aIID.equals(Ci.nsISearchEngine) ||

Просмотреть файл

@ -5,7 +5,7 @@
<InputEncoding>UTF-8</InputEncoding>
<Image width="16" height="16">data:image/png;base64,AAABAAEAEBAAAAEAGABoAwAAFgAAACgAAAAQAAAAIAAAAAEAGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADs9Pt8xetPtu9FsfFNtu%2BTzvb2%2B%2Fne4dFJeBw0egA%2FfAJAfAA8ewBBegAAAAD%2B%2FPtft98Mp%2BwWsfAVsvEbs%2FQeqvF8xO7%2F%2F%2F63yqkxdgM7gwE%2FggM%2BfQA%2BegBDeQDe7PIbotgQufcMufEPtfIPsvAbs%2FQvq%2Bfz%2Bf%2F%2B%2B%2FZKhR05hgBBhQI8hgBAgAI9ewD0%2B%2Fg3pswAtO8Cxf4Kw%2FsJvvYAqupKsNv%2B%2Fv7%2F%2FP5VkSU0iQA7jQA9hgBDgQU%2BfQH%2F%2Ff%2FQ6fM4sM4KsN8AteMCruIqqdbZ7PH8%2Fv%2Fg6Nc%2Fhg05kAA8jAM9iQI%2BhQA%2BgQDQu6b97uv%2F%2F%2F7V8Pqw3eiWz97q8%2Ff%2F%2F%2F%2F7%2FPptpkkqjQE4kwA7kAA5iwI8iAA8hQCOSSKdXjiyflbAkG7u2s%2F%2B%2F%2F39%2F%2F7r8utrqEYtjQE8lgA7kwA7kwA9jwA9igA9hACiWSekVRyeSgiYSBHx6N%2F%2B%2Fv7k7OFRmiYtlAA5lwI7lwI4lAA7kgI9jwE9iwI4iQCoVhWcTxCmb0K%2BooT8%2Fv%2F7%2F%2F%2FJ2r8fdwI1mwA3mQA3mgA8lAE8lAE4jwA9iwE%2BhwGfXifWvqz%2B%2Ff%2F58u%2Fev6Dt4tr%2B%2F%2F2ZuIUsggA7mgM6mAM3lgA5lgA6kQE%2FkwBChwHt4dv%2F%2F%2F728ei1bCi7VAC5XQ7kz7n%2F%2F%2F6bsZkgcB03lQA9lgM7kwA2iQktZToPK4r9%2F%2F%2F9%2F%2F%2FSqYK5UwDKZAS9WALIkFn%2B%2F%2F3%2F%2BP8oKccGGcIRJrERILYFEMwAAuEAAdX%2F%2Ff7%2F%2FP%2B%2BfDvGXQLIZgLEWgLOjlf7%2F%2F%2F%2F%2F%2F9QU90EAPQAAf8DAP0AAfMAAOUDAtr%2F%2F%2F%2F7%2B%2Fu2bCTIYwDPZgDBWQDSr4P%2F%2Fv%2F%2F%2FP5GRuABAPkAA%2FwBAfkDAPAAAesAAN%2F%2F%2B%2Fz%2F%2F%2F64g1C5VwDMYwK8Yg7y5tz8%2Fv%2FV1PYKDOcAAP0DAf4AAf0AAfYEAOwAAuAAAAD%2F%2FPvi28ymXyChTATRrIb8%2F%2F3v8fk6P8MAAdUCAvoAAP0CAP0AAfYAAO4AAACAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAQAA</Image>
<Url type="application/x-suggestions+json" method="GET" template="http://suggestqueries.google.com/complete/search?output=firefox&amp;client=firefox&amp;hl={moz:locale}&amp;q={searchTerms}"/>
<Url type="text/html" method="GET" template="http://www.google.com/search">
<Url type="text/html" method="GET" template="http://www.google.com/search" resultdomain="google.com">
<Param name="q" value="{searchTerms}"/>
<Param name="ie" value="utf-8"/>
<Param name="oe" value="utf-8"/>
@ -15,7 +15,7 @@
<MozParam name="channel" condition="purpose" purpose="contextmenu" value="rcs"/>
<MozParam name="channel" condition="purpose" purpose="keyword" value="fflb"/>
</Url>
<Url type="application/x-moz-default-purpose" method="GET" template="http://www.google.com/search">
<Url type="application/x-moz-default-purpose" method="GET" template="http://www.google.com/search" resultdomain="purpose.google.com">
<Param name="q" value="{searchTerms}"/>
<MozParam name="client" condition="defaultEngine" trueValue="firefox-a" falseValue="firefox"/>
<!-- MozParam with a default value if purpose is not specified -->

Просмотреть файл

@ -24,6 +24,7 @@
},
{
"template": "http://www.google.com/search",
"resultDomain": "google.com",
"rels": [
],
"params": [
@ -64,6 +65,7 @@
},
{
"template": "http://www.google.com/search",
"resultDomain": "purpose.google.com",
"rels": [
],
"type": "application/x-moz-default-purpose",

Просмотреть файл

@ -5,7 +5,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
Components.utils.import("resource://gre/modules/Promise.jsm");
Components.utils.import("resource://testing-common/AppInfo.jsm");
const BROWSER_SEARCH_PREF = "browser.search.";

Просмотреть файл

@ -199,6 +199,7 @@ let EXPECTED_ENGINE = {
type: "text/html",
method: "GET",
template: "http://www.google.com/search",
resultDomain: "google.com",
params: [
{
"name": "q",
@ -250,6 +251,7 @@ let EXPECTED_ENGINE = {
type: "application/x-moz-default-purpose",
method: "GET",
template: "http://www.google.com/search",
resultDomain: "purpose.google.com",
params: [
{
"name": "q",

Просмотреть файл

@ -0,0 +1,79 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
/*
* Tests getResultDomain API.
*/
"use strict";
const Ci = Components.interfaces;
Components.utils.import("resource://testing-common/httpd.js");
let waitForEngines = new Set([ "Test search engine",
"A second test engine",
"bacon" ]);
function promiseEnginesAdded() {
let deferred = Promise.defer();
let observe = function observe(aSubject, aTopic, aData) {
let engine = aSubject.QueryInterface(Ci.nsISearchEngine);
do_print("Observer: " + aData + " for " + engine.name);
if (aData != "engine-added") {
return;
}
waitForEngines.delete(engine.name);
if (waitForEngines.size > 0) {
return;
}
let engine1 = Services.search.getEngineByName("Test search engine");
do_check_eq(engine1.getResultDomain(), "google.com");
do_check_eq(engine1.getResultDomain("text/html"), "google.com");
do_check_eq(engine1.getResultDomain("application/x-moz-default-purpose"),
"purpose.google.com");
do_check_eq(engine1.getResultDomain("fake-response-type"), "");
let engine2 = Services.search.getEngineByName("A second test engine");
do_check_eq(engine2.getResultDomain(), "duckduckgo.com");
let engine3 = Services.search.getEngineByName("bacon");
do_check_eq(engine3.getResultDomain(), "bacon.moz");
deferred.resolve();
};
Services.obs.addObserver(observe, "browser-search-engine-modified", false);
do_register_cleanup(function cleanup() {
Services.obs.removeObserver(observe, "browser-search-engine-modified");
});
return deferred.promise;
}
function run_test() {
removeMetadata();
updateAppInfo();
run_next_test();
}
add_task(function* check_resultDomain() {
let httpServer = new HttpServer();
httpServer.start(-1);
httpServer.registerDirectory("/", do_get_cwd());
let baseUrl = "http://localhost:" + httpServer.identity.primaryPort;
do_register_cleanup(function cleanup() {
httpServer.stop(function() {});
});
let promise = promiseEnginesAdded();
Services.search.addEngine(baseUrl + "/data/engine.xml",
Ci.nsISearchEngine.DATA_XML,
null, false);
Services.search.addEngine(baseUrl + "/data/engine2.xml",
Ci.nsISearchEngine.DATA_XML,
null, false);
Services.search.addEngineWithDetails("bacon", "", "bacon", "Search Bacon",
"GET", "http://www.bacon.moz/?search={searchTerms}");
yield promise;
});

Просмотреть файл

@ -31,6 +31,7 @@ support-files =
[test_notifications.js]
[test_addEngine_callback.js]
[test_multipleIcons.js]
[test_resultDomain.js]
[test_serialize_file.js]
[test_async.js]
[test_sync.js]