Bug 1314373 - Fix parser issues raised by eslint for nsSearchService.js. r=mak

MozReview-Commit-ID: FRTCMgRtjTG

--HG--
extra : rebase_source : 6d8600f7f8943817b63d943076eafdafe1f6305e
This commit is contained in:
Mark Banner 2016-11-01 18:35:46 +00:00
parent 087dcd711e
commit 7e8abd3ad9
2 changed files with 300 additions and 298 deletions

View File

@ -241,7 +241,6 @@ toolkit/components/reader/JSDOMParser.js
# Uses preprocessing # Uses preprocessing
toolkit/content/widgets/wizard.xml toolkit/content/widgets/wizard.xml
toolkit/components/jsdownloads/src/DownloadIntegration.jsm toolkit/components/jsdownloads/src/DownloadIntegration.jsm
toolkit/components/search/nsSearchService.js
toolkit/components/url-classifier/** toolkit/components/url-classifier/**
toolkit/components/urlformatter/nsURLFormatter.js toolkit/components/urlformatter/nsURLFormatter.js
toolkit/identity/FirefoxAccounts.jsm toolkit/identity/FirefoxAccounts.jsm

View File

@ -1407,18 +1407,16 @@ Engine.prototype = {
* @returns {Promise} A promise, resolved successfully if initializing from * @returns {Promise} A promise, resolved successfully if initializing from
* data succeeds, rejected if it fails. * data succeeds, rejected if it fails.
*/ */
_asyncInitFromFile: function SRCH_ENG__asyncInitFromFile(file) { _asyncInitFromFile: Task.async(function* (file) {
return Task.spawn(function() { if (!file || !(yield OS.File.exists(file.path)))
if (!file || !(yield OS.File.exists(file.path))) FAIL("File must exist before calling initFromFile!", Cr.NS_ERROR_UNEXPECTED);
FAIL("File must exist before calling initFromFile!", Cr.NS_ERROR_UNEXPECTED);
let fileURI = NetUtil.ioService.newFileURI(file); let fileURI = NetUtil.ioService.newFileURI(file);
yield this._retrieveSearchXMLData(fileURI.spec); yield this._retrieveSearchXMLData(fileURI.spec);
// Now that the data is loaded, initialize the engine object // Now that the data is loaded, initialize the engine object
this._initFromData(); this._initFromData();
}.bind(this)); }),
},
/** /**
* Retrieves the engine data from a URI. Initializes the engine, flushes to * Retrieves the engine data from a URI. Initializes the engine, flushes to
@ -1457,14 +1455,12 @@ Engine.prototype = {
* @returns {Promise} A promise, resolved successfully if retrieveing data * @returns {Promise} A promise, resolved successfully if retrieveing data
* succeeds. * succeeds.
*/ */
_asyncInitFromURI: function SRCH_ENG__asyncInitFromURI(uri) { _asyncInitFromURI: Task.async(function* (uri) {
return Task.spawn(function() { LOG("_asyncInitFromURI: Loading engine from: \"" + uri.spec + "\".");
LOG("_asyncInitFromURI: Loading engine from: \"" + uri.spec + "\"."); yield this._retrieveSearchXMLData(uri.spec);
yield this._retrieveSearchXMLData(uri.spec); // Now that the data is loaded, initialize the engine object
// Now that the data is loaded, initialize the engine object this._initFromData();
this._initFromData(); }),
}.bind(this));
},
/** /**
* Retrieves the engine data for a given URI asynchronously. * Retrieves the engine data for a given URI asynchronously.
@ -2765,43 +2761,48 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if the initialization * @returns {Promise} A promise, resolved successfully if the initialization
* succeeds. * succeeds.
*/ */
_asyncInit: function SRCH_SVC__asyncInit() { _asyncInit: Task.async(function* () {
LOG("_asyncInit start");
migrateRegionPrefs(); migrateRegionPrefs();
return Task.spawn(function() {
LOG("_asyncInit start");
// See if we have a cache file so we don't have to parse a bunch of XML. // See if we have a cache file so we don't have to parse a bunch of XML.
let cache = {}; let cache = {};
// Not using checkForSyncCompletion here because we want to ensure we // Not using checkForSyncCompletion here because we want to ensure we
// fetch the country code and geo specific defaults asynchronously even // fetch the country code and geo specific defaults asynchronously even
// if a sync init has been forced. // if a sync init has been forced.
cache = yield this._asyncReadCacheFile(); cache = yield this._asyncReadCacheFile();
if (!gInitialized && cache.metaData) if (!gInitialized && cache.metaData)
this._metaData = cache.metaData; this._metaData = cache.metaData;
try { try {
yield checkForSyncCompletion(ensureKnownCountryCode(this)); yield checkForSyncCompletion(ensureKnownCountryCode(this));
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) { } catch (ex) {
LOG("_asyncInit: failure determining country code: " + ex); if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
throw ex;
} }
try { LOG("_asyncInit: failure determining country code: " + ex);
yield checkForSyncCompletion(this._asyncLoadEngines(cache)); }
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) { try {
this._initRV = Cr.NS_ERROR_FAILURE; yield checkForSyncCompletion(this._asyncLoadEngines(cache));
LOG("_asyncInit: failure loading engines: " + ex); } catch (ex) {
if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
throw ex;
} }
this._addObservers(); this._initRV = Cr.NS_ERROR_FAILURE;
gInitialized = true; LOG("_asyncInit: failure loading engines: " + ex);
this._cacheFileJSON = null; }
this._initObservers.resolve(this._initRV); this._addObservers();
Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "init-complete"); gInitialized = true;
Services.telemetry.getHistogramById("SEARCH_SERVICE_INIT_SYNC").add(false); this._cacheFileJSON = null;
this._recordEngineTelemetry(); this._initObservers.resolve(this._initRV);
Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "init-complete");
Services.telemetry.getHistogramById("SEARCH_SERVICE_INIT_SYNC").add(false);
this._recordEngineTelemetry();
LOG("_asyncInit: Completed _asyncInit"); LOG("_asyncInit: Completed _asyncInit");
}.bind(this)); }),
},
_metaData: { }, _metaData: { },
setGlobalAttr(name, val) { setGlobalAttr(name, val) {
@ -2995,136 +2996,138 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if loading data * @returns {Promise} A promise, resolved successfully if loading data
* succeeds. * succeeds.
*/ */
_asyncLoadEngines: function SRCH_SVC__asyncLoadEngines(cache) { _asyncLoadEngines: Task.async(function* (cache) {
return Task.spawn(function() { LOG("_asyncLoadEngines: start");
LOG("_asyncLoadEngines: start"); Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "find-jar-engines");
Services.obs.notifyObservers(null, SEARCH_SERVICE_TOPIC, "find-jar-engines"); let chromeURIs =
let chromeURIs = yield checkForSyncCompletion(this._asyncFindJAREngines());
yield checkForSyncCompletion(this._asyncFindJAREngines());
// Get the non-empty distribution directories into distDirs... // Get the non-empty distribution directories into distDirs...
let distDirs = []; let distDirs = [];
let locations; let locations;
try {
locations = getDir(NS_APP_DISTRIBUTION_SEARCH_DIR_LIST,
Ci.nsISimpleEnumerator);
} catch (e) {
// NS_APP_DISTRIBUTION_SEARCH_DIR_LIST is defined by each app
// so this throws during unit tests (but not xpcshell tests).
locations = {hasMoreElements: () => false};
}
while (locations.hasMoreElements()) {
let dir = locations.getNext().QueryInterface(Ci.nsIFile);
let iterator = new OS.File.DirectoryIterator(dir.path,
{ winPattern: "*.xml" });
try { try {
locations = getDir(NS_APP_DISTRIBUTION_SEARCH_DIR_LIST, // Add dir to distDirs if it contains any files.
Ci.nsISimpleEnumerator); yield checkForSyncCompletion(iterator.next());
} catch (e) { distDirs.push(dir);
// NS_APP_DISTRIBUTION_SEARCH_DIR_LIST is defined by each app } catch (ex) {
// so this throws during unit tests (but not xpcshell tests). // Catch for StopIteration exception.
locations = {hasMoreElements: () => false}; if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
} throw ex;
while (locations.hasMoreElements()) {
let dir = locations.getNext().QueryInterface(Ci.nsIFile);
let iterator = new OS.File.DirectoryIterator(dir.path,
{ winPattern: "*.xml" });
try {
// Add dir to distDirs if it contains any files.
yield checkForSyncCompletion(iterator.next());
distDirs.push(dir);
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) {
// Catch for StopIteration exception.
} finally {
iterator.close();
} }
} finally {
iterator.close();
} }
}
// Add the non-empty directories of NS_APP_SEARCH_DIR_LIST to // Add the non-empty directories of NS_APP_SEARCH_DIR_LIST to
// otherDirs... // otherDirs...
let otherDirs = []; let otherDirs = [];
let userSearchDir = getDir(NS_APP_USER_SEARCH_DIR); let userSearchDir = getDir(NS_APP_USER_SEARCH_DIR);
locations = getDir(NS_APP_SEARCH_DIR_LIST, Ci.nsISimpleEnumerator); locations = getDir(NS_APP_SEARCH_DIR_LIST, Ci.nsISimpleEnumerator);
while (locations.hasMoreElements()) { while (locations.hasMoreElements()) {
let dir = locations.getNext().QueryInterface(Ci.nsIFile); let dir = locations.getNext().QueryInterface(Ci.nsIFile);
if (cache.engines && dir.equals(userSearchDir)) if (cache.engines && dir.equals(userSearchDir))
continue;
let iterator = new OS.File.DirectoryIterator(dir.path,
{ winPattern: "*.xml" });
try {
// Add dir to otherDirs if it contains any files.
yield checkForSyncCompletion(iterator.next());
otherDirs.push(dir);
} catch (ex) {
// Catch for StopIteration exception.
if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
throw ex;
}
} finally {
iterator.close();
}
}
let hasModifiedDir = Task.async(function* (aList) {
let modifiedDir = false;
for (let dir of aList) {
let lastModifiedTime = cacheOtherPaths.get(dir.path);
if (!lastModifiedTime) {
continue; continue;
let iterator = new OS.File.DirectoryIterator(dir.path,
{ winPattern: "*.xml" });
try {
// Add dir to otherDirs if it contains any files.
yield checkForSyncCompletion(iterator.next());
otherDirs.push(dir);
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) {
// Catch for StopIteration exception.
} finally {
iterator.close();
}
}
function hasModifiedDir(aList) {
return Task.spawn(function() {
let modifiedDir = false;
for (let dir of aList) {
let lastModifiedTime = cacheOtherPaths.get(dir.path);
if (!lastModifiedTime) {
continue;
}
let info = yield OS.File.stat(dir.path);
if (lastModifiedTime != info.lastModificationDate.getTime()) {
modifiedDir = true;
break;
}
}
throw new Task.Result(modifiedDir);
});
}
function notInCacheVisibleEngines(aEngineName) {
return cache.visibleDefaultEngines.indexOf(aEngineName) == -1;
}
let buildID = Services.appinfo.platformBuildID;
let cacheOtherPaths = new Map();
if (cache.engines) {
for (let engine of cache.engines) {
if (engine._dirPath) {
cacheOtherPaths.set(engine._dirPath, engine._dirLastModifiedTime);
}
}
}
let rebuildCache = !cache.engines ||
cache.version != CACHE_VERSION ||
cache.locale != getLocale() ||
cache.buildID != buildID ||
cacheOtherPaths.size != otherDirs.length ||
otherDirs.some(d => !cacheOtherPaths.has(d.path)) ||
cache.visibleDefaultEngines.length != this._visibleDefaultEngines.length ||
this._visibleDefaultEngines.some(notInCacheVisibleEngines) ||
(yield checkForSyncCompletion(hasModifiedDir(otherDirs)));
if (rebuildCache) {
LOG("_asyncLoadEngines: Absent or outdated cache. Loading engines from disk.");
for (let loadDir of distDirs) {
let enginesFromDir =
yield checkForSyncCompletion(this._asyncLoadEnginesFromDir(loadDir));
enginesFromDir.forEach(this._addEngineToStore, this);
}
let enginesFromURLs =
yield checkForSyncCompletion(this._asyncLoadFromChromeURLs(chromeURIs));
enginesFromURLs.forEach(this._addEngineToStore, this);
LOG("_asyncLoadEngines: loading user-installed engines from the obsolete cache");
this._loadEnginesFromCache(cache, true);
for (let loadDir of otherDirs) {
let enginesFromDir =
yield checkForSyncCompletion(this._asyncLoadEnginesFromDir(loadDir));
enginesFromDir.forEach(this._addEngineToStore, this);
} }
this._loadEnginesMetadataFromCache(cache); let info = yield OS.File.stat(dir.path);
this._buildCache(); if (lastModifiedTime != info.lastModificationDate.getTime()) {
return; modifiedDir = true;
break;
}
}
return modifiedDir;
});
function notInCacheVisibleEngines(aEngineName) {
return cache.visibleDefaultEngines.indexOf(aEngineName) == -1;
}
let buildID = Services.appinfo.platformBuildID;
let cacheOtherPaths = new Map();
if (cache.engines) {
for (let engine of cache.engines) {
if (engine._dirPath) {
cacheOtherPaths.set(engine._dirPath, engine._dirLastModifiedTime);
}
}
}
let rebuildCache = !cache.engines ||
cache.version != CACHE_VERSION ||
cache.locale != getLocale() ||
cache.buildID != buildID ||
cacheOtherPaths.size != otherDirs.length ||
otherDirs.some(d => !cacheOtherPaths.has(d.path)) ||
cache.visibleDefaultEngines.length != this._visibleDefaultEngines.length ||
this._visibleDefaultEngines.some(notInCacheVisibleEngines) ||
(yield checkForSyncCompletion(hasModifiedDir(otherDirs)));
if (rebuildCache) {
LOG("_asyncLoadEngines: Absent or outdated cache. Loading engines from disk.");
for (let loadDir of distDirs) {
let enginesFromDir =
yield checkForSyncCompletion(this._asyncLoadEnginesFromDir(loadDir));
enginesFromDir.forEach(this._addEngineToStore, this);
}
let enginesFromURLs =
yield checkForSyncCompletion(this._asyncLoadFromChromeURLs(chromeURIs));
enginesFromURLs.forEach(this._addEngineToStore, this);
LOG("_asyncLoadEngines: loading user-installed engines from the obsolete cache");
this._loadEnginesFromCache(cache, true);
for (let loadDir of otherDirs) {
let enginesFromDir =
yield checkForSyncCompletion(this._asyncLoadEnginesFromDir(loadDir));
enginesFromDir.forEach(this._addEngineToStore, this);
} }
LOG("_asyncLoadEngines: loading from cache directories"); this._loadEnginesMetadataFromCache(cache);
this._loadEnginesFromCache(cache); this._buildCache();
return;
}
LOG("_asyncLoadEngines: done"); LOG("_asyncLoadEngines: loading from cache directories");
}.bind(this)); this._loadEnginesFromCache(cache);
},
LOG("_asyncLoadEngines: done");
}),
_asyncReInit: function () { _asyncReInit: function () {
LOG("_asyncReInit"); LOG("_asyncReInit");
@ -3256,45 +3259,43 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if retrieveing data * @returns {Promise} A promise, resolved successfully if retrieveing data
* succeeds. * succeeds.
*/ */
_asyncReadCacheFile: function SRCH_SVC__asyncReadCacheFile() { _asyncReadCacheFile: Task.async(function* () {
return Task.spawn(function() { let json;
let json; try {
try { let cacheFilePath = OS.Path.join(OS.Constants.Path.profileDir, CACHE_FILENAME);
let cacheFilePath = OS.Path.join(OS.Constants.Path.profileDir, CACHE_FILENAME); let bytes = yield OS.File.read(cacheFilePath, {compression: "lz4"});
let bytes = yield OS.File.read(cacheFilePath, {compression: "lz4"}); json = JSON.parse(new TextDecoder().decode(bytes));
json = JSON.parse(new TextDecoder().decode(bytes)); if (!json.engines || !json.engines.length)
if (!json.engines || !json.engines.length) throw "no engine in the file";
throw "no engine in the file"; this._cacheFileJSON = json;
this._cacheFileJSON = json; } catch (ex) {
} catch (ex) { LOG("_asyncReadCacheFile: Error reading cache file: " + ex);
LOG("_asyncReadCacheFile: Error reading cache file: " + ex); json = {};
json = {};
let oldMetadata = let oldMetadata =
OS.Path.join(OS.Constants.Path.profileDir, "search-metadata.json"); OS.Path.join(OS.Constants.Path.profileDir, "search-metadata.json");
try { try {
let bytes = yield OS.File.read(oldMetadata); let bytes = yield OS.File.read(oldMetadata);
let metadata = JSON.parse(new TextDecoder().decode(bytes)); let metadata = JSON.parse(new TextDecoder().decode(bytes));
if ("[global]" in metadata) { if ("[global]" in metadata) {
LOG("_asyncReadCacheFile: migrating metadata from search-metadata.json"); LOG("_asyncReadCacheFile: migrating metadata from search-metadata.json");
let data = metadata["[global]"]; let data = metadata["[global]"];
json.metaData = {}; json.metaData = {};
let fields = ["searchDefault", "searchDefaultHash", "searchDefaultExpir", let fields = ["searchDefault", "searchDefaultHash", "searchDefaultExpir",
"current", "hash", "current", "hash",
"visibleDefaultEngines", "visibleDefaultEnginesHash"]; "visibleDefaultEngines", "visibleDefaultEnginesHash"];
for (let field of fields) { for (let field of fields) {
let name = field.toLowerCase(); let name = field.toLowerCase();
if (name in data) if (name in data)
json.metaData[field] = data[name]; json.metaData[field] = data[name];
}
} }
delete metadata["[global]"]; }
json._oldMetadata = metadata; delete metadata["[global]"];
} catch (ex) {} json._oldMetadata = metadata;
} } catch (ex) {}
throw new Task.Result(json); }
}.bind(this)); return json;
}, }),
_batchTask: null, _batchTask: null,
get batchTask() { get batchTask() {
@ -3470,52 +3471,53 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if retrieveing data * @returns {Promise} A promise, resolved successfully if retrieveing data
* succeeds. * succeeds.
*/ */
_asyncLoadEnginesFromDir: function SRCH_SVC__asyncLoadEnginesFromDir(aDir) { _asyncLoadEnginesFromDir: Task.async(function* (aDir) {
LOG("_asyncLoadEnginesFromDir: Searching in " + aDir.path + " for search engines."); LOG("_asyncLoadEnginesFromDir: Searching in " + aDir.path + " for search engines.");
// Check whether aDir is the user profile dir // Check whether aDir is the user profile dir
let isInProfile = aDir.equals(getDir(NS_APP_USER_SEARCH_DIR)); let isInProfile = aDir.equals(getDir(NS_APP_USER_SEARCH_DIR));
let dirPath = aDir.path; let dirPath = aDir.path;
let iterator = new OS.File.DirectoryIterator(dirPath); let iterator = new OS.File.DirectoryIterator(dirPath);
return Task.spawn(function() {
let osfiles = yield iterator.nextBatch();
iterator.close();
let engines = []; let osfiles = yield iterator.nextBatch();
for (let osfile of osfiles) { iterator.close();
if (osfile.isDir || osfile.isSymLink)
continue;
let fileInfo = yield OS.File.stat(osfile.path); let engines = [];
if (fileInfo.size == 0) for (let osfile of osfiles) {
continue; if (osfile.isDir || osfile.isSymLink)
continue;
let parts = osfile.path.split("."); let fileInfo = yield OS.File.stat(osfile.path);
if (parts.length <= 1 || (parts.pop()).toLowerCase() != "xml") { if (fileInfo.size == 0)
// Not an engine continue;
continue;
}
let addedEngine = null; let parts = osfile.path.split(".");
try { if (parts.length <= 1 || (parts.pop()).toLowerCase() != "xml") {
let file = new FileUtils.File(osfile.path); // Not an engine
addedEngine = new Engine(file, !isInProfile); continue;
yield checkForSyncCompletion(addedEngine._asyncInitFromFile(file)); }
if (!isInProfile && !addedEngine._isDefault) {
addedEngine._dirPath = dirPath; let addedEngine = null;
let info = yield OS.File.stat(dirPath); try {
addedEngine._dirLastModifiedTime = let file = new FileUtils.File(osfile.path);
info.lastModificationDate.getTime(); addedEngine = new Engine(file, !isInProfile);
} yield checkForSyncCompletion(addedEngine._asyncInitFromFile(file));
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) { if (!isInProfile && !addedEngine._isDefault) {
LOG("_asyncLoadEnginesFromDir: Failed to load " + osfile.path + "!\n" + ex); addedEngine._dirPath = dirPath;
continue; let info = yield OS.File.stat(dirPath);
addedEngine._dirLastModifiedTime =
info.lastModificationDate.getTime();
} }
engines.push(addedEngine); engines.push(addedEngine);
} catch (ex) {
if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
throw ex;
}
LOG("_asyncLoadEnginesFromDir: Failed to load " + osfile.path + "!\n" + ex);
} }
throw new Task.Result(engines); }
}.bind(this)); return engines;
}, }),
_loadFromChromeURLs: function SRCH_SVC_loadFromChromeURLs(aURLs) { _loadFromChromeURLs: function SRCH_SVC_loadFromChromeURLs(aURLs) {
aURLs.forEach(function (url) { aURLs.forEach(function (url) {
@ -3542,23 +3544,24 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if loading data * @returns {Promise} A promise, resolved successfully if loading data
* succeeds. * succeeds.
*/ */
_asyncLoadFromChromeURLs: function SRCH_SVC__asyncLoadFromChromeURLs(aURLs) { _asyncLoadFromChromeURLs: Task.async(function* (aURLs) {
return Task.spawn(function() { let engines = [];
let engines = []; for (let url of aURLs) {
for (let url of aURLs) { try {
try { LOG("_asyncLoadFromChromeURLs: loading engine from chrome url: " + url);
LOG("_asyncLoadFromChromeURLs: loading engine from chrome url: " + url); let uri = NetUtil.newURI(url);
let uri = NetUtil.newURI(url); let engine = new Engine(uri, true);
let engine = new Engine(uri, true); yield checkForSyncCompletion(engine._asyncInitFromURI(uri));
yield checkForSyncCompletion(engine._asyncInitFromURI(uri)); engines.push(engine);
engines.push(engine); } catch (ex) {
} catch (ex if ex.result != Cr.NS_ERROR_ALREADY_INITIALIZED) { if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
LOG("_asyncLoadFromChromeURLs: failed to load engine: " + ex); throw ex;
} }
LOG("_asyncLoadFromChromeURLs: failed to load engine: " + ex);
} }
throw new Task.Result(engines); }
}.bind(this)); return engines;
}, }),
_convertChannelToFile: function(chan) { _convertChannelToFile: function(chan) {
let fileURI = chan.URI; let fileURI = chan.URI;
@ -3602,49 +3605,47 @@ SearchService.prototype = {
* @returns {Promise} A promise, resolved successfully if finding jar engines * @returns {Promise} A promise, resolved successfully if finding jar engines
* succeeds. * succeeds.
*/ */
_asyncFindJAREngines: function SRCH_SVC__asyncFindJAREngines() { _asyncFindJAREngines: Task.async(function* () {
return Task.spawn(function() { LOG("_asyncFindJAREngines: looking for engines in JARs")
LOG("_asyncFindJAREngines: looking for engines in JARs")
let listURL = APP_SEARCH_PREFIX + "list.json"; let listURL = APP_SEARCH_PREFIX + "list.json";
let chan = makeChannel(listURL); let chan = makeChannel(listURL);
if (!chan) { if (!chan) {
LOG("_asyncFindJAREngines: " + APP_SEARCH_PREFIX + " isn't registered"); LOG("_asyncFindJAREngines: " + APP_SEARCH_PREFIX + " isn't registered");
throw new Task.Result([]); return [];
} }
let uris = []; let uris = [];
// Read list.json to find the engines we need to load. // Read list.json to find the engines we need to load.
let deferred = Promise.defer(); let deferred = Promise.defer();
let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]. let request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
createInstance(Ci.nsIXMLHttpRequest); createInstance(Ci.nsIXMLHttpRequest);
request.overrideMimeType("text/plain"); request.overrideMimeType("text/plain");
request.onload = function(aEvent) { request.onload = function(aEvent) {
deferred.resolve(aEvent.target.responseText); deferred.resolve(aEvent.target.responseText);
}; };
request.onerror = function(aEvent) {
LOG("_asyncFindJAREngines: failed to read " + listURL);
// Couldn't find list.json, try list.txt
request.onerror = function(aEvent) { request.onerror = function(aEvent) {
LOG("_asyncFindJAREngines: failed to read " + listURL); LOG("_asyncFindJAREngines: failed to read " + APP_SEARCH_PREFIX + "list.txt");
// Couldn't find list.json, try list.txt deferred.resolve("");
request.onerror = function(aEvent) {
LOG("_asyncFindJAREngines: failed to read " + APP_SEARCH_PREFIX + "list.txt");
deferred.resolve("");
}
request.open("GET", NetUtil.newURI(APP_SEARCH_PREFIX + "list.txt").spec, true);
request.send();
};
request.open("GET", NetUtil.newURI(listURL).spec, true);
request.send();
let list = yield deferred.promise;
if (request.responseURL.endsWith(".txt")) {
this._parseListTxt(list, uris);
} else {
this._parseListJSON(list, uris);
} }
throw new Task.Result(uris); request.open("GET", NetUtil.newURI(APP_SEARCH_PREFIX + "list.txt").spec, true);
}.bind(this)); request.send();
}, };
request.open("GET", NetUtil.newURI(listURL).spec, true);
request.send();
let list = yield deferred.promise;
if (request.responseURL.endsWith(".txt")) {
this._parseListTxt(list, uris);
} else {
this._parseListJSON(list, uris);
}
return uris;
}),
_parseListJSON: function SRCH_SVC_parseListJSON(list, uris) { _parseListJSON: function SRCH_SVC_parseListJSON(list, uris) {
let searchSettings; let searchSettings;
@ -3898,18 +3899,20 @@ SearchService.prototype = {
if (!this._initStarted) { if (!this._initStarted) {
TelemetryStopwatch.start("SEARCH_SERVICE_INIT_MS"); TelemetryStopwatch.start("SEARCH_SERVICE_INIT_MS");
this._initStarted = true; this._initStarted = true;
Task.spawn(function task() { Task.spawn(function* task() {
try { try {
// Complete initialization by calling asynchronous initializer. // Complete initialization by calling asynchronous initializer.
yield self._asyncInit(); yield self._asyncInit();
TelemetryStopwatch.finish("SEARCH_SERVICE_INIT_MS"); TelemetryStopwatch.finish("SEARCH_SERVICE_INIT_MS");
} catch (ex if ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
// No need to pursue asynchronous because synchronous fallback was
// called and has finished.
TelemetryStopwatch.finish("SEARCH_SERVICE_INIT_MS");
} catch (ex) { } catch (ex) {
self._initObservers.reject(ex); if (ex.result == Cr.NS_ERROR_ALREADY_INITIALIZED) {
TelemetryStopwatch.cancel("SEARCH_SERVICE_INIT_MS"); // No need to pursue asynchronous because synchronous fallback was
// called and has finished.
TelemetryStopwatch.finish("SEARCH_SERVICE_INIT_MS");
} else {
self._initObservers.reject(ex);
TelemetryStopwatch.cancel("SEARCH_SERVICE_INIT_MS");
}
} }
}); });
} }