Commit a24060b6 authored by dpapad's avatar dpapad Committed by Commit Bot

Settings WebUI: Allow filtering the search engines list.

Bug: 731467
Cq-Include-Trybots: master.tryserver.chromium.linux:closure_compilation
Change-Id: I785ddcb08e90910c508bc38e7bb2a524de854949
Reviewed-on: https://chromium-review.googlesource.com/595194Reviewed-by: default avatarHector Carmona <hcarmona@chromium.org>
Commit-Queue: Demetrios Papadopoulos <dpapad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491244}
parent b94e0073
...@@ -1946,6 +1946,9 @@ ...@@ -1946,6 +1946,9 @@
<message name="IDS_SETTINGS_SEARCH_ENGINES" desc="Name of the settings page which manages search engines."> <message name="IDS_SETTINGS_SEARCH_ENGINES" desc="Name of the settings page which manages search engines.">
Search Engines Search Engines
</message> </message>
<message name="IDS_SETTINGS_SEARCH_ENGINES_SEARCH" desc="Label for a text input placeholder allowing the user to search/filter the displayed search engines">
Search
</message>
<message name="IDS_SETTINGS_SEARCH_ENGINES_ADD_SEARCH_ENGINE" desc="Title for a dialog that allows adding a new search engine."> <message name="IDS_SETTINGS_SEARCH_ENGINES_ADD_SEARCH_ENGINE" desc="Title for a dialog that allows adding a new search engine.">
Add search engine Add search engine
</message> </message>
......
...@@ -26,10 +26,6 @@ ...@@ -26,10 +26,6 @@
@apply(--settings-list-frame-padding); @apply(--settings-list-frame-padding);
} }
/* TODO(dbeam): this rule results in incorrectly showing a top border for
* "Other Search Engines", which hides the headers while still adding a
* dividing line (even though there's no content above the other engines
* to actually divide). */
settings-search-engine-entry { settings-search-engine-entry {
border-top: var(--settings-separator-line); border-top: var(--settings-separator-line);
} }
...@@ -48,7 +44,7 @@ ...@@ -48,7 +44,7 @@
} }
</style> </style>
<div id="outer"> <div id="outer">
<div id="headers" class="column-header" hidden$="[[hideHeaders]]"> <div id="headers" class="column-header">
<div class="name">$i18n{searchEnginesSearchEngine}</div> <div class="name">$i18n{searchEnginesSearchEngine}</div>
<div class="keyword">$i18n{searchEnginesKeyword}</div> <div class="keyword">$i18n{searchEnginesKeyword}</div>
<div class="url">$i18n{searchEnginesQueryURL}</div> <div class="url">$i18n{searchEnginesQueryURL}</div>
......
...@@ -13,9 +13,6 @@ Polymer({ ...@@ -13,9 +13,6 @@ Polymer({
/** @type {!Array<!SearchEngine>} */ /** @type {!Array<!SearchEngine>} */
engines: Array, engines: Array,
/** Whether column headers should be displayed */
hideHeaders: Boolean,
/** /**
* The scroll target that this list should use. * The scroll target that this list should use.
* @type {?HTMLElement} * @type {?HTMLElement}
......
...@@ -17,7 +17,8 @@ ...@@ -17,7 +17,8 @@
<template> <template>
<style include="settings-shared action-link"> <style include="settings-shared action-link">
.extension-engines, .extension-engines,
#noOtherEngines { #noOtherEngines,
.no-search-results {
@apply(--settings-list-frame-padding); @apply(--settings-list-frame-padding);
} }
...@@ -28,7 +29,12 @@ ...@@ -28,7 +29,12 @@
<div class="settings-box first"> <div class="settings-box first">
<h2>$i18n{searchEnginesDefault}</h2> <h2>$i18n{searchEnginesDefault}</h2>
</div> </div>
<settings-search-engines-list engines="[[defaultEngines]]"> <div class="no-search-results" hidden="[[matchingDefaultEngines_.length]]">
$i18n{searchNoResults}
</div>
<settings-search-engines-list
hidden="[[!matchingDefaultEngines_.length]]"
engines="[[matchingDefaultEngines_]]">
</settings-search-engines-list> </settings-search-engines-list>
<template is="dom-if" if="[[showAddSearchEngineDialog_]]" restamp> <template is="dom-if" if="[[showAddSearchEngineDialog_]]" restamp>
<settings-search-engine-dialog></settings-search-engine-dialog> <settings-search-engine-dialog></settings-search-engine-dialog>
...@@ -44,15 +50,25 @@ ...@@ -44,15 +50,25 @@
<div id="noOtherEngines" hidden="[[otherEngines.length]]"> <div id="noOtherEngines" hidden="[[otherEngines.length]]">
$i18n{searchEnginesNoOtherEngines} $i18n{searchEnginesNoOtherEngines}
</div> </div>
<settings-search-engines-list id="otherEngines" engines="[[otherEngines]]" <div class="no-search-results"
hide-headers scroll-target="[[subpageScrollTarget]]"> hidden="[[!showNoResultsMessage_(
otherEngines, matchingOtherEngines_)]]">
$i18n{searchNoResults}
</div>
<settings-search-engines-list id="otherEngines"
hidden="[[!matchingOtherEngines_.length]]"
engines="[[matchingOtherEngines_]]"
scroll-target="[[subpageScrollTarget]]">
</settings-search-engines-list> </settings-search-engines-list>
<template is="dom-if" if="[[showExtensionsList_]]"> <template is="dom-if" if="[[showExtensionsList_]]">
<div class="settings-box first"> <div class="settings-box first">
<h2>$i18n{searchEnginesExtension}</h2> <h2>$i18n{searchEnginesExtension}</h2>
</div> </div>
<div class="no-search-results" hidden="[[matchingExtensions_.length]]">
$i18n{searchNoResults}
</div>
<iron-list id="extensions" class="extension-engines fixed-height-list" <iron-list id="extensions" class="extension-engines fixed-height-list"
items="[[extensions]]" preserve-focus> items="[[matchingExtensions_]]" preserve-focus>
<template> <template>
<settings-omnibox-extension-entry engine="[[item]]" <settings-omnibox-extension-entry engine="[[item]]"
tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]" tabindex$="[[tabIndex]]" iron-list-tab-index="[[tabIndex]]"
......
...@@ -13,28 +13,13 @@ Polymer({ ...@@ -13,28 +13,13 @@ Polymer({
properties: { properties: {
/** @type {!Array<!SearchEngine>} */ /** @type {!Array<!SearchEngine>} */
defaultEngines: { defaultEngines: Array,
type: Array,
value: function() {
return [];
}
},
/** @type {!Array<!SearchEngine>} */ /** @type {!Array<!SearchEngine>} */
otherEngines: { otherEngines: Array,
type: Array,
value: function() {
return [];
}
},
/** @type {!Array<!SearchEngine>} */ /** @type {!Array<!SearchEngine>} */
extensions: { extensions: Array,
type: Array,
value: function() {
return [];
}
},
/** /**
* Needed by GlobalScrollTargetBehavior. * Needed by GlobalScrollTargetBehavior.
...@@ -54,6 +39,30 @@ Polymer({ ...@@ -54,6 +39,30 @@ Polymer({
computed: 'computeShowExtensionsList_(extensions)', computed: 'computeShowExtensionsList_(extensions)',
}, },
/** Filters out all search engines that do not match. */
filter: {
type: String,
value: '',
},
/** @private {!Array<!SearchEngine>} */
matchingDefaultEngines_: {
type: Array,
computed: 'computeMatchingEngines_(defaultEngines, filter)',
},
/** @private {!Array<!SearchEngine>} */
matchingOtherEngines_: {
type: Array,
computed: 'computeMatchingEngines_(otherEngines, filter)',
},
/** @private {!Array<!SearchEngine>} */
matchingExtensions_: {
type: Array,
computed: 'computeMatchingEngines_(extensions, filter)',
},
/** @private {HTMLElement} */ /** @private {HTMLElement} */
omniboxExtensionlastFocused_: Object, omniboxExtensionlastFocused_: Object,
}, },
...@@ -121,4 +130,31 @@ Polymer({ ...@@ -121,4 +130,31 @@ Polymer({
computeShowExtensionsList_: function() { computeShowExtensionsList_: function() {
return this.extensions.length > 0; return this.extensions.length > 0;
}, },
/**
* Filters the given list based on the currently existing filter string.
* @param {!Array<!SearchEngine>} list
* @return {!Array<!SearchEngine>}
* @private
*/
computeMatchingEngines_: function(list) {
if (this.filter == '')
return list;
var filter = this.filter.toLowerCase();
return list.filter(e => {
return [e.displayName, e.name, e.keyword, e.url].some(
term => term.toLowerCase().includes(filter));
});
},
/**
* @param {!Array<!SearchEngine>} list The original list.
* @param {!Array<!SearchEngine>} filteredList The filtered list.
* @return {boolean} Whether to show the "no results" message.
* @private
*/
showNoResultsMessage_: function(list, filteredList) {
return list.length > 0 && filteredList.length == 0;
},
}); });
...@@ -171,8 +171,10 @@ ...@@ -171,8 +171,10 @@
<template is="dom-if" route-path="/searchEngines"> <template is="dom-if" route-path="/searchEngines">
<settings-subpage <settings-subpage
associated-control="[[$$('#engines-subpage-trigger')]]" associated-control="[[$$('#engines-subpage-trigger')]]"
page-title="$i18n{searchEnginesManage}"> page-title="$i18n{searchEnginesManage}"
<settings-search-engines-page></settings-search-engines-page> search-label="$i18n{searchEnginesSearch}"
search-term="{{searchEnginesFilter_}}">
<settings-search-engines-page filter="[[searchEnginesFilter_]]">
</settings-subpage> </settings-subpage>
</template> </template>
<if expr="chromeos"> <if expr="chromeos">
......
...@@ -25,6 +25,9 @@ Polymer({ ...@@ -25,6 +25,9 @@ Polymer({
} }
}, },
/** @private Filter applied to search engines. */
searchEnginesFilter_: String,
/** @private {!SearchPageHotwordInfo|undefined} */ /** @private {!SearchPageHotwordInfo|undefined} */
hotwordInfo_: Object, hotwordInfo_: Object,
......
...@@ -1732,6 +1732,7 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) { ...@@ -1732,6 +1732,7 @@ void AddSearchEnginesStrings(content::WebUIDataSource* html_source) {
{"searchEnginesNoOtherEngines", {"searchEnginesNoOtherEngines",
IDS_SETTINGS_SEARCH_ENGINES_NO_OTHER_ENGINES}, IDS_SETTINGS_SEARCH_ENGINES_NO_OTHER_ENGINES},
{"searchEnginesExtension", IDS_SETTINGS_SEARCH_ENGINES_EXTENSION_ENGINES}, {"searchEnginesExtension", IDS_SETTINGS_SEARCH_ENGINES_EXTENSION_ENGINES},
{"searchEnginesSearch", IDS_SETTINGS_SEARCH_ENGINES_SEARCH},
{"searchEnginesSearchEngine", IDS_SETTINGS_SEARCH_ENGINES_SEARCH_ENGINE}, {"searchEnginesSearchEngine", IDS_SETTINGS_SEARCH_ENGINES_SEARCH_ENGINE},
{"searchEnginesKeyword", IDS_SETTINGS_SEARCH_ENGINES_KEYWORD}, {"searchEnginesKeyword", IDS_SETTINGS_SEARCH_ENGINES_KEYWORD},
{"searchEnginesQueryURL", IDS_SETTINGS_SEARCH_ENGINES_QUERY_URL}, {"searchEnginesQueryURL", IDS_SETTINGS_SEARCH_ENGINES_QUERY_URL},
......
...@@ -20,10 +20,10 @@ cr.define('settings_search_engines_page', function() { ...@@ -20,10 +20,10 @@ cr.define('settings_search_engines_page', function() {
displayName: name + " displayName", displayName: name + " displayName",
iconURL: "http://www.google.com/favicon.ico", iconURL: "http://www.google.com/favicon.ico",
isOmniboxExtension: false, isOmniboxExtension: false,
keyword: "google.com", keyword: name,
modelIndex: 0, modelIndex: 0,
name: name, name: name,
url: "https://search.foo.com/search?p=%s", url: "https://" + name + ".com/search?p=%s",
urlLocked: false, urlLocked: false,
}; };
} }
...@@ -283,10 +283,11 @@ cr.define('settings_search_engines_page', function() { ...@@ -283,10 +283,11 @@ cr.define('settings_search_engines_page', function() {
/** @type {!SearchEnginesInfo} */ /** @type {!SearchEnginesInfo} */
var searchEnginesInfo = { var searchEnginesInfo = {
defaults: [createSampleSearchEngine('G', false, false, false)], defaults: [createSampleSearchEngine(
'search_engine_G', false, false, false)],
others: [ others: [
createSampleSearchEngine('B', false, false, false), createSampleSearchEngine('search_engine_B', false, false, false),
createSampleSearchEngine('A', false, false, false), createSampleSearchEngine('search_engine_A', false, false, false),
], ],
extensions: [createSampleOmniboxExtension()], extensions: [createSampleOmniboxExtension()],
}; };
...@@ -377,6 +378,70 @@ cr.define('settings_search_engines_page', function() { ...@@ -377,6 +378,70 @@ cr.define('settings_search_engines_page', function() {
Polymer.dom.flush(); Polymer.dom.flush();
assertTrue(!!page.$$('settings-search-engine-dialog')); assertTrue(!!page.$$('settings-search-engine-dialog'));
}); });
// Tests that filtering the three search engines lists works, and that the
// "no search results" message is shown as expected.
test('FilterSearchEngines', function() {
Polymer.dom.flush();
function getListItems(listIndex) {
var ironList = listIndex == 2 /* extensions */ ?
page.shadowRoot.querySelector('iron-list') :
page.shadowRoot.querySelectorAll(
'settings-search-engines-list')[listIndex].shadowRoot.
querySelector('iron-list');
return ironList.items;
}
function getDefaultEntries() { return getListItems(0); }
function getOtherEntries() { return getListItems(1); }
function assertSearchResults(
defaultsCount, othersCount, extensionsCount) {
assertEquals(defaultsCount, getListItems(0).length);
assertEquals(othersCount, getListItems(1).length);
assertEquals(extensionsCount, getListItems(2).length);
var noResultsElements = Array.from(
page.shadowRoot.querySelectorAll('.no-search-results'));
assertEquals(defaultsCount > 0, noResultsElements[0].hidden);
assertEquals(othersCount > 0, noResultsElements[1].hidden);
assertEquals(extensionsCount > 0, noResultsElements[2].hidden);
}
assertSearchResults(1, 2, 1);
// Search by name
page.filter = searchEnginesInfo.defaults[0].name;
Polymer.dom.flush();
assertSearchResults(1, 0, 0);
// Search by displayName
page.filter = searchEnginesInfo.others[0].displayName;
Polymer.dom.flush();
assertSearchResults(0, 1, 0);
// Search by keyword
page.filter = searchEnginesInfo.others[1].keyword;
Polymer.dom.flush();
assertSearchResults(0, 1, 0);
// Search by URL
page.filter = 'search?';
Polymer.dom.flush();
assertSearchResults(1, 2, 0);
// Test case where none of the sublists have results.
page.filter = 'does not exist';
Polymer.dom.flush();
assertSearchResults(0, 0, 0);
// Test case where an 'extension' search engine matches.
page.filter = 'extension';
Polymer.dom.flush();
assertSearchResults(0, 0, 1);
});
}); });
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment