blob: 3de204caa0e8a73008efac0bb36d4b15b9a4fbfb [file] [log] [blame]
// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
Polymer({
is: 'cr-toolbar-search-field',
behaviors: [CrSearchFieldBehavior],
properties: {
narrow: {
type: Boolean,
reflectToAttribute: true,
},
showingSearch: {
type: Boolean,
value: false,
notify: true,
observer: 'showingSearchChanged_',
reflectToAttribute: true
},
// Prompt text to display in the search field.
label: String,
// Tooltip to display on the clear search button.
clearLabel: String,
// When true, show a loading spinner to indicate that the backend is
// processing the search. Will only show if the search field is open.
spinnerActive: {type: Boolean, reflectToAttribute: true},
/** @private */
hasSearchText_: {type: Boolean, reflectToAttribute: true},
/** @private */
isSpinnerShown_: {
type: Boolean,
computed: 'computeIsSpinnerShown_(spinnerActive, showingSearch)'
},
/** @private */
searchFocused_: {type: Boolean, value: false},
},
listeners: {
// Deliberately uses 'click' instead of 'tap' to fix crbug.com/624356.
'click': 'showSearch_',
},
/** @return {!HTMLInputElement} */
getSearchInput: function() {
return this.$.searchInput;
},
/**
* Sets the value of the search field. Overridden from CrSearchFieldBehavior.
* @param {string} value
* @param {boolean=} opt_noEvent Whether to prevent a 'search-changed' event
* firing for this change.
*/
setValue: function(value, opt_noEvent) {
CrSearchFieldBehavior.setValue.call(this, value, opt_noEvent);
this.onSearchInput_();
},
/** @return {boolean} */
isSearchFocused: function() {
return this.searchFocused_;
},
showAndFocus: function() {
this.showingSearch = true;
this.focus_();
},
/** @private */
focus_: function() {
this.getSearchInput().focus();
},
/**
* @param {boolean} narrow
* @return {number}
* @private
*/
computeIconTabIndex_: function(narrow) {
return narrow ? 0 : -1;
},
/**
* @return {boolean}
* @private
*/
computeIsSpinnerShown_: function() {
return this.spinnerActive && this.showingSearch;
},
/** @private */
onInputFocus_: function() {
this.searchFocused_ = true;
},
/** @private */
onInputBlur_: function() {
this.searchFocused_ = false;
if (!this.hasSearchText_)
this.showingSearch = false;
},
/**
* Update the state of the search field whenever the underlying input value
* changes. Unlike onsearch or onkeypress, this is reliably called immediately
* after any change, whether the result of user input or JS modification.
* @private
*/
onSearchInput_: function() {
var newValue = this.$.searchInput.value;
this.hasSearchText_ = newValue != '';
if (newValue != '')
this.showingSearch = true;
},
/** @private */
onSearchTermKeydown_: function(e) {
if (e.key == 'Escape')
this.showingSearch = false;
},
/**
* @param {Event} e
* @private
*/
showSearch_: function(e) {
if (e.target != this.$.clearSearch)
this.showingSearch = true;
},
/**
* @param {Event} e
* @private
*/
clearSearch_: function(e) {
this.setValue('');
this.focus_();
},
/**
* @param {boolean} current
* @param {boolean|undefined} previous
* @private
*/
showingSearchChanged_: function(current, previous) {
// Prevent unnecessary 'search-changed' event from firing on startup.
if (previous == undefined)
return;
if (this.showingSearch) {
this.focus_();
return;
}
this.setValue('');
this.getSearchInput().blur();
},
});