OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 cr.define('options', function() { | 5 cr.define('options', function() { |
6 const OptionsPage = options.OptionsPage; | 6 const OptionsPage = options.OptionsPage; |
7 | 7 |
8 /** | 8 /** |
9 * Encapsulated handling of a search bubble. | 9 * Encapsulated handling of a search bubble. |
10 * @constructor | 10 * @constructor |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 var searchField = document.createElement('input'); | 104 var searchField = document.createElement('input'); |
105 searchField.id = 'search-field'; | 105 searchField.id = 'search-field'; |
106 searchField.type = 'search'; | 106 searchField.type = 'search'; |
107 searchField.setAttribute('autosave', 'org.chromium.options.search'); | 107 searchField.setAttribute('autosave', 'org.chromium.options.search'); |
108 searchField.setAttribute('results', '10'); | 108 searchField.setAttribute('results', '10'); |
109 searchField.setAttribute('incremental', 'true'); | 109 searchField.setAttribute('incremental', 'true'); |
110 | 110 |
111 // Replace the contents of the navigation tab with the search field. | 111 // Replace the contents of the navigation tab with the search field. |
112 self.tab.textContent = ''; | 112 self.tab.textContent = ''; |
113 self.tab.appendChild(searchField); | 113 self.tab.appendChild(searchField); |
| 114 self.tab.onclick = self.tab.onkeypress = undefined; |
114 | 115 |
115 // Handle search events. (No need to throttle, WebKit's search field | 116 // Handle search events. (No need to throttle, WebKit's search field |
116 // will do that automatically.) | 117 // will do that automatically.) |
117 searchField.onsearch = function(e) { | 118 searchField.onsearch = function(e) { |
118 self.setSearchText_(this.value); | 119 self.setSearchText_(this.value); |
119 }; | 120 }; |
| 121 |
| 122 // Install handler for key presses. |
| 123 document.addEventListener('keydown', |
| 124 this.keyDownEventHandler_.bind(this)); |
| 125 |
| 126 // Focus the search field by default. |
| 127 searchField.focus(); |
120 }, | 128 }, |
121 | 129 |
122 /** | 130 /** |
123 * @inheritDoc | 131 * @inheritDoc |
124 */ | 132 */ |
125 get sticky() { | 133 get sticky() { |
126 return true; | 134 return true; |
127 }, | 135 }, |
128 | 136 |
129 /** | 137 /** |
(...skipping 23 matching lines...) Expand all Loading... |
153 * @private | 161 * @private |
154 */ | 162 */ |
155 setSearchActive_: function(active) { | 163 setSearchActive_: function(active) { |
156 // It's fine to exit if search wasn't active and we're not going to | 164 // It's fine to exit if search wasn't active and we're not going to |
157 // activate it now. | 165 // activate it now. |
158 if (!this.searchActive_ && !active) | 166 if (!this.searchActive_ && !active) |
159 return; | 167 return; |
160 | 168 |
161 if (this.searchActive_ != active) { | 169 if (this.searchActive_ != active) { |
162 this.searchActive_ = active; | 170 this.searchActive_ = active; |
163 if (active) { | 171 if (!active) { |
164 // Reset the search criteria, effectively hiding all the sections. | |
165 this.setSearchText_(''); | |
166 } else { | |
167 // Just wipe out any active search text since it's no longer relevant. | 172 // Just wipe out any active search text since it's no longer relevant. |
168 $('search-field').value = ''; | 173 $('search-field').value = ''; |
169 } | 174 } |
170 } | 175 } |
171 | 176 |
172 var pagesToSearch = this.getSearchablePages_(); | 177 var pagesToSearch = this.getSearchablePages_(); |
173 for (var key in pagesToSearch) { | 178 for (var key in pagesToSearch) { |
174 var page = pagesToSearch[key]; | 179 var page = pagesToSearch[key]; |
175 | 180 |
176 if (!active) | 181 if (!active) |
(...skipping 24 matching lines...) Expand all Loading... |
201 this.removeSearchBubbles_(); | 206 this.removeSearchBubbles_(); |
202 } | 207 } |
203 }, | 208 }, |
204 | 209 |
205 /** | 210 /** |
206 * Set the current search criteria. | 211 * Set the current search criteria. |
207 * @param {string} text Search text. | 212 * @param {string} text Search text. |
208 * @private | 213 * @private |
209 */ | 214 */ |
210 setSearchText_: function(text) { | 215 setSearchText_: function(text) { |
| 216 // Consider whitespace-only strings as empty. |
| 217 if (!text.replace(/^\s+/, '').length) |
| 218 text = ''; |
| 219 |
| 220 // Toggle the search page if necessary. |
| 221 if (text.length) { |
| 222 if (!this.searchActive_) |
| 223 OptionsPage.showPageByName(this.name); |
| 224 } else { |
| 225 if (this.searchActive_) |
| 226 OptionsPage.showDefaultPage(); |
| 227 return; |
| 228 } |
| 229 |
211 var foundMatches = false; | 230 var foundMatches = false; |
212 var bubbleControls = []; | 231 var bubbleControls = []; |
213 | 232 |
214 // Remove any prior search results. | 233 // Remove any prior search results. |
215 this.unhighlightMatches_(); | 234 this.unhighlightMatches_(); |
216 this.removeSearchBubbles_(); | 235 this.removeSearchBubbles_(); |
217 | 236 |
218 // Generate search text by applying lowercase and escaping any characters | 237 // Generate search text by applying lowercase and escaping any characters |
219 // that would be problematic for regular expressions. | 238 // that would be problematic for regular expressions. |
220 var searchText = | 239 var searchText = |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
280 for (var i = 0; i < length; i++) | 299 for (var i = 0; i < length; i++) |
281 bubbleControls.push(controls[i]); | 300 bubbleControls.push(controls[i]); |
282 } | 301 } |
283 | 302 |
284 foundMatches = true; | 303 foundMatches = true; |
285 } | 304 } |
286 } | 305 } |
287 } | 306 } |
288 | 307 |
289 // Configure elements on the search results page based on search results. | 308 // Configure elements on the search results page based on search results. |
290 if (searchText.length == 0) { | 309 if (foundMatches) |
291 $('searchPageInfo').classList.remove('search-hidden'); | |
292 $('searchPageNoMatches').classList.add('search-hidden'); | 310 $('searchPageNoMatches').classList.add('search-hidden'); |
293 } else if (foundMatches) { | 311 else |
294 $('searchPageInfo').classList.add('search-hidden'); | |
295 $('searchPageNoMatches').classList.add('search-hidden'); | |
296 } else { | |
297 $('searchPageInfo').classList.add('search-hidden'); | |
298 $('searchPageNoMatches').classList.remove('search-hidden'); | 312 $('searchPageNoMatches').classList.remove('search-hidden'); |
299 } | |
300 | 313 |
301 // Create search balloons for sub-page results. | 314 // Create search balloons for sub-page results. |
302 length = bubbleControls.length; | 315 length = bubbleControls.length; |
303 for (var i = 0; i < length; i++) | 316 for (var i = 0; i < length; i++) |
304 this.createSearchBubble_(bubbleControls[i], text); | 317 this.createSearchBubble_(bubbleControls[i], text); |
305 }, | 318 }, |
306 | 319 |
307 /** | 320 /** |
308 * Performs a string replacement based on a regex and replace string. | 321 * Performs a string replacement based on a regex and replace string. |
309 * @param {RegEx} regex A regular expression for finding search matches. | 322 * @param {RegEx} regex A regular expression for finding search matches. |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 page = OptionsPage.registeredPages[name]; | 450 page = OptionsPage.registeredPages[name]; |
438 if (page.parentPage && page.associatedSection) | 451 if (page.parentPage && page.associatedSection) |
439 pages.push(page); | 452 pages.push(page); |
440 } | 453 } |
441 for (name in OptionsPage.registeredOverlayPages) { | 454 for (name in OptionsPage.registeredOverlayPages) { |
442 page = OptionsPage.registeredOverlayPages[name]; | 455 page = OptionsPage.registeredOverlayPages[name]; |
443 if (page.associatedSection && page.pageDiv != undefined) | 456 if (page.associatedSection && page.pageDiv != undefined) |
444 pages.push(page); | 457 pages.push(page); |
445 } | 458 } |
446 return pages; | 459 return pages; |
| 460 }, |
| 461 |
| 462 /** |
| 463 * A function to handle key press events. |
| 464 * @return {Event} a keydown event. |
| 465 * @private |
| 466 */ |
| 467 keyDownEventHandler_: function(event) { |
| 468 // Focus the search field on an unused forward-slash. |
| 469 if (event.keyCode == 191 && |
| 470 !/INPUT|SELECT|BUTTON|TEXTAREA/.test(event.target.tagName)) { |
| 471 $('search-field').focus(); |
| 472 event.stopPropagation(); |
| 473 event.preventDefault(); |
| 474 } |
447 } | 475 } |
448 }; | 476 }; |
449 | 477 |
450 // Export | 478 // Export |
451 return { | 479 return { |
452 SearchPage: SearchPage | 480 SearchPage: SearchPage |
453 }; | 481 }; |
454 | 482 |
455 }); | 483 }); |
OLD | NEW |