VulpesOS/gaia/apps/search/js/providers/suggestions.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

140 lines
3.7 KiB
JavaScript
Executable file

(function() {
'use strict';
/* globals Promise, Provider, Search, MetricsHelper */
/* globals LazyLoader */
/* globals SearchProvider */
var suggestionsWrapper = document.getElementById('suggestions-wrapper');
var suggestionsProvider = document.getElementById('suggestions-provider');
var suggestionsSelect = document.getElementById('suggestions-select');
function providerUpdated() {
navigator.mozL10n.setAttributes(suggestionsProvider, 'search-header', {
provider: SearchProvider('title').toUpperCase()
});
var providers = SearchProvider.providers();
var selectFragment = document.createDocumentFragment();
var optionNode = document.createElement('option');
Object.keys(providers).forEach(provider => {
var option = optionNode.cloneNode();
option.value = provider;
option.text = providers[provider].title;
if (provider === SearchProvider.selected()) {
option.selected = true;
}
selectFragment.appendChild(option);
});
suggestionsSelect.innerHTML = '';
suggestionsSelect.appendChild(selectFragment);
}
function encodeTerms(str, search) {
return str.replace('{searchTerms}', encodeURIComponent(search));
}
function Suggestions() {}
Suggestions.prototype = {
__proto__: Provider.prototype,
name: 'Suggestions',
currentSearch: null,
init: function() {
this.metrics = new MetricsHelper();
this.metrics.init();
Provider.prototype.init.apply(this, arguments);
suggestionsSelect.addEventListener('change', function(e) {
SearchProvider.setProvider(e.target.value);
});
SearchProvider.ready().then(() => {
providerUpdated();
SearchProvider.providerUpdated(() => {
providerUpdated();
this.redoSearch();
});
});
},
redoSearch: function() {
if (!this.currentSearch) {
return;
}
this.search(this.currentSearch).then(results => {
this.render(results);
});
},
click: function(e) {
this.metrics.report('websearch', SearchProvider('title'));
var suggestion = e.target.dataset.suggestion;
var url = encodeTerms(SearchProvider('searchUrl'), suggestion);
Search.navigate(url);
},
search: function(input, preventRemote) {
this.currentSearch = preventRemote ? null : input;
this.render([input]);
if (!navigator.onLine || preventRemote) {
return Promise.resolve([input]);
}
suggestionsWrapper.dataset.loading = true;
return SearchProvider.ready().then(() => {
return new Promise((resolve, reject) => {
var url = encodeTerms(SearchProvider('suggestUrl'), input);
LazyLoader.getJSON(url, true).then(result => {
var results = result[1];
// We add an item to search the entered term as well
results.unshift(input);
resolve(results);
}).catch(function() {
suggestionsWrapper.dataset.loading = false;
reject();
});
});
});
},
render: function(items) {
var ul = document.createElement('ul');
ul.setAttribute('role', 'listbox');
items.forEach(function each(item) {
var li = document.createElement('li');
li.dataset.suggestion = li.textContent = item;
li.setAttribute('role', 'option');
ul.appendChild(li);
});
suggestionsWrapper.dataset.loading = false;
this.container.innerHTML = '';
if (ul.childNodes.length) {
this.container.appendChild(ul);
}
},
clear: function() {
Provider.prototype.clear.apply(this, arguments);
this.currentSearch = null;
}
};
Search.provider(new Suggestions());
}());