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 = ""; | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 }; |
OLD | NEW |