| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 VisibleSelection selection = VisibleSelection::selectionFromContents
OfNode(element); | 136 VisibleSelection selection = VisibleSelection::selectionFromContents
OfNode(element); |
| 137 markMisspellingsAndBadGrammar(selection); | 137 markMisspellingsAndBadGrammar(selection); |
| 138 if (!isTextField) | 138 if (!isTextField) |
| 139 parent->setAlreadySpellChecked(true); | 139 parent->setAlreadySpellChecked(true); |
| 140 } | 140 } |
| 141 } | 141 } |
| 142 } | 142 } |
| 143 | 143 |
| 144 void SpellChecker::ignoreSpelling() | 144 void SpellChecker::ignoreSpelling() |
| 145 { | 145 { |
| 146 if (RefPtr<Range> selectedRange = m_frame.selection().toNormalizedRange()) | 146 if (RefPtrWillBeRawPtr<Range> selectedRange = m_frame.selection().toNormaliz
edRange()) |
| 147 m_frame.document()->markers().removeMarkers(selectedRange.get(), Documen
tMarker::Spelling); | 147 m_frame.document()->markers().removeMarkers(selectedRange.get(), Documen
tMarker::Spelling); |
| 148 } | 148 } |
| 149 | 149 |
| 150 void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) | 150 void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection) |
| 151 { | 151 { |
| 152 // The basic approach is to search in two phases - from the selection end to
the end of the doc, and | 152 // The basic approach is to search in two phases - from the selection end to
the end of the doc, and |
| 153 // then we wrap and search from the doc start to (approximately) where we st
arted. | 153 // then we wrap and search from the doc start to (approximately) where we st
arted. |
| 154 | 154 |
| 155 // Start at the end of the selection, search to edge of document. Starting a
t the selection end makes | 155 // Start at the end of the selection, search to edge of document. Starting a
t the selection end makes |
| 156 // repeated "check spelling" commands work. | 156 // repeated "check spelling" commands work. |
| 157 VisibleSelection selection(m_frame.selection().selection()); | 157 VisibleSelection selection(m_frame.selection().selection()); |
| 158 RefPtr<Range> spellingSearchRange(rangeOfContents(m_frame.document())); | 158 RefPtrWillBeRawPtr<Range> spellingSearchRange(rangeOfContents(m_frame.docume
nt())); |
| 159 | 159 |
| 160 bool startedWithSelection = false; | 160 bool startedWithSelection = false; |
| 161 if (selection.start().deprecatedNode()) { | 161 if (selection.start().deprecatedNode()) { |
| 162 startedWithSelection = true; | 162 startedWithSelection = true; |
| 163 if (startBeforeSelection) { | 163 if (startBeforeSelection) { |
| 164 VisiblePosition start(selection.visibleStart()); | 164 VisiblePosition start(selection.visibleStart()); |
| 165 // We match AppKit's rule: Start 1 character before the selection. | 165 // We match AppKit's rule: Start 1 character before the selection. |
| 166 VisiblePosition oneBeforeStart = start.previous(); | 166 VisiblePosition oneBeforeStart = start.previous(); |
| 167 setStart(spellingSearchRange.get(), oneBeforeStart.isNotNull() ? one
BeforeStart : start); | 167 setStart(spellingSearchRange.get(), oneBeforeStart.isNotNull() ? one
BeforeStart : start); |
| 168 } else { | 168 } else { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 | 206 |
| 207 // We go to the end of our first range instead of the start of it, just to b
e sure | 207 // We go to the end of our first range instead of the start of it, just to b
e sure |
| 208 // we don't get foiled by any word boundary problems at the start. It means
we might | 208 // we don't get foiled by any word boundary problems at the start. It means
we might |
| 209 // do a tiny bit more searching. | 209 // do a tiny bit more searching. |
| 210 Node* searchEndNodeAfterWrap = spellingSearchRange->endContainer(); | 210 Node* searchEndNodeAfterWrap = spellingSearchRange->endContainer(); |
| 211 int searchEndOffsetAfterWrap = spellingSearchRange->endOffset(); | 211 int searchEndOffsetAfterWrap = spellingSearchRange->endOffset(); |
| 212 | 212 |
| 213 int misspellingOffset = 0; | 213 int misspellingOffset = 0; |
| 214 GrammarDetail grammarDetail; | 214 GrammarDetail grammarDetail; |
| 215 int grammarPhraseOffset = 0; | 215 int grammarPhraseOffset = 0; |
| 216 RefPtr<Range> grammarSearchRange; | 216 RefPtrWillBeRawPtr<Range> grammarSearchRange = nullptr; |
| 217 String badGrammarPhrase; | 217 String badGrammarPhrase; |
| 218 String misspelledWord; | 218 String misspelledWord; |
| 219 | 219 |
| 220 bool isSpelling = true; | 220 bool isSpelling = true; |
| 221 int foundOffset = 0; | 221 int foundOffset = 0; |
| 222 String foundItem; | 222 String foundItem; |
| 223 RefPtr<Range> firstMisspellingRange; | 223 RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
| 224 if (unifiedTextCheckerEnabled()) { | 224 if (unifiedTextCheckerEnabled()) { |
| 225 grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION); | 225 grammarSearchRange = spellingSearchRange->cloneRange(IGNORE_EXCEPTION); |
| 226 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchRange
).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, found
Offset, grammarDetail); | 226 foundItem = TextCheckingHelper(spellCheckerClient(), spellingSearchRange
).findFirstMisspellingOrBadGrammar(isGrammarCheckingEnabled(), isSpelling, found
Offset, grammarDetail); |
| 227 if (isSpelling) { | 227 if (isSpelling) { |
| 228 misspelledWord = foundItem; | 228 misspelledWord = foundItem; |
| 229 misspellingOffset = foundOffset; | 229 misspellingOffset = foundOffset; |
| 230 } else { | 230 } else { |
| 231 badGrammarPhrase = foundItem; | 231 badGrammarPhrase = foundItem; |
| 232 grammarPhraseOffset = foundOffset; | 232 grammarPhraseOffset = foundOffset; |
| 233 } | 233 } |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 279 | 279 |
| 280 if (!badGrammarPhrase.isEmpty()) { | 280 if (!badGrammarPhrase.isEmpty()) { |
| 281 // We found bad grammar. Since we only searched for bad grammar up to th
e first misspelled word, the bad grammar | 281 // We found bad grammar. Since we only searched for bad grammar up to th
e first misspelled word, the bad grammar |
| 282 // takes precedence and we ignore any potential misspelled word. Select
the grammar detail, update the spelling | 282 // takes precedence and we ignore any potential misspelled word. Select
the grammar detail, update the spelling |
| 283 // panel, and store a marker so we draw the green squiggle later. | 283 // panel, and store a marker so we draw the green squiggle later. |
| 284 | 284 |
| 285 ASSERT(badGrammarPhrase.length() > 0); | 285 ASSERT(badGrammarPhrase.length() > 0); |
| 286 ASSERT(grammarDetail.location != -1 && grammarDetail.length > 0); | 286 ASSERT(grammarDetail.location != -1 && grammarDetail.length > 0); |
| 287 | 287 |
| 288 // FIXME 4859190: This gets confused with doubled punctuation at the end
of a paragraph | 288 // FIXME 4859190: This gets confused with doubled punctuation at the end
of a paragraph |
| 289 RefPtr<Range> badGrammarRange = TextIterator::subrange(grammarSearchRang
e.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail.length); | 289 RefPtrWillBeRawPtr<Range> badGrammarRange = TextIterator::subrange(gramm
arSearchRange.get(), grammarPhraseOffset + grammarDetail.location, grammarDetail
.length); |
| 290 m_frame.selection().setSelection(VisibleSelection(badGrammarRange.get(),
SEL_DEFAULT_AFFINITY)); | 290 m_frame.selection().setSelection(VisibleSelection(badGrammarRange.get(),
SEL_DEFAULT_AFFINITY)); |
| 291 m_frame.selection().revealSelection(); | 291 m_frame.selection().revealSelection(); |
| 292 | 292 |
| 293 m_frame.document()->markers().addMarker(badGrammarRange.get(), DocumentM
arker::Grammar, grammarDetail.userDescription); | 293 m_frame.document()->markers().addMarker(badGrammarRange.get(), DocumentM
arker::Grammar, grammarDetail.userDescription); |
| 294 } else if (!misspelledWord.isEmpty()) { | 294 } else if (!misspelledWord.isEmpty()) { |
| 295 // We found a misspelling, but not any earlier bad grammar. Select the m
isspelling, update the spelling panel, and store | 295 // We found a misspelling, but not any earlier bad grammar. Select the m
isspelling, update the spelling panel, and store |
| 296 // a marker so we draw the red squiggle later. | 296 // a marker so we draw the red squiggle later. |
| 297 | 297 |
| 298 RefPtr<Range> misspellingRange = TextIterator::subrange(spellingSearchRa
nge.get(), misspellingOffset, misspelledWord.length()); | 298 RefPtrWillBeRawPtr<Range> misspellingRange = TextIterator::subrange(spel
lingSearchRange.get(), misspellingOffset, misspelledWord.length()); |
| 299 m_frame.selection().setSelection(VisibleSelection(misspellingRange.get()
, DOWNSTREAM)); | 299 m_frame.selection().setSelection(VisibleSelection(misspellingRange.get()
, DOWNSTREAM)); |
| 300 m_frame.selection().revealSelection(); | 300 m_frame.selection().revealSelection(); |
| 301 | 301 |
| 302 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); | 302 spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord); |
| 303 m_frame.document()->markers().addMarker(misspellingRange.get(), Document
Marker::Spelling); | 303 m_frame.document()->markers().addMarker(misspellingRange.get(), Document
Marker::Spelling); |
| 304 } | 304 } |
| 305 } | 305 } |
| 306 | 306 |
| 307 void SpellChecker::showSpellingGuessPanel() | 307 void SpellChecker::showSpellingGuessPanel() |
| 308 { | 308 { |
| 309 if (spellCheckerClient().spellingUIIsShowing()) { | 309 if (spellCheckerClient().spellingUIIsShowing()) { |
| 310 spellCheckerClient().showSpellingUI(false); | 310 spellCheckerClient().showSpellingUI(false); |
| 311 return; | 311 return; |
| 312 } | 312 } |
| 313 | 313 |
| 314 advanceToNextMisspelling(true); | 314 advanceToNextMisspelling(true); |
| 315 spellCheckerClient().showSpellingUI(true); | 315 spellCheckerClient().showSpellingUI(true); |
| 316 } | 316 } |
| 317 | 317 |
| 318 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) | 318 void SpellChecker::clearMisspellingsAndBadGrammar(const VisibleSelection &moving
Selection) |
| 319 { | 319 { |
| 320 RefPtr<Range> selectedRange = movingSelection.toNormalizedRange(); | 320 RefPtrWillBeRawPtr<Range> selectedRange = movingSelection.toNormalizedRange(
); |
| 321 if (selectedRange) | 321 if (selectedRange) |
| 322 m_frame.document()->markers().removeMarkers(selectedRange.get(), Documen
tMarker::MisspellingMarkers()); | 322 m_frame.document()->markers().removeMarkers(selectedRange.get(), Documen
tMarker::MisspellingMarkers()); |
| 323 } | 323 } |
| 324 | 324 |
| 325 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingS
election) | 325 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingS
election) |
| 326 { | 326 { |
| 327 markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnab
led() && isGrammarCheckingEnabled(), movingSelection); | 327 markMisspellingsAndBadGrammar(movingSelection, isContinuousSpellCheckingEnab
led() && isGrammarCheckingEnabled(), movingSelection); |
| 328 } | 328 } |
| 329 | 329 |
| 330 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) | 330 void SpellChecker::markMisspellingsAfterTypingToWord(const VisiblePosition &word
Start, const VisibleSelection& selectionAfterTyping) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 348 } else { | 348 } else { |
| 349 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjace
ntWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get()); | 349 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, adjace
ntWords.toNormalizedRange().get(), adjacentWords.toNormalizedRange().get()); |
| 350 } | 350 } |
| 351 return; | 351 return; |
| 352 } | 352 } |
| 353 | 353 |
| 354 if (!isContinuousSpellCheckingEnabled()) | 354 if (!isContinuousSpellCheckingEnabled()) |
| 355 return; | 355 return; |
| 356 | 356 |
| 357 // Check spelling of one word | 357 // Check spelling of one word |
| 358 RefPtr<Range> misspellingRange; | 358 RefPtrWillBeRawPtr<Range> misspellingRange = nullptr; |
| 359 markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundar
y), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange); | 359 markMisspellings(VisibleSelection(startOfWord(wordStart, LeftWordIfOnBoundar
y), endOfWord(wordStart, RightWordIfOnBoundary)), misspellingRange); |
| 360 | 360 |
| 361 // Autocorrect the misspelled word. | 361 // Autocorrect the misspelled word. |
| 362 if (!misspellingRange) | 362 if (!misspellingRange) |
| 363 return; | 363 return; |
| 364 | 364 |
| 365 // Get the misspelled word. | 365 // Get the misspelled word. |
| 366 const String misspelledWord = plainText(misspellingRange.get()); | 366 const String misspelledWord = plainText(misspellingRange.get()); |
| 367 String autocorrectedString = textChecker().getAutoCorrectSuggestionForMisspe
lledWord(misspelledWord); | 367 String autocorrectedString = textChecker().getAutoCorrectSuggestionForMisspe
lledWord(misspelledWord); |
| 368 | 368 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 380 m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForw
ard, CharacterGranularity); | 380 m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForw
ard, CharacterGranularity); |
| 381 } | 381 } |
| 382 | 382 |
| 383 if (!isGrammarCheckingEnabled()) | 383 if (!isGrammarCheckingEnabled()) |
| 384 return; | 384 return; |
| 385 | 385 |
| 386 // Check grammar of entire sentence | 386 // Check grammar of entire sentence |
| 387 markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wo
rdStart))); | 387 markBadGrammar(VisibleSelection(startOfSentence(wordStart), endOfSentence(wo
rdStart))); |
| 388 } | 388 } |
| 389 | 389 |
| 390 void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selectio
n, bool checkSpelling, RefPtr<Range>& firstMisspellingRange) | 390 void SpellChecker::markMisspellingsOrBadGrammar(const VisibleSelection& selectio
n, bool checkSpelling, RefPtrWillBeRawPtr<Range>& firstMisspellingRange) |
| 391 { | 391 { |
| 392 // This function is called with a selection already expanded to word boundar
ies. | 392 // This function is called with a selection already expanded to word boundar
ies. |
| 393 // Might be nice to assert that here. | 393 // Might be nice to assert that here. |
| 394 | 394 |
| 395 // This function is used only for as-you-type checking, so if that's off we
do nothing. Note that | 395 // This function is used only for as-you-type checking, so if that's off we
do nothing. Note that |
| 396 // grammar checking can only be on if spell checking is also on. | 396 // grammar checking can only be on if spell checking is also on. |
| 397 if (!isContinuousSpellCheckingEnabled()) | 397 if (!isContinuousSpellCheckingEnabled()) |
| 398 return; | 398 return; |
| 399 | 399 |
| 400 RefPtr<Range> searchRange(selection.toNormalizedRange()); | 400 RefPtrWillBeRawPtr<Range> searchRange(selection.toNormalizedRange()); |
| 401 if (!searchRange) | 401 if (!searchRange) |
| 402 return; | 402 return; |
| 403 | 403 |
| 404 // If we're not in an editable node, bail. | 404 // If we're not in an editable node, bail. |
| 405 Node* editableNode = searchRange->startContainer(); | 405 Node* editableNode = searchRange->startContainer(); |
| 406 if (!editableNode || !editableNode->rendererIsEditable()) | 406 if (!editableNode || !editableNode->rendererIsEditable()) |
| 407 return; | 407 return; |
| 408 | 408 |
| 409 if (!isSpellCheckingEnabledFor(editableNode)) | 409 if (!isSpellCheckingEnabledFor(editableNode)) |
| 410 return; | 410 return; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 424 if (!focusedElement) | 424 if (!focusedElement) |
| 425 return false; | 425 return false; |
| 426 return focusedElement->isSpellCheckingEnabled(); | 426 return focusedElement->isSpellCheckingEnabled(); |
| 427 } | 427 } |
| 428 | 428 |
| 429 bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const | 429 bool SpellChecker::isSpellCheckingEnabledInFocusedNode() const |
| 430 { | 430 { |
| 431 return isSpellCheckingEnabledFor(m_frame.selection().start().deprecatedNode(
)); | 431 return isSpellCheckingEnabledFor(m_frame.selection().start().deprecatedNode(
)); |
| 432 } | 432 } |
| 433 | 433 |
| 434 void SpellChecker::markMisspellings(const VisibleSelection& selection, RefPtr<Ra
nge>& firstMisspellingRange) | 434 void SpellChecker::markMisspellings(const VisibleSelection& selection, RefPtrWil
lBeRawPtr<Range>& firstMisspellingRange) |
| 435 { | 435 { |
| 436 markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange); | 436 markMisspellingsOrBadGrammar(selection, true, firstMisspellingRange); |
| 437 } | 437 } |
| 438 | 438 |
| 439 void SpellChecker::markBadGrammar(const VisibleSelection& selection) | 439 void SpellChecker::markBadGrammar(const VisibleSelection& selection) |
| 440 { | 440 { |
| 441 RefPtr<Range> firstMisspellingRange; | 441 RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
| 442 markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange); | 442 markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange); |
| 443 } | 443 } |
| 444 | 444 |
| 445 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask
textCheckingOptions, Range* spellingRange, Range* grammarRange) | 445 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask
textCheckingOptions, Range* spellingRange, Range* grammarRange) |
| 446 { | 446 { |
| 447 ASSERT(unifiedTextCheckerEnabled()); | 447 ASSERT(unifiedTextCheckerEnabled()); |
| 448 | 448 |
| 449 bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar; | 449 bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar; |
| 450 | 450 |
| 451 // This function is called with selections already expanded to word boundari
es. | 451 // This function is called with selections already expanded to word boundari
es. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 464 TextCheckingParagraph fullParagraphToCheck(rangeToCheck); | 464 TextCheckingParagraph fullParagraphToCheck(rangeToCheck); |
| 465 | 465 |
| 466 bool asynchronous = m_frame.settings() && m_frame.settings()->asynchronousSp
ellCheckingEnabled(); | 466 bool asynchronous = m_frame.settings() && m_frame.settings()->asynchronousSp
ellCheckingEnabled(); |
| 467 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT
oCheck, asynchronous); | 467 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT
oCheck, asynchronous); |
| 468 } | 468 } |
| 469 | 469 |
| 470 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) | 470 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) |
| 471 { | 471 { |
| 472 if (!node) | 472 if (!node) |
| 473 return; | 473 return; |
| 474 RefPtr<Range> rangeToCheck = Range::create(*m_frame.document(), firstPositio
nInNode(node), lastPositionInNode(node)); | 474 RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*m_frame.document(),
firstPositionInNode(node), lastPositionInNode(node)); |
| 475 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); | 475 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); |
| 476 bool asynchronous = true; | 476 bool asynchronous = true; |
| 477 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe
ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck, asynchronous); | 477 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe
ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck, asynchronous); |
| 478 } | 478 } |
| 479 | 479 |
| 480 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck, bool as
ynchronous) | 480 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck, bool as
ynchronous) |
| 481 { | 481 { |
| 482 if (fullParagraphToCheck.isRangeEmpty() || fullParagraphToCheck.isEmpty()) | 482 if (fullParagraphToCheck.isRangeEmpty() || fullParagraphToCheck.isEmpty()) |
| 483 return; | 483 return; |
| 484 | 484 |
| 485 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. | 485 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. |
| 486 const int kChunkSize = 16 * 1024; | 486 const int kChunkSize = 16 * 1024; |
| 487 int start = fullParagraphToCheck.checkingStart(); | 487 int start = fullParagraphToCheck.checkingStart(); |
| 488 int end = fullParagraphToCheck.checkingEnd(); | 488 int end = fullParagraphToCheck.checkingEnd(); |
| 489 start = std::min(start, end); | 489 start = std::min(start, end); |
| 490 end = std::max(start, end); | 490 end = std::max(start, end); |
| 491 const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1)
/ (kChunkSize) : 1; | 491 const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1)
/ (kChunkSize) : 1; |
| 492 int currentChunkStart = start; | 492 int currentChunkStart = start; |
| 493 RefPtr<Range> checkRange = fullParagraphToCheck.checkingRange(); | 493 RefPtrWillBeRawPtr<Range> checkRange = fullParagraphToCheck.checkingRange(); |
| 494 if (kNumChunksToCheck == 1 && asynchronous) { | 494 if (kNumChunksToCheck == 1 && asynchronous) { |
| 495 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange
.get(), checkRange.get(), asynchronous, 0); | 495 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange
.get(), checkRange.get(), asynchronous, 0); |
| 496 return; | 496 return; |
| 497 } | 497 } |
| 498 | 498 |
| 499 for (int iter = 0; iter < kNumChunksToCheck; ++iter) { | 499 for (int iter = 0; iter < kNumChunksToCheck; ++iter) { |
| 500 checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize
); | 500 checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize
); |
| 501 setStart(checkRange.get(), startOfSentence(VisiblePosition(checkRange->s
tartPosition()))); | 501 setStart(checkRange.get(), startOfSentence(VisiblePosition(checkRange->s
tartPosition()))); |
| 502 setEnd(checkRange.get(), endOfSentence(VisiblePosition(checkRange->endPo
sition()))); | 502 setEnd(checkRange.get(), endOfSentence(VisiblePosition(checkRange->endPo
sition()))); |
| 503 | 503 |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 561 int resultLength = result->length; | 561 int resultLength = result->length; |
| 562 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res
ultLocation + resultLength == ambiguousBoundaryOffset; | 562 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res
ultLocation + resultLength == ambiguousBoundaryOffset; |
| 563 | 563 |
| 564 // Only mark misspelling if: | 564 // Only mark misspelling if: |
| 565 // 1. Current text checking isn't done for autocorrection, in which case
shouldMarkSpelling is false. | 565 // 1. Current text checking isn't done for autocorrection, in which case
shouldMarkSpelling is false. |
| 566 // 2. Result falls within spellingRange. | 566 // 2. Result falls within spellingRange. |
| 567 // 3. The word in question doesn't end at an ambiguous boundary. For ins
tance, we would not mark | 567 // 3. The word in question doesn't end at an ambiguous boundary. For ins
tance, we would not mark |
| 568 // "wouldn'" as misspelled right after apostrophe is typed. | 568 // "wouldn'" as misspelled right after apostrophe is typed. |
| 569 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelli
ng && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng
th <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { | 569 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelli
ng && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng
th <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { |
| 570 ASSERT(resultLength > 0 && resultLocation >= 0); | 570 ASSERT(resultLength > 0 && resultLocation >= 0); |
| 571 RefPtr<Range> misspellingRange = paragraph.subrange(resultLocation,
resultLength); | 571 RefPtrWillBeRawPtr<Range> misspellingRange = paragraph.subrange(resu
ltLocation, resultLength); |
| 572 misspellingRange->startContainer()->document().markers().addMarker(m
isspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->ha
sh); | 572 misspellingRange->startContainer()->document().markers().addMarker(m
isspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->ha
sh); |
| 573 } else if (shouldMarkGrammar && result->decoration == TextDecorationType
Grammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) { | 573 } else if (shouldMarkGrammar && result->decoration == TextDecorationType
Grammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) { |
| 574 ASSERT(resultLength > 0 && resultLocation >= 0); | 574 ASSERT(resultLength > 0 && resultLocation >= 0); |
| 575 for (unsigned j = 0; j < result->details.size(); j++) { | 575 for (unsigned j = 0; j < result->details.size(); j++) { |
| 576 const GrammarDetail* detail = &result->details[j]; | 576 const GrammarDetail* detail = &result->details[j]; |
| 577 ASSERT(detail->length > 0 && detail->location >= 0); | 577 ASSERT(detail->length > 0 && detail->location >= 0); |
| 578 if (paragraph.checkingRangeCovers(resultLocation + detail->locat
ion, detail->length)) { | 578 if (paragraph.checkingRangeCovers(resultLocation + detail->locat
ion, detail->length)) { |
| 579 RefPtr<Range> badGrammarRange = paragraph.subrange(resultLoc
ation + detail->location, detail->length); | 579 RefPtrWillBeRawPtr<Range> badGrammarRange = paragraph.subran
ge(resultLocation + detail->location, detail->length); |
| 580 badGrammarRange->startContainer()->document().markers().addM
arker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, r
esult->hash); | 580 badGrammarRange->startContainer()->document().markers().addM
arker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, r
esult->hash); |
| 581 } | 581 } |
| 582 } | 582 } |
| 583 } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck &
& resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <
= spellingRangeEndOffset) { | 583 } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck &
& resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <
= spellingRangeEndOffset) { |
| 584 ASSERT(resultLength > 0 && resultLocation >= 0); | 584 ASSERT(resultLength > 0 && resultLocation >= 0); |
| 585 RefPtr<Range> invisibleSpellcheckRange = paragraph.subrange(resultLo
cation, resultLength); | 585 RefPtrWillBeRawPtr<Range> invisibleSpellcheckRange = paragraph.subra
nge(resultLocation, resultLength); |
| 586 invisibleSpellcheckRange->startContainer()->document().markers().add
Marker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, resu
lt->replacement, result->hash); | 586 invisibleSpellcheckRange->startContainer()->document().markers().add
Marker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, resu
lt->replacement, result->hash); |
| 587 } | 587 } |
| 588 } | 588 } |
| 589 | 589 |
| 590 if (selectionChanged) { | 590 if (selectionChanged) { |
| 591 TextCheckingParagraph extendedParagraph(paragraph); | 591 TextCheckingParagraph extendedParagraph(paragraph); |
| 592 // Restore the caret position if we have made any replacements | 592 // Restore the caret position if we have made any replacements |
| 593 extendedParagraph.expandRangeToNextEnd(); | 593 extendedParagraph.expandRangeToNextEnd(); |
| 594 if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffs
et <= extendedParagraph.rangeLength()) { | 594 if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffs
et <= extendedParagraph.rangeLength()) { |
| 595 RefPtr<Range> selectionRange = extendedParagraph.subrange(0, selecti
onOffset); | 595 RefPtrWillBeRawPtr<Range> selectionRange = extendedParagraph.subrang
e(0, selectionOffset); |
| 596 m_frame.selection().moveTo(selectionRange->endPosition(), DOWNSTREAM
); | 596 m_frame.selection().moveTo(selectionRange->endPosition(), DOWNSTREAM
); |
| 597 if (adjustSelectionForParagraphBoundaries) | 597 if (adjustSelectionForParagraphBoundaries) |
| 598 m_frame.selection().modify(FrameSelection::AlterationMove, Direc
tionForward, CharacterGranularity); | 598 m_frame.selection().modify(FrameSelection::AlterationMove, Direc
tionForward, CharacterGranularity); |
| 599 } else { | 599 } else { |
| 600 // If this fails for any reason, the fallback is to go one position
beyond the last replacement | 600 // If this fails for any reason, the fallback is to go one position
beyond the last replacement |
| 601 m_frame.selection().moveTo(m_frame.selection().selection().visibleEn
d()); | 601 m_frame.selection().moveTo(m_frame.selection().selection().visibleEn
d()); |
| 602 m_frame.selection().modify(FrameSelection::AlterationMove, Direction
Forward, CharacterGranularity); | 602 m_frame.selection().modify(FrameSelection::AlterationMove, Direction
Forward, CharacterGranularity); |
| 603 } | 603 } |
| 604 } | 604 } |
| 605 } | 605 } |
| 606 | 606 |
| 607 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellin
gSelection, bool markGrammar, const VisibleSelection& grammarSelection) | 607 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection& spellin
gSelection, bool markGrammar, const VisibleSelection& grammarSelection) |
| 608 { | 608 { |
| 609 if (unifiedTextCheckerEnabled()) { | 609 if (unifiedTextCheckerEnabled()) { |
| 610 if (!isContinuousSpellCheckingEnabled()) | 610 if (!isContinuousSpellCheckingEnabled()) |
| 611 return; | 611 return; |
| 612 | 612 |
| 613 // markMisspellingsAndBadGrammar() is triggered by selection change, in
which case we check spelling and grammar, but don't autocorrect misspellings. | 613 // markMisspellingsAndBadGrammar() is triggered by selection change, in
which case we check spelling and grammar, but don't autocorrect misspellings. |
| 614 TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling; | 614 TextCheckingTypeMask textCheckingOptions = TextCheckingTypeSpelling; |
| 615 if (markGrammar && isGrammarCheckingEnabled()) | 615 if (markGrammar && isGrammarCheckingEnabled()) |
| 616 textCheckingOptions |= TextCheckingTypeGrammar; | 616 textCheckingOptions |= TextCheckingTypeGrammar; |
| 617 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSe
lection.toNormalizedRange().get(), grammarSelection.toNormalizedRange().get()); | 617 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, spellingSe
lection.toNormalizedRange().get(), grammarSelection.toNormalizedRange().get()); |
| 618 return; | 618 return; |
| 619 } | 619 } |
| 620 | 620 |
| 621 RefPtr<Range> firstMisspellingRange; | 621 RefPtrWillBeRawPtr<Range> firstMisspellingRange = nullptr; |
| 622 markMisspellings(spellingSelection, firstMisspellingRange); | 622 markMisspellings(spellingSelection, firstMisspellingRange); |
| 623 if (markGrammar) | 623 if (markGrammar) |
| 624 markBadGrammar(grammarSelection); | 624 markBadGrammar(grammarSelection); |
| 625 } | 625 } |
| 626 | 626 |
| 627 void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
ctionAtWordBoundary) | 627 void SpellChecker::updateMarkersForWordsAffectedByEditing(bool doNotRemoveIfSele
ctionAtWordBoundary) |
| 628 { | 628 { |
| 629 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpe
lling)) | 629 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpe
lling)) |
| 630 return; | 630 return; |
| 631 | 631 |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 682 return; | 682 return; |
| 683 | 683 |
| 684 // Now we remove markers on everything between startOfFirstWord and endOfLas
tWord. | 684 // Now we remove markers on everything between startOfFirstWord and endOfLas
tWord. |
| 685 // However, if an autocorrection change a single word to multiple words, we
want to remove correction mark from all the | 685 // However, if an autocorrection change a single word to multiple words, we
want to remove correction mark from all the |
| 686 // resulted words even we only edit one of them. For example, assuming autoc
orrection changes "avantgarde" to "avant | 686 // resulted words even we only edit one of them. For example, assuming autoc
orrection changes "avantgarde" to "avant |
| 687 // garde", we will have CorrectionIndicator marker on both words and on the
whitespace between them. If we then edit garde, | 687 // garde", we will have CorrectionIndicator marker on both words and on the
whitespace between them. If we then edit garde, |
| 688 // we would like to remove the marker from word "avant" and whitespace as we
ll. So we need to get the continous range of | 688 // we would like to remove the marker from word "avant" and whitespace as we
ll. So we need to get the continous range of |
| 689 // of marker that contains the word in question, and remove marker on that w
hole range. | 689 // of marker that contains the word in question, and remove marker on that w
hole range. |
| 690 Document* document = m_frame.document(); | 690 Document* document = m_frame.document(); |
| 691 ASSERT(document); | 691 ASSERT(document); |
| 692 RefPtr<Range> wordRange = Range::create(*document, startOfFirstWord.deepEqui
valent(), endOfLastWord.deepEquivalent()); | 692 RefPtrWillBeRawPtr<Range> wordRange = Range::create(*document, startOfFirstW
ord.deepEquivalent(), endOfLastWord.deepEquivalent()); |
| 693 | 693 |
| 694 document->markers().removeMarkers(wordRange.get(), DocumentMarker::Misspelli
ngMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker); | 694 document->markers().removeMarkers(wordRange.get(), DocumentMarker::Misspelli
ngMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker); |
| 695 } | 695 } |
| 696 | 696 |
| 697 void SpellChecker::didEndEditingOnTextField(Element* e) | 697 void SpellChecker::didEndEditingOnTextField(Element* e) |
| 698 { | 698 { |
| 699 // Remove markers when deactivating a selection in an <input type="text"/>. | 699 // Remove markers when deactivating a selection in an <input type="text"/>. |
| 700 // Prevent new ones from appearing too. | 700 // Prevent new ones from appearing too. |
| 701 m_spellCheckRequester->cancelCheck(); | 701 m_spellCheckRequester->cancelCheck(); |
| 702 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl
ement(e); | 702 HTMLTextFormControlElement* textFormControlElement = toHTMLTextFormControlEl
ement(e); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 733 // oldSelection may no longer be in the document. | 733 // oldSelection may no longer be in the document. |
| 734 if (shouldCheckSpellingAndGrammar | 734 if (shouldCheckSpellingAndGrammar |
| 735 && closeTyping | 735 && closeTyping |
| 736 && oldSelection.isContentEditable() | 736 && oldSelection.isContentEditable() |
| 737 && oldSelection.start().inDocument() | 737 && oldSelection.start().inDocument() |
| 738 && !isSelectionInTextField(oldSelection)) { | 738 && !isSelectionInTextField(oldSelection)) { |
| 739 spellCheckOldSelection(oldSelection, newAdjacentWords, newSelectedSe
ntence); | 739 spellCheckOldSelection(oldSelection, newAdjacentWords, newSelectedSe
ntence); |
| 740 } | 740 } |
| 741 | 741 |
| 742 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTyp
eSpelling)) { | 742 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTyp
eSpelling)) { |
| 743 if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange()) | 743 if (RefPtrWillBeRawPtr<Range> wordRange = newAdjacentWords.toNormali
zedRange()) |
| 744 m_frame.document()->markers().removeMarkers(wordRange.get(), Doc
umentMarker::Spelling); | 744 m_frame.document()->markers().removeMarkers(wordRange.get(), Doc
umentMarker::Spelling); |
| 745 } | 745 } |
| 746 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTyp
eGrammar)) { | 746 if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTyp
eGrammar)) { |
| 747 if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRa
nge()) | 747 if (RefPtrWillBeRawPtr<Range> sentenceRange = newSelectedSentence.to
NormalizedRange()) |
| 748 m_frame.document()->markers().removeMarkers(sentenceRange.get(),
DocumentMarker::Grammar); | 748 m_frame.document()->markers().removeMarkers(sentenceRange.get(),
DocumentMarker::Grammar); |
| 749 } | 749 } |
| 750 } | 750 } |
| 751 | 751 |
| 752 // When continuous spell checking is off, existing markers disappear after t
he selection changes. | 752 // When continuous spell checking is off, existing markers disappear after t
he selection changes. |
| 753 if (!isContinuousSpellCheckingEnabled) | 753 if (!isContinuousSpellCheckingEnabled) |
| 754 m_frame.document()->markers().removeMarkers(DocumentMarker::Spelling); | 754 m_frame.document()->markers().removeMarkers(DocumentMarker::Spelling); |
| 755 if (!isContinuousGrammarCheckingEnabled) | 755 if (!isContinuousGrammarCheckingEnabled) |
| 756 m_frame.document()->markers().removeMarkers(DocumentMarker::Grammar); | 756 m_frame.document()->markers().removeMarkers(DocumentMarker::Grammar); |
| 757 } | 757 } |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 839 return WebCore::unifiedTextCheckerEnabled(&m_frame); | 839 return WebCore::unifiedTextCheckerEnabled(&m_frame); |
| 840 } | 840 } |
| 841 | 841 |
| 842 void SpellChecker::cancelCheck() | 842 void SpellChecker::cancelCheck() |
| 843 { | 843 { |
| 844 m_spellCheckRequester->cancelCheck(); | 844 m_spellCheckRequester->cancelCheck(); |
| 845 } | 845 } |
| 846 | 846 |
| 847 void SpellChecker::requestTextChecking(const Element& element) | 847 void SpellChecker::requestTextChecking(const Element& element) |
| 848 { | 848 { |
| 849 RefPtr<Range> rangeToCheck = rangeOfContents(const_cast<Element*>(&element))
; | 849 RefPtrWillBeRawPtr<Range> rangeToCheck = rangeOfContents(const_cast<Element*
>(&element)); |
| 850 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe
ck, rangeToCheck)); | 850 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe
ck, rangeToCheck)); |
| 851 } | 851 } |
| 852 | 852 |
| 853 | 853 |
| 854 } // namespace WebCore | 854 } // namespace WebCore |
| OLD | NEW |