OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 this._maxItemsHeight = maxItemsHeight; | 60 this._maxItemsHeight = maxItemsHeight; |
61 this._maybeHideBound = this._maybeHide.bind(this); | 61 this._maybeHideBound = this._maybeHide.bind(this); |
62 this._container = createElementWithClass('div', 'suggest-box-container'); | 62 this._container = createElementWithClass('div', 'suggest-box-container'); |
63 this._rowHeight = 17; | 63 this._rowHeight = 17; |
64 /** @type {!UI.ListControl<!UI.SuggestBox.Suggestion>} */ | 64 /** @type {!UI.ListControl<!UI.SuggestBox.Suggestion>} */ |
65 this._list = new UI.ListControl(this); | 65 this._list = new UI.ListControl(this); |
66 this._element = this._list.element; | 66 this._element = this._list.element; |
67 this._element.classList.add('suggest-box'); | 67 this._element.classList.add('suggest-box'); |
68 this._container.appendChild(this._element); | 68 this._container.appendChild(this._element); |
69 this._element.addEventListener('mousedown', this._onBoxMouseDown.bind(this),
true); | 69 this._element.addEventListener('mousedown', this._onBoxMouseDown.bind(this),
true); |
70 this._detailsPopup = this._container.createChild('div', 'suggest-box details
-popup monospace'); | |
71 this._detailsPopup.classList.add('hidden'); | |
72 this._asyncDetailsCallback = null; | |
73 /** @type {!Map<!UI.SuggestBox.Suggestion, !Promise<{detail: string, descrip
tion: string}>>} */ | |
74 this._asyncDetailsPromises = new Map(); | |
75 this._userInteracted = false; | 70 this._userInteracted = false; |
76 this._captureEnter = captureEnter; | 71 this._captureEnter = captureEnter; |
77 this._viewportWidth = '100vw'; | 72 this._viewportWidth = '100vw'; |
78 this._hasVerticalScroll = false; | 73 this._hasVerticalScroll = false; |
79 this._userEnteredText = ''; | 74 this._userEnteredText = ''; |
80 } | 75 } |
81 | 76 |
82 /** | 77 /** |
83 * @return {boolean} | 78 * @return {boolean} |
84 */ | 79 */ |
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 * @param {?Element} fromElement | 283 * @param {?Element} fromElement |
289 * @param {?Element} toElement | 284 * @param {?Element} toElement |
290 */ | 285 */ |
291 selectedItemChanged(from, to, fromElement, toElement) { | 286 selectedItemChanged(from, to, fromElement, toElement) { |
292 if (fromElement) | 287 if (fromElement) |
293 fromElement.classList.remove('selected', 'force-white-icons'); | 288 fromElement.classList.remove('selected', 'force-white-icons'); |
294 if (toElement) | 289 if (toElement) |
295 toElement.classList.add('selected', 'force-white-icons'); | 290 toElement.classList.add('selected', 'force-white-icons'); |
296 if (!to) | 291 if (!to) |
297 return; | 292 return; |
298 this._detailsPopup.classList.add('hidden'); | |
299 this._asyncDetails(to).then(details => { | |
300 if (this._list.selectedItem() === to) | |
301 this._showDetailsPopup(details); | |
302 }); | |
303 this._applySuggestion(true); | 293 this._applySuggestion(true); |
304 } | 294 } |
305 | 295 |
306 /** | 296 /** |
307 * @param {!Event} event | 297 * @param {!Event} event |
308 */ | 298 */ |
309 _onItemMouseDown(event) { | 299 _onItemMouseDown(event) { |
310 if (!this._list.onClick(event)) | 300 if (!this._list.onClick(event)) |
311 return; | 301 return; |
312 this._userInteracted = true; | 302 this._userInteracted = true; |
313 this.acceptSuggestion(); | 303 this.acceptSuggestion(); |
314 event.consume(true); | 304 event.consume(true); |
315 } | 305 } |
316 | 306 |
317 /** | 307 /** |
318 * @param {!UI.SuggestBox.Suggestion} item | |
319 * @return {!Promise<?{detail: string, description: string}>} | |
320 */ | |
321 _asyncDetails(item) { | |
322 if (!this._asyncDetailsCallback) | |
323 return Promise.resolve(/** @type {?{description: string, detail: string}}
*/ (null)); | |
324 if (!this._asyncDetailsPromises.has(item)) | |
325 this._asyncDetailsPromises.set(item, this._asyncDetailsCallback(item)); | |
326 return /** @type {!Promise<?{detail: string, description: string}>} */ (this
._asyncDetailsPromises.get(item)); | |
327 } | |
328 | |
329 /** | |
330 * @param {?{detail: string, description: string}} details | |
331 */ | |
332 _showDetailsPopup(details) { | |
333 this._detailsPopup.removeChildren(); | |
334 if (!details) | |
335 return; | |
336 this._detailsPopup.createChild('section', 'detail').createTextChild(details.
detail); | |
337 this._detailsPopup.createChild('section', 'description').createTextChild(det
ails.description); | |
338 this._detailsPopup.classList.remove('hidden'); | |
339 } | |
340 | |
341 /** | |
342 * @param {!UI.SuggestBox.Suggestions} completions | 308 * @param {!UI.SuggestBox.Suggestions} completions |
343 * @param {boolean} canShowForSingleItem | 309 * @param {boolean} canShowForSingleItem |
344 * @param {string} userEnteredText | 310 * @param {string} userEnteredText |
345 * @return {boolean} | 311 * @return {boolean} |
346 */ | 312 */ |
347 _canShowBox(completions, canShowForSingleItem, userEnteredText) { | 313 _canShowBox(completions, canShowForSingleItem, userEnteredText) { |
348 if (!completions || !completions.length) | 314 if (!completions || !completions.length) |
349 return false; | 315 return false; |
350 | 316 |
351 if (completions.length > 1) | 317 if (completions.length > 1) |
352 return true; | 318 return true; |
353 | 319 |
354 if (!completions[0].title.startsWith(userEnteredText)) | 320 if (!completions[0].title.startsWith(userEnteredText)) |
355 return true; | 321 return true; |
356 | 322 |
357 // Do not show a single suggestion if it is the same as user-entered query,
even if allowed to show single-item suggest boxes. | 323 // Do not show a single suggestion if it is the same as user-entered query,
even if allowed to show single-item suggest boxes. |
358 return canShowForSingleItem && completions[0].title !== userEnteredText; | 324 return canShowForSingleItem && completions[0].title !== userEnteredText; |
359 } | 325 } |
360 | 326 |
361 /** | 327 /** |
362 * @param {!AnchorBox} anchorBox | 328 * @param {!AnchorBox} anchorBox |
363 * @param {!UI.SuggestBox.Suggestions} completions | 329 * @param {!UI.SuggestBox.Suggestions} completions |
364 * @param {boolean} selectHighestPriority | 330 * @param {boolean} selectHighestPriority |
365 * @param {boolean} canShowForSingleItem | 331 * @param {boolean} canShowForSingleItem |
366 * @param {string} userEnteredText | 332 * @param {string} userEnteredText |
367 * @param {function(number): !Promise<{detail:string, description:string}>=} a
syncDetails | |
368 */ | 333 */ |
369 updateSuggestions( | 334 updateSuggestions(anchorBox, completions, selectHighestPriority, canShowForSin
gleItem, userEnteredText) { |
370 anchorBox, | |
371 completions, | |
372 selectHighestPriority, | |
373 canShowForSingleItem, | |
374 userEnteredText, | |
375 asyncDetails) { | |
376 delete this._onlyCompletion; | 335 delete this._onlyCompletion; |
377 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) { | 336 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) { |
378 this._asyncDetailsPromises.clear(); | |
379 if (asyncDetails) | |
380 this._asyncDetailsCallback = item => asyncDetails(completions.indexOf(it
em)); | |
381 else | |
382 this._asyncDetailsCallback = null; | |
383 this._userEnteredText = userEnteredText; | 337 this._userEnteredText = userEnteredText; |
384 | 338 |
385 this._show(); | 339 this._show(); |
386 this._updateBoxPosition(anchorBox, completions.length); | 340 this._updateBoxPosition(anchorBox, completions.length); |
387 this._updateWidth(completions); | 341 this._updateWidth(completions); |
388 | 342 |
389 this._list.setHeightMode(UI.ListHeightMode.Fixed); | 343 this._list.setHeightMode(UI.ListHeightMode.Fixed); |
390 this._list.replaceAllItems(completions); | 344 this._list.replaceAllItems(completions); |
391 | 345 |
392 var highestPriorityItem = -1; | 346 var highestPriorityItem = -1; |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
506 this.element.style.left = containerBox.x + 'px'; | 460 this.element.style.left = containerBox.x + 'px'; |
507 this.element.style.top = containerBox.y + 'px'; | 461 this.element.style.top = containerBox.y + 'px'; |
508 this.element.style.height = containerBox.height + 'px'; | 462 this.element.style.height = containerBox.height + 'px'; |
509 this.element.style.width = containerBox.width + 'px'; | 463 this.element.style.width = containerBox.width + 'px'; |
510 } | 464 } |
511 | 465 |
512 dispose() { | 466 dispose() { |
513 this.element.remove(); | 467 this.element.remove(); |
514 } | 468 } |
515 }; | 469 }; |
OLD | NEW |