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

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

Issue 2285993002: DevTools: Fix flickering hint when typing in TextPrompt (Closed)
Patch Set: Created 4 years, 3 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 | « no previous file | 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 27 matching lines...) Expand all
38 { 38 {
39 /** 39 /**
40 * @type {!Element|undefined} 40 * @type {!Element|undefined}
41 */ 41 */
42 this._proxyElement; 42 this._proxyElement;
43 this._proxyElementDisplay = "inline-block"; 43 this._proxyElementDisplay = "inline-block";
44 this._loadCompletions = completions; 44 this._loadCompletions = completions;
45 this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>."; 45 this._completionStopCharacters = stopCharacters || " =:[({;,!+-*/&|^<>.";
46 this._autocompletionTimeout = WebInspector.TextPrompt.DefaultAutocompletionT imeout; 46 this._autocompletionTimeout = WebInspector.TextPrompt.DefaultAutocompletionT imeout;
47 this._title = ""; 47 this._title = "";
48 this._previousText = "";
48 } 49 }
49 50
50 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; 51 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250;
51 52
52 /** @enum {symbol} */ 53 /** @enum {symbol} */
53 WebInspector.TextPrompt.Events = { 54 WebInspector.TextPrompt.Events = {
54 ItemApplied: Symbol("text-prompt-item-applied"), 55 ItemApplied: Symbol("text-prompt-item-applied"),
55 ItemAccepted: Symbol("text-prompt-item-accepted") 56 ItemAccepted: Symbol("text-prompt-item-accepted")
56 }; 57 };
57 58
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
182 setText: function(x) 183 setText: function(x)
183 { 184 {
184 this._removeSuggestionAids(); 185 this._removeSuggestionAids();
185 if (!x) { 186 if (!x) {
186 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt. 187 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt.
187 this._element.removeChildren(); 188 this._element.removeChildren();
188 this._element.createChild("br"); 189 this._element.createChild("br");
189 } else { 190 } else {
190 this._element.textContent = x; 191 this._element.textContent = x;
191 } 192 }
193 this._previousText = this.userEnteredText();
192 194
193 this.moveCaretToEndOfPrompt(); 195 this.moveCaretToEndOfPrompt();
194 this._element.scrollIntoView(); 196 this._element.scrollIntoView();
195 }, 197 },
196 198
197 /** 199 /**
198 * @return {string} 200 * @return {string}
199 */ 201 */
200 title: function() 202 title: function()
201 { 203 {
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 } 282 }
281 283
282 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); 284 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
283 }, 285 },
284 286
285 /** 287 /**
286 * @param {boolean=} force 288 * @param {boolean=} force
287 */ 289 */
288 _updateAutoComplete: function(force) 290 _updateAutoComplete: function(force)
289 { 291 {
290 this.clearAutoComplete(); 292 var singleCharInput = false;
293 var singleCharDelete = false;
294 var text = this.userEnteredText();
295 if (this._previousText === text.substring(0, text.length - 1))
296 singleCharInput = true;
297 else if (this._previousText.substring(0, this._previousText.length - 1) === text)
298 singleCharDelete = true;
299 this.clearAutoComplete(false, singleCharInput, singleCharDelete);
291 this.autoCompleteSoon(force); 300 this.autoCompleteSoon(force);
292 }, 301 },
293 302
294 /** 303 /**
295 * @param {!Event} event 304 * @param {!Event} event
296 */ 305 */
297 onMouseWheel: function(event) 306 onMouseWheel: function(event)
298 { 307 {
299 // Subclasses can implement. 308 // Subclasses can implement.
300 }, 309 },
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 event.consume(true); 363 event.consume(true);
355 }, 364 },
356 365
357 /** 366 /**
358 * @param {!Event} event 367 * @param {!Event} event
359 */ 368 */
360 onInput: function(event) 369 onInput: function(event)
361 { 370 {
362 if (this._needUpdateAutocomplete) 371 if (this._needUpdateAutocomplete)
363 this._updateAutoComplete(); 372 this._updateAutoComplete();
373 this._previousText = this.userEnteredText();
364 }, 374 },
365 375
366 /** 376 /**
367 * @return {boolean} 377 * @return {boolean}
368 */ 378 */
369 acceptAutoComplete: function() 379 acceptAutoComplete: function()
370 { 380 {
371 var result = false; 381 var result = false;
372 if (this.isSuggestBoxVisible()) 382 if (this.isSuggestBoxVisible())
373 result = this._suggestBox.acceptSuggestion(); 383 result = this._suggestBox.acceptSuggestion();
374 if (!result) 384 if (!result)
375 result = this._acceptSuggestionInternal(); 385 result = this._acceptSuggestionInternal();
376 386
377 return result; 387 return result;
378 }, 388 },
379 389
380 /** 390 /**
381 * @param {boolean=} includeTimeout 391 * @param {boolean=} includeTimeout
392 * @param {boolean=} singleCharInput
393 * @param {boolean=} singleDeleteChar
382 */ 394 */
383 clearAutoComplete: function(includeTimeout) 395 clearAutoComplete: function(includeTimeout, singleCharInput, singleDeleteCha r)
lushnikov 2016/08/29 22:10:41 why are these arguments a part of public interface
einbinder 2016/08/30 22:22:35 Done.
384 { 396 {
385 if (includeTimeout && this._completeTimeout) { 397
386 clearTimeout(this._completeTimeout); 398 if (includeTimeout)
387 delete this._completeTimeout; 399 this._clearAutocompleteTimeout();
388 } 400
389 delete this._waitingForCompletions; 401 delete this._waitingForCompletions;
390 402
391 if (!this.autoCompleteElement) 403 if (!this.autoCompleteElement)
392 return; 404 return;
393 405 if (singleCharInput) {
394 this.autoCompleteElement.remove(); 406 this._hintPrefix += this.autoCompleteElement.textContent.charAt(0);
395 delete this.autoCompleteElement; 407 this.autoCompleteElement.textContent = this.autoCompleteElement.text Content.substring(1);
408 } else if (singleDeleteChar && this._hintPrefix) {
409 this.autoCompleteElement.textContent = this._hintPrefix.charAt(this. _hintPrefix.length - 1) + this.autoCompleteElement.textContent;
410 this._hintPrefix = this._hintPrefix.substring(0, this._hintPrefix.le ngth - 1);
411 } else {
412 this.autoCompleteElement.remove();
413 delete this.autoCompleteElement;
414 }
396 delete this._userEnteredRange; 415 delete this._userEnteredRange;
397 delete this._userEnteredText; 416 delete this._userEnteredText;
398 }, 417 },
399 418
419 _clearAutocompleteTimeout: function()
420 {
421 if (this._completeTimeout) {
422 clearTimeout(this._completeTimeout);
423 delete this._completeTimeout;
424 }
425 },
426
400 /** 427 /**
401 * @param {boolean=} force 428 * @param {boolean=} force
402 */ 429 */
403 autoCompleteSoon: function(force) 430 autoCompleteSoon: function(force)
404 { 431 {
405 var immediately = this.isSuggestBoxVisible() || force; 432 var immediately = this.isSuggestBoxVisible() || force;
406 if (!this._completeTimeout) 433 if (!this._completeTimeout)
407 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout); 434 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout);
408 }, 435 },
409 436
410 /** 437 /**
411 * @param {boolean=} force 438 * @param {boolean=} force
412 * @param {boolean=} reverse 439 * @param {boolean=} reverse
413 */ 440 */
414 complete: function(force, reverse) 441 complete: function(force, reverse)
415 { 442 {
416 this.clearAutoComplete(true); 443 this._clearAutocompleteTimeout();
417 var selection = this._element.getComponentSelection(); 444 var selection = this._element.getComponentSelection();
418 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null; 445 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null;
419 if (!selectionRange) 446 if (!selectionRange)
420 return; 447 return;
421 448
422 var shouldExit; 449 var shouldExit;
423 450
424 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) 451 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( ))
425 shouldExit = true; 452 shouldExit = true;
426 else if (!selection.isCollapsed) 453 else if (!selection.isCollapsed)
427 shouldExit = true; 454 shouldExit = true;
428 else if (!force) { 455 else if (!force) {
429 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. 456 // BUG72018: Do not show suggest box if caret is followed by a non-s top character.
430 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); 457 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward");
431 if (wordSuffixRange.toString().length) 458 if (wordSuffixRange.toString().length + this.userEnteredText().lengt h - this.text().length)
432 shouldExit = true; 459 shouldExit = true;
433 } 460 }
434 if (shouldExit) { 461 if (shouldExit) {
435 this.hideSuggestBox(); 462 this._removeSuggestionAids();
436 return; 463 return;
437 } 464 }
438 465
439 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); 466 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward");
440 this._waitingForCompletions = true; 467 this._waitingForCompletions = true;
441 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force)); 468 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force));
442 }, 469 },
443 470
444 disableDefaultSuggestionForEmptyInput: function() 471 disableDefaultSuggestionForEmptyInput: function()
445 { 472 {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 var annotatedCompletions = completions.map(item => ({title: item})); 546 var annotatedCompletions = completions.map(item => ({title: item}));
520 547
521 if (prefix || force) { 548 if (prefix || force) {
522 if (prefix) 549 if (prefix)
523 annotatedCompletions = annotatedCompletions.concat(this.addition alCompletions(prefix)); 550 annotatedCompletions = annotatedCompletions.concat(this.addition alCompletions(prefix));
524 else 551 else
525 annotatedCompletions = this.additionalCompletions(prefix).concat (annotatedCompletions); 552 annotatedCompletions = this.additionalCompletions(prefix).concat (annotatedCompletions);
526 } 553 }
527 554
528 if (!this._waitingForCompletions || !annotatedCompletions.length) { 555 if (!this._waitingForCompletions || !annotatedCompletions.length) {
529 this.hideSuggestBox(); 556 this._removeSuggestionAids();
530 return; 557 return;
531 } 558 }
532 559
533 delete this._waitingForCompletions; 560 delete this._waitingForCompletions;
534 561
535 var selectionRange = selection.getRangeAt(0); 562 var selectionRange = selection.getRangeAt(0);
536 563
537 var fullWordRange = this._createRange(); 564 var fullWordRange = this._createRange();
538 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); 565 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset);
539 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); 566 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et);
(...skipping 19 matching lines...) Expand all
559 var completionText = annotatedCompletions[selectedIndex].title; 586 var completionText = annotatedCompletions[selectedIndex].title;
560 var prefixText = this._userEnteredRange.toString(); 587 var prefixText = this._userEnteredRange.toString();
561 var suffixText = completionText.substring(wordPrefixLength); 588 var suffixText = completionText.substring(wordPrefixLength);
562 this._userEnteredRange.deleteContents(); 589 this._userEnteredRange.deleteContents();
563 this._element.normalize(); 590 this._element.normalize();
564 var finalSelectionRange = this._createRange(); 591 var finalSelectionRange = this._createRange();
565 592
566 var prefixTextNode = createTextNode(prefixText); 593 var prefixTextNode = createTextNode(prefixText);
567 fullWordRange.insertNode(prefixTextNode); 594 fullWordRange.insertNode(prefixTextNode);
568 595
596 if (this.autoCompleteElement)
597 this.autoCompleteElement.remove();
569 this.autoCompleteElement = createElementWithClass("span", "auto-comp lete-text"); 598 this.autoCompleteElement = createElementWithClass("span", "auto-comp lete-text");
570 this.autoCompleteElement.textContent = suffixText; 599 this.autoCompleteElement.textContent = suffixText;
600 this._hintPrefix = completionText.substring(0, wordPrefixLength);
571 601
572 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling); 602 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling);
573 603
574 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); 604 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
575 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); 605 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
576 selection.removeAllRanges(); 606 selection.removeAllRanges();
577 selection.addRange(finalSelectionRange); 607 selection.addRange(finalSelectionRange);
578 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); 608 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied);
579 } 609 }
580 }, 610 },
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 }, 1060 },
1031 1061
1032 /** 1062 /**
1033 * @return {string|undefined} 1063 * @return {string|undefined}
1034 */ 1064 */
1035 _currentHistoryItem: function() 1065 _currentHistoryItem: function()
1036 { 1066 {
1037 return this._data[this._data.length - this._historyOffset]; 1067 return this._data[this._data.length - this._historyOffset];
1038 } 1068 }
1039 }; 1069 };
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698