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

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: Add test 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 | « third_party/WebKit/LayoutTests/inspector/text-prompt-hint-expected.txt ('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 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 clearHint = true;
293 if (this.autoCompleteElement) {
lushnikov 2016/09/01 21:25:33 can we hide autoCompleteElement inside text prompt
einbinder 2016/09/01 23:28:46 Yes, I am planning a TextPrompt rewrite/refactor.
294 var text = this.userEnteredText();
295 if (this._previousText === text.substring(0, text.length - 1)) {
lushnikov 2016/09/01 21:25:33 can we generalize this to the "this.userEnteredTex
einbinder 2016/09/01 23:28:46 No, it's checking that exactly one character was d
296 this._hintPrefix += this.autoCompleteElement.textContent.charAt( 0);
297 this.autoCompleteElement.textContent = this.autoCompleteElement. textContent.substring(1);
298 clearHint = false;
299 }
lushnikov 2016/09/01 21:25:33 nit: else on the same line as "}"
einbinder 2016/09/01 23:28:46 Done.
300 else if (this._previousText.substring(0, this._previousText.length - 1) === text) {
301 this.autoCompleteElement.textContent = this._hintPrefix.charAt(t his._hintPrefix.length - 1) + this.autoCompleteElement.textContent;
302 this._hintPrefix = this._hintPrefix.substring(0, this._hintPrefi x.length - 1);
303 clearHint = false;
304 }
305 }
306 if (clearHint)
307 this.clearAutoComplete(false);
308 delete this._waitingForCompletions;
291 this.autoCompleteSoon(force); 309 this.autoCompleteSoon(force);
292 }, 310 },
293 311
294 /** 312 /**
295 * @param {!Event} event 313 * @param {!Event} event
296 */ 314 */
297 onMouseWheel: function(event) 315 onMouseWheel: function(event)
298 { 316 {
299 // Subclasses can implement. 317 // Subclasses can implement.
300 }, 318 },
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 event.consume(true); 372 event.consume(true);
355 }, 373 },
356 374
357 /** 375 /**
358 * @param {!Event} event 376 * @param {!Event} event
359 */ 377 */
360 onInput: function(event) 378 onInput: function(event)
361 { 379 {
362 if (this._needUpdateAutocomplete) 380 if (this._needUpdateAutocomplete)
363 this._updateAutoComplete(); 381 this._updateAutoComplete();
382 this._previousText = this.userEnteredText();
364 }, 383 },
365 384
366 /** 385 /**
367 * @return {boolean} 386 * @return {boolean}
368 */ 387 */
369 acceptAutoComplete: function() 388 acceptAutoComplete: function()
370 { 389 {
371 var result = false; 390 var result = false;
372 if (this.isSuggestBoxVisible()) 391 if (this.isSuggestBoxVisible())
373 result = this._suggestBox.acceptSuggestion(); 392 result = this._suggestBox.acceptSuggestion();
374 if (!result) 393 if (!result)
375 result = this._acceptSuggestionInternal(); 394 result = this._acceptSuggestionInternal();
376 395
377 return result; 396 return result;
378 }, 397 },
379 398
380 /** 399 /**
381 * @param {boolean=} includeTimeout 400 * @param {boolean=} includeTimeout
382 */ 401 */
383 clearAutoComplete: function(includeTimeout) 402 clearAutoComplete: function(includeTimeout)
lushnikov 2016/09/01 21:25:33 I'm confused with TextPrompt API. So there are th
einbinder 2016/09/01 23:28:46 I think we can get away with always hiding Suggest
384 { 403 {
385 if (includeTimeout && this._completeTimeout) { 404 if (includeTimeout)
lushnikov 2016/09/01 21:25:33 why would anyone ever want to call this with inclu
einbinder 2016/09/01 23:28:46 I don't think there is a good reason.
386 clearTimeout(this._completeTimeout); 405 this._clearAutocompleteTimeout();
387 delete this._completeTimeout; 406
388 }
389 delete this._waitingForCompletions; 407 delete this._waitingForCompletions;
390 408
391 if (!this.autoCompleteElement) 409 if (!this.autoCompleteElement)
392 return; 410 return;
393 411
394 this.autoCompleteElement.remove(); 412 this.autoCompleteElement.remove();
395 delete this.autoCompleteElement; 413 delete this.autoCompleteElement;
396 delete this._userEnteredRange; 414 delete this._userEnteredRange;
397 delete this._userEnteredText; 415 delete this._userEnteredText;
398 }, 416 },
399 417
418 _clearAutocompleteTimeout: function()
419 {
420 if (this._completeTimeout) {
421 clearTimeout(this._completeTimeout);
422 delete this._completeTimeout;
423 }
424 },
425
400 /** 426 /**
401 * @param {boolean=} force 427 * @param {boolean=} force
402 */ 428 */
403 autoCompleteSoon: function(force) 429 autoCompleteSoon: function(force)
404 { 430 {
405 var immediately = this.isSuggestBoxVisible() || force; 431 var immediately = this.isSuggestBoxVisible() || force;
406 if (!this._completeTimeout) 432 if (!this._completeTimeout)
407 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout); 433 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout);
408 }, 434 },
409 435
410 /** 436 /**
411 * @param {boolean=} force 437 * @param {boolean=} force
412 * @param {boolean=} reverse 438 * @param {boolean=} reverse
413 */ 439 */
414 complete: function(force, reverse) 440 complete: function(force, reverse)
415 { 441 {
416 this.clearAutoComplete(true); 442 this._clearAutocompleteTimeout();
417 var selection = this._element.getComponentSelection(); 443 var selection = this._element.getComponentSelection();
418 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null; 444 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null;
419 if (!selectionRange) 445 if (!selectionRange)
420 return; 446 return;
421 447
422 var shouldExit; 448 var shouldExit;
423 449
424 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) 450 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( ))
425 shouldExit = true; 451 shouldExit = true;
426 else if (!selection.isCollapsed) 452 else if (!selection.isCollapsed)
427 shouldExit = true; 453 shouldExit = true;
428 else if (!force) { 454 else if (!force) {
429 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. 455 // 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"); 456 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward");
431 if (wordSuffixRange.toString().length) 457 if (wordSuffixRange.toString().length + this.userEnteredText().lengt h - this.text().length)
432 shouldExit = true; 458 shouldExit = true;
433 } 459 }
434 if (shouldExit) { 460 if (shouldExit) {
435 this.hideSuggestBox(); 461 this._removeSuggestionAids();
436 return; 462 return;
437 } 463 }
438 464
439 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); 465 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward");
440 this._waitingForCompletions = true; 466 this._waitingForCompletions = true;
441 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force)); 467 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force));
442 }, 468 },
443 469
444 disableDefaultSuggestionForEmptyInput: function() 470 disableDefaultSuggestionForEmptyInput: function()
445 { 471 {
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 var annotatedCompletions = completions.map(item => ({title: item})); 545 var annotatedCompletions = completions.map(item => ({title: item}));
520 546
521 if (prefix || force) { 547 if (prefix || force) {
522 if (prefix) 548 if (prefix)
523 annotatedCompletions = annotatedCompletions.concat(this.addition alCompletions(prefix)); 549 annotatedCompletions = annotatedCompletions.concat(this.addition alCompletions(prefix));
524 else 550 else
525 annotatedCompletions = this.additionalCompletions(prefix).concat (annotatedCompletions); 551 annotatedCompletions = this.additionalCompletions(prefix).concat (annotatedCompletions);
526 } 552 }
527 553
528 if (!this._waitingForCompletions || !annotatedCompletions.length) { 554 if (!this._waitingForCompletions || !annotatedCompletions.length) {
529 this.hideSuggestBox(); 555 this._removeSuggestionAids();
530 return; 556 return;
531 } 557 }
532 558
533 delete this._waitingForCompletions; 559 delete this._waitingForCompletions;
534 560
535 var selectionRange = selection.getRangeAt(0); 561 var selectionRange = selection.getRangeAt(0);
536 562
537 var fullWordRange = this._createRange(); 563 var fullWordRange = this._createRange();
538 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); 564 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset);
539 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); 565 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et);
(...skipping 19 matching lines...) Expand all
559 var completionText = annotatedCompletions[selectedIndex].title; 585 var completionText = annotatedCompletions[selectedIndex].title;
560 var prefixText = this._userEnteredRange.toString(); 586 var prefixText = this._userEnteredRange.toString();
561 var suffixText = completionText.substring(wordPrefixLength); 587 var suffixText = completionText.substring(wordPrefixLength);
562 this._userEnteredRange.deleteContents(); 588 this._userEnteredRange.deleteContents();
563 this._element.normalize(); 589 this._element.normalize();
564 var finalSelectionRange = this._createRange(); 590 var finalSelectionRange = this._createRange();
565 591
566 var prefixTextNode = createTextNode(prefixText); 592 var prefixTextNode = createTextNode(prefixText);
567 fullWordRange.insertNode(prefixTextNode); 593 fullWordRange.insertNode(prefixTextNode);
568 594
569 this.autoCompleteElement = createElementWithClass("span", "auto-comp lete-text"); 595 if (!this.autoCompleteElement)
596 this.autoCompleteElement = createElementWithClass("span", "auto- complete-text");
570 this.autoCompleteElement.textContent = suffixText; 597 this.autoCompleteElement.textContent = suffixText;
598 this._hintPrefix = completionText.substring(0, wordPrefixLength);
571 599
572 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling); 600 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling);
573 601
574 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); 602 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
575 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); 603 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
576 selection.removeAllRanges(); 604 selection.removeAllRanges();
577 selection.addRange(finalSelectionRange); 605 selection.addRange(finalSelectionRange);
578 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); 606 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied);
579 } 607 }
580 }, 608 },
(...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 }, 1058 },
1031 1059
1032 /** 1060 /**
1033 * @return {string|undefined} 1061 * @return {string|undefined}
1034 */ 1062 */
1035 _currentHistoryItem: function() 1063 _currentHistoryItem: function()
1036 { 1064 {
1037 return this._data[this._data.length - this._historyOffset]; 1065 return this._data[this._data.length - this._historyOffset];
1038 } 1066 }
1039 }; 1067 };
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/inspector/text-prompt-hint-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698