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

Side by Side Diff: Source/WebCore/inspector/front-end/TextPrompt.js

Issue 9131006: Revert 105252 - Merge 105140 - Web Inspector: [TextPrompt] Autocomplete adds unwanted text that's... (Closed) Base URL: http://svn.webkit.org/repository/webkit/branches/chromium/963/
Patch Set: Created 8 years, 11 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
« no previous file with comments | « Source/WebCore/inspector/front-end/StylesSidebarPane.js ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2011 Google Inc. All rights reserved. 3 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
7 * are met: 7 * are met:
8 * 8 *
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 WebInspector.setCurrentFocusElement(WebInspector.previousFocusElemen t()); 130 WebInspector.setCurrentFocusElement(WebInspector.previousFocusElemen t());
131 }, 131 },
132 132
133 get text() 133 get text()
134 { 134 {
135 return this._element.textContent; 135 return this._element.textContent;
136 }, 136 },
137 137
138 set text(x) 138 set text(x)
139 { 139 {
140 this._removeSuggestionAids(); 140 this.clearAutoComplete(true);
141 if (!x) { 141 if (!x) {
142 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt. 142 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt.
143 this._element.removeChildren(); 143 this._element.removeChildren();
144 this._element.appendChild(document.createElement("br")); 144 this._element.appendChild(document.createElement("br"));
145 } else 145 } else
146 this._element.textContent = x; 146 this._element.textContent = x;
147 147
148 this.moveCaretToEndOfPrompt(); 148 this.moveCaretToEndOfPrompt();
149 this._element.scrollIntoView(); 149 this._element.scrollIntoView();
150 }, 150 },
(...skipping 28 matching lines...) Expand all
179 _stopEditing: function() 179 _stopEditing: function()
180 { 180 {
181 this._element.tabIndex = this._oldTabIndex; 181 this._element.tabIndex = this._oldTabIndex;
182 if (this._blurListener) 182 if (this._blurListener)
183 this._element.removeEventListener("blur", this._blurListener, false) ; 183 this._element.removeEventListener("blur", this._blurListener, false) ;
184 this._element.removeStyleClass("editing"); 184 this._element.removeStyleClass("editing");
185 delete this._isEditing; 185 delete this._isEditing;
186 WebInspector.markBeingEdited(this._element, false); 186 WebInspector.markBeingEdited(this._element, false);
187 }, 187 },
188 188
189 _removeSuggestionAids: function()
190 {
191 this.clearAutoComplete();
192 this.hideSuggestBox();
193 },
194
195 _selectStart: function(event) 189 _selectStart: function(event)
196 { 190 {
197 if (this._selectionTimeout) 191 if (this._selectionTimeout)
198 clearTimeout(this._selectionTimeout); 192 clearTimeout(this._selectionTimeout);
199 193
200 this._removeSuggestionAids(); 194 this.clearAutoComplete();
201 195
202 function moveBackIfOutside() 196 function moveBackIfOutside()
203 { 197 {
204 delete this._selectionTimeout; 198 delete this._selectionTimeout;
205 if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed ) { 199 if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed )
206 this.moveCaretToEndOfPrompt(); 200 this.moveCaretToEndOfPrompt();
207 this.autoCompleteSoon(); 201 this.autoCompleteSoon();
208 }
209 } 202 }
210 203
211 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); 204 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
212 }, 205 },
213 206
214 /** 207 /**
215 * @param {boolean=} force 208 * @param {boolean=} force
216 */ 209 */
217 defaultKeyHandler: function(event, force) 210 defaultKeyHandler: function(event, force)
218 { 211 {
219 this.clearAutoComplete(); 212 this.clearAutoComplete();
220 this.autoCompleteSoon(force); 213 this.autoCompleteSoon(force);
221 return false; 214 return false;
222 }, 215 },
223 216
224 onKeyDown: function(event) 217 onKeyDown: function(event)
225 { 218 {
226 var handled = false; 219 var handled = false;
227 var invokeDefault = true; 220 var invokeDefault = true;
228 221
229 switch (event.keyIdentifier) { 222 switch (event.keyIdentifier) {
230 case "Up": 223 case "Up":
231 handled = this.upKeyPressed(event); 224 handled = this.upKeyPressed(event);
232 break; 225 break;
233 case "Down": 226 case "Down":
234 handled = this.downKeyPressed(event); 227 handled = this.downKeyPressed(event);
235 break; 228 break;
236 case "PageUp":
237 handled = this.pageUpKeyPressed(event);
238 break;
239 case "PageDown":
240 handled = this.pageDownKeyPressed(event);
241 break;
242 case "U+0009": // Tab 229 case "U+0009": // Tab
243 handled = this.tabKeyPressed(event); 230 handled = this.tabKeyPressed(event);
244 break; 231 break;
245 case "Enter": 232 case "Enter":
246 handled = this.enterKeyPressed(event); 233 handled = this.enterKeyPressed(event);
247 break; 234 break;
248 case "Left":
249 case "Home":
250 this._removeSuggestionAids();
251 invokeDefault = false;
252 break;
253 case "Right": 235 case "Right":
254 case "End": 236 case "End":
255 if (this.isCaretAtEndOfPrompt()) 237 if (this.isSuggestBoxVisible() && this.isCaretAtEndOfPrompt())
238 handled = this._suggestBox.tabKeyPressed(event);
239 else {
256 handled = this.acceptAutoComplete(); 240 handled = this.acceptAutoComplete();
257 else 241 if (!handled)
258 this._removeSuggestionAids(); 242 this.autoCompleteSoon();
259 invokeDefault = false; 243 }
260 break; 244 break;
261 case "U+001B": // Esc 245 case "U+001B": // Esc
262 if (this.isSuggestBoxVisible()) { 246 if (this.isSuggestBoxVisible()) {
263 this._suggestBox.hide(); 247 this._suggestBox.hide();
264 handled = true; 248 handled = true;
249 break;
265 } 250 }
266 break;
267 case "U+0020": // Space 251 case "U+0020": // Space
268 if (this._suggestForceable && event.ctrlKey && !event.metaKey && !ev ent.altKey && !event.shiftKey) { 252 if (this._suggestForceable && event.ctrlKey && !event.metaKey && !ev ent.altKey && !event.shiftKey) {
269 this.defaultKeyHandler(event, true); 253 this.defaultKeyHandler(event, true);
270 handled = true; 254 handled = true;
271 } 255 }
272 break; 256 break;
273 case "Alt": 257 case "Alt":
274 case "Meta": 258 case "Meta":
275 case "Shift": 259 case "Shift":
276 case "Control": 260 case "Control":
277 invokeDefault = false; 261 invokeDefault = false;
278 break; 262 break;
279 } 263 }
280 264
281 if (!handled && invokeDefault) 265 if (!handled && invokeDefault)
282 handled = this.defaultKeyHandler(event); 266 handled = this.defaultKeyHandler(event);
283 267
284 if (handled) { 268 if (handled) {
285 event.preventDefault(); 269 event.preventDefault();
286 event.stopPropagation(); 270 event.stopPropagation();
287 } 271 }
288 272
289 return handled; 273 return handled;
290 }, 274 },
291 275
292 acceptAutoComplete: function() 276 acceptAutoComplete: function()
293 { 277 {
294 var result = false;
295 if (this.isSuggestBoxVisible()) 278 if (this.isSuggestBoxVisible())
296 result = this._suggestBox.acceptSuggestion(); 279 return this._suggestBox.acceptSuggestion();
297 if (!result) 280 return this.acceptSuggestion();
298 result = this.acceptSuggestion();
299
300 return result;
301 }, 281 },
302 282
303 /** 283 /**
304 * @param {boolean=} includeTimeout 284 * @param {boolean=} includeTimeout
305 */ 285 */
306 clearAutoComplete: function(includeTimeout) 286 clearAutoComplete: function(includeTimeout)
307 { 287 {
308 if (includeTimeout && this._completeTimeout) { 288 if (includeTimeout && this._completeTimeout) {
309 clearTimeout(this._completeTimeout); 289 clearTimeout(this._completeTimeout);
310 delete this._completeTimeout; 290 delete this._completeTimeout;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 var selectionRange = selection.getRangeAt(0); 341 var selectionRange = selection.getRangeAt(0);
362 var isEmptyInput = selectionRange.commonAncestorContainer === this._elem ent; // this._element has no child Text nodes. 342 var isEmptyInput = selectionRange.commonAncestorContainer === this._elem ent; // this._element has no child Text nodes.
363 343
364 var shouldExit; 344 var shouldExit;
365 345
366 // Do not attempt to auto-complete an empty input in the auto mode (only on demand). 346 // Do not attempt to auto-complete an empty input in the auto mode (only on demand).
367 if (auto && isEmptyInput && !force) 347 if (auto && isEmptyInput && !force)
368 shouldExit = true; 348 shouldExit = true;
369 else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContain er.isDescendant(this._element)) 349 else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContain er.isDescendant(this._element))
370 shouldExit = true; 350 shouldExit = true;
371 else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSugge stBoxVisible()) 351 else if (auto && !this._suggestBox && !force && !this.isCaretAtEndOfProm pt())
372 shouldExit = true; 352 shouldExit = true;
373 else if (!selection.isCollapsed) 353 else if (!selection.isCollapsed)
374 shouldExit = true; 354 shouldExit = true;
375 else if (!force) { 355 else if (!force) {
376 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. 356 // BUG72018: Do not show suggest box if caret is followed by a non-s top character.
377 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); 357 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward");
378 if (wordSuffixRange.toString().length) 358 if (wordSuffixRange.toString().length)
379 shouldExit = true; 359 shouldExit = true;
380 } 360 }
381 if (shouldExit) { 361 if (shouldExit) {
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); 398 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset);
419 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); 399 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et);
420 400
421 if (originalWordPrefixRange.toString() + selectionRange.toString() != fu llWordRange.toString()) 401 if (originalWordPrefixRange.toString() + selectionRange.toString() != fu llWordRange.toString())
422 return; 402 return;
423 403
424 this._userEnteredRange = fullWordRange; 404 this._userEnteredRange = fullWordRange;
425 this._userEnteredText = fullWordRange.toString(); 405 this._userEnteredText = fullWordRange.toString();
426 406
427 if (this._suggestBox) 407 if (this._suggestBox)
428 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), completions, !this.isCaretAtEndOfPrompt()); 408 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), completions);
429 409
430 var wordPrefixLength = originalWordPrefixRange.toString().length; 410 var wordPrefixLength = originalWordPrefixRange.toString().length;
431 411
432 if (auto) 412 if (auto)
433 var completionText = completions[0]; 413 var completionText = completions[0];
434 else { 414 else {
435 if (completions.length === 1) { 415 if (completions.length === 1) {
436 var completionText = completions[0]; 416 var completionText = completions[0];
437 wordPrefixLength = completionText.length; 417 wordPrefixLength = completionText.length;
438 } else { 418 } else {
(...skipping 26 matching lines...) Expand all
465 var completionText = completions[0]; 445 var completionText = completions[0];
466 else if (nextIndex < 0) 446 else if (nextIndex < 0)
467 var completionText = completions[completions.length - 1] ; 447 var completionText = completions[completions.length - 1] ;
468 else 448 else
469 var completionText = completions[nextIndex]; 449 var completionText = completions[nextIndex];
470 } 450 }
471 } 451 }
472 } 452 }
473 453
474 if (auto) { 454 if (auto) {
475 if (this.isCaretAtEndOfPrompt()) { 455 this._userEnteredRange.deleteContents();
476 this._userEnteredRange.deleteContents(); 456 this._element.pruneEmptyTextNodes();
477 this._element.pruneEmptyTextNodes(); 457 var finalSelectionRange = document.createRange();
478 var finalSelectionRange = document.createRange(); 458 var prefixText = completionText.substring(0, wordPrefixLength);
479 var prefixText = completionText.substring(0, wordPrefixLength); 459 var suffixText = completionText.substring(wordPrefixLength);
480 var suffixText = completionText.substring(wordPrefixLength);
481 460
482 var prefixTextNode = document.createTextNode(prefixText); 461 var prefixTextNode = document.createTextNode(prefixText);
483 fullWordRange.insertNode(prefixTextNode); 462 fullWordRange.insertNode(prefixTextNode);
484 463
485 this.autoCompleteElement = document.createElement("span"); 464 this.autoCompleteElement = document.createElement("span");
486 this.autoCompleteElement.className = "auto-complete-text"; 465 this.autoCompleteElement.className = "auto-complete-text";
487 this.autoCompleteElement.textContent = suffixText; 466 this.autoCompleteElement.textContent = suffixText;
488 467
489 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling); 468 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling);
490 469
491 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); 470 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
492 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); 471 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
493 selection.removeAllRanges(); 472 selection.removeAllRanges();
494 selection.addRange(finalSelectionRange); 473 selection.addRange(finalSelectionRange);
495 }
496 } else 474 } else
497 this.applySuggestion(completionText, completions.length > 1, origina lWordPrefixRange); 475 this.applySuggestion(completionText, completions.length > 1, origina lWordPrefixRange);
498 }, 476 },
499 477
500 /** 478 /**
501 * @param {Range=} originalPrefixRange 479 * @param {Range=} originalPrefixRange
502 */ 480 */
503 applySuggestion: function(completionText, isIntermediateSuggestion, original PrefixRange) 481 applySuggestion: function(completionText, isIntermediateSuggestion, original PrefixRange)
504 { 482 {
505 var wordPrefixLength; 483 var wordPrefixLength;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 var node = selectionRange.startContainer; 558 var node = selectionRange.startContainer;
581 if (node !== this._element && !node.isDescendant(this._element)) 559 if (node !== this._element && !node.isDescendant(this._element))
582 return false; 560 return false;
583 561
584 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length) 562 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length)
585 return false; 563 return false;
586 564
587 var foundNextText = false; 565 var foundNextText = false;
588 while (node) { 566 while (node) {
589 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { 567 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
590 if (foundNextText && (!this.autoCompleteElement || !this.autoCom pleteElement.isAncestor(node))) 568 if (foundNextText)
591 return false; 569 return false;
592 foundNextText = true; 570 foundNextText = true;
593 } 571 }
594 572
595 node = node.traverseNextNode(this._element); 573 node = node.traverseNextNode(this._element);
596 } 574 }
597 575
598 return true; 576 return true;
599 }, 577 },
600 578
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 var offset = this._element.childNodes.length; 628 var offset = this._element.childNodes.length;
651 selectionRange.setStart(this._element, offset); 629 selectionRange.setStart(this._element, offset);
652 selectionRange.setEnd(this._element, offset); 630 selectionRange.setEnd(this._element, offset);
653 631
654 selection.removeAllRanges(); 632 selection.removeAllRanges();
655 selection.addRange(selectionRange); 633 selection.addRange(selectionRange);
656 }, 634 },
657 635
658 tabKeyPressed: function(event) 636 tabKeyPressed: function(event)
659 { 637 {
660 // Just consume the key. 638 if (this.isSuggestBoxVisible())
639 return this._suggestBox.tabKeyPressed(event);
640
641 this.complete(false, false, event.shiftKey);
661 return true; 642 return true;
662 }, 643 },
663 644
664 enterKeyPressed: function(event) 645 enterKeyPressed: function(event)
665 { 646 {
666 if (this.isSuggestBoxVisible()) 647 if (this.isSuggestBoxVisible())
667 return this._suggestBox.enterKeyPressed(event); 648 return this._suggestBox.enterKeyPressed(event);
668 649
669 return false; 650 return false;
670 }, 651 },
671 652
672 upKeyPressed: function(event) 653 upKeyPressed: function(event)
673 { 654 {
674 if (this.isSuggestBoxVisible()) 655 if (this.isSuggestBoxVisible())
675 return this._suggestBox.upKeyPressed(event); 656 return this._suggestBox.upKeyPressed(event);
676 657
677 return false; 658 return false;
678 }, 659 },
679 660
680 downKeyPressed: function(event) 661 downKeyPressed: function(event)
681 { 662 {
682 if (this.isSuggestBoxVisible()) 663 if (this.isSuggestBoxVisible())
683 return this._suggestBox.downKeyPressed(event); 664 return this._suggestBox.downKeyPressed(event);
684 665
685 return false; 666 return false;
686 }, 667 }
687
688 pageUpKeyPressed: function(event)
689 {
690 if (this.isSuggestBoxVisible())
691 return this._suggestBox.pageUpKeyPressed(event);
692
693 return false;
694 },
695
696 pageDownKeyPressed: function(event)
697 {
698 if (this.isSuggestBoxVisible())
699 return this._suggestBox.pageDownKeyPressed(event);
700
701 return false;
702 },
703 } 668 }
704 669
705 WebInspector.TextPrompt.prototype.__proto__ = WebInspector.Object.prototype; 670 WebInspector.TextPrompt.prototype.__proto__ = WebInspector.Object.prototype;
706 671
707 /** 672 /**
708 * @constructor 673 * @constructor
709 * @extends {WebInspector.TextPrompt} 674 * @extends {WebInspector.TextPrompt}
710 * @param {function(Range, boolean, function(*))} completions 675 * @param {function(Range, boolean, function(*))} completions
711 * @param {string} stopCharacters 676 * @param {string} stopCharacters
712 */ 677 */
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
1015 var result = this._applySuggestion(text, false); 980 var result = this._applySuggestion(text, false);
1016 this.hide(); 981 this.hide();
1017 if (!result) 982 if (!result)
1018 return false; 983 return false;
1019 984
1020 this._textPrompt.acceptSuggestion(); 985 this._textPrompt.acceptSuggestion();
1021 986
1022 return true; 987 return true;
1023 }, 988 },
1024 989
1025 _onNextItem: function(event, isPageScroll) 990 _onNextItem: function(event)
1026 { 991 {
1027 var children = this.contentElement.childNodes; 992 var children = this.contentElement.childNodes;
1028 if (!children.length) 993 if (!children.length)
1029 return false; 994 return false;
1030 995
1031 if (!this._selectedElement) 996 if (this._selectedElement)
997 this._selectedElement = this._selectedElement.nextSibling || this.co ntentElement.firstChild;
998 else
1032 this._selectedElement = this.contentElement.firstChild; 999 this._selectedElement = this.contentElement.firstChild;
1033 else {
1034 if (!isPageScroll)
1035 this._selectedElement = this._selectedElement.nextSibling || thi s.contentElement.firstChild;
1036 else {
1037 var candidate = this._selectedElement;
1038
1039 for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --ite msLeft) {
1040 if (candidate.nextSibling)
1041 candidate = candidate.nextSibling;
1042 else
1043 break;
1044 }
1045
1046 this._selectedElement = candidate;
1047 }
1048 }
1049 this._updateSelection(); 1000 this._updateSelection();
1050 this._applySuggestion(undefined, true); 1001 this._applySuggestion(undefined, true);
1051 return true; 1002 return true;
1052 }, 1003 },
1053 1004
1054 _onPreviousItem: function(event, isPageScroll) 1005 _onPreviousItem: function(event)
1055 { 1006 {
1056 var children = this.contentElement.childNodes; 1007 var children = this.contentElement.childNodes;
1057 if (!children.length) 1008 if (!children.length)
1058 return false; 1009 return false;
1059 1010
1060 if (!this._selectedElement) 1011 if (this._selectedElement)
1012 this._selectedElement = this._selectedElement.previousSibling || thi s.contentElement.lastChild;
1013 else
1061 this._selectedElement = this.contentElement.lastChild; 1014 this._selectedElement = this.contentElement.lastChild;
1062 else {
1063 if (!isPageScroll)
1064 this._selectedElement = this._selectedElement.previousSibling || this.contentElement.lastChild;
1065 else {
1066 var candidate = this._selectedElement;
1067
1068 for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --ite msLeft) {
1069 if (candidate.previousSibling)
1070 candidate = candidate.previousSibling;
1071 else
1072 break;
1073 }
1074
1075 this._selectedElement = candidate;
1076 }
1077 }
1078 this._updateSelection(); 1015 this._updateSelection();
1079 this._applySuggestion(undefined, true); 1016 this._applySuggestion(undefined, true);
1080 return true; 1017 return true;
1081 }, 1018 },
1082 1019
1083 /** 1020 /**
1084 * @param {AnchorBox} anchorBox 1021 * @param {AnchorBox} anchorBox
1085 * @param {Array.<string>=} completions 1022 * @param {Array.<string>=} completions
1086 * @param {boolean=} canShowForSingleItem
1087 */ 1023 */
1088 updateSuggestions: function(anchorBox, completions, canShowForSingleItem) 1024 updateSuggestions: function(anchorBox, completions)
1089 { 1025 {
1090 if (this._suggestTimeout) { 1026 if (this._suggestTimeout) {
1091 clearTimeout(this._suggestTimeout); 1027 clearTimeout(this._suggestTimeout);
1092 delete this._suggestTimeout; 1028 delete this._suggestTimeout;
1093 } 1029 }
1094 this._completionsReady(anchorBox, completions, canShowForSingleItem); 1030 this._completionsReady(anchorBox, completions);
1095 }, 1031 },
1096 1032
1097 _onItemMouseDown: function(text, event) 1033 _onItemMouseDown: function(text, event)
1098 { 1034 {
1099 this.acceptSuggestion(text); 1035 this.acceptSuggestion(text);
1100 event.stopPropagation(); 1036 event.stopPropagation();
1101 event.preventDefault(); 1037 event.preventDefault();
1102 }, 1038 },
1103 1039
1104 _createItemElement: function(prefix, text) 1040 _createItemElement: function(prefix, text)
1105 { 1041 {
1106 var element = document.createElement("div"); 1042 var element = document.createElement("div");
1107 element.className = "suggest-box-content-item source-code"; 1043 element.className = "suggest-box-content-item source-code";
1108 element.tabIndex = -1; 1044 element.tabIndex = -1;
1109 if (prefix && prefix.length && !text.indexOf(prefix)) { 1045 if (prefix && prefix.length && !text.indexOf(prefix)) {
1110 var prefixElement = element.createChild("span", "prefix"); 1046 var prefixElement = element.createChild("span", "prefix");
1111 prefixElement.textContent = prefix; 1047 prefixElement.textContent = prefix;
1112 var suffixElement = element.createChild("span", "suffix"); 1048 var suffixElement = element.createChild("span", "suffix");
1113 suffixElement.textContent = text.substring(prefix.length); 1049 suffixElement.textContent = text.substring(prefix.length);
1114 } else { 1050 } else {
1115 var suffixElement = element.createChild("span", "suffix"); 1051 var suffixElement = element.createChild("span", "suffix");
1116 suffixElement.textContent = text; 1052 suffixElement.textContent = text;
1117 } 1053 }
1118 element.addEventListener("mousedown", this._onItemMouseDown.bind(this, t ext), false); 1054 element.addEventListener("mousedown", this._onItemMouseDown.bind(this, t ext), false);
1119 return element; 1055 return element;
1120 }, 1056 },
1121 1057
1122 /** 1058 _updateItems: function(items)
1123 * @param {boolean=} canShowForSingleItem
1124 */
1125 _updateItems: function(items, canShowForSingleItem)
1126 { 1059 {
1060 var children = this.contentElement.children;
1061 this._selectedIndex = Math.min(children.length - 1, this._selectedIndex) ;
1062 var selectedItemText = this._selectedIndex >= 0 ? children[this._selecte dIndex].textContent : null;
1063 var itemIndex = 0;
1064 var child = this.contentElement.firstChild;
1065 var childText = child ? child.textContent : null;
1127 this.contentElement.removeChildren(); 1066 this.contentElement.removeChildren();
1128 1067
1129 var userEnteredText = this._textPrompt._userEnteredText; 1068 var userEnteredText = this._textPrompt._userEnteredText;
1130 for (var i = 0; i < items.length; ++i) { 1069 for (var i = 0; i < items.length; ++i) {
1131 var item = items[i]; 1070 var item = items[i];
1132 var currentItemElement = this._createItemElement(userEnteredText, it em); 1071 var currentItemElement = this._createItemElement(userEnteredText, it em);
1133 this.contentElement.appendChild(currentItemElement); 1072 this.contentElement.appendChild(currentItemElement);
1134 } 1073 }
1135 1074
1136 this._selectedElement = canShowForSingleItem ? this.contentElement.first Child : null; 1075 this._selectedElement = this.contentElement.firstChild;
1137 this._updateSelection(); 1076 this._updateSelection();
1138 }, 1077 },
1139 1078
1140 _updateSelection: function() 1079 _updateSelection: function()
1141 { 1080 {
1142 // FIXME: might want some optimization if becomes a bottleneck. 1081 // FIXME: might want some optimization if becomes a bottleneck.
1143 for (var child = this.contentElement.firstChild; child; child = child.ne xtSibling) { 1082 for (var child = this.contentElement.firstChild; child; child = child.ne xtSibling) {
1144 if (child !== this._selectedElement) 1083 if (child !== this._selectedElement)
1145 child.removeStyleClass("selected"); 1084 child.removeStyleClass("selected");
1146 } 1085 }
1147 if (this._selectedElement) { 1086 if (this._selectedElement) {
1148 this._selectedElement.addStyleClass("selected"); 1087 this._selectedElement.addStyleClass("selected");
1149 this._selectedElement.scrollIntoViewIfNeeded(false); 1088 this._selectedElement.scrollIntoViewIfNeeded(false);
1150 } 1089 }
1151 }, 1090 },
1152 1091
1153 /** 1092 /**
1154 * @param {Array.<string>=} completions
1155 * @param {boolean=} canShowForSingleItem
1156 */
1157 _canShowBox: function(completions, canShowForSingleItem)
1158 {
1159 if (!completions || !completions.length)
1160 return false;
1161
1162 if (completions.length > 1)
1163 return true;
1164
1165 // Do not show a single suggestion if it is the same as user-entered pre fix, even if allowed to show single-item suggest boxes.
1166 return canShowForSingleItem && completions[0] !== this._textPrompt._user EnteredText;
1167 },
1168
1169 _rememberRowCountPerViewport: function()
1170 {
1171 if (!this.contentElement.firstChild)
1172 return;
1173
1174 this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeigh t / this.contentElement.firstChild.offsetHeight);
1175 },
1176
1177 /**
1178 * @param {AnchorBox} anchorBox 1093 * @param {AnchorBox} anchorBox
1179 * @param {Array.<string>=} completions 1094 * @param {Array.<string>=} completions
1180 * @param {boolean=} canShowForSingleItem
1181 */ 1095 */
1182 _completionsReady: function(anchorBox, completions, canShowForSingleItem) 1096 _completionsReady: function(anchorBox, completions)
1183 { 1097 {
1184 if (this._canShowBox(completions, canShowForSingleItem)) { 1098 if (!completions || !completions.length) {
1185 this._updateItems(completions, canShowForSingleItem); 1099 this.hide()
1186 this._updateBoxPosition(anchorBox); 1100 return;
1101 }
1102
1103 this._updateItems(completions);
1104 this._updateBoxPosition(anchorBox);
1105 if (this.contentElement.children.length && this.contentElement.children. length > 1) {
1106 // Will not be shown if a sole suggestion is equal to the user input .
1187 this._element.addStyleClass("visible"); 1107 this._element.addStyleClass("visible");
1188 this._rememberRowCountPerViewport();
1189 } else 1108 } else
1190 this.hide(); 1109 this.hide();
1191 }, 1110 },
1192 1111
1193 upKeyPressed: function(event) 1112 upKeyPressed: function(event)
1194 { 1113 {
1195 return this._onPreviousItem(event); 1114 return this._onPreviousItem(event);
1196 }, 1115 },
1197 1116
1198 downKeyPressed: function(event) 1117 downKeyPressed: function(event)
1199 { 1118 {
1200 return this._onNextItem(event); 1119 return this._onNextItem(event);
1201 }, 1120 },
1202 1121
1203 pageUpKeyPressed: function(event)
1204 {
1205 return this._onPreviousItem(event, true);
1206 },
1207
1208 pageDownKeyPressed: function(event)
1209 {
1210 return this._onNextItem(event, true);
1211 },
1212
1213 enterKeyPressed: function(event) 1122 enterKeyPressed: function(event)
1214 { 1123 {
1215 var hasSelectedItem = !!this._selectedElement;
1216 this.acceptSuggestion(); 1124 this.acceptSuggestion();
1217 1125 return true;
1218 // Report the event as non-handled if there is no selected item,
1219 // to commit the input or handle it otherwise.
1220 return hasSelectedItem;
1221 }, 1126 },
1222 1127
1223 tabKeyPressed: function(event) 1128 tabKeyPressed: function(event)
1224 { 1129 {
1225 return this.enterKeyPressed(event); 1130 return this.enterKeyPressed(event);
1226 } 1131 }
1227 } 1132 }
OLDNEW
« no previous file with comments | « Source/WebCore/inspector/front-end/StylesSidebarPane.js ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698