Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 182 setText: function(x) | 183 setText: function(x) |
| 183 { | 184 { |
| 184 this.clearAutoComplete(); | 185 this.clearAutoComplete(); |
| 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 } | 276 } |
| 275 | 277 |
| 276 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); | 278 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); |
| 277 }, | 279 }, |
| 278 | 280 |
| 279 /** | 281 /** |
| 280 * @param {boolean=} force | 282 * @param {boolean=} force |
| 281 */ | 283 */ |
| 282 _updateAutoComplete: function(force) | 284 _updateAutoComplete: function(force) |
| 283 { | 285 { |
| 284 this.clearAutoComplete(); | 286 var clearHint = true; |
| 287 if (this.autoCompleteElement) { | |
| 288 var text = this.userEnteredText(); | |
| 289 if (this._previousText === text.substring(0, text.length - 1)) { | |
| 290 this._hintPrefix += this.autoCompleteElement.textContent.charAt( 0); | |
| 291 this.autoCompleteElement.textContent = this.autoCompleteElement. textContent.substring(1); | |
| 292 clearHint = false; | |
| 293 } else if (this._previousText.substring(0, this._previousText.length - 1) === text) { | |
|
lushnikov
2016/09/07 22:11:01
let's use .startsWith?
einbinder
2016/10/18 00:57:33
Done.
| |
| 294 this.autoCompleteElement.textContent = this._hintPrefix.charAt(t his._hintPrefix.length - 1) + this.autoCompleteElement.textContent; | |
| 295 this._hintPrefix = this._hintPrefix.substring(0, this._hintPrefi x.length - 1); | |
| 296 clearHint = false; | |
| 297 } | |
| 298 } | |
| 299 if (clearHint) | |
| 300 this.clearAutoComplete(); | |
| 301 delete this._waitingForCompletions; | |
|
lushnikov
2016/09/07 22:11:01
why would you need to delete this?
The _waitingFo
einbinder
2016/10/18 00:57:33
Done.
| |
| 285 this.autoCompleteSoon(force); | 302 this.autoCompleteSoon(force); |
| 286 }, | 303 }, |
| 287 | 304 |
| 288 /** | 305 /** |
| 289 * @param {!Event} event | 306 * @param {!Event} event |
| 290 */ | 307 */ |
| 291 onMouseWheel: function(event) | 308 onMouseWheel: function(event) |
| 292 { | 309 { |
| 293 // Subclasses can implement. | 310 // Subclasses can implement. |
| 294 }, | 311 }, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 348 event.consume(true); | 365 event.consume(true); |
| 349 }, | 366 }, |
| 350 | 367 |
| 351 /** | 368 /** |
| 352 * @param {!Event} event | 369 * @param {!Event} event |
| 353 */ | 370 */ |
| 354 onInput: function(event) | 371 onInput: function(event) |
| 355 { | 372 { |
| 356 if (this._needUpdateAutocomplete) | 373 if (this._needUpdateAutocomplete) |
| 357 this._updateAutoComplete(); | 374 this._updateAutoComplete(); |
| 375 this._previousText = this.userEnteredText(); | |
| 358 }, | 376 }, |
| 359 | 377 |
| 360 /** | 378 /** |
| 361 * @return {boolean} | 379 * @return {boolean} |
| 362 */ | 380 */ |
| 363 acceptAutoComplete: function() | 381 acceptAutoComplete: function() |
| 364 { | 382 { |
| 365 var result = false; | 383 var result = false; |
| 366 if (this.isSuggestBoxVisible()) | 384 if (this.isSuggestBoxVisible()) |
| 367 result = this._suggestBox.acceptSuggestion(); | 385 result = this._suggestBox.acceptSuggestion(); |
| 368 if (!result) | 386 if (!result) |
| 369 result = this._acceptSuggestionInternal(); | 387 result = this._acceptSuggestionInternal(); |
| 370 | 388 |
| 371 return result; | 389 return result; |
| 372 }, | 390 }, |
| 373 | 391 |
| 374 clearAutoComplete: function() | 392 clearAutoComplete: function() |
| 375 { | 393 { |
| 376 if (this.isSuggestBoxVisible()) | 394 if (this.isSuggestBoxVisible()) |
| 377 this._suggestBox.hide(); | 395 this._suggestBox.hide(); |
| 378 | 396 |
| 379 if (this._completeTimeout) { | 397 this._clearAutocompleteTimeout(); |
| 380 clearTimeout(this._completeTimeout); | 398 |
| 381 delete this._completeTimeout; | |
| 382 } | |
| 383 delete this._waitingForCompletions; | 399 delete this._waitingForCompletions; |
| 384 | 400 |
| 385 if (!this.autoCompleteElement) | 401 if (!this.autoCompleteElement) |
| 386 return; | 402 return; |
| 387 | 403 |
| 388 this.autoCompleteElement.remove(); | 404 this.autoCompleteElement.remove(); |
| 389 delete this.autoCompleteElement; | 405 delete this.autoCompleteElement; |
| 390 delete this._userEnteredRange; | 406 delete this._userEnteredRange; |
| 391 delete this._userEnteredText; | 407 delete this._userEnteredText; |
| 392 }, | 408 }, |
| 393 | 409 |
| 410 _clearAutocompleteTimeout: function() | |
| 411 { | |
| 412 if (this._completeTimeout) { | |
| 413 clearTimeout(this._completeTimeout); | |
| 414 delete this._completeTimeout; | |
| 415 } | |
| 416 }, | |
| 417 | |
| 394 /** | 418 /** |
| 395 * @param {boolean=} force | 419 * @param {boolean=} force |
| 396 */ | 420 */ |
| 397 autoCompleteSoon: function(force) | 421 autoCompleteSoon: function(force) |
| 398 { | 422 { |
| 399 var immediately = this.isSuggestBoxVisible() || force; | 423 var immediately = this.isSuggestBoxVisible() || force; |
| 400 if (!this._completeTimeout) | 424 if (!this._completeTimeout) |
| 401 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout); | 425 this._completeTimeout = setTimeout(this.complete.bind(this, force), immediately ? 0 : this._autocompletionTimeout); |
| 402 }, | 426 }, |
| 403 | 427 |
| 404 /** | 428 /** |
| 405 * @param {boolean=} force | 429 * @param {boolean=} force |
| 406 * @param {boolean=} reverse | 430 * @param {boolean=} reverse |
| 407 */ | 431 */ |
| 408 complete: function(force, reverse) | 432 complete: function(force, reverse) |
| 409 { | 433 { |
| 410 this.clearAutoComplete(); | 434 this._clearAutocompleteTimeout(); |
| 411 var selection = this._element.getComponentSelection(); | 435 var selection = this._element.getComponentSelection(); |
| 412 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null; | 436 var selectionRange = selection && selection.rangeCount ? selection.getRa ngeAt(0) : null; |
| 413 if (!selectionRange) | 437 if (!selectionRange) |
| 414 return; | 438 return; |
| 415 | 439 |
| 416 var shouldExit; | 440 var shouldExit; |
| 417 | 441 |
| 418 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) | 442 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) |
| 419 shouldExit = true; | 443 shouldExit = true; |
| 420 else if (!selection.isCollapsed) | 444 else if (!selection.isCollapsed) |
| 421 shouldExit = true; | 445 shouldExit = true; |
| 422 else if (!force) { | 446 else if (!force) { |
| 423 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. | 447 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. |
| 424 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); | 448 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); |
| 425 if (wordSuffixRange.toString().length) | 449 if (wordSuffixRange.toString().length + this.userEnteredText().lengt h - this.text().length) |
| 426 shouldExit = true; | 450 shouldExit = true; |
| 427 } | 451 } |
| 428 if (shouldExit) { | 452 if (shouldExit) { |
| 429 this.clearAutoComplete(); | 453 this.clearAutoComplete(); |
| 430 return; | 454 return; |
| 431 } | 455 } |
| 432 | 456 |
| 433 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); | 457 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); |
| 434 this._waitingForCompletions = true; | 458 this._waitingForCompletions = true; |
| 435 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force)); | 459 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, selection, wordPr efixRange, !!reverse, !!force)); |
| (...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 var completionText = annotatedCompletions[selectedIndex].title; | 577 var completionText = annotatedCompletions[selectedIndex].title; |
| 554 var prefixText = this._userEnteredRange.toString(); | 578 var prefixText = this._userEnteredRange.toString(); |
| 555 var suffixText = completionText.substring(wordPrefixLength); | 579 var suffixText = completionText.substring(wordPrefixLength); |
| 556 this._userEnteredRange.deleteContents(); | 580 this._userEnteredRange.deleteContents(); |
| 557 this._element.normalize(); | 581 this._element.normalize(); |
| 558 var finalSelectionRange = this._createRange(); | 582 var finalSelectionRange = this._createRange(); |
| 559 | 583 |
| 560 var prefixTextNode = createTextNode(prefixText); | 584 var prefixTextNode = createTextNode(prefixText); |
| 561 fullWordRange.insertNode(prefixTextNode); | 585 fullWordRange.insertNode(prefixTextNode); |
| 562 | 586 |
| 563 this.autoCompleteElement = createElementWithClass("span", "auto-comp lete-text"); | 587 if (!this.autoCompleteElement) |
| 588 this.autoCompleteElement = createElementWithClass("span", "auto- complete-text"); | |
| 564 this.autoCompleteElement.textContent = suffixText; | 589 this.autoCompleteElement.textContent = suffixText; |
| 590 this._hintPrefix = completionText.substring(0, wordPrefixLength); | |
| 565 | 591 |
| 566 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling); | 592 prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, pre fixTextNode.nextSibling); |
| 567 | 593 |
| 568 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); | 594 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); |
| 569 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); | 595 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); |
| 570 selection.removeAllRanges(); | 596 selection.removeAllRanges(); |
| 571 selection.addRange(finalSelectionRange); | 597 selection.addRange(finalSelectionRange); |
| 572 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); | 598 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); |
| 573 } | 599 } |
| 574 }, | 600 }, |
| (...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1018 }, | 1044 }, |
| 1019 | 1045 |
| 1020 /** | 1046 /** |
| 1021 * @return {string|undefined} | 1047 * @return {string|undefined} |
| 1022 */ | 1048 */ |
| 1023 _currentHistoryItem: function() | 1049 _currentHistoryItem: function() |
| 1024 { | 1050 { |
| 1025 return this._data[this._data.length - this._historyOffset]; | 1051 return this._data[this._data.length - this._historyOffset]; |
| 1026 } | 1052 } |
| 1027 }; | 1053 }; |
| OLD | NEW |