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 23 matching lines...) Expand all Loading... | |
| 34 */ | 34 */ |
| 35 WebInspector.TextPrompt = function() | 35 WebInspector.TextPrompt = function() |
| 36 { | 36 { |
| 37 /** | 37 /** |
| 38 * @type {!Element|undefined} | 38 * @type {!Element|undefined} |
| 39 */ | 39 */ |
| 40 this._proxyElement; | 40 this._proxyElement; |
| 41 this._proxyElementDisplay = "inline-block"; | 41 this._proxyElementDisplay = "inline-block"; |
| 42 this._autocompletionTimeout = WebInspector.TextPrompt.DefaultAutocompletionT imeout; | 42 this._autocompletionTimeout = WebInspector.TextPrompt.DefaultAutocompletionT imeout; |
| 43 this._title = ""; | 43 this._title = ""; |
| 44 this._prefixRange = null; | |
| 44 this._previousText = ""; | 45 this._previousText = ""; |
| 45 this._currentSuggestion = ""; | 46 this._currentSuggestion = ""; |
| 46 this._completionRequestId = 0; | 47 this._completionRequestId = 0; |
| 48 this._ghostTextElement = createElementWithClass("span", "auto-complete-text" ); | |
| 47 }; | 49 }; |
| 48 | 50 |
| 49 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; | 51 WebInspector.TextPrompt.DefaultAutocompletionTimeout = 250; |
| 50 | 52 |
| 51 /** @enum {symbol} */ | 53 /** @enum {symbol} */ |
| 52 WebInspector.TextPrompt.Events = { | 54 WebInspector.TextPrompt.Events = { |
| 53 ItemApplied: Symbol("text-prompt-item-applied"), | 55 ItemApplied: Symbol("text-prompt-item-applied"), |
| 54 ItemAccepted: Symbol("text-prompt-item-accepted") | 56 ItemAccepted: Symbol("text-prompt-item-accepted") |
| 55 }; | 57 }; |
| 56 | 58 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 this._proxyElement.appendChild(element); | 140 this._proxyElement.appendChild(element); |
| 139 this._element.classList.add("text-prompt"); | 141 this._element.classList.add("text-prompt"); |
| 140 this._element.addEventListener("keydown", this._boundOnKeyDown, false); | 142 this._element.addEventListener("keydown", this._boundOnKeyDown, false); |
| 141 this._element.addEventListener("input", this._boundOnInput, false); | 143 this._element.addEventListener("input", this._boundOnInput, false); |
| 142 this._element.addEventListener("mousewheel", this._boundOnMouseWheel, fa lse); | 144 this._element.addEventListener("mousewheel", this._boundOnMouseWheel, fa lse); |
| 143 this._element.addEventListener("selectstart", this._boundClearAutocomple te, false); | 145 this._element.addEventListener("selectstart", this._boundClearAutocomple te, false); |
| 144 this._element.addEventListener("blur", this._boundClearAutocomplete, fal se); | 146 this._element.addEventListener("blur", this._boundClearAutocomplete, fal se); |
| 145 this._element.ownerDocument.defaultView.addEventListener("resize", this. _boundClearAutocomplete, false); | 147 this._element.ownerDocument.defaultView.addEventListener("resize", this. _boundClearAutocomplete, false); |
| 146 | 148 |
| 147 if (this._suggestBoxEnabled) | 149 if (this._suggestBoxEnabled) |
| 148 this._suggestBox = new WebInspector.SuggestBox(this); | 150 this._suggestBox = new WebInspector.SuggestBox(this, 20, true); |
| 149 | 151 |
| 150 if (this._title) | 152 if (this._title) |
| 151 this._proxyElement.title = this._title; | 153 this._proxyElement.title = this._title; |
| 152 | 154 |
| 153 return this._proxyElement; | 155 return this._proxyElement; |
| 154 }, | 156 }, |
| 155 | 157 |
| 156 detach: function() | 158 detach: function() |
| 157 { | 159 { |
| 158 this._removeFromElement(); | 160 this._removeFromElement(); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 170 { | 172 { |
| 171 return this._element.textContent; | 173 return this._element.textContent; |
| 172 }, | 174 }, |
| 173 | 175 |
| 174 /** | 176 /** |
| 175 * @return {string} | 177 * @return {string} |
| 176 */ | 178 */ |
| 177 text: function() | 179 text: function() |
| 178 { | 180 { |
| 179 var text = this.textWithCurrentSuggestion(); | 181 var text = this.textWithCurrentSuggestion(); |
| 180 if (this._ghostTextElement) { | 182 if (this._ghostTextElement.parentNode) { |
| 181 var addition = this._ghostTextElement.textContent; | 183 var addition = this._ghostTextElement.textContent; |
| 182 text = text.substring(0, text.length - addition.length); | 184 text = text.substring(0, text.length - addition.length); |
| 183 } | 185 } |
| 184 return text; | 186 return text; |
| 185 }, | 187 }, |
| 186 | 188 |
| 187 /** | 189 /** |
| 188 * @param {string} x | 190 * @param {string} x |
| 189 */ | 191 */ |
| 190 setText: function(x) | 192 setText: function(x) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 onMouseWheel: function(event) | 271 onMouseWheel: function(event) |
| 270 { | 272 { |
| 271 // Subclasses can implement. | 273 // Subclasses can implement. |
| 272 }, | 274 }, |
| 273 | 275 |
| 274 /** | 276 /** |
| 275 * @param {!Event} event | 277 * @param {!Event} event |
| 276 */ | 278 */ |
| 277 onKeyDown: function(event) | 279 onKeyDown: function(event) |
| 278 { | 280 { |
| 279 if (isEnterKey(event)) | |
| 280 return; | |
| 281 | |
| 282 var handled = false; | 281 var handled = false; |
| 283 | 282 |
| 284 switch (event.key) { | 283 switch (event.key) { |
| 285 case "Tab": | 284 case "Tab": |
| 286 handled = this.tabKeyPressed(event); | 285 handled = this.tabKeyPressed(event); |
| 287 break; | 286 break; |
| 288 case "ArrowLeft": | 287 case "ArrowLeft": |
| 289 case "Home": | 288 case "Home": |
| 290 this.clearAutocomplete(); | 289 this.clearAutocomplete(); |
| 291 break; | 290 break; |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 322 event.consume(true); | 321 event.consume(true); |
| 323 }, | 322 }, |
| 324 | 323 |
| 325 /** | 324 /** |
| 326 * @param {!Event} event | 325 * @param {!Event} event |
| 327 */ | 326 */ |
| 328 onInput: function(event) | 327 onInput: function(event) |
| 329 { | 328 { |
| 330 var text = this.text(); | 329 var text = this.text(); |
| 331 var hasCommonPrefix = text.startsWith(this._previousText) || this._previ ousText.startsWith(text); | 330 var hasCommonPrefix = text.startsWith(this._previousText) || this._previ ousText.startsWith(text); |
| 332 if (this._ghostTextElement && hasCommonPrefix) | 331 if (this._prefixRange && hasCommonPrefix) |
| 333 this._ghostTextElement.textContent = this._currentSuggestion.substri ng(text.length); | 332 this._prefixRange.endColumn += text.length - this._previousText.leng th; |
| 334 else | 333 this._refreshGhostText(); |
| 335 this._clearGhostTextElement(); | |
| 336 this._previousText = text; | 334 this._previousText = text; |
| 337 | 335 |
| 338 this.autoCompleteSoon(); | 336 this.autoCompleteSoon(); |
| 339 }, | 337 }, |
| 340 | 338 |
| 341 /** | 339 /** |
| 342 * @return {boolean} | 340 * @return {boolean} |
| 343 */ | 341 */ |
| 344 acceptAutoComplete: function() | 342 acceptAutoComplete: function() |
| 345 { | 343 { |
| 346 var result = false; | 344 var result = false; |
| 347 if (this._isSuggestBoxVisible()) | 345 if (this._isSuggestBoxVisible()) |
| 348 result = this._suggestBox.acceptSuggestion(); | 346 result = this._suggestBox.acceptSuggestion(); |
| 349 if (!result) | 347 if (!result) |
| 350 result = this._acceptSuggestionInternal(); | 348 result = this._acceptSuggestionInternal(); |
| 351 | 349 |
| 352 return result; | 350 return result; |
| 353 }, | 351 }, |
| 354 | 352 |
| 355 clearAutocomplete: function() | 353 clearAutocomplete: function() |
| 356 { | 354 { |
| 357 if (this._isSuggestBoxVisible()) | 355 if (this._isSuggestBoxVisible()) |
| 358 this._suggestBox.hide(); | 356 this._suggestBox.hide(); |
| 359 this._clearGhostTextElement(); | 357 this._clearAutocompleteTimeout(); |
| 358 this._prefixRange = null; | |
| 359 this._refreshGhostText(); | |
| 360 }, | 360 }, |
| 361 | 361 |
| 362 _clearGhostTextElement: function() | 362 _refreshGhostText: function() |
| 363 { | 363 { |
| 364 this._clearAutocompleteTimeout(); | 364 if (this._prefixRange && this._isCaretAtEndOfPrompt()) { |
| 365 | 365 this._ghostTextElement.textContent = this._currentSuggestion.substri ng(this._prefixRange.endColumn - this._prefixRange.startColumn); |
| 366 if (!this._ghostTextElement) | 366 this._element.appendChild(this._ghostTextElement); |
| 367 return; | 367 } else { |
| 368 | 368 this._ghostTextElement.remove(); |
| 369 this._ghostTextElement.remove(); | 369 } |
| 370 delete this._ghostTextElement; | |
| 371 delete this._userEnteredRange; | |
| 372 delete this._userEnteredText; | |
| 373 }, | 370 }, |
| 374 | 371 |
| 375 _clearAutocompleteTimeout: function() | 372 _clearAutocompleteTimeout: function() |
| 376 { | 373 { |
| 377 if (this._completeTimeout) { | 374 if (this._completeTimeout) { |
| 378 clearTimeout(this._completeTimeout); | 375 clearTimeout(this._completeTimeout); |
| 379 delete this._completeTimeout; | 376 delete this._completeTimeout; |
| 380 } | 377 } |
| 381 this._completionRequestId++; | 378 this._completionRequestId++; |
| 382 }, | 379 }, |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 405 | 402 |
| 406 var shouldExit; | 403 var shouldExit; |
| 407 | 404 |
| 408 if (!force && !this._isCaretAtEndOfPrompt() && !this._isSuggestBoxVisibl e()) | 405 if (!force && !this._isCaretAtEndOfPrompt() && !this._isSuggestBoxVisibl e()) |
| 409 shouldExit = true; | 406 shouldExit = true; |
| 410 else if (!selection.isCollapsed) | 407 else if (!selection.isCollapsed) |
| 411 shouldExit = true; | 408 shouldExit = true; |
| 412 else if (!force) { | 409 else if (!force) { |
| 413 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. | 410 // BUG72018: Do not show suggest box if caret is followed by a non-s top character. |
| 414 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); | 411 var wordSuffixRange = selectionRange.startContainer.rangeOfWord(sele ctionRange.endOffset, this._completionStopCharacters, this._element, "forward"); |
| 415 var autocompleteTextLength = (this._ghostTextElement && this._ghostT extElement.parentNode) ? this._ghostTextElement.textContent.length : 0; | 412 var autocompleteTextLength = this._ghostTextElement.parentNode ? thi s._ghostTextElement.textContent.length : 0; |
| 416 if (wordSuffixRange.toString().length !== autocompleteTextLength) | 413 if (wordSuffixRange.toString().length !== autocompleteTextLength) |
| 417 shouldExit = true; | 414 shouldExit = true; |
| 418 } | 415 } |
| 419 if (shouldExit) { | 416 if (shouldExit) { |
| 420 this.clearAutocomplete(); | 417 this.clearAutocomplete(); |
| 421 return; | 418 return; |
| 422 } | 419 } |
| 423 | 420 |
| 424 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); | 421 var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectio nRange.startOffset, this._completionStopCharacters, this._element, "backward"); |
| 425 this._loadCompletions(/** @type {!Element} */ (this._proxyElement), word PrefixRange, force || false, this._completionsReady.bind(this, ++this._completio nRequestId, selection, wordPrefixRange, !!reverse, !!force)); | 422 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... | |
| 502 | 499 |
| 503 var fullWordRange = this._createRange(); | 500 var fullWordRange = this._createRange(); |
| 504 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); | 501 fullWordRange.setStart(originalWordPrefixRange.startContainer, originalW ordPrefixRange.startOffset); |
| 505 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); | 502 fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffs et); |
| 506 | 503 |
| 507 if (prefix + selectionRange.toString() !== fullWordRange.toString()) | 504 if (prefix + selectionRange.toString() !== fullWordRange.toString()) |
| 508 return; | 505 return; |
| 509 | 506 |
| 510 selectedIndex = (this._disableDefaultSuggestionForEmptyInput && !this.te xt()) ? -1 : (selectedIndex || 0); | 507 selectedIndex = (this._disableDefaultSuggestionForEmptyInput && !this.te xt()) ? -1 : (selectedIndex || 0); |
| 511 | 508 |
| 512 this._userEnteredRange = fullWordRange; | 509 if (this._suggestBox) |
| 513 this._userEnteredText = fullWordRange.toString(); | 510 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), annotatedCompletions, selectedIndex, !this._isCaretAtEndOfPr ompt(), this.text()); |
| 514 | 511 |
| 515 if (this._suggestBox) | 512 var beforeRange = this._createRange(); |
| 516 this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selecti on, fullWordRange), annotatedCompletions, selectedIndex, !this._isCaretAtEndOfPr ompt(), this._userEnteredText); | 513 beforeRange.setStart(this._element, 0); |
| 514 beforeRange.setEnd(fullWordRange.startContainer, fullWordRange.startOffs et); | |
| 515 this._prefixRange = new WebInspector.TextRange(0, beforeRange.toString() .length, 0, beforeRange.toString().length + fullWordRange.toString().length); | |
| 517 | 516 |
| 518 if (selectedIndex === -1) | 517 if (selectedIndex === -1) |
| 519 return; | 518 return; |
| 520 | 519 this.applySuggestion(annotatedCompletions[selectedIndex].title, true); |
| 521 var wordPrefixLength = originalWordPrefixRange.toString().length; | |
| 522 | |
| 523 if (this._isCaretAtEndOfPrompt()) { | |
| 524 var suggestion = annotatedCompletions[selectedIndex].title; | |
| 525 var prefixText = this._userEnteredRange.toString(); | |
| 526 var suffixText = suggestion.substring(wordPrefixLength); | |
| 527 this._userEnteredRange.deleteContents(); | |
| 528 this._element.normalize(); | |
| 529 var finalSelectionRange = this._createRange(); | |
| 530 | |
| 531 var prefixTextNode = createTextNode(prefixText); | |
| 532 fullWordRange.insertNode(prefixTextNode); | |
| 533 | |
| 534 if (!this._ghostTextElement) | |
| 535 this._ghostTextElement = createElementWithClass("span", "auto-co mplete-text"); | |
| 536 this._ghostTextElement.textContent = suffixText; | |
| 537 this._currentSuggestion = suggestion; | |
| 538 | |
| 539 prefixTextNode.parentNode.insertBefore(this._ghostTextElement, prefi xTextNode.nextSibling); | |
| 540 | |
| 541 finalSelectionRange.setStart(prefixTextNode, wordPrefixLength); | |
| 542 finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength); | |
| 543 selection.removeAllRanges(); | |
| 544 selection.addRange(finalSelectionRange); | |
| 545 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); | |
| 546 } | |
| 547 }, | 520 }, |
| 548 | 521 |
| 549 /** | 522 /** |
| 550 * @override | 523 * @override |
| 551 * @param {string} suggestion | 524 * @param {string} suggestion |
| 552 * @param {boolean=} isIntermediateSuggestion | 525 * @param {boolean=} isIntermediateSuggestion |
| 553 */ | 526 */ |
| 554 applySuggestion: function(suggestion, isIntermediateSuggestion) | 527 applySuggestion: function(suggestion, isIntermediateSuggestion) |
| 555 { | 528 { |
| 556 this._applySuggestion(suggestion, isIntermediateSuggestion); | 529 if (!this._prefixRange) |
| 530 return; | |
| 531 this._currentSuggestion = suggestion; | |
| 532 this._refreshGhostText(); | |
| 533 if (isIntermediateSuggestion) | |
| 534 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied); | |
| 557 }, | 535 }, |
| 558 | 536 |
| 559 /** | 537 /** |
| 560 * @param {string} suggestion | |
| 561 * @param {boolean=} isIntermediateSuggestion | |
| 562 */ | |
| 563 _applySuggestion: function(suggestion, isIntermediateSuggestion) | |
| 564 { | |
| 565 if (!this._userEnteredRange) { | |
| 566 // We could have already cleared autocompletion range by the time th is is called. (crbug.com/587683) | |
| 567 return; | |
| 568 } | |
| 569 | |
| 570 var wordPrefixLength = this._userEnteredText ? this._userEnteredText.len gth : 0; | |
| 571 | |
| 572 this._userEnteredRange.deleteContents(); | |
| 573 this._element.normalize(); | |
| 574 var finalSelectionRange = this._createRange(); | |
| 575 var suggestionNode = createTextNode(suggestion); | |
| 576 this._userEnteredRange.insertNode(suggestionNode); | |
| 577 if (this._ghostTextElement) { | |
| 578 this._ghostTextElement.remove(); | |
| 579 delete this._ghostTextElement; | |
| 580 } | |
| 581 | |
| 582 if (isIntermediateSuggestion) | |
| 583 finalSelectionRange.setStart(suggestionNode, wordPrefixLength); | |
| 584 else | |
| 585 finalSelectionRange.setStart(suggestionNode, suggestion.length); | |
| 586 | |
| 587 finalSelectionRange.setEnd(suggestionNode, suggestion.length); | |
| 588 | |
| 589 var selection = this._element.getComponentSelection(); | |
| 590 selection.removeAllRanges(); | |
| 591 selection.addRange(finalSelectionRange); | |
| 592 if (isIntermediateSuggestion) | |
| 593 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApp lied, { itemText: suggestion }); | |
| 594 }, | |
| 595 | |
| 596 /** | |
| 597 * @override | 538 * @override |
| 598 */ | 539 */ |
| 599 acceptSuggestion: function() | 540 acceptSuggestion: function() |
| 600 { | 541 { |
| 601 this._acceptSuggestionInternal(); | 542 this._acceptSuggestionInternal(); |
| 602 }, | 543 }, |
| 603 | 544 |
| 604 /** | 545 /** |
| 605 * @return {boolean} | 546 * @return {boolean} |
| 606 */ | 547 */ |
| 607 _acceptSuggestionInternal: function() | 548 _acceptSuggestionInternal: function() |
| 608 { | 549 { |
| 609 if (!this._ghostTextElement || !this._ghostTextElement.parentNode) | 550 if (!this._prefixRange) |
| 610 return false; | 551 return false; |
| 611 | 552 |
| 612 var text = this._ghostTextElement.textContent; | 553 this._ghostTextElement.remove(); |
|
lushnikov
2016/10/27 00:35:50
let's get rid of that
einbinder
2016/10/27 00:56:49
Done.
| |
| 613 var textNode = createTextNode(text); | 554 var text = this.text(); |
| 614 this._ghostTextElement.parentNode.replaceChild(textNode, this._ghostText Element); | 555 this._element.textContent = text.substring(0, this._prefixRange.startCol umn) + this._currentSuggestion + text.substring(this._prefixRange.endColumn); |
| 615 delete this._ghostTextElement; | 556 this._setDOMSelection(this._prefixRange.startColumn + this._currentSugge stion.length, this._prefixRange.startColumn + this._currentSuggestion.length); |
| 616 | |
| 617 var finalSelectionRange = this._createRange(); | |
| 618 finalSelectionRange.setStart(textNode, text.length); | |
| 619 finalSelectionRange.setEnd(textNode, text.length); | |
| 620 | |
| 621 var selection = this._element.getComponentSelection(); | |
| 622 selection.removeAllRanges(); | |
| 623 selection.addRange(finalSelectionRange); | |
| 624 | 557 |
| 625 this.clearAutocomplete(); | 558 this.clearAutocomplete(); |
| 626 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepte d); | 559 this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepte d); |
| 627 | 560 |
| 628 return true; | 561 return true; |
| 629 }, | 562 }, |
| 630 | 563 |
| 631 /** | 564 /** |
| 565 * @param {number} startColumn | |
| 566 * @param {number} endColumn | |
| 567 */ | |
| 568 _setDOMSelection: function(startColumn, endColumn) | |
| 569 { | |
| 570 this._element.normalize(); | |
| 571 var node = this._element.childNodes[0]; | |
| 572 if (!node || node === this._ghostTextElement) | |
| 573 return; | |
| 574 var range = this._createRange(); | |
| 575 range.setStart(node, startColumn); | |
| 576 range.setEnd(node, endColumn); | |
| 577 var selection = this._element.getComponentSelection(); | |
| 578 selection.removeAllRanges(); | |
| 579 selection.addRange(range); | |
| 580 }, | |
| 581 | |
| 582 /** | |
| 632 * @return {boolean} | 583 * @return {boolean} |
| 633 */ | 584 */ |
| 634 _isSuggestBoxVisible: function() | 585 _isSuggestBoxVisible: function() |
| 635 { | 586 { |
| 636 return this._suggestBox && this._suggestBox.visible(); | 587 return this._suggestBox && this._suggestBox.visible(); |
| 637 }, | 588 }, |
| 638 | 589 |
| 639 /** | 590 /** |
| 640 * @return {boolean} | 591 * @return {boolean} |
| 641 */ | 592 */ |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 662 var node = selectionRange.startContainer; | 613 var node = selectionRange.startContainer; |
| 663 if (!node.isSelfOrDescendant(this._element)) | 614 if (!node.isSelfOrDescendant(this._element)) |
| 664 return false; | 615 return false; |
| 665 | 616 |
| 666 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length) | 617 if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < nod e.nodeValue.length) |
| 667 return false; | 618 return false; |
| 668 | 619 |
| 669 var foundNextText = false; | 620 var foundNextText = false; |
| 670 while (node) { | 621 while (node) { |
| 671 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { | 622 if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) { |
| 672 if (foundNextText && (!this._ghostTextElement || !this._ghostTex tElement.isAncestor(node))) | 623 if (foundNextText && !this._ghostTextElement.isAncestor(node)) |
| 673 return false; | 624 return false; |
| 674 foundNextText = true; | 625 foundNextText = true; |
| 675 } | 626 } |
| 676 | 627 |
| 677 node = node.traverseNextNode(this._element); | 628 node = node.traverseNextNode(this._element); |
| 678 } | 629 } |
| 679 | 630 |
| 680 return true; | 631 return true; |
| 681 }, | 632 }, |
| 682 | 633 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 711 /** | 662 /** |
| 712 * @return {?Element} | 663 * @return {?Element} |
| 713 */ | 664 */ |
| 714 proxyElementForTests: function() | 665 proxyElementForTests: function() |
| 715 { | 666 { |
| 716 return this._proxyElement || null; | 667 return this._proxyElement || null; |
| 717 }, | 668 }, |
| 718 | 669 |
| 719 __proto__: WebInspector.Object.prototype | 670 __proto__: WebInspector.Object.prototype |
| 720 }; | 671 }; |
| OLD | NEW |