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

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

Issue 2493373002: DevTools: rename WebInspector into modules. (Closed)
Patch Set: for bots Created 4 years, 1 month 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 12 matching lines...) Expand all
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30 /** 30 /**
31 * @interface 31 * @interface
32 */ 32 */
33 WebInspector.SuggestBoxDelegate = function() {}; 33 UI.SuggestBoxDelegate = function() {};
34 34
35 WebInspector.SuggestBoxDelegate.prototype = { 35 UI.SuggestBoxDelegate.prototype = {
36 /** 36 /**
37 * @param {string} suggestion 37 * @param {string} suggestion
38 * @param {boolean=} isIntermediateSuggestion 38 * @param {boolean=} isIntermediateSuggestion
39 */ 39 */
40 applySuggestion: function(suggestion, isIntermediateSuggestion) {}, 40 applySuggestion: function(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: function() {}, 45 acceptSuggestion: function() {},
46 }; 46 };
47 47
48 /** 48 /**
49 * @implements {WebInspector.StaticViewportControl.Provider} 49 * @implements {UI.StaticViewportControl.Provider}
50 * @unrestricted 50 * @unrestricted
51 */ 51 */
52 WebInspector.SuggestBox = class { 52 UI.SuggestBox = class {
53 /** 53 /**
54 * @param {!WebInspector.SuggestBoxDelegate} suggestBoxDelegate 54 * @param {!UI.SuggestBoxDelegate} suggestBoxDelegate
55 * @param {number=} maxItemsHeight 55 * @param {number=} maxItemsHeight
56 * @param {boolean=} captureEnter 56 * @param {boolean=} captureEnter
57 */ 57 */
58 constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) { 58 constructor(suggestBoxDelegate, maxItemsHeight, captureEnter) {
59 this._suggestBoxDelegate = suggestBoxDelegate; 59 this._suggestBoxDelegate = suggestBoxDelegate;
60 this._length = 0; 60 this._length = 0;
61 this._selectedIndex = -1; 61 this._selectedIndex = -1;
62 this._selectedElement = null; 62 this._selectedElement = null;
63 this._maxItemsHeight = maxItemsHeight; 63 this._maxItemsHeight = maxItemsHeight;
64 this._maybeHideBound = this._maybeHide.bind(this); 64 this._maybeHideBound = this._maybeHide.bind(this);
65 this._container = createElementWithClass('div', 'suggest-box-container'); 65 this._container = createElementWithClass('div', 'suggest-box-container');
66 this._viewport = new WebInspector.StaticViewportControl(this); 66 this._viewport = new UI.StaticViewportControl(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>} */ 78 /** @type {!Array<!Element>} */
79 this._elementList = []; 79 this._elementList = [];
80 this._rowHeight = 17; 80 this._rowHeight = 17;
81 this._viewportWidth = '100vw'; 81 this._viewportWidth = '100vw';
82 this._hasVerticalScroll = false; 82 this._hasVerticalScroll = false;
83 this._userEnteredText = ''; 83 this._userEnteredText = '';
84 /** @type {!WebInspector.SuggestBox.Suggestions} */ 84 /** @type {!UI.SuggestBox.Suggestions} */
85 this._items = []; 85 this._items = [];
86 } 86 }
87 87
88 /** 88 /**
89 * @return {boolean} 89 * @return {boolean}
90 */ 90 */
91 visible() { 91 visible() {
92 return !!this._container.parentElement; 92 return !!this._container.parentElement;
93 } 93 }
94 94
95 /** 95 /**
96 * @param {!AnchorBox} anchorBox 96 * @param {!AnchorBox} anchorBox
97 */ 97 */
98 setPosition(anchorBox) { 98 setPosition(anchorBox) {
99 this._updateBoxPosition(anchorBox); 99 this._updateBoxPosition(anchorBox);
100 } 100 }
101 101
102 /** 102 /**
103 * @param {!AnchorBox} anchorBox 103 * @param {!AnchorBox} anchorBox
104 */ 104 */
105 _updateBoxPosition(anchorBox) { 105 _updateBoxPosition(anchorBox) {
106 console.assert(this._overlay); 106 console.assert(this._overlay);
107 if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._la stItemCount === this.itemCount()) 107 if (this._lastAnchorBox && this._lastAnchorBox.equals(anchorBox) && this._la stItemCount === this.itemCount())
108 return; 108 return;
109 this._lastItemCount = this.itemCount(); 109 this._lastItemCount = this.itemCount();
110 this._lastAnchorBox = anchorBox; 110 this._lastAnchorBox = anchorBox;
111 111
112 // Position relative to main DevTools element. 112 // Position relative to main DevTools element.
113 var container = WebInspector.Dialog.modalHostView().element; 113 var container = UI.Dialog.modalHostView().element;
114 anchorBox = anchorBox.relativeToElement(container); 114 anchorBox = anchorBox.relativeToElement(container);
115 var totalHeight = container.offsetHeight; 115 var totalHeight = container.offsetHeight;
116 var aboveHeight = anchorBox.y; 116 var aboveHeight = anchorBox.y;
117 var underHeight = totalHeight - anchorBox.y - anchorBox.height; 117 var underHeight = totalHeight - anchorBox.y - anchorBox.height;
118 118
119 this._overlay.setLeftOffset(anchorBox.x); 119 this._overlay.setLeftOffset(anchorBox.x);
120 120
121 var under = underHeight >= aboveHeight; 121 var under = underHeight >= aboveHeight;
122 if (under) 122 if (under)
123 this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true); 123 this._overlay.setVerticalOffset(anchorBox.y + anchorBox.height, true);
(...skipping 13 matching lines...) Expand all
137 this._element.style.width = '100vw'; 137 this._element.style.width = '100vw';
138 return; 138 return;
139 } 139 }
140 // If there are no scrollbars, set the width to the width of the largest row . 140 // If there are no scrollbars, set the width to the width of the largest row .
141 var maxIndex = 0; 141 var maxIndex = 0;
142 for (var i = 0; i < this._items.length; i++) { 142 for (var i = 0; i < this._items.length; i++) {
143 if (this._items[i].title.length > this._items[maxIndex].title.length) 143 if (this._items[i].title.length > this._items[maxIndex].title.length)
144 maxIndex = i; 144 maxIndex = i;
145 } 145 }
146 var element = /** @type {!Element} */ (this.itemElement(maxIndex)); 146 var element = /** @type {!Element} */ (this.itemElement(maxIndex));
147 this._element.style.width = WebInspector.measurePreferredSize(element, this. _element).width + 'px'; 147 this._element.style.width = UI.measurePreferredSize(element, this._element). width + 'px';
148 } 148 }
149 149
150 /** 150 /**
151 * @param {!Event} event 151 * @param {!Event} event
152 */ 152 */
153 _onBoxMouseDown(event) { 153 _onBoxMouseDown(event) {
154 if (this._hideTimeoutId) { 154 if (this._hideTimeoutId) {
155 window.clearTimeout(this._hideTimeoutId); 155 window.clearTimeout(this._hideTimeoutId);
156 delete this._hideTimeoutId; 156 delete this._hideTimeoutId;
157 } 157 }
158 event.preventDefault(); 158 event.preventDefault();
159 } 159 }
160 160
161 _maybeHide() { 161 _maybeHide() {
162 if (!this._hideTimeoutId) 162 if (!this._hideTimeoutId)
163 this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0); 163 this._hideTimeoutId = window.setTimeout(this.hide.bind(this), 0);
164 } 164 }
165 165
166 /** 166 /**
167 * // FIXME: make SuggestBox work for multiple documents. 167 * // FIXME: make SuggestBox work for multiple documents.
168 * @suppressGlobalPropertiesCheck 168 * @suppressGlobalPropertiesCheck
169 */ 169 */
170 _show() { 170 _show() {
171 if (this.visible()) 171 if (this.visible())
172 return; 172 return;
173 this._bodyElement = document.body; 173 this._bodyElement = document.body;
174 this._bodyElement.addEventListener('mousedown', this._maybeHideBound, true); 174 this._bodyElement.addEventListener('mousedown', this._maybeHideBound, true);
175 this._overlay = new WebInspector.SuggestBox.Overlay(); 175 this._overlay = new UI.SuggestBox.Overlay();
176 this._overlay.setContentElement(this._container); 176 this._overlay.setContentElement(this._container);
177 var measuringElement = this._createItemElement('1', '12'); 177 var measuringElement = this._createItemElement('1', '12');
178 this._viewport.element.appendChild(measuringElement); 178 this._viewport.element.appendChild(measuringElement);
179 this._rowHeight = measuringElement.getBoundingClientRect().height; 179 this._rowHeight = measuringElement.getBoundingClientRect().height;
180 measuringElement.remove(); 180 measuringElement.remove();
181 } 181 }
182 182
183 hide() { 183 hide() {
184 if (!this.visible()) 184 if (!this.visible())
185 return; 185 return;
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 if (index > -1) 285 if (index > -1)
286 element.createChild('span', 'query').textContent = displayText.substring(i ndex, index + query.length); 286 element.createChild('span', 'query').textContent = displayText.substring(i ndex, index + query.length);
287 element.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0); 287 element.createChild('span').textContent = displayText.substring(index > -1 ? index + query.length : 0);
288 element.__fullValue = text; 288 element.__fullValue = text;
289 element.createChild('span', 'spacer'); 289 element.createChild('span', 'spacer');
290 element.addEventListener('mousedown', this._onItemMouseDown.bind(this), fals e); 290 element.addEventListener('mousedown', this._onItemMouseDown.bind(this), fals e);
291 return element; 291 return element;
292 } 292 }
293 293
294 /** 294 /**
295 * @param {!WebInspector.SuggestBox.Suggestions} items 295 * @param {!UI.SuggestBox.Suggestions} items
296 * @param {string} userEnteredText 296 * @param {string} userEnteredText
297 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails 297 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails
298 */ 298 */
299 _updateItems(items, userEnteredText, asyncDetails) { 299 _updateItems(items, userEnteredText, asyncDetails) {
300 this._length = items.length; 300 this._length = items.length;
301 this._asyncDetailsPromises.clear(); 301 this._asyncDetailsPromises.clear();
302 this._asyncDetailsCallback = asyncDetails; 302 this._asyncDetailsCallback = asyncDetails;
303 this._elementList = []; 303 this._elementList = [];
304 delete this._selectedElement; 304 delete this._selectedElement;
305 305
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 this._selectedElement.classList.add('selected'); 347 this._selectedElement.classList.add('selected');
348 this._detailsPopup.classList.add('hidden'); 348 this._detailsPopup.classList.add('hidden');
349 var elem = this._selectedElement; 349 var elem = this._selectedElement;
350 this._asyncDetails(index).then(showDetails.bind(this), function() {}); 350 this._asyncDetails(index).then(showDetails.bind(this), function() {});
351 351
352 if (scrollIntoView) 352 if (scrollIntoView)
353 this._viewport.scrollItemIntoView(index); 353 this._viewport.scrollItemIntoView(index);
354 354
355 /** 355 /**
356 * @param {?{detail: string, description: string}} details 356 * @param {?{detail: string, description: string}} details
357 * @this {WebInspector.SuggestBox} 357 * @this {UI.SuggestBox}
358 */ 358 */
359 function showDetails(details) { 359 function showDetails(details) {
360 if (elem === this._selectedElement) 360 if (elem === this._selectedElement)
361 this._showDetailsPopup(details); 361 this._showDetailsPopup(details);
362 } 362 }
363 } 363 }
364 364
365 /** 365 /**
366 * @param {!WebInspector.SuggestBox.Suggestions} completions 366 * @param {!UI.SuggestBox.Suggestions} completions
367 * @param {boolean} canShowForSingleItem 367 * @param {boolean} canShowForSingleItem
368 * @param {string} userEnteredText 368 * @param {string} userEnteredText
369 * @return {boolean} 369 * @return {boolean}
370 */ 370 */
371 _canShowBox(completions, canShowForSingleItem, userEnteredText) { 371 _canShowBox(completions, canShowForSingleItem, userEnteredText) {
372 if (!completions || !completions.length) 372 if (!completions || !completions.length)
373 return false; 373 return false;
374 374
375 if (completions.length > 1) 375 if (completions.length > 1)
376 return true; 376 return true;
377 377
378 if (!completions[0].title.startsWith(userEnteredText)) 378 if (!completions[0].title.startsWith(userEnteredText))
379 return true; 379 return true;
380 380
381 // Do not show a single suggestion if it is the same as user-entered query, even if allowed to show single-item suggest boxes. 381 // Do not show a single suggestion if it is the same as user-entered query, even if allowed to show single-item suggest boxes.
382 return canShowForSingleItem && completions[0].title !== userEnteredText; 382 return canShowForSingleItem && completions[0].title !== userEnteredText;
383 } 383 }
384 384
385 _ensureRowCountPerViewport() { 385 _ensureRowCountPerViewport() {
386 if (this._rowCountPerViewport) 386 if (this._rowCountPerViewport)
387 return; 387 return;
388 if (!this._items.length) 388 if (!this._items.length)
389 return; 389 return;
390 390
391 this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect() .height / this._rowHeight); 391 this._rowCountPerViewport = Math.floor(this._element.getBoundingClientRect() .height / this._rowHeight);
392 } 392 }
393 393
394 /** 394 /**
395 * @param {!AnchorBox} anchorBox 395 * @param {!AnchorBox} anchorBox
396 * @param {!WebInspector.SuggestBox.Suggestions} completions 396 * @param {!UI.SuggestBox.Suggestions} completions
397 * @param {number} selectedIndex 397 * @param {number} selectedIndex
398 * @param {boolean} canShowForSingleItem 398 * @param {boolean} canShowForSingleItem
399 * @param {string} userEnteredText 399 * @param {string} userEnteredText
400 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails 400 * @param {function(number): !Promise<{detail:string, description:string}>=} a syncDetails
401 */ 401 */
402 updateSuggestions(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText, asyncDetails) { 402 updateSuggestions(anchorBox, completions, selectedIndex, canShowForSingleItem, userEnteredText, asyncDetails) {
403 delete this._onlyCompletion; 403 delete this._onlyCompletion;
404 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) { 404 if (this._canShowBox(completions, canShowForSingleItem, userEnteredText)) {
405 this._updateItems(completions, userEnteredText, asyncDetails); 405 this._updateItems(completions, userEnteredText, asyncDetails);
406 this._show(); 406 this._show();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 if (!this._elementList[index]) 507 if (!this._elementList[index])
508 this._elementList[index] = 508 this._elementList[index] =
509 this._createItemElement(this._userEnteredText, this._items[index].titl e, this._items[index].className); 509 this._createItemElement(this._userEnteredText, this._items[index].titl e, this._items[index].className);
510 return this._elementList[index]; 510 return this._elementList[index];
511 } 511 }
512 }; 512 };
513 513
514 /** 514 /**
515 * @typedef {!Array.<{title: string, className: (string|undefined)}>} 515 * @typedef {!Array.<{title: string, className: (string|undefined)}>}
516 */ 516 */
517 WebInspector.SuggestBox.Suggestions; 517 UI.SuggestBox.Suggestions;
518 518
519 /** 519 /**
520 * @unrestricted 520 * @unrestricted
521 */ 521 */
522 WebInspector.SuggestBox.Overlay = class { 522 UI.SuggestBox.Overlay = class {
523 /** 523 /**
524 * // FIXME: make SuggestBox work for multiple documents. 524 * // FIXME: make SuggestBox work for multiple documents.
525 * @suppressGlobalPropertiesCheck 525 * @suppressGlobalPropertiesCheck
526 */ 526 */
527 constructor() { 527 constructor() {
528 this.element = createElementWithClass('div', 'suggest-box-overlay'); 528 this.element = createElementWithClass('div', 'suggest-box-overlay');
529 var root = WebInspector.createShadowRootWithCoreStyles(this.element, 'ui/sug gestBox.css'); 529 var root = UI.createShadowRootWithCoreStyles(this.element, 'ui/suggestBox.cs s');
530 this._leftSpacerElement = root.createChild('div', 'suggest-box-left-spacer') ; 530 this._leftSpacerElement = root.createChild('div', 'suggest-box-left-spacer') ;
531 this._horizontalElement = root.createChild('div', 'suggest-box-horizontal'); 531 this._horizontalElement = root.createChild('div', 'suggest-box-horizontal');
532 this._topSpacerElement = this._horizontalElement.createChild('div', 'suggest -box-top-spacer'); 532 this._topSpacerElement = this._horizontalElement.createChild('div', 'suggest -box-top-spacer');
533 this._bottomSpacerElement = this._horizontalElement.createChild('div', 'sugg est-box-bottom-spacer'); 533 this._bottomSpacerElement = this._horizontalElement.createChild('div', 'sugg est-box-bottom-spacer');
534 this._resize(); 534 this._resize();
535 document.body.appendChild(this.element); 535 document.body.appendChild(this.element);
536 } 536 }
537 537
538 /** 538 /**
539 * @param {number} offset 539 * @param {number} offset
(...skipping 19 matching lines...) Expand all
559 } 559 }
560 560
561 /** 561 /**
562 * @param {!Element} element 562 * @param {!Element} element
563 */ 563 */
564 setContentElement(element) { 564 setContentElement(element) {
565 this._horizontalElement.insertBefore(element, this._bottomSpacerElement); 565 this._horizontalElement.insertBefore(element, this._bottomSpacerElement);
566 } 566 }
567 567
568 _resize() { 568 _resize() {
569 var container = WebInspector.Dialog.modalHostView().element; 569 var container = UI.Dialog.modalHostView().element;
570 var containerBox = container.boxInWindow(container.ownerDocument.defaultView ); 570 var containerBox = container.boxInWindow(container.ownerDocument.defaultView );
571 571
572 this.element.style.left = containerBox.x + 'px'; 572 this.element.style.left = containerBox.x + 'px';
573 this.element.style.top = containerBox.y + 'px'; 573 this.element.style.top = containerBox.y + 'px';
574 this.element.style.height = containerBox.height + 'px'; 574 this.element.style.height = containerBox.height + 'px';
575 this.element.style.width = containerBox.width + 'px'; 575 this.element.style.width = containerBox.width + 'px';
576 } 576 }
577 577
578 dispose() { 578 dispose() {
579 this.element.remove(); 579 this.element.remove();
580 } 580 }
581 }; 581 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698