Chromium Code Reviews| 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 |