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._prefixRange = null; | |
48 this._previousText = ""; | 49 this._previousText = ""; |
49 this._currentHintText = ""; | 50 this._currentHintText = ""; |
50 this._completionRequestId = 0; | 51 this._completionRequestId = 0; |
52 this._autocompleteElement = createElementWithClass("span", "auto-complete-te xt"); | |
51 } | 53 } |
52 | 54 |
53 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; | 55 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; |
54 | 56 |
55 /** @enum {symbol} */ | 57 /** @enum {symbol} */ |
56 WebInspector.TextPrompt.Events = { | 58 WebInspector.TextPrompt.Events = { |
57 ItemApplied: Symbol("text-prompt-item-applied"), | 59 ItemApplied: Symbol("text-prompt-item-applied"), |
58 ItemAccepted: Symbol("text-prompt-item-accepted") | 60 ItemAccepted: Symbol("text-prompt-item-accepted") |
59 }; | 61 }; |
60 | 62 |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
133 this._proxyElement.appendChild(element); | 135 this._proxyElement.appendChild(element); |
134 this._element.classList.add("text-prompt"); | 136 this._element.classList.add("text-prompt"); |
135 this._element.addEventListener("keydown", this._boundOnKeyDown, false); | 137 this._element.addEventListener("keydown", this._boundOnKeyDown, false); |
136 this._element.addEventListener("input", this._boundOnInput, false); | 138 this._element.addEventListener("input", this._boundOnInput, false); |
137 this._element.addEventListener("mousewheel", this._boundOnMouseWheel, fa lse); | 139 this._element.addEventListener("mousewheel", this._boundOnMouseWheel, fa lse); |
138 this._element.addEventListener("selectstart", this._boundSelectStart, fa lse); | 140 this._element.addEventListener("selectstart", this._boundSelectStart, fa lse); |
139 this._element.addEventListener("blur", this._boundClearAutocomplete, fal se); | 141 this._element.addEventListener("blur", this._boundClearAutocomplete, fal se); |
140 this._element.ownerDocument.defaultView.addEventListener("resize", this. _boundClearAutocomplete, false); | 142 this._element.ownerDocument.defaultView.addEventListener("resize", this. _boundClearAutocomplete, false); |
141 | 143 |
142 if (this._suggestBoxEnabled) | 144 if (this._suggestBoxEnabled) |
143 this._suggestBox = new WebInspector.SuggestBox(this); | 145 this._suggestBox = new WebInspector.SuggestBox(this, 20, true); |
144 | 146 |
145 if (this._title) | 147 if (this._title) |
146 this._proxyElement.title = this._title; | 148 this._proxyElement.title = this._title; |
147 | 149 |
148 return this._proxyElement; | 150 return this._proxyElement; |
149 }, | 151 }, |
150 | 152 |
151 detach: function() | 153 detach: function() |
152 { | 154 { |
153 this._removeFromElement(); | 155 this._removeFromElement(); |
(...skipping 11 matching lines...) Expand all Loading... | |
165 { | 167 { |
166 return this._element.textContent; | 168 return this._element.textContent; |
167 }, | 169 }, |
168 | 170 |
169 /** | 171 /** |
170 * @return {string} | 172 * @return {string} |
171 */ | 173 */ |
172 userEnteredText: function() | 174 userEnteredText: function() |
173 { | 175 { |
174 var text = this.text(); | 176 var text = this.text(); |
175 if (this._autocompleteElement) { | 177 if (this._autocompleteElement.parentNode) { |
176 var addition = this._autocompleteElement.textContent; | 178 var addition = this._autocompleteElement.textContent; |
177 text = text.substring(0, text.length - addition.length); | 179 text = text.substring(0, text.length - addition.length); |
178 } | 180 } |
179 return text; | 181 return text; |
180 }, | 182 }, |
181 | 183 |
182 /** | 184 /** |
183 * @param {string} x | 185 * @param {string} x |
184 */ | 186 */ |
185 setText: function(x) | 187 setText: function(x) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
263 if (this._selectionTimeout) | 265 if (this._selectionTimeout) |
264 clearTimeout(this._selectionTimeout); | 266 clearTimeout(this._selectionTimeout); |
265 | 267 |
266 this.clearAutocomplete(); | 268 this.clearAutocomplete(); |
267 | 269 |
268 /** | 270 /** |
269 * @this {WebInspector.TextPrompt} | 271 * @this {WebInspector.TextPrompt} |
270 */ | 272 */ |
271 function moveBackIfOutside() | 273 function moveBackIfOutside() |
272 { | 274 { |
273 delete this._selectionTimeout; | 275 delete this._selectionTimeout; |
lushnikov
2016/10/24 21:27:21
what does this do?
| |
274 if (!this.isCaretInsidePrompt() && this._element.isComponentSelectio nCollapsed()) { | 276 if (!this.isCaretInsidePrompt() && this._element.isComponentSelectio nCollapsed()) { |
275 this.moveCaretToEndOfPrompt(); | 277 this.moveCaretToEndOfPrompt(); |
276 this.autoCompleteSoon(); | 278 this.autoCompleteSoon(); |
277 } | 279 } |
278 } | 280 } |
279 | 281 |
280 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); | 282 this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100); |
281 }, | 283 }, |
282 | 284 |
283 | |
284 /** | 285 /** |
285 * @param {!Event} event | 286 * @param {!Event} event |
286 */ | 287 */ |
287 onMouseWheel: function(event) | 288 onMouseWheel: function(event) |
288 { | 289 { |
289 // Subclasses can implement. | 290 // Subclasses can implement. |
290 }, | 291 }, |
291 | 292 |
292 /** | 293 /** |
293 * @param {!Event} event | 294 * @param {!Event} event |
294 */ | 295 */ |
295 onKeyDown: function(event) | 296 onKeyDown: function(event) |
296 { | 297 { |
297 if (isEnterKey(event)) | |
298 return; | |
299 | |
300 var handled = false; | 298 var handled = false; |
301 | 299 |
302 switch (event.key) { | 300 switch (event.key) { |
303 case "Tab": | 301 case "Tab": |
304 handled = this.tabKeyPressed(event); | 302 handled = this.tabKeyPressed(event); |
305 break; | 303 break; |
306 case "ArrowLeft": | 304 case "ArrowLeft": |
307 case "Home": | 305 case "Home": |
308 this.clearAutocomplete(); | 306 this.clearAutocomplete(); |
309 break; | 307 break; |
(...skipping 30 matching lines...) Expand all Loading... | |
340 event.consume(true); | 338 event.consume(true); |
341 }, | 339 }, |
342 | 340 |
343 /** | 341 /** |
344 * @param {!Event} event | 342 * @param {!Event} event |
345 */ | 343 */ |
346 onInput: function(event) | 344 onInput: function(event) |
347 { | 345 { |
348 var text = this.userEnteredText(); | 346 var text = this.userEnteredText(); |
349 var hasCommonPrefix = text.startsWith(this._previousText) || this._previ ousText.startsWith(text); | 347 var hasCommonPrefix = text.startsWith(this._previousText) || this._previ ousText.startsWith(text); |
350 if (this._autocompleteElement && hasCommonPrefix) | 348 if (this._prefixRange && hasCommonPrefix) { |
lushnikov
2016/10/24 21:27:20
let's check that cursor is in the end of the promp
| |
351 this._autocompleteElement.textContent = this._currentHintText.substr ing(text.length); | 349 this._prefixRange.endColumn += text.length - this._previousText.leng th; |
lushnikov
2016/10/24 21:27:20
this._prefixRange.endColumn = text.length;
| |
352 else | 350 this._setAutocompleteText(this._currentHintText); |
351 } else { | |
353 this._clearAutocompleteElement(); | 352 this._clearAutocompleteElement(); |
353 } | |
354 this._previousText = text; | 354 this._previousText = text; |
355 | 355 |
356 this.autoCompleteSoon(); | 356 this.autoCompleteSoon(); |
357 }, | 357 }, |
358 | 358 |
359 /** | 359 /** |
360 * @return {boolean} | 360 * @return {boolean} |
361 */ | 361 */ |
362 acceptAutoComplete: function() | 362 acceptAutoComplete: function() |
363 { | 363 { |
(...skipping 10 matching lines...) Expand all Loading... | |
374 { | 374 { |
375 if (this.isSuggestBoxVisible()) | 375 if (this.isSuggestBoxVisible()) |
376 this._suggestBox.hide(); | 376 this._suggestBox.hide(); |
377 this._clearAutocompleteElement(); | 377 this._clearAutocompleteElement(); |
378 }, | 378 }, |
379 | 379 |
380 _clearAutocompleteElement: function() | 380 _clearAutocompleteElement: function() |
381 { | 381 { |
382 this._clearAutocompleteTimeout(); | 382 this._clearAutocompleteTimeout(); |
383 | 383 |
384 if (!this._autocompleteElement) | 384 this._autocompleteElement.remove(); |
385 return; | 385 this._prefixRange = null; |
lushnikov
2016/10/24 21:27:20
this should probably go inside clearAutocomplete -
| |
386 }, | |
386 | 387 |
387 this._autocompleteElement.remove(); | 388 /** |
388 delete this._autocompleteElement; | 389 * @param {string} text |
389 delete this._userEnteredRange; | 390 */ |
390 delete this._userEnteredText; | 391 _setAutocompleteText: function(text) |
lushnikov
2016/10/24 21:27:20
text -> suggestion
| |
392 { | |
393 if (this.isCaretAtEndOfPrompt() && this._prefixRange) { | |
394 this._autocompleteElement.textContent = text.substring(this._prefixR ange.endColumn - this._prefixRange.startColumn); | |
395 this._element.appendChild(this._autocompleteElement); | |
396 } | |
397 this._currentHintText = text; | |
391 }, | 398 }, |
392 | 399 |
393 _clearAutocompleteTimeout: function() | 400 _clearAutocompleteTimeout: function() |
394 { | 401 { |
395 if (this._completeTimeout) { | 402 if (this._completeTimeout) { |
396 clearTimeout(this._completeTimeout); | 403 clearTimeout(this._completeTimeout); |
397 delete this._completeTimeout; | 404 delete this._completeTimeout; |
398 } | 405 } |
399 this._completionRequestId++; | 406 this._completionRequestId++; |
400 }, | 407 }, |
(...skipping 22 matching lines...) Expand all Loading... | |
423 | 430 |
424 var shouldExit; | 431 var shouldExit; |
425 | 432 |
426 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) | 433 if (!force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible( )) |
427 shouldExit = true; | 434 shouldExit = true; |
428 else if (!selection.isCollapsed) | 435 else if (!selection.isCollapsed) |
429 shouldExit = true; | 436 shouldExit = true; |
430 else if (!force) { | 437 else if (!force) { |
431 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. | 438 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. |
432 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); | 439 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); |
433 var autocompleteTextLength = (this._autocompleteElement && this._aut ocompleteElement.parentNode) ? this._autocompleteElement.textContent.length : 0; | 440 var autocompleteTextLength = this._autocompleteElement.parentNode ? this._autocompleteElement.textContent.length : 0; |
434 if (wordSuffixRange.toString().length !== autocompleteTextLength) | 441 if (wordSuffixRange.toString().length !== autocompleteTextLength) |
435 shouldExit = true; | 442 shouldExit = true; |
436 } | 443 } |
437 if (shouldExit) { | 444 if (shouldExit) { |
438 this.clearAutocomplete(); | 445 this.clearAutocomplete(); |
439 return; | 446 return; |
440 } | 447 } |
441 | 448 |
442 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); | 449 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); |
443 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, ++this._completio nRequestId, selection, wordPrefixRange, !!reverse, !!force)); | 450 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, ++this._completio nRequestId, selection, wordPrefixRange, !!reverse, !!force)); |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
520 | 527 |
521 var fullWordRange = this._createRange(); | 528 var fullWordRange = this._createRange(); |
522 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); | 529 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); |
523 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); | 530 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); |
524 | 531 |
525 if (prefix + selectionRange.toString() !== fullWordRange.toString()) | 532 if (prefix + selectionRange.toString() !== fullWordRange.toString()) |
526 return; | 533 return; |
527 | 534 |
528 selectedIndex = (this._disableDefaultSuggestionForEmptyInput && !this.te xt()) ? -1 : (selectedIndex || 0); | 535 selectedIndex = (this._disableDefaultSuggestionForEmptyInput && !this.te xt()) ? -1 : (selectedIndex || 0); |
529 | 536 |
530 this._userEnteredRange = fullWordRange; | 537 if (this._suggestBox) |
531 this._userEnteredText = fullWordRange.toString(); | 538 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), annotatedCompletions, selectedIndex, !this.isCaretAtEndOfPro mpt(), this.userEnteredText()); |
532 | 539 |
533 if (this._suggestBox) | 540 var beforeRange = this._createRange(); |
534 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), annotatedCompletions, selectedIndex, !this.isCaretAtEndOfPro mpt(), this._userEnteredText); | 541 beforeRange.setStart(this._element, 0); |
542 beforeRange.setEnd(fullWordRange.startContainer, fullWordRange.startOffs et); | |
543 this._prefixRange = new WebInspector.TextRange(0, beforeRange.toString() .length, 0, beforeRange.toString().length + fullWordRange.toString().length); | |
lushnikov
2016/10/24 21:27:20
let's convert range to string only once - i rememb
| |
535 | 544 |
536 if (selectedIndex === -1) | 545 if (selectedIndex === -1) |
537 return; | 546 return; |
538 | 547 this.applySuggestion(annotatedCompletions[selectedIndex].title, true); |
539 var wordPrefixLength = originalWordPrefixRange.toString().length; | |
540 | |
541 if (this.isCaretAtEndOfPrompt()) { | |
542 var completionText = annotatedCompletions[selectedIndex].title; | |
543 var prefixText = this._userEnteredRange.toString(); | |
544 var suffixText = completionText.substring(wordPrefixLength); | |
545 this._userEnteredRange.deleteContents(); | |
546 this._element.normalize(); | |
547 var finalSelectionRange = this._createRange(); | |
548 | |
549 var prefixTextNode = createTextNode(prefixText); | |
550 fullWordRange.insertNode(prefixTextNode); | |
551 | |
552 if (!this._autocompleteElement) | |
553 this._autocompleteElement = createElementWithClass("span", "auto -complete-text"); | |
554 this._autocompleteElement.textContent = suffixText; | |
555 this._currentHintText = completionText; | |
556 | |
557 prefixTextNode.parentNode.insertBefore(this._autocompleteElement, pr efixTextNode.nextSibling); | |
558 | |
559 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); | |
560 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); | |
561 selection.removeAllRanges(); | |
562 selection.addRange(finalSelectionRange); | |
563 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); | |
564 } | |
565 }, | 548 }, |
566 | 549 |
567 /** | 550 /** |
568 * @override | 551 * @override |
569 * @param {string} completionText | 552 * @param {string} completionText |
570 * @param {boolean=} isIntermediateSuggestion | 553 * @param {boolean=} isIntermediateSuggestion |
571 */ | 554 */ |
572 applySuggestion: function(completionText, isIntermediateSuggestion) | 555 applySuggestion: function(completionText, isIntermediateSuggestion) |
573 { | 556 { |
574 this._applySuggestion(completionText, isIntermediateSuggestion); | 557 if (!this._prefixRange) |
558 return; | |
559 this._setAutocompleteText(completionText); | |
560 if (isIntermediateSuggestion) | |
561 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); | |
575 }, | 562 }, |
576 | 563 |
577 /** | 564 /** |
578 * @param {string} completionText | |
579 * @param {boolean=} isIntermediateSuggestion | |
580 */ | |
581 _applySuggestion: function(completionText, isIntermediateSuggestion) | |
582 { | |
583 if (!this._userEnteredRange) { | |
584 // We could have already cleared autocompletion range by the time th is is called. (crbug.com/587683) | |
585 return; | |
586 } | |
587 | |
588 var wordPrefixLength = this._userEnteredText ? this._userEnteredText.len gth : 0; | |
589 | |
590 this._userEnteredRange.deleteContents(); | |
591 this._element.normalize(); | |
592 var finalSelectionRange = this._createRange(); | |
593 var completionTextNode = createTextNode(completionText); | |
594 this._userEnteredRange.insertNode(completionTextNode); | |
595 if (this._autocompleteElement) { | |
596 this._autocompleteElement.remove(); | |
597 delete this._autocompleteElement; | |
598 } | |
599 | |
600 if (isIntermediateSuggestion) | |
601 finalSelectionRange.setStart(completionTextNode, wordPrefixLength); | |
602 else | |
603 finalSelectionRange.setStart(completionTextNode, completionText.leng th); | |
604 | |
605 finalSelectionRange.setEnd(completionTextNode, completionText.length); | |
606 | |
607 var selection = this._element.getComponentSelection(); | |
608 selection.removeAllRanges(); | |
609 selection.addRange(finalSelectionRange); | |
610 if (isIntermediateSuggestion) | |
611 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied, { itemText: completionText }); | |
612 }, | |
613 | |
614 /** | |
615 * @override | 565 * @override |
616 */ | 566 */ |
617 acceptSuggestion: function() | 567 acceptSuggestion: function() |
618 { | 568 { |
619 this._acceptSuggestionInternal(); | 569 this._acceptSuggestionInternal(); |
620 }, | 570 }, |
621 | 571 |
622 /** | 572 /** |
623 * @return {boolean} | 573 * @return {boolean} |
624 */ | 574 */ |
625 _acceptSuggestionInternal: function() | 575 _acceptSuggestionInternal: function() |
626 { | 576 { |
627 if (!this._autocompleteElement || !this._autocompleteElement.parentNode) | 577 if (!this._prefixRange) |
628 return false; | 578 return false; |
629 | 579 |
630 var text = this._autocompleteElement.textContent; | 580 this._autocompleteElement.remove(); |
631 var textNode = createTextNode(text); | 581 var text = this.userEnteredText(); |
632 this._autocompleteElement.parentNode.replaceChild(textNode, this._autoco mpleteElement); | 582 this._element.textContent = text.substring(0, this._prefixRange.startCol umn) + this._currentHintText + text.substring(this._prefixRange.endColumn); |
633 delete this._autocompleteElement; | 583 this._setDOMSelection(this._prefixRange.startColumn + this._currentHintT ext.length, this._prefixRange.startColumn + this._currentHintText.length); |
634 | |
635 var finalSelectionRange = this._createRange(); | |
636 finalSelectionRange.setStart(textNode, text.length); | |
637 finalSelectionRange.setEnd(textNode, text.length); | |
638 | |
639 var selection = this._element.getComponentSelection(); | |
640 selection.removeAllRanges(); | |
641 selection.addRange(finalSelectionRange); | |
642 | 584 |
643 this.clearAutocomplete(); | 585 this.clearAutocomplete(); |
644 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepte d); | 586 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepte d); |
645 | 587 |
646 return true; | 588 return true; |
647 }, | 589 }, |
648 | 590 |
649 /** | 591 /** |
592 * @param {number} startColumn | |
593 * @param {number} endColumn | |
594 */ | |
595 _setDOMSelection: function(startColumn, endColumn) | |
596 { | |
597 this._element.normalize(); | |
598 var node = this._element.childNodes[0]; | |
599 if (!node || node === this._autocompleteElement) | |
600 return; | |
601 var range = this._createRange(); | |
602 range.setStart(node, startColumn); | |
603 range.setEnd(node, endColumn); | |
604 var selection = this._element.getComponentSelection(); | |
605 selection.removeAllRanges(); | |
606 selection.addRange(range); | |
607 }, | |
608 | |
609 /** | |
650 * @return {boolean} | 610 * @return {boolean} |
651 */ | 611 */ |
652 isSuggestBoxVisible: function() | 612 isSuggestBoxVisible: function() |
653 { | 613 { |
654 return this._suggestBox && this._suggestBox.visible(); | 614 return this._suggestBox && this._suggestBox.visible(); |
655 }, | 615 }, |
656 | 616 |
657 /** | 617 /** |
658 * @return {boolean} | 618 * @return {boolean} |
659 */ | 619 */ |
(...skipping 20 matching lines...) Expand all Loading... | |
680 var node = selectionRange.startContainer; | 640 var node = selectionRange.startContainer; |
681 if (!node.isSelfOrDescendant(this._element)) | 641 if (!node.isSelfOrDescendant(this._element)) |
682 return false; | 642 return false; |
683 | 643 |
684 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length) | 644 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length) |
685 return false; | 645 return false; |
686 | 646 |
687 var foundNextText = false; | 647 var foundNextText = false; |
688 while (node) { | 648 while (node) { |
689 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { | 649 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { |
690 if (foundNextText && (!this._autocompleteElement || !this._autoc ompleteElement.isAncestor(node))) | 650 if (foundNextText && !this._autocompleteElement.isAncestor(node) ) |
691 return false; | 651 return false; |
692 foundNextText = true; | 652 foundNextText = true; |
693 } | 653 } |
694 | 654 |
695 node = node.traverseNextNode(this._element); | 655 node = node.traverseNextNode(this._element); |
696 } | 656 } |
697 | 657 |
698 return true; | 658 return true; |
699 }, | 659 }, |
700 | 660 |
701 /** | 661 /** |
702 * @return {boolean} | 662 * @return {boolean} |
703 */ | 663 */ |
704 isCaretOnFirstLine: function() | 664 isCaretOnFirstLine: function() |
705 { | 665 { |
706 var selection = this._element.getComponentSelection(); | 666 var selection = this._element.getComponentSelection(); |
lushnikov
2016/10/24 21:27:20
let's rely on the _prefixRange her
| |
707 var focusNode = selection.focusNode; | 667 var focusNode = selection.focusNode; |
708 if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.par entNode !== this._element) | 668 if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.par entNode !== this._element) |
709 return true; | 669 return true; |
710 | 670 |
711 if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\ n") !== -1) | 671 if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\ n") !== -1) |
712 return false; | 672 return false; |
713 focusNode = focusNode.previousSibling; | 673 focusNode = focusNode.previousSibling; |
714 | 674 |
715 while (focusNode) { | 675 while (focusNode) { |
716 if (focusNode.nodeType !== Node.TEXT_NODE) | 676 if (focusNode.nodeType !== Node.TEXT_NODE) |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
996 }, | 956 }, |
997 | 957 |
998 /** | 958 /** |
999 * @return {string|undefined} | 959 * @return {string|undefined} |
1000 */ | 960 */ |
1001 _currentHistoryItem: function() | 961 _currentHistoryItem: function() |
1002 { | 962 { |
1003 return this._data[this._data.length - this._historyOffset]; | 963 return this._data[this._data.length - this._historyOffset]; |
1004 } | 964 } |
1005 }; | 965 }; |
OLD | NEW |