OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved. |
3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 3 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
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 * 1. Redistributions of source code must retain the above copyright | 8 * 1. Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright | 10 * 2. Redistributions in binary form must reproduce the above copyright |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 // TODO(xiaochengh): |sentenceStart > range.startPosition()| is possible, | 127 // TODO(xiaochengh): |sentenceStart > range.startPosition()| is possible, |
128 // which would trigger a DCHECK in EphemeralRange's constructor if we return | 128 // which would trigger a DCHECK in EphemeralRange's constructor if we return |
129 // it directly. However, this shouldn't happen and needs to be fixed. | 129 // it directly. However, this shouldn't happen and needs to be fixed. |
130 return expandEndToSentenceBoundary(EphemeralRange( | 130 return expandEndToSentenceBoundary(EphemeralRange( |
131 sentenceStart.isNotNull() && sentenceStart < range.startPosition() | 131 sentenceStart.isNotNull() && sentenceStart < range.startPosition() |
132 ? sentenceStart | 132 ? sentenceStart |
133 : range.startPosition(), | 133 : range.startPosition(), |
134 range.endPosition())); | 134 range.endPosition())); |
135 } | 135 } |
136 | 136 |
| 137 SelectionInDOMTree selectWord(const VisiblePosition& position) { |
| 138 // TODO(yosin): We should fix |startOfWord()| and |endOfWord()| not to return |
| 139 // null position. |
| 140 const VisiblePosition& start = startOfWord(position, LeftWordIfOnBoundary); |
| 141 const VisiblePosition& end = endOfWord(position, RightWordIfOnBoundary); |
| 142 return SelectionInDOMTree::Builder() |
| 143 .setBaseAndExtentDeprecated(start.deepEquivalent(), end.deepEquivalent()) |
| 144 .setAffinity(start.affinity()) |
| 145 .build(); |
| 146 } |
| 147 |
137 } // namespace | 148 } // namespace |
138 | 149 |
139 SpellChecker* SpellChecker::create(LocalFrame& frame) { | 150 SpellChecker* SpellChecker::create(LocalFrame& frame) { |
140 return new SpellChecker(frame); | 151 return new SpellChecker(frame); |
141 } | 152 } |
142 | 153 |
143 static SpellCheckerClient& emptySpellCheckerClient() { | 154 static SpellCheckerClient& emptySpellCheckerClient() { |
144 DEFINE_STATIC_LOCAL(EmptySpellCheckerClient, client, ()); | 155 DEFINE_STATIC_LOCAL(EmptySpellCheckerClient, client, ()); |
145 return client; | 156 return client; |
146 } | 157 } |
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 VisiblePosition start = createVisiblePosition( | 448 VisiblePosition start = createVisiblePosition( |
438 cmd.endingSelection().start(), cmd.endingSelection().affinity()); | 449 cmd.endingSelection().start(), cmd.endingSelection().affinity()); |
439 VisiblePosition previous = previousPositionOf(start); | 450 VisiblePosition previous = previousPositionOf(start); |
440 | 451 |
441 VisiblePosition wordStartOfPrevious = | 452 VisiblePosition wordStartOfPrevious = |
442 startOfWord(previous, LeftWordIfOnBoundary); | 453 startOfWord(previous, LeftWordIfOnBoundary); |
443 | 454 |
444 if (cmd.commandTypeOfOpenCommand() == | 455 if (cmd.commandTypeOfOpenCommand() == |
445 TypingCommand::InsertParagraphSeparator) { | 456 TypingCommand::InsertParagraphSeparator) { |
446 VisiblePosition nextWord = nextWordPosition(start); | 457 VisiblePosition nextWord = nextWordPosition(start); |
447 VisibleSelection words = | 458 // TODO(yosin): We should make |endOfWord()| not to return null position. |
448 createVisibleSelection(wordStartOfPrevious, endOfWord(nextWord)); | 459 VisibleSelection words = createVisibleSelection( |
| 460 SelectionInDOMTree::Builder() |
| 461 .setBaseAndExtentDeprecated(wordStartOfPrevious.deepEquivalent(), |
| 462 endOfWord(nextWord).deepEquivalent()) |
| 463 .setAffinity(wordStartOfPrevious.affinity()) |
| 464 .build()); |
449 markMisspellingsAfterLineBreak(words); | 465 markMisspellingsAfterLineBreak(words); |
450 return; | 466 return; |
451 } | 467 } |
452 | 468 |
453 if (previous.isNull()) | 469 if (previous.isNull()) |
454 return; | 470 return; |
455 VisiblePosition currentWordStart = startOfWord(start, LeftWordIfOnBoundary); | 471 VisiblePosition currentWordStart = startOfWord(start, LeftWordIfOnBoundary); |
456 if (wordStartOfPrevious.deepEquivalent() == currentWordStart.deepEquivalent()) | 472 if (wordStartOfPrevious.deepEquivalent() == currentWordStart.deepEquivalent()) |
457 return; | 473 return; |
458 markMisspellingsAfterTypingToWord(wordStartOfPrevious); | 474 markMisspellingsAfterTypingToWord(wordStartOfPrevious); |
459 } | 475 } |
460 | 476 |
461 void SpellChecker::markMisspellingsAfterLineBreak( | 477 void SpellChecker::markMisspellingsAfterLineBreak( |
462 const VisibleSelection& wordSelection) { | 478 const VisibleSelection& wordSelection) { |
463 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); | 479 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); |
464 | 480 |
465 markMisspellingsAndBadGrammar(wordSelection); | 481 markMisspellingsAndBadGrammar(wordSelection); |
466 } | 482 } |
467 | 483 |
468 void SpellChecker::markMisspellingsAfterTypingToWord( | 484 void SpellChecker::markMisspellingsAfterTypingToWord( |
469 const VisiblePosition& wordStart) { | 485 const VisiblePosition& wordStart) { |
470 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); | 486 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); |
471 | 487 |
472 VisibleSelection adjacentWords = | 488 VisibleSelection adjacentWords = |
473 createVisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundary), | 489 createVisibleSelection(selectWord(wordStart)); |
474 endOfWord(wordStart, RightWordIfOnBoundary)); | |
475 markMisspellingsAndBadGrammar(adjacentWords); | 490 markMisspellingsAndBadGrammar(adjacentWords); |
476 } | 491 } |
477 | 492 |
478 bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const { | 493 bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const { |
479 Node* focusedNode = frame().selection().start().anchorNode(); | 494 Node* focusedNode = frame().selection().start().anchorNode(); |
480 if (!focusedNode) | 495 if (!focusedNode) |
481 return false; | 496 return false; |
482 const Element* focusedElement = focusedNode->isElementNode() | 497 const Element* focusedElement = focusedNode->isElementNode() |
483 ? toElement(focusedNode) | 498 ? toElement(focusedNode) |
484 : focusedNode->parentElement(); | 499 : focusedNode->parentElement(); |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 | 876 |
862 VisibleSelection newAdjacentWords; | 877 VisibleSelection newAdjacentWords; |
863 const VisibleSelection newSelection = frame().selection().selection(); | 878 const VisibleSelection newSelection = frame().selection().selection(); |
864 if (isSelectionInTextFormControl(newSelection)) { | 879 if (isSelectionInTextFormControl(newSelection)) { |
865 const Position newStart = newSelection.start(); | 880 const Position newStart = newSelection.start(); |
866 newAdjacentWords.setWithoutValidation( | 881 newAdjacentWords.setWithoutValidation( |
867 HTMLTextFormControlElement::startOfWord(newStart), | 882 HTMLTextFormControlElement::startOfWord(newStart), |
868 HTMLTextFormControlElement::endOfWord(newStart)); | 883 HTMLTextFormControlElement::endOfWord(newStart)); |
869 } else { | 884 } else { |
870 if (newSelection.isContentEditable()) { | 885 if (newSelection.isContentEditable()) { |
871 const VisiblePosition newStart(newSelection.visibleStart()); | |
872 newAdjacentWords = | 886 newAdjacentWords = |
873 createVisibleSelection(startOfWord(newStart, LeftWordIfOnBoundary), | 887 createVisibleSelection(selectWord(newSelection.visibleStart())); |
874 endOfWord(newStart, RightWordIfOnBoundary)); | |
875 } | 888 } |
876 } | 889 } |
877 | 890 |
878 // When typing we check spelling elsewhere, so don't redo it here. | 891 // When typing we check spelling elsewhere, so don't redo it here. |
879 // If this is a change in selection resulting from a delete operation, | 892 // If this is a change in selection resulting from a delete operation, |
880 // oldSelection may no longer be in the document. | 893 // oldSelection may no longer be in the document. |
881 // FIXME(http://crbug.com/382809): if oldSelection is on a textarea | 894 // FIXME(http://crbug.com/382809): if oldSelection is on a textarea |
882 // element, we cause synchronous layout. | 895 // element, we cause synchronous layout. |
883 spellCheckOldSelection(oldSelectionStart, newAdjacentWords); | 896 spellCheckOldSelection(oldSelectionStart, newAdjacentWords); |
884 } | 897 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 void SpellChecker::spellCheckOldSelection( | 935 void SpellChecker::spellCheckOldSelection( |
923 const Position& oldSelectionStart, | 936 const Position& oldSelectionStart, |
924 const VisibleSelection& newAdjacentWords) { | 937 const VisibleSelection& newAdjacentWords) { |
925 if (!isSpellCheckingEnabled()) | 938 if (!isSpellCheckingEnabled()) |
926 return; | 939 return; |
927 | 940 |
928 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); | 941 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); |
929 | 942 |
930 VisiblePosition oldStart = createVisiblePosition(oldSelectionStart); | 943 VisiblePosition oldStart = createVisiblePosition(oldSelectionStart); |
931 VisibleSelection oldAdjacentWords = | 944 VisibleSelection oldAdjacentWords = |
932 createVisibleSelection(startOfWord(oldStart, LeftWordIfOnBoundary), | 945 createVisibleSelection(selectWord(oldStart)); |
933 endOfWord(oldStart, RightWordIfOnBoundary)); | |
934 if (oldAdjacentWords == newAdjacentWords) | 946 if (oldAdjacentWords == newAdjacentWords) |
935 return; | 947 return; |
936 markMisspellingsAndBadGrammar(oldAdjacentWords); | 948 markMisspellingsAndBadGrammar(oldAdjacentWords); |
937 } | 949 } |
938 | 950 |
939 static Node* findFirstMarkable(Node* node) { | 951 static Node* findFirstMarkable(Node* node) { |
940 while (node) { | 952 while (node) { |
941 if (!node->layoutObject()) | 953 if (!node->layoutObject()) |
942 return 0; | 954 return 0; |
943 if (node->layoutObject()->isText()) | 955 if (node->layoutObject()->isText()) |
(...skipping 185 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1129 startOfNextParagraph(createVisiblePosition(paragraphEnd)); | 1141 startOfNextParagraph(createVisiblePosition(paragraphEnd)); |
1130 paragraphStart = newParagraphStart.toParentAnchoredPosition(); | 1142 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
1131 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPosition(); | 1143 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPosition(); |
1132 firstIteration = false; | 1144 firstIteration = false; |
1133 totalLengthProcessed += currentLength; | 1145 totalLengthProcessed += currentLength; |
1134 } | 1146 } |
1135 return std::make_pair(firstFoundItem, firstFoundOffset); | 1147 return std::make_pair(firstFoundItem, firstFoundOffset); |
1136 } | 1148 } |
1137 | 1149 |
1138 } // namespace blink | 1150 } // namespace blink |
OLD | NEW |