Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
214 lines
5.9 KiB
JavaScript
Executable file
214 lines
5.9 KiB
JavaScript
Executable file
'use strict';
|
|
|
|
/* exported SearchProvider */
|
|
/* globals LazyLoader */
|
|
/* globals SettingsListener */
|
|
/* globals Format */
|
|
|
|
(function(exports) {
|
|
|
|
// When the "search_providers_input.json" file is edited, both this
|
|
// and PROVIDERS_VERSION in app/search/test/marionette/lib/search.js
|
|
// should be bumped so existing clients reload the updated data
|
|
var VERSION = 3;
|
|
|
|
// Cache for current provider configuration
|
|
var SEARCH_CACHE_KEY = 'search.cache';
|
|
// The users current provider selection
|
|
var SEARCH_PROVIDER_KEY = 'search.provider';
|
|
|
|
// File containing the provider configurations for all partners
|
|
var DEFAULT_PROVIDERS_URL = '/shared/js/search_providers.json';
|
|
|
|
// Store the users current provider selection
|
|
var provider = null;
|
|
|
|
// Store the list of available providers
|
|
var providers = {};
|
|
var defaultEngine = null;
|
|
|
|
// Notify a client when provider configuration changes
|
|
var updatedFun;
|
|
|
|
// Allow consumers to wait for data to be initialised
|
|
var readyPromise;
|
|
var resolver;
|
|
|
|
function extend(dest, source) {
|
|
for (var k in source) {
|
|
if (source.hasOwnProperty(k)) {
|
|
var value = source[k];
|
|
if (dest.hasOwnProperty(k) &&
|
|
typeof dest[k] === 'object' &&
|
|
typeof value === 'object') {
|
|
extend(dest[k], value);
|
|
} else {
|
|
dest[k] = value;
|
|
}
|
|
}
|
|
}
|
|
return dest;
|
|
}
|
|
|
|
function resolveUrl(urlConf) {
|
|
var params = Object.keys(urlConf.params).map(function(k) {
|
|
return k + '=' + urlConf.params[k];
|
|
}).join('&');
|
|
return urlConf.url + (params ? '?' + params : '');
|
|
}
|
|
|
|
// We havent got valid cached data so load the json configuration
|
|
// file and pick the configuration based on the current
|
|
// partner code
|
|
function loadProviderConfig() {
|
|
LazyLoader.getJSON(DEFAULT_PROVIDERS_URL).then(result => {
|
|
|
|
var conns = navigator.mozMobileConnections || [];
|
|
var mccs = Array.prototype.slice.call(conns).map(function(conn) {
|
|
if (conn.voice && conn.voice.network) {
|
|
return Format.padLeft(conn.voice.network.mcc, 3, '0') + '-' +
|
|
Format.padLeft(conn.voice.network.mnc, 3, '0');
|
|
}
|
|
});
|
|
var engines = SearchProvider.pickEngines(result, mccs,
|
|
result.partner_code || null,
|
|
navigator.language);
|
|
defaultEngine = engines.defaultEngine;
|
|
providers = engines.providers;
|
|
|
|
// Cache for future lookups
|
|
var cache = {};
|
|
cache[SEARCH_CACHE_KEY] = {};
|
|
cache[SEARCH_CACHE_KEY].defaultEngine = defaultEngine;
|
|
cache[SEARCH_CACHE_KEY].providers = providers;
|
|
cache[SEARCH_CACHE_KEY].version = VERSION;
|
|
navigator.mozSettings.createLock().set(cache);
|
|
|
|
providersLoaded();
|
|
});
|
|
}
|
|
|
|
// Once the providers are loaded, find the users current provider
|
|
// selection
|
|
function providersLoaded() {
|
|
SettingsListener.observe(SEARCH_PROVIDER_KEY, false, value => {
|
|
if (value === false || !(value in providers)) {
|
|
provider = defaultEngine;
|
|
} else {
|
|
provider = value;
|
|
}
|
|
|
|
if (resolver && isReady()) {
|
|
resolver();
|
|
resolver = null;
|
|
}
|
|
|
|
if (updatedFun) {
|
|
updatedFun();
|
|
}
|
|
});
|
|
}
|
|
|
|
function isReady() {
|
|
return provider !== null && Object.keys(providers).length;
|
|
}
|
|
|
|
var SearchProvider = function(key) {
|
|
if (!provider || !(key in providers[provider])) {
|
|
return false;
|
|
}
|
|
return providers[provider][key];
|
|
};
|
|
|
|
SearchProvider.providerUpdated = function(cb) {
|
|
updatedFun = cb;
|
|
};
|
|
|
|
SearchProvider.setProvider = function(value) {
|
|
if (!(value in providers)) {
|
|
return false;
|
|
}
|
|
var setting = {};
|
|
setting[SEARCH_PROVIDER_KEY] = value;
|
|
navigator.mozSettings.createLock().set(setting);
|
|
};
|
|
|
|
SearchProvider.selected = function() {
|
|
return provider;
|
|
};
|
|
|
|
SearchProvider.providers = function() {
|
|
return providers;
|
|
};
|
|
|
|
SearchProvider.pickEngines = function(config, sims, partnerCode, locale) {
|
|
|
|
config = JSON.parse(JSON.stringify(config));
|
|
|
|
var engine = config.defaultEngines;
|
|
var usersConfig = {defaultEngine: null, providers: {}};
|
|
|
|
if (partnerCode in config.partnerConfig &&
|
|
locale in config.partnerConfig[partnerCode]) {
|
|
engine = config.partnerConfig[partnerCode][locale];
|
|
}
|
|
|
|
sims.forEach(function(sim) {
|
|
if (sim in config.simConfigs && locale in config.simConfigs[sim]) {
|
|
engine = config.simConfigs[sim][locale];
|
|
}
|
|
});
|
|
|
|
usersConfig.defaultEngine = engine.defaultEngine;
|
|
Object.keys(engine.providers).forEach(function (provider) {
|
|
var obj = config.search_providers[provider];
|
|
|
|
if (locale in config.locales && provider in config.locales[locale]) {
|
|
obj = extend(obj, config.locales[locale][provider]);
|
|
}
|
|
|
|
obj = extend(obj, engine.providers[provider]);
|
|
|
|
usersConfig.providers[provider] = {
|
|
'title': obj.title,
|
|
'searchUrl': resolveUrl(obj.search),
|
|
'suggestUrl': resolveUrl(obj.suggest)
|
|
};
|
|
});
|
|
|
|
return usersConfig;
|
|
};
|
|
|
|
SearchProvider.ready = function() {
|
|
|
|
if (readyPromise) {
|
|
return readyPromise;
|
|
}
|
|
|
|
// Attempt to load cached provider configuration
|
|
var req = navigator.mozSettings.createLock().get(SEARCH_CACHE_KEY);
|
|
req.onsuccess = function() {
|
|
// Do a version check so if the data has updated since it
|
|
// was cached, reload it
|
|
if (req.result[SEARCH_CACHE_KEY] &&
|
|
req.result[SEARCH_CACHE_KEY].version === VERSION) {
|
|
defaultEngine = req.result[SEARCH_CACHE_KEY].defaultEngine;
|
|
providers = req.result[SEARCH_CACHE_KEY].providers;
|
|
providersLoaded();
|
|
} else {
|
|
// There was no cache or it failed the version check, reload
|
|
// from file
|
|
loadProviderConfig();
|
|
}
|
|
};
|
|
|
|
readyPromise = new Promise(resolve => {
|
|
resolver = resolve;
|
|
});
|
|
|
|
return readyPromise;
|
|
};
|
|
|
|
exports.SearchProvider = SearchProvider;
|
|
|
|
})(window);
|