Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(343)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/ui/SuggestBox.js

Issue 2592433003: [DevTools] Replace ViewportControl with ListControl. (Closed)
Patch Set: partial Created 3 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 28 matching lines...) Expand all
39 */ 39 */
40 applySuggestion(suggestion, isIntermediateSuggestion) {}, 40 applySuggestion(suggestion, isIntermediateSuggestion) {},
41 41
42 /** 42 /**
43 * acceptSuggestion will be always called after call to applySuggestion with i sIntermediateSuggestion being equal to false. 43 * acceptSuggestion will be always called after call to applySuggestion with i sIntermediateSuggestion being equal to false.
44 */ 44 */
45 acceptSuggestion() {}, 45 acceptSuggestion() {},
46 }; 46 };
47 47
48 /** 48 /**
49 * @implements {UI.ViewportControl.Provider}
50 * @unrestricted 49 * @unrestricted
51 */ 50 */
52 UI.SuggestBox = class { 51 UI.SuggestBox = class {
53 /** 52 /**
54 * @param {!UI.SuggestBoxDelegate} suggestBoxDelegate 53 * @param {!UI.SuggestBoxDelegate} suggestBoxDelegate
55 * @param {number=} maxItemsHeight 54 * @param {number=} maxItemsHeight
56 * @param {boolean=} captureEnter 55 * @param {boolean=} captureEnter
57 */ 56 */
58 constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) { 57 constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) {
59 this._suggestBoxDelegate = suggestBoxDelegate; 58 this._suggestBoxDelegate = suggestBoxDelegate;
60 this._length = 0;
61 this._selectedIndex = -1; 59 this._selectedIndex = -1;
62 this._selectedElement = null; 60 this._selectedElement = null;
63 this._maxItemsHeight = maxItemsHeight; 61 this._maxItemsHeight = maxItemsHeight;
64 this._maybeHideBound = this._maybeHide.bind(this); 62 this._maybeHideBound = this._maybeHide.bind(this);
65 this._container = createElementWithClass('div', 'suggest-box-container'); 63 this._container = createElementWithClass('div', 'suggest-box-container');
66 this._viewport = new UI.ViewportControl(this); 64 /** @type {!UI.ViewportControl<!UI.SuggestBox.Suggestion>} */
65 this._viewport = new UI.ViewportControl();
66 this._viewport.setRenderer(this._createItemElement.bind(this));
67 this._element = this._viewport.element; 67 this._element = this._viewport.element;
68 this._element.classList.add('suggest-box'); 68 this._element.classList.add('suggest-box');
69 this._container.appendChild(this._element); 69 this._container.appendChild(this._element);
70 this._element.addEventListener('mousedown', this._onBoxMouseDown.bind(this), true); 70 this._element.addEventListener('mousedown', this._onBoxMouseDown.bind(this), true);
71 this._detailsPopup = this._container.createChild('div', 'suggest-box details -popup monospace'); 71 this._detailsPopup = this._container.createChild('div', 'suggest-box details -popup monospace');
72 this._detailsPopup.classList.add('hidden'); 72 this._detailsPopup.classList.add('hidden');
73 this._asyncDetailsCallback = null; 73 this._asyncDetailsCallback = null;
74 /** @type {!Map<number, !Promise<{detail: string, description: string}>>} */ 74 /** @type {!Map<number, !Promise<{detail: string, description: string}>>} */
75 this._asyncDetailsPromises = new Map(); 75 this._asyncDetailsPromises = new Map();
76 this._userInteracted = false; 76 this._userInteracted = false;
77 this._captureEnter = captureEnter; 77 this._captureEnter = captureEnter;
78 /** @type {!Array<!Element>} */
79 this._elementList = [];
80 this._rowHeight = 17;
81 this._viewportWidth = '100vw'; 78 this._viewportWidth = '100vw';
82 this._hasVerticalScroll = false; 79 this._hasVerticalScroll = false;
83 this._userEnteredText = ''; 80 this._userEnteredText = '';
84 /** @type {!UI.SuggestBox.Suggestions} */
85 this._items = [];
86 } 81 }
87 82
88 /** 83 /**
89 * @return {boolean} 84 * @return {boolean}
90 */ 85 */
91 visible() { 86 visible() {
92 return !!this._container.parentElement; 87 return !!this._container.parentElement;
93 } 88 }
94 89
95 /** 90 /**
96 * @param {!AnchorBox} anchorBox 91 * @param {!AnchorBox} anchorBox
97 */ 92 */
98 setPosition(anchorBox) { 93 setPosition(anchorBox) {
99 this._updateBoxPosition(anchorBox); 94 this._updateBoxPosition(anchorBox);
100 } 95 }
101 96
102 /** 97 /**
103 * @param {!AnchorBox} anchorBox 98 * @param {!AnchorBox} anchorBox
104 */ 99 */
105 _updateBoxPosition(anchorBox) { 100 _updateBoxPosition(anchorBox) {
106 console.assert(this._overlay); 101 console.assert(this._overlay);
107 if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._la stItemCount === this.itemCount()) 102 if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._la stItemCount === this._viewport.length())
108 return; 103 return;
109 this._lastItemCount = this.itemCount(); 104 this._lastItemCount = this._viewport.length();
110 this._lastAnchorBox = anchorBox; 105 this._lastAnchorBox = anchorBox;
111 106
112 // Position relative to main DevTools element. 107 // Position relative to main DevTools element.
113 var container = UI.Dialog.modalHostView().element; 108 var container = UI.Dialog.modalHostView().element;
114 anchorBox = anchorBox.relativeToElement(container); 109 anchorBox = anchorBox.relativeToElement(container);
115 var totalHeight = container.offsetHeight; 110 var totalHeight = container.offsetHeight;
116 var aboveHeight = anchorBox.y; 111 var aboveHeight = anchorBox.y;
117 var underHeight = totalHeight - anchorBox.y - anchorBox.height; 112 var underHeight = totalHeight - anchorBox.y - anchorBox.height;
118 113
119 this._overlay.setLeftOffset(anchorBox.x); 114 this._overlay.setLeftOffset(anchorBox.x);
120 115
121 var under = underHeight >= aboveHeight; 116 var under = underHeight >= aboveHeight;
122 if (under) 117 if (under)
123 this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true); 118 this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true);
124 else 119 else
125 this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false); 120 this._overlay.setVerticalOffset(totalHeight - anchorBox.y, false);
126 121
127 var spacer = 6; 122 var spacer = 6;
123 var rowHeight = this._viewport.measuredElementHeight();
128 var maxHeight = Math.min( 124 var maxHeight = Math.min(
129 Math.max(underHeight, aboveHeight) - spacer, 125 Math.max(underHeight, aboveHeight) - spacer,
130 this._maxItemsHeight ? this._maxItemsHeight * this._rowHeight : Infinity ); 126 this._maxItemsHeight ? this._maxItemsHeight * rowHeight : Infinity);
131 var height = this._rowHeight * this._items.length; 127 var height = rowHeight * this._viewport.length();
132 this._hasVerticalScroll = height > maxHeight; 128 this._hasVerticalScroll = height > maxHeight;
133 this._element.style.height = Math.min(maxHeight, height) + 'px'; 129 this._element.style.height = Math.min(maxHeight, height) + 'px';
134 } 130 }
135 131
136 _updateWidth() { 132 _updateWidth() {
137 if (this._hasVerticalScroll) { 133 if (this._hasVerticalScroll) {
138 this._element.style.width = '100vw'; 134 this._element.style.width = '100vw';
139 return; 135 return;
140 } 136 }
137 if (!this._viewport.length())
138 return;
141 // If there are no scrollbars, set the width to the width of the largest row . 139 // If there are no scrollbars, set the width to the width of the largest row .
140 var maxItem = this._viewport.itemAtIndex(0);
142 var maxIndex = 0; 141 var maxIndex = 0;
143 for (var i = 0; i < this._items.length; i++) { 142 for (var i = 1; i < this._viewport.length(); i++) {
144 if (this._items[i].title.length > this._items[maxIndex].title.length) 143 var item = this._viewport.itemAtIndex(i);
144 if (item.title.length > maxItem.title.length) {
145 maxItem = item;
145 maxIndex = i; 146 maxIndex = i;
147 }
146 } 148 }
147 var element = /** @type {!Element} */ (this.itemElement(maxIndex)); 149 this._element.style.width =
148 this._element.style.width = UI.measurePreferredSize(element, this._element). width + 'px'; 150 UI.measurePreferredSize(this._viewport.elementAtIndex(maxIndex), this._e lement).width + 'px';
149 } 151 }
150 152
151 /** 153 /**
152 * @param {!Event} event 154 * @param {!Event} event
153 */ 155 */
154 _onBoxMouseDown(event) { 156 _onBoxMouseDown(event) {
155 if (this._hideTimeoutId) { 157 if (this._hideTimeoutId) {
156 window.clearTimeout(this._hideTimeoutId); 158 window.clearTimeout(this._hideTimeoutId);
157 delete this._hideTimeoutId; 159 delete this._hideTimeoutId;
158 } 160 }
159 event.preventDefault(); 161 event.preventDefault();
160 } 162 }
161 163
162 _maybeHide() { 164 _maybeHide() {
163 if (!this._hideTimeoutId) 165 if (!this._hideTimeoutId)
164 this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0); 166 this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0);
165 } 167 }
166 168
167 /** 169 /**
168 * // FIXME: make SuggestBox work for multiple documents. 170 * // FIXME: make SuggestBox work for multiple documents.
169 * @suppressGlobalPropertiesCheck 171 * @suppressGlobalPropertiesCheck
170 */ 172 */
171 _show() { 173 _show() {
172 if (this.visible()) 174 if (this.visible())
173 return; 175 return;
174 this._bodyElement = document.body; 176 this._bodyElement = document.body;
175 this._bodyElement.addEventListener('mousedown', this._maybeHideBound, true); 177 this._bodyElement.addEventListener('mousedown', this._maybeHideBound, true);
176 this._overlay = new UI.SuggestBox.Overlay(); 178 this._overlay = new UI.SuggestBox.Overlay();
177 this._overlay.setContentElement(this._container); 179 this._overlay.setContentElement(this._container);
178 var measuringElement = this._createItemElement('1', '12');
179 this._viewport.element.appendChild(measuringElement);
180 this._rowHeight = measuringElement.getBoundingClientRect().height;
181 measuringElement.remove();
182 } 180 }
183 181
184 hide() { 182 hide() {
185 if (!this.visible()) 183 if (!this.visible())
186 return; 184 return;
187 185
188 this._userInteracted = false; 186 this._userInteracted = false;
189 this._bodyElement.removeEventListener('mousedown', this._maybeHideBound, tru e); 187 this._bodyElement.removeEventListener('mousedown', this._maybeHideBound, tru e);
190 delete this._bodyElement; 188 delete this._bodyElement;
191 this._container.remove(); 189 this._container.remove();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 232
235 return true; 233 return true;
236 } 234 }
237 235
238 /** 236 /**
239 * @param {number} shift 237 * @param {number} shift
240 * @param {boolean=} isCircular 238 * @param {boolean=} isCircular
241 * @return {boolean} is changed 239 * @return {boolean} is changed
242 */ 240 */
243 _selectClosest(shift, isCircular) { 241 _selectClosest(shift, isCircular) {
244 if (!this._length) 242 var length = this._viewport.length();
243 if (!length)
245 return false; 244 return false;
246 245
247 this._userInteracted = true; 246 this._userInteracted = true;
248 247
249 if (this._selectedIndex === -1 && shift < 0) 248 if (this._selectedIndex === -1 && shift < 0)
250 shift += 1; 249 shift += 1;
251 250
252 var index = this._selectedIndex + shift; 251 var index = this._selectedIndex + shift;
253 252
254 if (isCircular) 253 if (isCircular)
255 index = (this._length + index) % this._length; 254 index = (length + index) % length;
256 else 255 else
257 index = Number.constrain(index, 0, this._length - 1); 256 index = Number.constrain(index, 0, length - 1);
258 257
259 this._selectItem(index); 258 this._selectItem(index);
260 return true; 259 return true;
261 } 260 }
262 261
263 /** 262 /**
264 * @param {!Event} event 263 * @param {!Event} event
265 */ 264 */
266 _onItemMouseDown(event) { 265 _onItemMouseDown(event) {
267 this._selectedElement = event.currentTarget; 266 this._selectedElement = event.currentTarget;
268 this.acceptSuggestion(); 267 this.acceptSuggestion();
269 event.consume(true); 268 event.consume(true);
270 } 269 }
271 270
272 /** 271 /**
273 * @param {string} query 272 * @param {!UI.SuggestBox.Suggestion} item
274 * @param {string} title
275 * @param {string=} subtitle
276 * @param {string=} iconType
277 * @param {boolean=} isSecondary
278 * @return {!Element} 273 * @return {!Element}
279 */ 274 */
280 _createItemElement(query, title, subtitle, iconType, isSecondary) { 275 _createItemElement(item) {
276 var query = this._userEnteredText;
281 var element = createElementWithClass('div', 'suggest-box-content-item source -code'); 277 var element = createElementWithClass('div', 'suggest-box-content-item source -code');
282 if (iconType) { 278 if (item.iconType) {
283 var icon = UI.Icon.create(iconType, 'suggestion-icon'); 279 var icon = UI.Icon.create(item.iconType, 'suggestion-icon');
284 element.appendChild(icon); 280 element.appendChild(icon);
285 } 281 }
286 if (isSecondary) 282 if (item.isSecondary)
287 element.classList.add('secondary'); 283 element.classList.add('secondary');
288 element.tabIndex = -1; 284 element.tabIndex = -1;
289 var displayText = title.trimEnd(50 + query.length); 285 var displayText = item.title.trimEnd(50 + query.length);
290 286
291 var titleElement = element.createChild('span', 'suggestion-title'); 287 var titleElement = element.createChild('span', 'suggestion-title');
292 var index = displayText.toLowerCase().indexOf(query.toLowerCase()); 288 var index = displayText.toLowerCase().indexOf(query.toLowerCase());
293 if (index > 0) 289 if (index > 0)
294 titleElement.createChild('span').textContent = displayText.substring(0, in dex); 290 titleElement.createChild('span').textContent = displayText.substring(0, in dex);
295 if (index > -1) 291 if (index > -1)
296 titleElement.createChild('span', 'query').textContent = displayText.substr ing(index, index + query.length); 292 titleElement.createChild('span', 'query').textContent = displayText.substr ing(index, index + query.length);
297 titleElement.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0); 293 titleElement.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0);
298 titleElement.createChild('span', 'spacer'); 294 titleElement.createChild('span', 'spacer');
299 if (subtitle) { 295 if (item.subtitle) {
300 var subtitleElement = element.createChild('span', 'suggestion-subtitle'); 296 var subtitleElement = element.createChild('span', 'suggestion-subtitle');
301 subtitleElement.textContent = subtitle.trimEnd(15); 297 subtitleElement.textContent = item.subtitle.trimEnd(15);
302 } 298 }
303 element.__fullValue = title; 299 element.__fullValue = item.title;
304 element.addEventListener('mousedown', this._onItemMouseDown.bind(this), fals e); 300 element.addEventListener('mousedown', this._onItemMouseDown.bind(this), fals e);
305 return element; 301 return element;
306 } 302 }
307 303
308 /** 304 /**
309 * @param {!UI.SuggestBox.Suggestions} items
310 * @param {string} userEnteredText
311 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails
312 */
313 _updateItems(items, userEnteredText, asyncDetails) {
314 this._length = items.length;
315 this._asyncDetailsPromises.clear();
316 this._asyncDetailsCallback = asyncDetails;
317 this._elementList = [];
318 delete this._selectedElement;
319
320 this._userEnteredText = userEnteredText;
321 this._items = items;
322 }
323
324 /**
325 * @param {number} index 305 * @param {number} index
326 * @return {!Promise<?{detail: string, description: string}>} 306 * @return {!Promise<?{detail: string, description: string}>}
327 */ 307 */
328 _asyncDetails(index) { 308 _asyncDetails(index) {
329 if (!this._asyncDetailsCallback) 309 if (!this._asyncDetailsCallback)
330 return Promise.resolve(/** @type {?{description: string, detail: string}} */ (null)); 310 return Promise.resolve(/** @type {?{description: string, detail: string}} */ (null));
331 if (!this._asyncDetailsPromises.has(index)) 311 if (!this._asyncDetailsPromises.has(index))
332 this._asyncDetailsPromises.set(index, this._asyncDetailsCallback(index)); 312 this._asyncDetailsPromises.set(index, this._asyncDetailsCallback(index));
333 return /** @type {!Promise<?{detail: string, description: string}>} */ (this ._asyncDetailsPromises.get(index)); 313 return /** @type {!Promise<?{detail: string, description: string}>} */ (this ._asyncDetailsPromises.get(index));
334 } 314 }
(...skipping 16 matching lines...) Expand all
351 _selectItem(index) { 331 _selectItem(index) {
352 if (this._selectedElement) { 332 if (this._selectedElement) {
353 this._selectedElement.classList.remove('selected'); 333 this._selectedElement.classList.remove('selected');
354 this._selectedElement.classList.remove('force-white-icons'); 334 this._selectedElement.classList.remove('force-white-icons');
355 } 335 }
356 336
357 this._selectedIndex = index; 337 this._selectedIndex = index;
358 if (index < 0) 338 if (index < 0)
359 return; 339 return;
360 340
361 this._selectedElement = this.itemElement(index); 341 this._selectedElement = this._viewport.elementAtIndex(index);
362 this._selectedElement.classList.add('selected'); 342 this._selectedElement.classList.add('selected');
363 this._selectedElement.classList.add('force-white-icons'); 343 this._selectedElement.classList.add('force-white-icons');
364 this._detailsPopup.classList.add('hidden'); 344 this._detailsPopup.classList.add('hidden');
365 var elem = this._selectedElement; 345 var elem = this._selectedElement;
366 this._asyncDetails(index).then(showDetails.bind(this), function() {}); 346 this._asyncDetails(index).then(showDetails.bind(this), function() {});
367 347
368 this._viewport.scrollItemIntoView(index); 348 this._viewport.scrollItemAtIndexIntoView(index);
369 this._applySuggestion(true); 349 this._applySuggestion(true);
370 350
371 /** 351 /**
372 * @param {?{detail: string, description: string}} details 352 * @param {?{detail: string, description: string}} details
373 * @this {UI.SuggestBox} 353 * @this {UI.SuggestBox}
374 */ 354 */
375 function showDetails(details) { 355 function showDetails(details) {
376 if (elem === this._selectedElement) 356 if (elem === this._selectedElement)
377 this._showDetailsPopup(details); 357 this._showDetailsPopup(details);
378 } 358 }
(...skipping 12 matching lines...) Expand all
391 if (completions.length > 1) 371 if (completions.length > 1)
392 return true; 372 return true;
393 373
394 if (!completions[0].title.startsWith(userEnteredText)) 374 if (!completions[0].title.startsWith(userEnteredText))
395 return true; 375 return true;
396 376
397 // Do not show a single suggestion if it is the same as user-entered query, even if allowed to show single-item suggest boxes. 377 // Do not show a single suggestion if it is the same as user-entered query, even if allowed to show single-item suggest boxes.
398 return canShowForSingleItem && completions[0].title !== userEnteredText; 378 return canShowForSingleItem && completions[0].title !== userEnteredText;
399 } 379 }
400 380
401 _ensureRowCountPerViewport() {
402 if (this._rowCountPerViewport)
403 return;
404 if (!this._items.length)
405 return;
406
407 this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect() .height / this._rowHeight);
408 }
409
410 /** 381 /**
411 * @param {!AnchorBox} anchorBox 382 * @param {!AnchorBox} anchorBox
412 * @param {!UI.SuggestBox.Suggestions} completions 383 * @param {!UI.SuggestBox.Suggestions} completions
413 * @param {boolean} selectHighestPriority 384 * @param {boolean} selectHighestPriority
414 * @param {boolean} canShowForSingleItem 385 * @param {boolean} canShowForSingleItem
415 * @param {string} userEnteredText 386 * @param {string} userEnteredText
416 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails 387 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails
417 */ 388 */
418 updateSuggestions( 389 updateSuggestions(
419 anchorBox, 390 anchorBox,
420 completions, 391 completions,
421 selectHighestPriority, 392 selectHighestPriority,
422 canShowForSingleItem, 393 canShowForSingleItem,
423 userEnteredText, 394 userEnteredText,
424 asyncDetails) { 395 asyncDetails) {
425 delete this._onlyCompletion; 396 delete this._onlyCompletion;
426 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) { 397 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
427 this._updateItems(completions, userEnteredText, asyncDetails); 398 this._asyncDetailsPromises.clear();
399 this._asyncDetailsCallback = asyncDetails;
400 delete this._selectedElement;
401 this._userEnteredText = userEnteredText;
402 this._viewport.setFixedMeasuredHeights();
403 this._viewport.replaceAllItems(completions);
428 this._show(); 404 this._show();
429 this._updateBoxPosition(anchorBox); 405 this._updateBoxPosition(anchorBox);
406 this._viewport.slowRefresh();
430 this._updateWidth(); 407 this._updateWidth();
431 this._viewport.refresh();
432 var highestPriorityItem = -1; 408 var highestPriorityItem = -1;
433 if (selectHighestPriority) { 409 if (selectHighestPriority) {
434 var highestPriority = -Infinity; 410 var highestPriority = -Infinity;
435 for (var i = 0; i < completions.length; i++) { 411 for (var i = 0; i < completions.length; i++) {
436 var priority = completions[i].priority || 0; 412 var priority = completions[i].priority || 0;
437 if (highestPriority < priority) { 413 if (highestPriority < priority) {
438 highestPriority = priority; 414 highestPriority = priority;
439 highestPriorityItem = i; 415 highestPriorityItem = i;
440 } 416 }
441 } 417 }
442 } 418 }
443 this._selectItem(highestPriorityItem); 419 this._selectItem(highestPriorityItem);
444 delete this._rowCountPerViewport;
445 } else { 420 } else {
446 if (completions.length === 1) { 421 if (completions.length === 1) {
447 this._onlyCompletion = completions[0].title; 422 this._onlyCompletion = completions[0].title;
448 this._applySuggestion(true); 423 this._applySuggestion(true);
449 } 424 }
450 this.hide(); 425 this.hide();
451 } 426 }
452 } 427 }
453 428
454 /** 429 /**
(...skipping 27 matching lines...) Expand all
482 * @return {boolean} 457 * @return {boolean}
483 */ 458 */
484 downKeyPressed() { 459 downKeyPressed() {
485 return this._selectClosest(1, true); 460 return this._selectClosest(1, true);
486 } 461 }
487 462
488 /** 463 /**
489 * @return {boolean} 464 * @return {boolean}
490 */ 465 */
491 pageUpKeyPressed() { 466 pageUpKeyPressed() {
492 this._ensureRowCountPerViewport(); 467 return this._selectClosest(-this._viewport.elementsPerViewport(), false);
493 return this._selectClosest(-this._rowCountPerViewport, false);
494 } 468 }
495 469
496 /** 470 /**
497 * @return {boolean} 471 * @return {boolean}
498 */ 472 */
499 pageDownKeyPressed() { 473 pageDownKeyPressed() {
500 this._ensureRowCountPerViewport(); 474 return this._selectClosest(this._viewport.elementsPerViewport(), false);
501 return this._selectClosest(this._rowCountPerViewport, false);
502 } 475 }
503 476
504 /** 477 /**
505 * @return {boolean} 478 * @return {boolean}
506 */ 479 */
507 enterKeyPressed() { 480 enterKeyPressed() {
508 if (!this._userInteracted && this._captureEnter) 481 if (!this._userInteracted && this._captureEnter)
509 return false; 482 return false;
510 483
511 var hasSelectedItem = !!this._selectedElement || this._onlyCompletion; 484 var hasSelectedItem = !!this._selectedElement || this._onlyCompletion;
512 this.acceptSuggestion(); 485 this.acceptSuggestion();
513 486
514 // Report the event as non-handled if there is no selected item, 487 // Report the event as non-handled if there is no selected item,
515 // to commit the input or handle it otherwise. 488 // to commit the input or handle it otherwise.
516 return hasSelectedItem; 489 return hasSelectedItem;
517 } 490 }
518
519 /**
520 * @override
521 * @param {number} index
522 * @return {number}
523 */
524 fastItemHeight(index) {
525 return this._rowHeight;
526 }
527
528 /**
529 * @override
530 * @return {number}
531 */
532 itemCount() {
533 return this._items.length;
534 }
535
536 /**
537 * @override
538 * @param {number} index
539 * @return {?Element}
540 */
541 itemElement(index) {
542 if (!this._elementList[index]) {
543 this._elementList[index] = this._createItemElement(
544 this._userEnteredText, this._items[index].title, this._items[index].su btitle, this._items[index].iconType,
545 this._items[index].isSecondary);
546 }
547 return this._elementList[index];
548 }
549 }; 491 };
550 492
551 /** 493 /**
552 * @typedef {!Array.<{title: string, subtitle: (string|undefined), iconType: (st ring|undefined), priority: (number|undefined), isSecondary: (boolean|undefined)} >} 494 * @typedef {!{title: string, subtitle: (string|undefined), iconType: (string|un defined), priority: (number|undefined), isSecondary: (boolean|undefined)}}
495 */
496 UI.SuggestBox.Suggestion;
497
498 /**
499 * @typedef {!Array<!UI.SuggestBox.Suggestion>}
553 */ 500 */
554 UI.SuggestBox.Suggestions; 501 UI.SuggestBox.Suggestions;
555 502
556 /** 503 /**
557 * @unrestricted 504 * @unrestricted
558 */ 505 */
559 UI.SuggestBox.Overlay = class { 506 UI.SuggestBox.Overlay = class {
560 /** 507 /**
561 * // FIXME: make SuggestBox work for multiple documents. 508 * // FIXME: make SuggestBox work for multiple documents.
562 * @suppressGlobalPropertiesCheck 509 * @suppressGlobalPropertiesCheck
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
609 this.element.style.left = containerBox.x + 'px'; 556 this.element.style.left = containerBox.x + 'px';
610 this.element.style.top = containerBox.y + 'px'; 557 this.element.style.top = containerBox.y + 'px';
611 this.element.style.height = containerBox.height + 'px'; 558 this.element.style.height = containerBox.height + 'px';
612 this.element.style.width = containerBox.width + 'px'; 559 this.element.style.width = containerBox.width + 'px';
613 } 560 }
614 561
615 dispose() { 562 dispose() {
616 this.element.remove(); 563 this.element.remove();
617 } 564 }
618 }; 565 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698