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 |