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 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
480 return; | 480 return; |
481 | 481 |
482 // If we're not in an editable node, bail. | 482 // If we're not in an editable node, bail. |
483 Node* editableNode = spellingRange.startPosition().computeContainerNode(); | 483 Node* editableNode = spellingRange.startPosition().computeContainerNode(); |
484 if (!editableNode || !editableNode->hasEditableStyle()) | 484 if (!editableNode || !editableNode->hasEditableStyle()) |
485 return; | 485 return; |
486 | 486 |
487 if (!isSpellCheckingEnabledFor(editableNode)) | 487 if (!isSpellCheckingEnabledFor(editableNode)) |
488 return; | 488 return; |
489 | 489 |
490 RefPtrWillBeRawPtr<Range> rangeToCheck = createRange(shouldMarkGrammar ? gra mmarRange : spellingRange); | 490 TextCheckingParagraph fullParagraphToCheck(shouldMarkGrammar ? grammarRange : spellingRange); |
491 TextCheckingParagraph fullParagraphToCheck(rangeToCheck); | |
492 | 491 |
493 bool asynchronous = frame().settings() && frame().settings()->asynchronousSp ellCheckingEnabled(); | 492 bool asynchronous = frame().settings() && frame().settings()->asynchronousSp ellCheckingEnabled(); |
494 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT oCheck, asynchronous); | 493 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT oCheck, asynchronous); |
495 } | 494 } |
496 | 495 |
497 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) | 496 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) |
498 { | 497 { |
499 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma r"); | 498 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma r"); |
500 if (!node) | 499 if (!node) |
501 return; | 500 return; |
502 RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*frame().document(), firstPositionInNode(node), lastPositionInNode(node)); | 501 RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*frame().document(), firstPositionInNode(node), lastPositionInNode(node)); |
503 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); | 502 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); |
504 bool asynchronous = true; | 503 bool asynchronous = true; |
505 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck, asynchronous); | 504 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck, asynchronous); |
506 } | 505 } |
507 | 506 |
508 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck, bool as ynchronous) | 507 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck, bool as ynchronous) |
509 { | 508 { |
510 if (fullParagraphToCheck.isRangeEmpty() || fullParagraphToCheck.isEmpty()) | 509 if (fullParagraphToCheck.isRangeEmpty() || fullParagraphToCheck.isEmpty()) |
511 return; | 510 return; |
512 | 511 |
513 // Since the text may be quite big chunk it up and adjust to the sentence bo undary. | 512 // Since the text may be quite big chunk it up and adjust to the sentence bo undary. |
514 const int kChunkSize = 16 * 1024; | 513 const int kChunkSize = 16 * 1024; |
515 int start = fullParagraphToCheck.checkingStart(); | 514 int start = fullParagraphToCheck.checkingStart(); |
516 int end = fullParagraphToCheck.checkingEnd(); | 515 int end = fullParagraphToCheck.checkingEnd(); |
517 start = std::min(start, end); | 516 start = std::min(start, end); |
518 end = std::max(start, end); | 517 end = std::max(start, end); |
519 const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1) / (kChunkSize) : 1; | 518 const int kNumChunksToCheck = asynchronous ? (end - start + kChunkSize - 1) / (kChunkSize) : 1; |
520 int currentChunkStart = start; | 519 int currentChunkStart = start; |
521 RefPtrWillBeRawPtr<Range> checkRange = fullParagraphToCheck.checkingRange(); | 520 EphemeralRange checkRange = fullParagraphToCheck.checkingRange(); |
yosin_UTC9
2015/09/10 01:58:39
nit: |const EphemeralRange|.
| |
522 if (kNumChunksToCheck == 1 && asynchronous) { | 521 if (kNumChunksToCheck == 1 && asynchronous) { |
523 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange .get(), checkRange.get(), asynchronous, 0); | 522 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange , checkRange, asynchronous, 0); |
524 return; | 523 return; |
525 } | 524 } |
526 | 525 |
527 for (int iter = 0; iter < kNumChunksToCheck; ++iter) { | 526 for (int iter = 0; iter < kNumChunksToCheck; ++iter) { |
528 checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize ); | 527 checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize ); |
yosin_UTC9
2015/09/10 01:58:39
nit: Let's use new variable name. We don't want to
| |
529 expandRangeToSentenceBoundary(*checkRange); | 528 checkRange = expandRangeToSentenceBoundary(checkRange); |
530 | 529 |
531 int checkingLength = 0; | 530 int checkingLength = 0; |
532 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange .get(), checkRange.get(), asynchronous, iter, &checkingLength); | 531 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange , checkRange, asynchronous, iter, &checkingLength); |
533 currentChunkStart += checkingLength; | 532 currentChunkStart += checkingLength; |
534 } | 533 } |
535 } | 534 } |
536 | 535 |
537 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, Range* checkRange, Range* paragraphRange, bool asynchronou s, int requestNumber, int* checkingLength) | 536 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textCheckingOptions, const EphemeralRange& checkRange, const EphemeralRange& pa ragraphRange, bool asynchronous, int requestNumber, int* checkingLength) |
538 { | 537 { |
539 TextCheckingParagraph sentenceToCheck(checkRange, paragraphRange); | 538 TextCheckingParagraph sentenceToCheck(checkRange, paragraphRange); |
540 if (checkingLength) | 539 if (checkingLength) |
541 *checkingLength = sentenceToCheck.checkingLength(); | 540 *checkingLength = sentenceToCheck.checkingLength(); |
542 | 541 |
543 RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::create(re solveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkR ange, paragraphRange, requestNumber); | 542 RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::create(re solveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, create Range(checkRange), createRange(paragraphRange), requestNumber); |
544 if (!request) | 543 if (!request) |
545 return; | 544 return; |
546 | 545 |
547 if (asynchronous) { | 546 if (asynchronous) { |
548 m_spellCheckRequester->requestCheckingFor(request); | 547 m_spellCheckRequester->requestCheckingFor(request); |
549 } else { | 548 } else { |
550 Vector<TextCheckingResult> results; | 549 Vector<TextCheckingResult> results; |
551 checkTextOfParagraph(textChecker(), sentenceToCheck.text(), resolveTextC heckingTypeMask(textCheckingOptions), results); | 550 checkTextOfParagraph(textChecker(), sentenceToCheck.text(), resolveTextC heckingTypeMask(textCheckingOptions), results); |
552 markAndReplaceFor(request, results); | 551 markAndReplaceFor(request, results); |
553 } | 552 } |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
591 int resultLength = result->length; | 590 int resultLength = result->length; |
592 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res ultLocation + resultLength == ambiguousBoundaryOffset; | 591 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res ultLocation + resultLength == ambiguousBoundaryOffset; |
593 | 592 |
594 // Only mark misspelling if: | 593 // Only mark misspelling if: |
595 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false. | 594 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false. |
596 // 2. Result falls within spellingRange. | 595 // 2. Result falls within spellingRange. |
597 // 3. The word in question doesn't end at an ambiguous boundary. For ins tance, we would not mark | 596 // 3. The word in question doesn't end at an ambiguous boundary. For ins tance, we would not mark |
598 // "wouldn'" as misspelled right after apostrophe is typed. | 597 // "wouldn'" as misspelled right after apostrophe is typed. |
599 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelli ng && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng th <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { | 598 if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelli ng && resultLocation >= paragraph.checkingStart() && resultLocation + resultLeng th <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { |
600 ASSERT(resultLength > 0 && resultLocation >= 0); | 599 ASSERT(resultLength > 0 && resultLocation >= 0); |
601 const EphemeralRange misspellingRange = calculateCharacterSubrange(E phemeralRange(paragraph.paragraphRange().get()), resultLocation, resultLength); | 600 const EphemeralRange misspellingRange = calculateCharacterSubrange(p aragraph.paragraphRange(), resultLocation, resultLength); |
602 frame().document()->markers().addMarker(misspellingRange.startPositi on(), misspellingRange.endPosition(), DocumentMarker::Spelling, result->replacem ent, result->hash); | 601 frame().document()->markers().addMarker(misspellingRange.startPositi on(), misspellingRange.endPosition(), DocumentMarker::Spelling, result->replacem ent, result->hash); |
603 } else if (shouldMarkGrammar && result->decoration == TextDecorationType Grammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) { | 602 } else if (shouldMarkGrammar && result->decoration == TextDecorationType Grammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) { |
604 ASSERT(resultLength > 0 && resultLocation >= 0); | 603 ASSERT(resultLength > 0 && resultLocation >= 0); |
605 for (unsigned j = 0; j < result->details.size(); j++) { | 604 for (unsigned j = 0; j < result->details.size(); j++) { |
606 const GrammarDetail* detail = &result->details[j]; | 605 const GrammarDetail* detail = &result->details[j]; |
607 ASSERT(detail->length > 0 && detail->location >= 0); | 606 ASSERT(detail->length > 0 && detail->location >= 0); |
608 if (paragraph.checkingRangeCovers(resultLocation + detail->locat ion, detail->length)) { | 607 if (paragraph.checkingRangeCovers(resultLocation + detail->locat ion, detail->length)) { |
609 const EphemeralRange badGrammarRange = calculateCharacterSub range(EphemeralRange(paragraph.paragraphRange().get()), resultLocation + detail- >location, detail->length); | 608 const EphemeralRange badGrammarRange = calculateCharacterSub range(paragraph.paragraphRange(), resultLocation + detail->location, detail->len gth); |
610 frame().document()->markers().addMarker(badGrammarRange.star tPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, detail->use rDescription, result->hash); | 609 frame().document()->markers().addMarker(badGrammarRange.star tPosition(), badGrammarRange.endPosition(), DocumentMarker::Grammar, detail->use rDescription, result->hash); |
611 } | 610 } |
612 } | 611 } |
613 } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck & & resultLocation >= paragraph.checkingStart() && resultLocation + resultLength < = spellingRangeEndOffset) { | 612 } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck & & resultLocation >= paragraph.checkingStart() && resultLocation + resultLength < = spellingRangeEndOffset) { |
614 ASSERT(resultLength > 0 && resultLocation >= 0); | 613 ASSERT(resultLength > 0 && resultLocation >= 0); |
615 const EphemeralRange invisibleSpellcheckRange = calculateCharacterSu brange(EphemeralRange(paragraph.paragraphRange().get()), resultLocation, resultL ength); | 614 const EphemeralRange invisibleSpellcheckRange = calculateCharacterSu brange(paragraph.paragraphRange(), resultLocation, resultLength); |
616 frame().document()->markers().addMarker(invisibleSpellcheckRange.sta rtPosition(), invisibleSpellcheckRange.endPosition(), DocumentMarker::InvisibleS pellcheck, result->replacement, result->hash); | 615 frame().document()->markers().addMarker(invisibleSpellcheckRange.sta rtPosition(), invisibleSpellcheckRange.endPosition(), DocumentMarker::InvisibleS pellcheck, result->replacement, result->hash); |
617 } | 616 } |
618 } | 617 } |
619 | 618 |
620 if (selectionChanged) { | 619 if (selectionChanged) { |
621 TextCheckingParagraph extendedParagraph(paragraph); | 620 TextCheckingParagraph extendedParagraph(paragraph); |
622 // Restore the caret position if we have made any replacements | 621 // Restore the caret position if we have made any replacements |
623 extendedParagraph.expandRangeToNextEnd(); | 622 extendedParagraph.expandRangeToNextEnd(); |
624 if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffs et <= extendedParagraph.rangeLength()) { | 623 if (restoreSelectionAfterChange && selectionOffset >= 0 && selectionOffs et <= extendedParagraph.rangeLength()) { |
625 RefPtrWillBeRawPtr<Range> selectionRange = extendedParagraph.subrang e(0, selectionOffset); | 624 EphemeralRange selectionRange = extendedParagraph.subrange(0, select ionOffset); |
yosin_UTC9
2015/09/10 01:58:39
nit: |const EphemeralRange|
| |
626 frame().selection().moveTo(selectionRange->endPosition(), TextAffini ty::Downstream); | 625 frame().selection().moveTo(selectionRange.endPosition(), TextAffinit y::Downstream); |
627 if (adjustSelectionForParagraphBoundaries) | 626 if (adjustSelectionForParagraphBoundaries) |
628 frame().selection().modify(FrameSelection::AlterationMove, Direc tionForward, CharacterGranularity); | 627 frame().selection().modify(FrameSelection::AlterationMove, Direc tionForward, CharacterGranularity); |
629 } else { | 628 } else { |
630 // If this fails for any reason, the fallback is to go one position beyond the last replacement | 629 // If this fails for any reason, the fallback is to go one position beyond the last replacement |
631 frame().selection().moveTo(frame().selection().selection().visibleEn d()); | 630 frame().selection().moveTo(frame().selection().selection().visibleEn d()); |
632 frame().selection().modify(FrameSelection::AlterationMove, Direction Forward, CharacterGranularity); | 631 frame().selection().modify(FrameSelection::AlterationMove, Direction Forward, CharacterGranularity); |
633 } | 632 } |
634 } | 633 } |
635 } | 634 } |
636 | 635 |
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
938 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe ck, rangeToCheck)); | 937 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe ck, rangeToCheck)); |
939 } | 938 } |
940 | 939 |
941 DEFINE_TRACE(SpellChecker) | 940 DEFINE_TRACE(SpellChecker) |
942 { | 941 { |
943 visitor->trace(m_frame); | 942 visitor->trace(m_frame); |
944 visitor->trace(m_spellCheckRequester); | 943 visitor->trace(m_spellCheckRequester); |
945 } | 944 } |
946 | 945 |
947 } // namespace blink | 946 } // namespace blink |
OLD | NEW |