| 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 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 { | 121 { |
| 122 return spellCheckerClient().textChecker(); | 122 return spellCheckerClient().textChecker(); |
| 123 } | 123 } |
| 124 | 124 |
| 125 SpellChecker::SpellChecker(LocalFrame& frame) | 125 SpellChecker::SpellChecker(LocalFrame& frame) |
| 126 : m_frame(&frame) | 126 : m_frame(&frame) |
| 127 , m_spellCheckRequester(SpellCheckRequester::create(frame)) | 127 , m_spellCheckRequester(SpellCheckRequester::create(frame)) |
| 128 { | 128 { |
| 129 } | 129 } |
| 130 | 130 |
| 131 bool SpellChecker::isContinuousSpellCheckingEnabled() const | 131 bool SpellChecker::isSpellCheckingEnabled() const |
| 132 { | 132 { |
| 133 return spellCheckerClient().isContinuousSpellCheckingEnabled(); | 133 return spellCheckerClient().isSpellCheckingEnabled(); |
| 134 } | 134 } |
| 135 | 135 |
| 136 void SpellChecker::toggleContinuousSpellChecking() | 136 void SpellChecker::toggleSpellCheckingEnabled() |
| 137 { | 137 { |
| 138 spellCheckerClient().toggleContinuousSpellChecking(); | 138 spellCheckerClient().toggleSpellCheckingEnabled(); |
| 139 if (isContinuousSpellCheckingEnabled()) | 139 if (isSpellCheckingEnabled()) |
| 140 return; | 140 return; |
| 141 for (Frame* frame = this->frame().page()->mainFrame(); frame; frame = frame-
>tree().traverseNext()) { | 141 for (Frame* frame = this->frame().page()->mainFrame(); frame; frame = frame-
>tree().traverseNext()) { |
| 142 if (!frame->isLocalFrame()) | 142 if (!frame->isLocalFrame()) |
| 143 continue; | 143 continue; |
| 144 for (Node& node : NodeTraversal::startsAt(toLocalFrame(frame)->document(
)->rootNode())) | 144 for (Node& node : NodeTraversal::startsAt(toLocalFrame(frame)->document(
)->rootNode())) |
| 145 node.setAlreadySpellChecked(false); | 145 node.setAlreadySpellChecked(false); |
| 146 } | 146 } |
| 147 } | 147 } |
| 148 | 148 |
| 149 void SpellChecker::didBeginEditing(Element* element) | 149 void SpellChecker::didBeginEditing(Element* element) |
| 150 { | 150 { |
| 151 if (!isContinuousSpellCheckingEnabled()) | 151 if (!isSpellCheckingEnabled()) |
| 152 return; | 152 return; |
| 153 | 153 |
| 154 bool isTextField = false; | 154 bool isTextField = false; |
| 155 HTMLTextFormControlElement* enclosingHTMLTextFormControlElement = 0; | 155 HTMLTextFormControlElement* enclosingHTMLTextFormControlElement = 0; |
| 156 if (!isHTMLTextFormControlElement(*element)) | 156 if (!isHTMLTextFormControlElement(*element)) |
| 157 enclosingHTMLTextFormControlElement = enclosingTextFormControl(Position:
:firstPositionInNode(element)); | 157 enclosingHTMLTextFormControlElement = enclosingTextFormControl(Position:
:firstPositionInNode(element)); |
| 158 element = enclosingHTMLTextFormControlElement ? enclosingHTMLTextFormControl
Element : element; | 158 element = enclosingHTMLTextFormControlElement ? enclosingHTMLTextFormControl
Element : element; |
| 159 Element* parent = element; | 159 Element* parent = element; |
| 160 if (isHTMLTextFormControlElement(*element)) { | 160 if (isHTMLTextFormControlElement(*element)) { |
| 161 HTMLTextFormControlElement* textControl = toHTMLTextFormControlElement(e
lement); | 161 HTMLTextFormControlElement* textControl = toHTMLTextFormControlElement(e
lement); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 spellCheckerClient().showSpellingUI(true); | 288 spellCheckerClient().showSpellingUI(true); |
| 289 } | 289 } |
| 290 | 290 |
| 291 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) | 291 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) |
| 292 { | 292 { |
| 293 removeMarkers(movingSelection, DocumentMarker::MisspellingMarkers()); | 293 removeMarkers(movingSelection, DocumentMarker::MisspellingMarkers()); |
| 294 } | 294 } |
| 295 | 295 |
| 296 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& selecti
on) | 296 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& selecti
on) |
| 297 { | 297 { |
| 298 if (!isContinuousSpellCheckingEnabled()) | 298 if (!isSpellCheckingEnabled()) |
| 299 return; | 299 return; |
| 300 | 300 |
| 301 const EphemeralRange& range = selection.toNormalizedEphemeralRange(); | 301 const EphemeralRange& range = selection.toNormalizedEphemeralRange(); |
| 302 if (range.isNull()) | 302 if (range.isNull()) |
| 303 return; | 303 return; |
| 304 | 304 |
| 305 // If we're not in an editable node, bail. | 305 // If we're not in an editable node, bail. |
| 306 Node* editableNode = range.startPosition().computeContainerNode(); | 306 Node* editableNode = range.startPosition().computeContainerNode(); |
| 307 if (!editableNode || !hasEditableStyle(*editableNode)) | 307 if (!editableNode || !hasEditableStyle(*editableNode)) |
| 308 return; | 308 return; |
| 309 | 309 |
| 310 if (!isSpellCheckingEnabledFor(editableNode)) | 310 if (!isSpellCheckingEnabledFor(editableNode)) |
| 311 return; | 311 return; |
| 312 | 312 |
| 313 TextCheckingParagraph fullParagraphToCheck(expandRangeToSentenceBoundary(ran
ge)); | 313 TextCheckingParagraph fullParagraphToCheck(expandRangeToSentenceBoundary(ran
ge)); |
| 314 chunkAndMarkAllMisspellingsAndBadGrammar(fullParagraphToCheck); | 314 chunkAndMarkAllMisspellingsAndBadGrammar(fullParagraphToCheck); |
| 315 } | 315 } |
| 316 | 316 |
| 317 void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe
lection) | 317 void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe
lection) |
| 318 { | 318 { |
| 319 if (!isContinuousSpellCheckingEnabled()) | 319 if (!isSpellCheckingEnabled()) |
| 320 return; | 320 return; |
| 321 | 321 |
| 322 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); | 322 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); |
| 323 | 323 |
| 324 markMisspellingsAndBadGrammar(wordSelection); | 324 markMisspellingsAndBadGrammar(wordSelection); |
| 325 } | 325 } |
| 326 | 326 |
| 327 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) | 327 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) |
| 328 { | 328 { |
| 329 if (!isContinuousSpellCheckingEnabled()) | 329 if (!isSpellCheckingEnabled()) |
| 330 return; | 330 return; |
| 331 | 331 |
| 332 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); | 332 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); |
| 333 | 333 |
| 334 VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, Lef
tWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); | 334 VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, Lef
tWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); |
| 335 markMisspellingsAndBadGrammar(adjacentWords); | 335 markMisspellingsAndBadGrammar(adjacentWords); |
| 336 } | 336 } |
| 337 | 337 |
| 338 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const | 338 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const |
| 339 { | 339 { |
| (...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 635 oldSelection.start().document()->updateStyleAndLayoutIgnorePendingStylesheet
s(); | 635 oldSelection.start().document()->updateStyleAndLayoutIgnorePendingStylesheet
s(); |
| 636 return oldSelection.isContentEditable(); | 636 return oldSelection.isContentEditable(); |
| 637 } | 637 } |
| 638 | 638 |
| 639 void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio
n, FrameSelection::SetSelectionOptions options) | 639 void SpellChecker::respondToChangedSelection(const VisibleSelection& oldSelectio
n, FrameSelection::SetSelectionOptions options) |
| 640 { | 640 { |
| 641 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection"); | 641 TRACE_EVENT0("blink", "SpellChecker::respondToChangedSelection"); |
| 642 if (!isSpellCheckingEnabledFor(oldSelection)) | 642 if (!isSpellCheckingEnabledFor(oldSelection)) |
| 643 return; | 643 return; |
| 644 | 644 |
| 645 // When continuous spell checking is off, existing markers disappear after t
he selection changes. | 645 // When spell checking is off, existing markers disappear after the selectio
n changes. |
| 646 if (!isContinuousSpellCheckingEnabled()) { | 646 if (!isSpellCheckingEnabled()) { |
| 647 frame().document()->markers().removeMarkers(DocumentMarker::Spelling); | 647 frame().document()->markers().removeMarkers(DocumentMarker::Spelling); |
| 648 frame().document()->markers().removeMarkers(DocumentMarker::Grammar); | 648 frame().document()->markers().removeMarkers(DocumentMarker::Grammar); |
| 649 return; | 649 return; |
| 650 } | 650 } |
| 651 | 651 |
| 652 if (!(options & FrameSelection::CloseTyping)) | 652 if (!(options & FrameSelection::CloseTyping)) |
| 653 return; | 653 return; |
| 654 if (!shouldCheckOldSelection(oldSelection)) | 654 if (!shouldCheckOldSelection(oldSelection)) |
| 655 return; | 655 return; |
| 656 | 656 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this. | 699 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this. |
| 700 return; | 700 return; |
| 701 } | 701 } |
| 702 | 702 |
| 703 VisibleSelection empty; | 703 VisibleSelection empty; |
| 704 spellCheckOldSelection(frame().selection().selection(), empty); | 704 spellCheckOldSelection(frame().selection().selection(), empty); |
| 705 } | 705 } |
| 706 | 706 |
| 707 void SpellChecker::spellCheckOldSelection(const VisibleSelection& oldSelection,
const VisibleSelection& newAdjacentWords) | 707 void SpellChecker::spellCheckOldSelection(const VisibleSelection& oldSelection,
const VisibleSelection& newAdjacentWords) |
| 708 { | 708 { |
| 709 if (!isContinuousSpellCheckingEnabled()) | 709 if (!isSpellCheckingEnabled()) |
| 710 return; | 710 return; |
| 711 | 711 |
| 712 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); | 712 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); |
| 713 | 713 |
| 714 VisiblePosition oldStart(oldSelection.visibleStart()); | 714 VisiblePosition oldStart(oldSelection.visibleStart()); |
| 715 VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, L
eftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); | 715 VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, L
eftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); |
| 716 if (oldAdjacentWords == newAdjacentWords) | 716 if (oldAdjacentWords == newAdjacentWords) |
| 717 return; | 717 return; |
| 718 markMisspellingsAndBadGrammar(oldAdjacentWords); | 718 markMisspellingsAndBadGrammar(oldAdjacentWords); |
| 719 } | 719 } |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); | 889 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); |
| 890 paragraphStart = newParagraphStart.toParentAnchoredPosition(); | 890 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
| 891 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); | 891 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); |
| 892 firstIteration = false; | 892 firstIteration = false; |
| 893 totalLengthProcessed += currentLength; | 893 totalLengthProcessed += currentLength; |
| 894 } | 894 } |
| 895 return std::make_pair(firstFoundItem, firstFoundOffset); | 895 return std::make_pair(firstFoundItem, firstFoundOffset); |
| 896 } | 896 } |
| 897 | 897 |
| 898 } // namespace blink | 898 } // namespace blink |
| OLD | NEW |