diff --git a/mozilla/browser/components/search/content/engineManager.js b/mozilla/browser/components/search/content/engineManager.js index 966f59f6a83..5b82f084634 100644 --- a/mozilla/browser/components/search/content/engineManager.js +++ b/mozilla/browser/components/search/content/engineManager.js @@ -266,6 +266,8 @@ EngineStore.prototype = { for each (var engine in this._engines) if (engine.name == aName) return engine; + + return null; }, _cloneEngine: function ES_cloneObj(aEngine) { diff --git a/mozilla/browser/components/search/nsIBrowserSearchService.idl b/mozilla/browser/components/search/nsIBrowserSearchService.idl index cc3ceb068a4..dad61d5e44c 100755 --- a/mozilla/browser/components/search/nsIBrowserSearchService.idl +++ b/mozilla/browser/components/search/nsIBrowserSearchService.idl @@ -276,7 +276,9 @@ interface nsIBrowserSearchService : nsISupports [retval, array, size_is(engineCount)] out nsISearchEngine engines); /** - * Returns an array of all default search engines. + * Returns an array of all default search engines. This includes all loaded + * engines that aren't in the user's profile directory + * (NS_APP_USER_SEARCH_DIR). * * @returns an array of nsISearchEngine objects. */ diff --git a/mozilla/browser/components/search/nsSearchService.js b/mozilla/browser/components/search/nsSearchService.js index 4d2c8ed1cb3..3fafb1ace83 100755 --- a/mozilla/browser/components/search/nsSearchService.js +++ b/mozilla/browser/components/search/nsSearchService.js @@ -57,6 +57,12 @@ const NS_APP_USER_SEARCH_DIR = "UsrSrchPlugns"; const NS_APP_SEARCH_DIR = "SrchPlugns"; const NS_APP_USER_PROFILE_50_DIR = "ProfD"; +// Search engine "locations". If this list is changed, be sure to update +// the engine's _isDefault function accordingly. +const SEARCH_APP_DIR = 1; +const SEARCH_PROFILE_DIR = 2; +const SEARCH_IN_EXTENSION = 3; + // See documentation in nsIBrowserSearchService.idl. const SEARCH_ENGINE_TOPIC = "browser-search-engine-modified"; const QUIT_APPLICATION_TOPIC = "quit-application"; @@ -727,9 +733,9 @@ function ParamSubstitution(aParamValue, aSearchTerms, aEngine) { } catch (ex) { } - // Custom search parameters. These are only available to app-shipped search + // Custom search parameters. These are only available to default search // engines. - if (aEngine._isInAppDir) { + if (aEngine._isDefault) { value = value.replace(MOZ_PARAM_LOCALE, getLocale()); value = value.replace(MOZ_PARAM_DIST_ID, distributionID); value = value.replace(MOZ_PARAM_OFFICIAL, MOZ_OFFICIAL); @@ -974,8 +980,9 @@ Engine.prototype = { // Whether to set this as the current engine as soon as it is loaded. This // is only used when the engine is first added to the list. _useNow: true, - // Whether the search engine file is in the app dir. - __isInAppDir: null, + // Where the engine was loaded from. Can be one of: SEARCH_APP_DIR, + // SEARCH_PROFILE_DIR, SEARCH_IN_EXTENSION. + __installLocation: null, // The number of days between update checks for new versions _updateInterval: null, // The url to check at for a new update @@ -1413,8 +1420,8 @@ Engine.prototype = { LOG("_parseURL: Url element has an invalid param"); } } else if (param.localName == "MozParam" && - // We only support MozParams for appdir-shipped search engines - this._isInAppDir) { + // We only support MozParams for default search engines + this._isDefault) { var value; switch (param.getAttribute("condition")) { case "defaultEngine": @@ -2023,7 +2030,7 @@ Engine.prototype = { get _id() { ENSURE_WARN(this._file, "No _file for id!", Cr.NS_ERROR_FAILURE); - if (this._file.parent.equals(getDir(NS_APP_USER_SEARCH_DIR))) + if (this._isInProfile) return "[profile]/" + this._file.leafName; if (this._isInAppDir) @@ -2034,13 +2041,35 @@ Engine.prototype = { return this._file.path; }, - get _isInAppDir() { + get _installLocation() { ENSURE_WARN(this._file && this._file.exists(), - "_isInAppDir: engine has no file!", + "_installLocation: engine has no file!", Cr.NS_ERROR_FAILURE); - if (this.__isInAppDir === null) - this.__isInAppDir = this._file.parent.equals(getDir(NS_APP_SEARCH_DIR)); - return this.__isInAppDir; + + if (this.__installLocation === null) { + if (this._file.parent.equals(getDir(NS_APP_SEARCH_DIR))) + this.__installLocation = SEARCH_APP_DIR; + else if (this._file.parent.equals(getDir(NS_APP_USER_SEARCH_DIR))) + this.__installLocation = SEARCH_PROFILE_DIR; + else + this.__installLocation = SEARCH_IN_EXTENSION; + } + + return this.__installLocation; + }, + + get _isInAppDir() { + return this._installLocation == SEARCH_APP_DIR; + }, + get _isInProfile() { + return this._installLocation == SEARCH_PROFILE_DIR; + }, + + get _isDefault() { + // For now, our concept of a "default engine" is "one that is not in the + // user's profile directory", which is currently equivalent to "is app- or + // extension-shipped". + return !this._isInProfile; }, get _hasUpdates() { @@ -2577,21 +2606,47 @@ SearchService.prototype = { }, getDefaultEngines: function SRCH_SVC_getDefault(aCount) { - function isDefault (engine) { - return engine._isInAppDir; + function isDefault(engine) { + return engine._isDefault; }; var engines = this._sortedEngines.filter(isDefault); var engineOrder = {}; + var engineName; var i = 1; - while (true) { - var name = getLocalizedPref(BROWSER_SEARCH_PREF + "order." + i); - if (!name) + // Build a list of engines which we have ordering information for. + // We're rebuilding the list here because _sortedEngines contain the + // current order, but we want the original order. + + // First, look at the "browser.search.order.extra" branch. + try { + var prefB = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefBranch); + var extras = prefB.getChildList(BROWSER_SEARCH_PREF + "order.extra.", + {}); + + for each (var prefName in extras) { + engineName = prefB.getCharPref(prefName); + + if (!(engineName in engineOrder)) + engineOrder[engineName] = i++; + } + } catch (e) { + LOG("Getting extra order prefs failed: " + e); + } + + // Now look through the "browser.search.order" branch. + for (var j = 1; ; j++) { + engineName = getLocalizedPref(BROWSER_SEARCH_PREF + "order." + j); + if (!engineName) break; - engineOrder[name] = i++; + if (!(engineName in engineOrder)) + engineOrder[engineName] = i++; } + LOG("getDefaultEngines: engineOrder: " + engineOrder.toSource()); + function compareEngines (a, b) { var aIdx = engineOrder[a.name]; var bIdx = engineOrder[b.name]; @@ -2744,8 +2799,8 @@ SearchService.prototype = { restoreDefaultEngines: function SRCH_SVC_resetDefaultEngines() { for each (var e in this._engines) { - // Unhide all appdir-installed engines - if (e.hidden && e._isInAppDir) + // Unhide all default engines + if (e.hidden && e._isDefault) e.hidden = false; } },