| 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 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 472 if (!editableNode || !editableNode->hasEditableStyle()) | 472 if (!editableNode || !editableNode->hasEditableStyle()) |
| 473 return; | 473 return; |
| 474 | 474 |
| 475 if (!isSpellCheckingEnabledFor(editableNode)) | 475 if (!isSpellCheckingEnabledFor(editableNode)) |
| 476 return; | 476 return; |
| 477 | 477 |
| 478 TextCheckingParagraph fullParagraphToCheck(shouldMarkGrammar ? grammarRange
: spellingRange); | 478 TextCheckingParagraph fullParagraphToCheck(shouldMarkGrammar ? grammarRange
: spellingRange); |
| 479 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT
oCheck); | 479 chunkAndMarkAllMisspellingsAndBadGrammar(textCheckingOptions, fullParagraphT
oCheck); |
| 480 } | 480 } |
| 481 | 481 |
| 482 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) |
| 483 { |
| 484 ASSERT(range.isNotNull()); |
| 485 const VisiblePosition& visibleEnd = createVisiblePosition(range.endPosition(
)); |
| 486 ASSERT(visibleEnd.isNotNull()); |
| 487 const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent(); |
| 488 return EphemeralRange(range.startPosition(), sentenceEnd.isNotNull() ? sente
nceEnd : range.endPosition()); |
| 489 } |
| 490 |
| 491 static EphemeralRange expandRangeToSentenceBoundary(const EphemeralRange& range) |
| 492 { |
| 493 ASSERT(range.isNotNull()); |
| 494 const VisiblePosition& visibleStart = createVisiblePosition(range.startPosit
ion()); |
| 495 ASSERT(visibleStart.isNotNull()); |
| 496 const Position& sentenceStart = startOfSentence(visibleStart).deepEquivalent
(); |
| 497 return expandEndToSentenceBoundary(EphemeralRange(sentenceStart.isNull() ? r
ange.startPosition() : sentenceStart, range.endPosition())); |
| 498 } |
| 499 |
| 482 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) | 500 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node) |
| 483 { | 501 { |
| 484 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma
r"); | 502 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma
r"); |
| 485 if (!node) | 503 if (!node) |
| 486 return; | 504 return; |
| 487 RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*frame().document(),
firstPositionInNode(node), lastPositionInNode(node)); | 505 RefPtrWillBeRawPtr<Range> rangeToCheck = Range::create(*frame().document(),
firstPositionInNode(node), lastPositionInNode(node)); |
| 488 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); | 506 TextCheckingParagraph textToCheck(rangeToCheck, rangeToCheck); |
| 489 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe
ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck); | 507 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe
ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck); |
| 490 } | 508 } |
| 491 | 509 |
| 492 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck) | 510 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck) |
| 493 { | 511 { |
| 494 if (fullParagraphToCheck.isEmpty()) | 512 if (fullParagraphToCheck.isEmpty()) |
| 495 return; | 513 return; |
| 514 const EphemeralRange& paragraphRange = fullParagraphToCheck.paragraphRange()
; |
| 496 | 515 |
| 497 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. | 516 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. |
| 498 const int kChunkSize = 16 * 1024; | 517 const int kChunkSize = 16 * 1024; |
| 499 int start = fullParagraphToCheck.checkingStart(); | 518 CharacterIterator checkRangeIterator(fullParagraphToCheck.checkingRange(), T
extIteratorEmitsObjectReplacementCharacter); |
| 500 int end = fullParagraphToCheck.checkingEnd(); | 519 for (int requestNum = 0; !checkRangeIterator.atEnd(); requestNum++) { |
| 501 start = std::min(start, end); | 520 EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrang
e(0, kChunkSize); |
| 502 end = std::max(start, end); | 521 EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chu
nkRange) : expandRangeToSentenceBoundary(chunkRange); |
| 503 const int kNumChunksToCheck = (end - start + kChunkSize - 1) / kChunkSize; | 522 |
| 504 int currentChunkStart = start; | 523 RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::creat
e(resolveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, ch
eckRange, paragraphRange, requestNum); |
| 505 if (kNumChunksToCheck == 1) { | 524 if (request) |
| 506 EphemeralRange checkRange = fullParagraphToCheck.checkingRange(); | 525 m_spellCheckRequester->requestCheckingFor(request); |
| 507 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange
, checkRange, 0); | 526 |
| 508 return; | 527 if (!checkRangeIterator.atEnd()) { |
| 528 checkRangeIterator.advance(1); |
| 529 // The layout should be already update due to the initialization of
checkRangeIterator, |
| 530 // so comparePositions can be directly called. |
| 531 if (comparePositions(chunkRange.endPosition(), checkRange.endPositio
n()) < 0) |
| 532 checkRangeIterator.advance(TextIterator::rangeLength(chunkRange.
endPosition(), checkRange.endPosition())); |
| 533 } |
| 509 } | 534 } |
| 510 | |
| 511 for (int iter = 0; iter < kNumChunksToCheck; ++iter) { | |
| 512 EphemeralRange checkRange = expandRangeToSentenceBoundary(fullParagraphT
oCheck.subrange(currentChunkStart, kChunkSize)); | |
| 513 int checkingLength = 0; | |
| 514 markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange
, checkRange, iter, &checkingLength); | |
| 515 currentChunkStart += checkingLength; | |
| 516 } | |
| 517 } | |
| 518 | |
| 519 void SpellChecker::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask
textCheckingOptions, const EphemeralRange& checkRange, const EphemeralRange& pa
ragraphRange, int requestNumber, int* checkingLength) | |
| 520 { | |
| 521 TextCheckingParagraph sentenceToCheck(checkRange, paragraphRange); | |
| 522 if (checkingLength) | |
| 523 *checkingLength = sentenceToCheck.checkingLength(); | |
| 524 | |
| 525 RefPtrWillBeRawPtr<SpellCheckRequest> request = SpellCheckRequest::create(re
solveTextCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkR
ange, paragraphRange, requestNumber); | |
| 526 if (!request) | |
| 527 return; | |
| 528 | |
| 529 m_spellCheckRequester->requestCheckingFor(request); | |
| 530 } | 535 } |
| 531 | 536 |
| 532 void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r
equest, const Vector<TextCheckingResult>& results) | 537 void SpellChecker::markAndReplaceFor(PassRefPtrWillBeRawPtr<SpellCheckRequest> r
equest, const Vector<TextCheckingResult>& results) |
| 533 { | 538 { |
| 534 TRACE_EVENT0("blink", "SpellChecker::markAndReplaceFor"); | 539 TRACE_EVENT0("blink", "SpellChecker::markAndReplaceFor"); |
| 535 ASSERT(request); | 540 ASSERT(request); |
| 536 if (!request->isValid()) | 541 if (!request->isValid()) |
| 537 return; | 542 return; |
| 538 | 543 |
| 539 TextCheckingTypeMask textCheckingOptions = request->data().mask(); | 544 TextCheckingTypeMask textCheckingOptions = request->data().mask(); |
| (...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 903 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe
ck, rangeToCheck)); | 908 m_spellCheckRequester->requestCheckingFor(SpellCheckRequest::create(TextChec
kingTypeSpelling | TextCheckingTypeGrammar, TextCheckingProcessBatch, rangeToChe
ck, rangeToCheck)); |
| 904 } | 909 } |
| 905 | 910 |
| 906 DEFINE_TRACE(SpellChecker) | 911 DEFINE_TRACE(SpellChecker) |
| 907 { | 912 { |
| 908 visitor->trace(m_frame); | 913 visitor->trace(m_frame); |
| 909 visitor->trace(m_spellCheckRequester); | 914 visitor->trace(m_spellCheckRequester); |
| 910 } | 915 } |
| 911 | 916 |
| 912 } // namespace blink | 917 } // namespace blink |
| OLD | NEW |