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 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 for (Frame* frame = this->frame().page()->mainFrame(); frame; frame = frame-
>tree().traverseNext()) { | 116 for (Frame* frame = this->frame().page()->mainFrame(); frame; frame = frame-
>tree().traverseNext()) { |
117 if (!frame->isLocalFrame()) | 117 if (!frame->isLocalFrame()) |
118 continue; | 118 continue; |
119 for (Node& node : NodeTraversal::startsAt(toLocalFrame(frame)->document(
)->rootNode())) | 119 for (Node& node : NodeTraversal::startsAt(toLocalFrame(frame)->document(
)->rootNode())) |
120 node.setAlreadySpellChecked(false); | 120 node.setAlreadySpellChecked(false); |
121 } | 121 } |
122 } | 122 } |
123 | 123 |
124 void SpellChecker::didBeginEditing(Element* element) | 124 void SpellChecker::didBeginEditing(Element* element) |
125 { | 125 { |
126 if (isContinuousSpellCheckingEnabled() && unifiedTextCheckerEnabled()) { | 126 if (!isContinuousSpellCheckingEnabled()) |
127 bool isTextField = false; | 127 return; |
128 HTMLTextFormControlElement* enclosingHTMLTextFormControlElement = 0; | |
129 if (!isHTMLTextFormControlElement(*element)) | |
130 enclosingHTMLTextFormControlElement = enclosingTextFormControl(Posit
ion::firstPositionInNode(element)); | |
131 element = enclosingHTMLTextFormControlElement ? enclosingHTMLTextFormCon
trolElement : element; | |
132 Element* parent = element; | |
133 if (isHTMLTextFormControlElement(*element)) { | |
134 HTMLTextFormControlElement* textControl = toHTMLTextFormControlEleme
nt(element); | |
135 parent = textControl; | |
136 element = textControl->innerEditorElement(); | |
137 if (!element) | |
138 return; | |
139 isTextField = isHTMLInputElement(*textControl) && toHTMLInputElement
(*textControl).isTextField(); | |
140 } | |
141 | 128 |
142 if (isTextField || !parent->isAlreadySpellChecked()) { | 129 bool isTextField = false; |
143 if (EditingStrategy::editingIgnoresContent(element)) | 130 HTMLTextFormControlElement* enclosingHTMLTextFormControlElement = 0; |
144 return; | 131 if (!isHTMLTextFormControlElement(*element)) |
145 // We always recheck textfields because markers are removed from the
m on blur. | 132 enclosingHTMLTextFormControlElement = enclosingTextFormControl(Position:
:firstPositionInNode(element)); |
146 VisibleSelection selection = VisibleSelection::selectionFromContents
OfNode(element); | 133 element = enclosingHTMLTextFormControlElement ? enclosingHTMLTextFormControl
Element : element; |
147 markMisspellingsAndBadGrammar(selection); | 134 Element* parent = element; |
148 if (!isTextField) | 135 if (isHTMLTextFormControlElement(*element)) { |
149 parent->setAlreadySpellChecked(true); | 136 HTMLTextFormControlElement* textControl = toHTMLTextFormControlElement(e
lement); |
150 } | 137 parent = textControl; |
| 138 element = textControl->innerEditorElement(); |
| 139 if (!element) |
| 140 return; |
| 141 isTextField = isHTMLInputElement(*textControl) && toHTMLInputElement(*te
xtControl).isTextField(); |
| 142 } |
| 143 |
| 144 if (isTextField || !parent->isAlreadySpellChecked()) { |
| 145 if (EditingStrategy::editingIgnoresContent(element)) |
| 146 return; |
| 147 // We always recheck textfields because markers are removed from them on
blur. |
| 148 VisibleSelection selection = VisibleSelection::selectionFromContentsOfNo
de(element); |
| 149 markMisspellingsAndBadGrammar(selection); |
| 150 if (!isTextField) |
| 151 parent->setAlreadySpellChecked(true); |
151 } | 152 } |
152 } | 153 } |
153 | 154 |
154 void SpellChecker::ignoreSpelling() | 155 void SpellChecker::ignoreSpelling() |
155 { | 156 { |
156 removeMarkers(frame().selection().selection(), DocumentMarker::Spelling); | 157 removeMarkers(frame().selection().selection(), DocumentMarker::Spelling); |
157 } | 158 } |
158 | 159 |
159 void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) | 160 void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) |
160 { | 161 { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
219 if (spellingSearchStart == spellingSearchEnd) | 220 if (spellingSearchStart == spellingSearchEnd) |
220 return; // nothing to search in | 221 return; // nothing to search in |
221 | 222 |
222 // We go to the end of our first range instead of the start of it, just to b
e sure | 223 // We go to the end of our first range instead of the start of it, just to b
e sure |
223 // we don't get foiled by any word boundary problems at the start. It means
we might | 224 // we don't get foiled by any word boundary problems at the start. It means
we might |
224 // do a tiny bit more searching. | 225 // do a tiny bit more searching. |
225 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode(); | 226 Node* searchEndNodeAfterWrap = spellingSearchEnd.computeContainerNode(); |
226 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); | 227 int searchEndOffsetAfterWrap = spellingSearchEnd.offsetInContainerNode(); |
227 | 228 |
228 int misspellingOffset = 0; | 229 int misspellingOffset = 0; |
229 String misspelledWord; | 230 String misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSea
rchStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset)
; |
230 | |
231 if (unifiedTextCheckerEnabled()) { | |
232 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset); | |
233 } else { | |
234 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); | |
235 } | |
236 | 231 |
237 // If we did not find a misspelled word, wrap and try again (but don't bothe
r if we started at the beginning of the | 232 // If we did not find a misspelled word, wrap and try again (but don't bothe
r if we started at the beginning of the |
238 // block rather than at a selection). | 233 // block rather than at a selection). |
239 if (startedWithSelection && !misspelledWord) { | 234 if (startedWithSelection && !misspelledWord) { |
240 spellingSearchStart = Position::editingPositionOf(topNode, 0); | 235 spellingSearchStart = Position::editingPositionOf(topNode, 0); |
241 // going until the end of the very first chunk we tested is far enough | 236 // going until the end of the very first chunk we tested is far enough |
242 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap,
searchEndOffsetAfterWrap); | 237 spellingSearchEnd = Position::editingPositionOf(searchEndNodeAfterWrap,
searchEndOffsetAfterWrap); |
243 | 238 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSearch
Start, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset); |
244 if (unifiedTextCheckerEnabled()) { | |
245 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe
archStart, spellingSearchEnd).findFirstMisspellingOrBadGrammar(misspellingOffset
); | |
246 } else { | |
247 misspelledWord = TextCheckingHelper(spellCheckerClient(), spellingSe
archStart, spellingSearchEnd).findFirstMisspelling(misspellingOffset, false); | |
248 } | |
249 } | 239 } |
250 | 240 |
251 if (!misspelledWord.isEmpty()) { | 241 if (!misspelledWord.isEmpty()) { |
252 // We found a misspelling. Select the misspelling, update the spelling p
anel, and store | 242 // We found a misspelling. Select the misspelling, update the spelling p
anel, and store |
253 // a marker so we draw the red squiggle later. | 243 // a marker so we draw the red squiggle later. |
254 | 244 |
255 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem
eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled
Word.length()); | 245 const EphemeralRange misspellingRange = calculateCharacterSubrange(Ephem
eralRange(spellingSearchStart, spellingSearchEnd), misspellingOffset, misspelled
Word.length()); |
256 frame().selection().setSelection(VisibleSelection(misspellingRange)); | 246 frame().selection().setSelection(VisibleSelection(misspellingRange)); |
257 frame().selection().revealSelection(); | 247 frame().selection().revealSelection(); |
258 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); | 248 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); |
(...skipping 12 matching lines...) Expand all Loading... |
271 spellCheckerClient().showSpellingUI(true); | 261 spellCheckerClient().showSpellingUI(true); |
272 } | 262 } |
273 | 263 |
274 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) | 264 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) |
275 { | 265 { |
276 removeMarkers(movingSelection, DocumentMarker::MisspellingMarkers()); | 266 removeMarkers(movingSelection, DocumentMarker::MisspellingMarkers()); |
277 } | 267 } |
278 | 268 |
279 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingS
election) | 269 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingS
election) |
280 { | 270 { |
281 markMisspellingsAndBadGrammar(movingSelection, movingSelection); | 271 markAllMisspellingsAndBadGrammar(movingSelection, movingSelection); |
282 } | 272 } |
283 | 273 |
284 void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe
lection) | 274 void SpellChecker::markMisspellingsAfterLineBreak(const VisibleSelection& wordSe
lection) |
285 { | 275 { |
286 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); | |
287 | |
288 if (!unifiedTextCheckerEnabled()) { | |
289 markMisspellings(wordSelection); | |
290 return; | |
291 } | |
292 | |
293 if (!isContinuousSpellCheckingEnabled()) | 276 if (!isContinuousSpellCheckingEnabled()) |
294 return; | 277 return; |
295 | 278 |
| 279 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterLineBreak"); |
| 280 |
296 VisibleSelection wholeParagraph( | 281 VisibleSelection wholeParagraph( |
297 startOfParagraph(wordSelection.visibleStart()), | 282 startOfParagraph(wordSelection.visibleStart()), |
298 endOfParagraph(wordSelection.visibleEnd())); | 283 endOfParagraph(wordSelection.visibleEnd())); |
299 | 284 |
300 markAllMisspellingsAndBadGrammarInRanges(wordSelection.toNormalizedEphemeral
Range(), wholeParagraph.toNormalizedEphemeralRange()); | 285 markAllMisspellingsAndBadGrammar(wordSelection, wholeParagraph); |
301 } | 286 } |
302 | 287 |
303 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) | 288 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) |
304 { | 289 { |
305 if (!isContinuousSpellCheckingEnabled()) | 290 if (!isContinuousSpellCheckingEnabled()) |
306 return; | 291 return; |
307 | 292 |
308 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); | 293 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterTypingToWord"); |
309 | 294 |
310 if (unifiedTextCheckerEnabled()) { | 295 VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart, Lef
tWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); |
311 VisibleSelection adjacentWords = VisibleSelection(startOfWord(wordStart,
LeftWordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary)); | 296 VisibleSelection selectedSentence = VisibleSelection(startOfSentence(wordSta
rt), endOfSentence(wordStart)); |
312 VisibleSelection selectedSentence = VisibleSelection(startOfSentence(wor
dStart), endOfSentence(wordStart)); | 297 markAllMisspellingsAndBadGrammar(adjacentWords, selectedSentence); |
313 markAllMisspellingsAndBadGrammarInRanges(adjacentWords.toNormalizedEphem
eralRange(), selectedSentence.toNormalizedEphemeralRange()); | |
314 return; | |
315 } | |
316 | |
317 // Check spelling of one word | |
318 bool result = markMisspellings(VisibleSelection(startOfWord(wordStart, LeftW
ordIfOnBoundary), endOfWord(wordStart, RightWordIfOnBoundary))); | |
319 | |
320 if (!result) | |
321 return; | |
322 | |
323 // Check grammar of entire sentence | |
324 markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wo
rdStart))); | |
325 } | |
326 | |
327 bool SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selectio
n, bool checkSpelling) | |
328 { | |
329 // This function is called with a selection already expanded to word boundar
ies. | |
330 // Might be nice to assert that here. | |
331 | |
332 // This function is used only for as-you-type checking, so if that's off we
do nothing. Note that | |
333 // grammar checking can only be on if spell checking is also on. | |
334 if (!isContinuousSpellCheckingEnabled()) | |
335 return false; | |
336 | |
337 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsOrBadGrammar"); | |
338 | |
339 const EphemeralRange range = selection.toNormalizedEphemeralRange(); | |
340 if (range.isNull()) | |
341 return false; | |
342 | |
343 // If we're not in an editable node, bail. | |
344 Node* editableNode = range.startPosition().computeContainerNode(); | |
345 if (!editableNode || !hasEditableStyle(*editableNode)) | |
346 return false; | |
347 | |
348 if (!isSpellCheckingEnabledFor(editableNode)) | |
349 return false; | |
350 | |
351 TextCheckingHelper checker(spellCheckerClient(), range.startPosition(), rang
e.endPosition()); | |
352 if (checkSpelling) | |
353 return checker.markAllMisspellings(); | |
354 | |
355 return false; | |
356 } | 298 } |
357 | 299 |
358 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const | 300 bool SpellChecker::isSpellCheckingEnabledFor(Node* node) const |
359 { | 301 { |
360 if (!node) | 302 if (!node) |
361 return false; | 303 return false; |
362 const Element* focusedElement = node->isElementNode() ? toElement(node) : no
de->parentElement(); | 304 const Element* focusedElement = node->isElementNode() ? toElement(node) : no
de->parentElement(); |
363 if (!focusedElement) | 305 if (!focusedElement) |
364 return false; | 306 return false; |
365 return focusedElement->isSpellCheckingEnabled(); | 307 return focusedElement->isSpellCheckingEnabled(); |
(...skipping 14 matching lines...) Expand all Loading... |
380 if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->
type() == InputTypeNames::password) | 322 if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->
type() == InputTypeNames::password) |
381 return false; | 323 return false; |
382 } | 324 } |
383 if (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf(*sele
ction.start().anchorNode())) { | 325 if (HTMLElement* element = Traversal<HTMLElement>::firstAncestorOrSelf(*sele
ction.start().anchorNode())) { |
384 if (element->spellcheck()) | 326 if (element->spellcheck()) |
385 return true; | 327 return true; |
386 } | 328 } |
387 return false; | 329 return false; |
388 } | 330 } |
389 | 331 |
390 bool SpellChecker::markMisspellings(const VisibleSelection& selection) | 332 void SpellChecker::markAllMisspellingsAndBadGrammar(const VisibleSelection& spel
lingSelection, const VisibleSelection& grammarSelection) |
391 { | 333 { |
392 return markMisspellingsOrBadGrammar(selection, true); | 334 if (!isContinuousSpellCheckingEnabled()) |
393 } | 335 return; |
394 | |
395 void SpellChecker::markBadGrammar(const VisibleSelection& selection) | |
396 { | |
397 markMisspellingsOrBadGrammar(selection, false); | |
398 } | |
399 | |
400 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(const EphemeralRange
& spellingRange, const EphemeralRange& grammarRange) | |
401 { | |
402 DCHECK(unifiedTextCheckerEnabled()); | |
403 | 336 |
404 // This function is called with selections already expanded to word boundari
es. | 337 // This function is called with selections already expanded to word boundari
es. |
| 338 // This function is triggered by selection change, in which case we check |
| 339 // spelling and grammar, but don't autocorrect misspellings. |
| 340 |
| 341 const EphemeralRange& spellingRange = spellingSelection.toNormalizedEphemera
lRange(); |
| 342 const EphemeralRange& grammarRange = grammarSelection.toNormalizedEphemeralR
ange(); |
405 if (spellingRange.isNull() || grammarRange.isNull()) | 343 if (spellingRange.isNull() || grammarRange.isNull()) |
406 return; | 344 return; |
407 | 345 |
408 // If we're not in an editable node, bail. | 346 // If we're not in an editable node, bail. |
409 Node* editableNode = spellingRange.startPosition().computeContainerNode(); | 347 Node* editableNode = spellingRange.startPosition().computeContainerNode(); |
410 if (!editableNode || !hasEditableStyle(*editableNode)) | 348 if (!editableNode || !hasEditableStyle(*editableNode)) |
411 return; | 349 return; |
412 | 350 |
413 if (!isSpellCheckingEnabledFor(editableNode)) | 351 if (!isSpellCheckingEnabledFor(editableNode)) |
414 return; | 352 return; |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
573 if (adjustSelectionForParagraphBoundaries) | 511 if (adjustSelectionForParagraphBoundaries) |
574 frame().selection().modify(FrameSelection::AlterationMove, Direc
tionForward, CharacterGranularity); | 512 frame().selection().modify(FrameSelection::AlterationMove, Direc
tionForward, CharacterGranularity); |
575 } else { | 513 } else { |
576 // If this fails for any reason, the fallback is to go one position
beyond the last replacement | 514 // If this fails for any reason, the fallback is to go one position
beyond the last replacement |
577 frame().selection().moveTo(frame().selection().selection().visibleEn
d()); | 515 frame().selection().moveTo(frame().selection().selection().visibleEn
d()); |
578 frame().selection().modify(FrameSelection::AlterationMove, Direction
Forward, CharacterGranularity); | 516 frame().selection().modify(FrameSelection::AlterationMove, Direction
Forward, CharacterGranularity); |
579 } | 517 } |
580 } | 518 } |
581 } | 519 } |
582 | 520 |
583 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellin
gSelection, const VisibleSelection& grammarSelection) | |
584 { | |
585 if (unifiedTextCheckerEnabled()) { | |
586 if (!isContinuousSpellCheckingEnabled()) | |
587 return; | |
588 | |
589 // markMisspellingsAndBadGrammar() is triggered by selection change, in
which case we check spelling and grammar, but don't autocorrect misspellings. | |
590 markAllMisspellingsAndBadGrammarInRanges(spellingSelection.toNormalizedE
phemeralRange(), grammarSelection.toNormalizedEphemeralRange()); | |
591 return; | |
592 } | |
593 | |
594 markMisspellings(spellingSelection); | |
595 if (isContinuousSpellCheckingEnabled()) | |
596 markBadGrammar(grammarSelection); | |
597 } | |
598 | |
599 void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
ctionAtWordBoundary) | 521 void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
ctionAtWordBoundary) |
600 { | 522 { |
601 DCHECK(frame().selection().isAvailable()); | 523 DCHECK(frame().selection().isAvailable()); |
602 TRACE_EVENT0("blink", "SpellChecker::updateMarkersForWordsAffectedByEditing"
); | 524 TRACE_EVENT0("blink", "SpellChecker::updateMarkersForWordsAffectedByEditing"
); |
603 if (!isSpellCheckingEnabledFor(frame().selection().selection())) | 525 if (!isSpellCheckingEnabledFor(frame().selection().selection())) |
604 return; | 526 return; |
605 | 527 |
606 // We want to remove the markers from a word if an editing command will chan
ge the word. This can happen in one of | 528 // We want to remove the markers from a word if an editing command will chan
ge the word. This can happen in one of |
607 // several scenarios: | 529 // several scenarios: |
608 // 1. Insert in the middle of a word. | 530 // 1. Insert in the middle of a word. |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
681 void SpellChecker::didEndEditingOnTextField(Element* e) | 603 void SpellChecker::didEndEditingOnTextField(Element* e) |
682 { | 604 { |
683 TRACE_EVENT0("blink", "SpellChecker::didEndEditingOnTextField"); | 605 TRACE_EVENT0("blink", "SpellChecker::didEndEditingOnTextField"); |
684 | 606 |
685 // Remove markers when deactivating a selection in an <input type="text"/>. | 607 // Remove markers when deactivating a selection in an <input type="text"/>. |
686 // Prevent new ones from appearing too. | 608 // Prevent new ones from appearing too. |
687 m_spellCheckRequester->cancelCheck(); | 609 m_spellCheckRequester->cancelCheck(); |
688 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl
ement(e); | 610 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl
ement(e); |
689 HTMLElement* innerEditor = textFormControlElement->innerEditorElement(); | 611 HTMLElement* innerEditor = textFormControlElement->innerEditorElement(); |
690 DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling); | 612 DocumentMarker::MarkerTypes markerTypes(DocumentMarker::Spelling); |
691 if (unifiedTextCheckerEnabled()) | 613 markerTypes.add(DocumentMarker::Grammar); |
692 markerTypes.add(DocumentMarker::Grammar); | |
693 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) | 614 for (Node& node : NodeTraversal::inclusiveDescendantsOf(*innerEditor)) |
694 frame().document()->markers().removeMarkers(&node, markerTypes); | 615 frame().document()->markers().removeMarkers(&node, markerTypes); |
695 } | 616 } |
696 | 617 |
697 void SpellChecker::replaceMisspelledRange(const String& text) | 618 void SpellChecker::replaceMisspelledRange(const String& text) |
698 { | 619 { |
699 EphemeralRange caretRange = frame().selection().selection().toNormalizedEphe
meralRange(); | 620 EphemeralRange caretRange = frame().selection().selection().toNormalizedEphe
meralRange(); |
700 if (caretRange.isNull()) | 621 if (caretRange.isNull()) |
701 return; | 622 return; |
702 DocumentMarkerVector markers = frame().document()->markers().markersInRange(
caretRange, DocumentMarker::MisspellingMarkers()); | 623 DocumentMarkerVector markers = frame().document()->markers().markersInRange(
caretRange, DocumentMarker::MisspellingMarkers()); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this. | 705 // textFieldDidEndEditing() and textFieldDidBeginEditing() handle this. |
785 return; | 706 return; |
786 } | 707 } |
787 | 708 |
788 VisibleSelection empty; | 709 VisibleSelection empty; |
789 spellCheckOldSelection(frame().selection().selection(), empty); | 710 spellCheckOldSelection(frame().selection().selection(), empty); |
790 } | 711 } |
791 | 712 |
792 void SpellChecker::spellCheckOldSelection(const VisibleSelection& oldSelection,
const VisibleSelection& newAdjacentWords) | 713 void SpellChecker::spellCheckOldSelection(const VisibleSelection& oldSelection,
const VisibleSelection& newAdjacentWords) |
793 { | 714 { |
| 715 if (!isContinuousSpellCheckingEnabled()) |
| 716 return; |
| 717 |
794 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); | 718 TRACE_EVENT0("blink", "SpellChecker::spellCheckOldSelection"); |
795 | 719 |
796 VisiblePosition oldStart(oldSelection.visibleStart()); | 720 VisiblePosition oldStart(oldSelection.visibleStart()); |
797 VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, L
eftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); | 721 VisibleSelection oldAdjacentWords = VisibleSelection(startOfWord(oldStart, L
eftWordIfOnBoundary), endOfWord(oldStart, RightWordIfOnBoundary)); |
798 if (oldAdjacentWords == newAdjacentWords) | 722 if (oldAdjacentWords == newAdjacentWords) |
799 return; | 723 return; |
800 if (isContinuousSpellCheckingEnabled()) { | 724 VisibleSelection selectedSentence = VisibleSelection(startOfSentence(oldStar
t), endOfSentence(oldStart)); |
801 VisibleSelection selectedSentence = VisibleSelection(startOfSentence(old
Start), endOfSentence(oldStart)); | 725 markAllMisspellingsAndBadGrammar(oldAdjacentWords, selectedSentence); |
802 markMisspellingsAndBadGrammar(oldAdjacentWords, selectedSentence); | |
803 return; | |
804 } | |
805 markMisspellingsAndBadGrammar(oldAdjacentWords, oldAdjacentWords); | |
806 } | 726 } |
807 | 727 |
808 static Node* findFirstMarkable(Node* node) | 728 static Node* findFirstMarkable(Node* node) |
809 { | 729 { |
810 while (node) { | 730 while (node) { |
811 if (!node->layoutObject()) | 731 if (!node->layoutObject()) |
812 return 0; | 732 return 0; |
813 if (node->layoutObject()->isText()) | 733 if (node->layoutObject()->isText()) |
814 return node; | 734 return node; |
815 if (node->layoutObject()->isTextControl()) | 735 if (node->layoutObject()->isTextControl()) |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
847 } | 767 } |
848 | 768 |
849 void SpellChecker::removeMarkers(const VisibleSelection& selection, DocumentMark
er::MarkerTypes markerTypes) | 769 void SpellChecker::removeMarkers(const VisibleSelection& selection, DocumentMark
er::MarkerTypes markerTypes) |
850 { | 770 { |
851 const EphemeralRange range = selection.toNormalizedEphemeralRange(); | 771 const EphemeralRange range = selection.toNormalizedEphemeralRange(); |
852 if (range.isNull()) | 772 if (range.isNull()) |
853 return; | 773 return; |
854 frame().document()->markers().removeMarkers(range, markerTypes); | 774 frame().document()->markers().removeMarkers(range, markerTypes); |
855 } | 775 } |
856 | 776 |
857 bool SpellChecker::unifiedTextCheckerEnabled() const | |
858 { | |
859 return blink::unifiedTextCheckerEnabled(m_frame); | |
860 } | |
861 | |
862 void SpellChecker::cancelCheck() | 777 void SpellChecker::cancelCheck() |
863 { | 778 { |
864 m_spellCheckRequester->cancelCheck(); | 779 m_spellCheckRequester->cancelCheck(); |
865 } | 780 } |
866 | 781 |
867 void SpellChecker::requestTextChecking(const Element& element) | 782 void SpellChecker::requestTextChecking(const Element& element) |
868 { | 783 { |
869 const EphemeralRange rangeToCheck = EphemeralRange::rangeOfContents(element)
; | 784 const EphemeralRange rangeToCheck = EphemeralRange::rangeOfContents(element)
; |
870 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingProcessBatch, rangeToCheck, rangeToCheck)); | 785 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingProcessBatch, rangeToCheck, rangeToCheck)); |
871 } | 786 } |
872 | 787 |
873 DEFINE_TRACE(SpellChecker) | 788 DEFINE_TRACE(SpellChecker) |
874 { | 789 { |
875 visitor->trace(m_frame); | 790 visitor->trace(m_frame); |
876 visitor->trace(m_spellCheckRequester); | 791 visitor->trace(m_spellCheckRequester); |
877 } | 792 } |
878 | 793 |
879 void SpellChecker::prepareForLeakDetection() | 794 void SpellChecker::prepareForLeakDetection() |
880 { | 795 { |
881 m_spellCheckRequester->prepareForLeakDetection(); | 796 m_spellCheckRequester->prepareForLeakDetection(); |
882 } | 797 } |
883 | 798 |
884 } // namespace blink | 799 } // namespace blink |
OLD | NEW |