1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
10 * @param {element} element Root element of the search box.
13 function SearchBox(element) {
16 * @type {AutocompleteList}
18 this.autocompleteList = new SearchBox.AutocompleteList(element.ownerDocument);
21 * Root element of the search box.
24 this.element = element;
27 * Text input of the search box.
30 this.inputElement = element.querySelector('input');
33 * Clear button of the search box.
36 this.clearButton = element.querySelector('.clear');
41 this.inputElement.addEventListener('input', this.updateStyles_.bind(this));
42 this.inputElement.addEventListener('keydown', this.onKeyDown_.bind(this));
43 this.inputElement.addEventListener('focus', this.onFocus_.bind(this));
44 this.inputElement.addEventListener('blur', this.onBlur_.bind(this));
45 this.inputElement.ownerDocument.addEventListener('dragover',
46 this.onDragEnter_.bind(this),
48 this.inputElement.ownerDocument.addEventListener('dragend',
49 this.onDragEnd_.bind(this),
51 element.parentNode.appendChild(this.autocompleteList);
55 * Autocomplete list for search box.
56 * @param {HTMLDocument} document Document.
59 SearchBox.AutocompleteList = function(document) {
60 var self = cr.ui.AutocompleteList.call(this);
61 self.__proto__ = SearchBox.AutocompleteList.prototype;
62 self.id = 'autocomplete-list';
63 self.autoExpands = true;
64 self.itemConstructor = SearchBox.AutocompleteListItem_.bind(null, document);
65 self.addEventListener('mouseover', self.onMouseOver_.bind(self));
69 SearchBox.AutocompleteList.prototype = {
70 __proto__: cr.ui.AutocompleteList.prototype
74 * Do nothing when a suggestion is selected.
77 SearchBox.AutocompleteList.prototype.handleSelectedSuggestion = function() {};
80 * Change the selection by a mouse over instead of just changing the
81 * color of moused over element with :hover in CSS. Here's why:
83 * 1) The user selects an item A with up/down keys (item A is highlighted)
84 * 2) Then the user moves the cursor to another item B
86 * If we just change the color of moused over element (item B), both
87 * the item A and B are highlighted. This is bad. We should change the
88 * selection so only the item B is highlighted.
90 * @param {Event} event Event.
93 SearchBox.AutocompleteList.prototype.onMouseOver_ = function(event) {
94 if (event.target.itemInfo)
95 this.selectedItem = event.target.itemInfo;
99 * ListItem element for autocomplete.
101 * @param {HTMLDocument} document Document.
102 * @param {Object} item An object representing a suggestion.
106 SearchBox.AutocompleteListItem_ = function(document, item) {
107 var li = new cr.ui.ListItem();
110 var icon = document.createElement('div');
111 icon.className = 'detail-icon';
113 var text = document.createElement('div');
114 text.className = 'detail-text';
116 if (item.isHeaderItem) {
117 icon.setAttribute('search-icon', '');
119 strf('SEARCH_DRIVE_HTML', util.htmlEscape(item.searchQuery));
121 var iconType = FileType.getIcon(item.entry);
122 icon.setAttribute('file-type-icon', iconType);
123 // highlightedBaseName is a piece of HTML with meta characters properly
124 // escaped. See the comment at fileManagerPrivate.searchDriveMetadata().
125 text.innerHTML = item.highlightedBaseName;
127 li.appendChild(icon);
128 li.appendChild(text);
133 * Clears the search query.
135 SearchBox.prototype.clear = function() {
136 this.inputElement.value = '';
137 this.updateStyles_();
141 * Handles a focus event of the search box.
144 SearchBox.prototype.onFocus_ = function() {
145 this.element.classList.toggle('has-cursor', true);
146 this.inputElement.tabIndex = '99'; // See: go/filesapp-tabindex.
147 this.autocompleteList.attachToInput(this.inputElement);
151 * Handles a blur event of the search box.
154 SearchBox.prototype.onBlur_ = function() {
155 this.element.classList.toggle('has-cursor', false);
156 this.inputElement.tabIndex = '-1';
157 this.autocompleteList.detach();
161 * Handles a keydown event of the search box.
164 SearchBox.prototype.onKeyDown_ = function() {
165 // Handle only Esc key now.
166 if (event.keyCode != 27 || this.inputElement.value)
168 this.inputElement.blur();
172 * Handles a dragenter event and refuses a drag source of files.
173 * @param {DragEvent} event The dragenter event.
176 SearchBox.prototype.onDragEnter_ = function(event) {
177 // For normal elements, they does not accept drag drop by default, and accept
178 // it by using event.preventDefault. But input elements accept drag drop
179 // by default. So disable the input element here to prohibit drag drop.
180 if (event.dataTransfer.types.indexOf('text/plain') === -1)
181 this.inputElement.style.pointerEvents = 'none';
185 * Handles a dragend event.
188 SearchBox.prototype.onDragEnd_ = function() {
189 this.inputElement.style.pointerEvents = '';
193 * Updates styles of the search box.
196 SearchBox.prototype.updateStyles_ = function() {
197 this.element.classList.toggle('has-text',
198 !!this.inputElement.value);