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

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: currentHintText Created 4 years, 2 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/http/tests/inspector-unit/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 = "";
49 this._currentHintText = "";
48 this._completionRequestId = 0; 50 this._completionRequestId = 0;
49 } 51 }
50 52
51 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; 53 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250;
52 54
53 /** @enum {symbol} */ 55 /** @enum {symbol} */
54 WebInspector.TextPrompt.Events = { 56 WebInspector.TextPrompt.Events = {
55 ItemApplied: Symbol("text-prompt-item-applied"), 57 ItemApplied: Symbol("text-prompt-item-applied"),
56 ItemAccepted: Symbol("text-prompt-item-accepted") 58 ItemAccepted: Symbol("text-prompt-item-accepted")
57 }; 59 };
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
183 setText: function(x) 185 setText: function(x)
184 { 186 {
185 this.clearAutocomplete(); 187 this.clearAutocomplete();
186 if (!x) { 188 if (!x) {
187 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt. 189 // Append a break element instead of setting textContent to make sur e the selection is inside the prompt.
188 this._element.removeChildren(); 190 this._element.removeChildren();
189 this._element.createChild("br"); 191 this._element.createChild("br");
190 } else { 192 } else {
191 this._element.textContent = x; 193 this._element.textContent = x;
192 } 194 }
195 this._previousText = this.userEnteredText();
193 196
194 this.moveCaretToEndOfPrompt(); 197 this.moveCaretToEndOfPrompt();
195 this._element.scrollIntoView(); 198 this._element.scrollIntoView();
196 }, 199 },
197 200
198 /** 201 /**
199 * @return {string} 202 * @return {string}
200 */ 203 */
201 title: function() 204 title: function()
202 { 205 {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
273 this.autoCompleteSoon(); 276 this.autoCompleteSoon();
274 } 277 }
275 } 278 }
276 279
277 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); 280 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
278 }, 281 },
279 282
280 /** 283 /**
281 * @param {boolean=} force 284 * @param {boolean=} force
282 */ 285 */
283 _updateAutoComplete: function(force) 286 _updateAutoComplete: function(force)
lushnikov 2016/10/19 23:36:47 let's get rid of this method - it's confusing
einbinder 2016/10/20 01:21:44 Done.
284 { 287 {
285 this._clearAutocompleteElement(); 288 var clearHint = true;
289 if (this._autocompleteElement) {
lushnikov 2016/10/19 23:36:47 var hasCommonPrefix = text.startsWith(this._previo
einbinder 2016/10/20 01:21:44 Done.
290 var text = this.userEnteredText();
291 if (text.startsWith(this._previousText) || this._previousText.starts With(text)) {
292 this._autocompleteElement.textContent = this._currentHintText.su bstring(text.length);
293 clearHint = false;
294 }
295 }
296 if (clearHint)
297 this._clearAutocompleteElement();
286 this.autoCompleteSoon(force); 298 this.autoCompleteSoon(force);
287 }, 299 },
288 300
289 /** 301 /**
290 * @param {!Event} event 302 * @param {!Event} event
291 */ 303 */
292 onMouseWheel: function(event) 304 onMouseWheel: function(event)
293 { 305 {
294 // Subclasses can implement. 306 // Subclasses can implement.
295 }, 307 },
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
349 event.consume(true); 361 event.consume(true);
350 }, 362 },
351 363
352 /** 364 /**
353 * @param {!Event} event 365 * @param {!Event} event
354 */ 366 */
355 onInput: function(event) 367 onInput: function(event)
356 { 368 {
357 if (this._needUpdateAutocomplete) 369 if (this._needUpdateAutocomplete)
358 this._updateAutoComplete(); 370 this._updateAutoComplete();
371 this._previousText = this.userEnteredText();
359 }, 372 },
360 373
361 /** 374 /**
362 * @return {boolean} 375 * @return {boolean}
363 */ 376 */
364 acceptAutoComplete: function() 377 acceptAutoComplete: function()
365 { 378 {
366 var result = false; 379 var result = false;
367 if (this.isSuggestBoxVisible()) 380 if (this.isSuggestBoxVisible())
368 result = this._suggestBox.acceptSuggestion(); 381 result = this._suggestBox.acceptSuggestion();
369 if (!result) 382 if (!result)
370 result = this._acceptSuggestionInternal(); 383 result = this._acceptSuggestionInternal();
371 384
372 return result; 385 return result;
373 }, 386 },
374 387
375 clearAutocomplete: function() 388 clearAutocomplete: function()
376 { 389 {
377 if (this.isSuggestBoxVisible()) 390 if (this.isSuggestBoxVisible())
378 this._suggestBox.hide(); 391 this._suggestBox.hide();
379 this._clearAutocompleteElement(); 392 this._clearAutocompleteElement();
380 }, 393 },
381 394
382 _clearAutocompleteElement: function() 395 _clearAutocompleteElement: function()
383 { 396 {
384 if (this._completeTimeout) { 397 this._clearAutocompleteTimeout();
385 clearTimeout(this._completeTimeout); 398 this._completionRequestId++;
lushnikov 2016/10/19 23:36:47 let's move this into _clearAutocompleteTimeout
einbinder 2016/10/20 01:21:44 Done.
386 delete this._completeTimeout;
387 }
388 399
389 if (!this._autocompleteElement) 400 if (!this._autocompleteElement)
390 return; 401 return;
391 402
392 this._autocompleteElement.remove(); 403 this._autocompleteElement.remove();
393 delete this._autocompleteElement; 404 delete this._autocompleteElement;
394 delete this._userEnteredRange; 405 delete this._userEnteredRange;
395 delete this._userEnteredText; 406 delete this._userEnteredText;
396 }, 407 },
397 408
409 _clearAutocompleteTimeout: function()
410 {
411 if (this._completeTimeout) {
412 clearTimeout(this._completeTimeout);
413 delete this._completeTimeout;
414 }
415 },
416
398 /** 417 /**
399 * @param {boolean=} force 418 * @param {boolean=} force
400 */ 419 */
401 autoCompleteSoon: function(force) 420 autoCompleteSoon: function(force)
402 { 421 {
403 var immediately = this.isSuggestBoxVisible() || force; 422 var immediately = this.isSuggestBoxVisible() || force;
404 if (!this._completeTimeout) 423 if (!this._completeTimeout)
405 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout); 424 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout);
406 }, 425 },
407 426
408 /** 427 /**
409 * @param {boolean=} force 428 * @param {boolean=} force
410 * @param {boolean=} reverse 429 * @param {boolean=} reverse
411 */ 430 */
412 complete: function(force, reverse) 431 complete: function(force, reverse)
413 { 432 {
414 this.clearAutocomplete(); 433 this._clearAutocompleteTimeout();
415 var selection = this._element.getComponentSelection(); 434 var selection = this._element.getComponentSelection();
416 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null; 435 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null;
417 if (!selectionRange) 436 if (!selectionRange)
418 return; 437 return;
419 438
420 var shouldExit; 439 var shouldExit;
421 440
422 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) 441 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( ))
423 shouldExit = true; 442 shouldExit = true;
424 else if (!selection.isCollapsed) 443 else if (!selection.isCollapsed)
425 shouldExit = true; 444 shouldExit = true;
426 else if (!force) { 445 else if (!force) {
427 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. 446 // BUG72018: Do not show suggest box if caret is followed by a non-s top character.
428 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); 447 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward");
429 if (wordSuffixRange.toString().length) 448 if (wordSuffixRange.toString().length + this.userEnteredText().lengt h - this.text().length)
430 shouldExit = true; 449 shouldExit = true;
431 } 450 }
432 if (shouldExit) { 451 if (shouldExit) {
433 this.clearAutocomplete(); 452 this.clearAutocomplete();
434 return; 453 return;
435 } 454 }
436 455
437 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); 456 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward");
438 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, ++this._completio nRequestId, selection, wordPrefixRange, !!reverse, !!force)); 457 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, ++this._completio nRequestId, selection, wordPrefixRange, !!reverse, !!force));
439 }, 458 },
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 var completionText = annotatedCompletions[selectedIndex].title; 577 var completionText = annotatedCompletions[selectedIndex].title;
559 var prefixText = this._userEnteredRange.toString(); 578 var prefixText = this._userEnteredRange.toString();
560 var suffixText = completionText.substring(wordPrefixLength); 579 var suffixText = completionText.substring(wordPrefixLength);
561 this._userEnteredRange.deleteContents(); 580 this._userEnteredRange.deleteContents();
562 this._element.normalize(); 581 this._element.normalize();
563 var finalSelectionRange = this._createRange(); 582 var finalSelectionRange = this._createRange();
564 583
565 var prefixTextNode = createTextNode(prefixText); 584 var prefixTextNode = createTextNode(prefixText);
566 fullWordRange.insertNode(prefixTextNode); 585 fullWordRange.insertNode(prefixTextNode);
567 586
568 this._autocompleteElement = createElementWithClass("span", "auto-com plete-text"); 587 if (!this._autocompleteElement)
588 this._autocompleteElement = createElementWithClass("span", "auto -complete-text");
569 this._autocompleteElement.textContent = suffixText; 589 this._autocompleteElement.textContent = suffixText;
590 this._currentHintText = completionText;
570 591
571 prefixTextNode.parentNode.insertBefore(this._autocompleteElement, pr efixTextNode.nextSibling); 592 prefixTextNode.parentNode.insertBefore(this._autocompleteElement, pr efixTextNode.nextSibling);
572 593
573 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); 594 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
574 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); 595 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
575 selection.removeAllRanges(); 596 selection.removeAllRanges();
576 selection.addRange(finalSelectionRange); 597 selection.addRange(finalSelectionRange);
577 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); 598 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied);
578 } 599 }
579 }, 600 },
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after
1028 }, 1049 },
1029 1050
1030 /** 1051 /**
1031 * @return {string|undefined} 1052 * @return {string|undefined}
1032 */ 1053 */
1033 _currentHistoryItem: function() 1054 _currentHistoryItem: function()
1034 { 1055 {
1035 return this._data[this._data.length - this._historyOffset]; 1056 return this._data[this._data.length - this._historyOffset];
1036 } 1057 }
1037 }; 1058 };
OLDNEW
« no previous file with comments | « third_party/WebKit/LayoutTests/http/tests/inspector-unit/text-prompt-hint-expected.txt ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698