| 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 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 | 448 |
| 449 // If we're not in an editable node, bail. | 449 // If we're not in an editable node, bail. |
| 450 Node* editableNode = spellingRange.startPosition().computeContainerNode(); | 450 Node* editableNode = spellingRange.startPosition().computeContainerNode(); |
| 451 if (!editableNode || !hasEditableStyle(*editableNode)) | 451 if (!editableNode || !hasEditableStyle(*editableNode)) |
| 452 return; | 452 return; |
| 453 | 453 |
| 454 if (!isSpellCheckingEnabledFor(editableNode)) | 454 if (!isSpellCheckingEnabledFor(editableNode)) |
| 455 return; | 455 return; |
| 456 | 456 |
| 457 TextCheckingParagraph fullParagraphToCheck(spellingRange); | 457 TextCheckingParagraph fullParagraphToCheck(spellingRange); |
| 458 chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeSpelling, fullParag
raphToCheck); | 458 chunkAndMarkAllMisspellings(fullParagraphToCheck); |
| 459 } | 459 } |
| 460 | 460 |
| 461 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) | 461 static EphemeralRange expandEndToSentenceBoundary(const EphemeralRange& range) |
| 462 { | 462 { |
| 463 DCHECK(range.isNotNull()); | 463 DCHECK(range.isNotNull()); |
| 464 const VisiblePosition& visibleEnd = createVisiblePosition(range.endPosition(
)); | 464 const VisiblePosition& visibleEnd = createVisiblePosition(range.endPosition(
)); |
| 465 DCHECK(visibleEnd.isNotNull()); | 465 DCHECK(visibleEnd.isNotNull()); |
| 466 const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent(); | 466 const Position& sentenceEnd = endOfSentence(visibleEnd).deepEquivalent(); |
| 467 return EphemeralRange(range.startPosition(), sentenceEnd.isNotNull() ? sente
nceEnd : range.endPosition()); | 467 return EphemeralRange(range.startPosition(), sentenceEnd.isNotNull() ? sente
nceEnd : range.endPosition()); |
| 468 } | 468 } |
| 469 | 469 |
| 470 static EphemeralRange expandRangeToSentenceBoundary(const EphemeralRange& range) | 470 static EphemeralRange expandRangeToSentenceBoundary(const EphemeralRange& range) |
| 471 { | 471 { |
| 472 DCHECK(range.isNotNull()); | 472 DCHECK(range.isNotNull()); |
| 473 const VisiblePosition& visibleStart = createVisiblePosition(range.startPosit
ion()); | 473 const VisiblePosition& visibleStart = createVisiblePosition(range.startPosit
ion()); |
| 474 DCHECK(visibleStart.isNotNull()); | 474 DCHECK(visibleStart.isNotNull()); |
| 475 const Position& sentenceStart = startOfSentence(visibleStart).deepEquivalent
(); | 475 const Position& sentenceStart = startOfSentence(visibleStart).deepEquivalent
(); |
| 476 return expandEndToSentenceBoundary(EphemeralRange(sentenceStart.isNull() ? r
ange.startPosition() : sentenceStart, range.endPosition())); | 476 return expandEndToSentenceBoundary(EphemeralRange(sentenceStart.isNull() ? r
ange.startPosition() : sentenceStart, range.endPosition())); |
| 477 } | 477 } |
| 478 | 478 |
| 479 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node, const Ep
hemeralRange& insertedRange) | 479 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(Node* node, const Ep
hemeralRange& insertedRange) |
| 480 { | 480 { |
| 481 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma
r"); | 481 TRACE_EVENT0("blink", "SpellChecker::chunkAndMarkAllMisspellingsAndBadGramma
r"); |
| 482 if (!node) | 482 if (!node) |
| 483 return; | 483 return; |
| 484 EphemeralRange paragraphRange(Position::firstPositionInNode(node), Position:
:lastPositionInNode(node)); | 484 EphemeralRange paragraphRange(Position::firstPositionInNode(node), Position:
:lastPositionInNode(node)); |
| 485 TextCheckingParagraph textToCheck(insertedRange, paragraphRange); | 485 TextCheckingParagraph textToCheck(insertedRange, paragraphRange); |
| 486 chunkAndMarkAllMisspellingsAndBadGrammar(resolveTextCheckingTypeMask(TextChe
ckingTypeSpelling | TextCheckingTypeGrammar), textToCheck); | 486 chunkAndMarkAllMisspellings(textToCheck); |
| 487 } | 487 } |
| 488 | 488 |
| 489 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(TextCheckingTypeMask
textCheckingOptions, const TextCheckingParagraph& fullParagraphToCheck) | 489 void SpellChecker::chunkAndMarkAllMisspellings(const TextCheckingParagraph& full
ParagraphToCheck) |
| 490 { | 490 { |
| 491 if (fullParagraphToCheck.isEmpty()) | 491 if (fullParagraphToCheck.isEmpty()) |
| 492 return; | 492 return; |
| 493 const EphemeralRange& paragraphRange = fullParagraphToCheck.paragraphRange()
; | 493 const EphemeralRange& paragraphRange = fullParagraphToCheck.paragraphRange()
; |
| 494 | 494 |
| 495 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. | 495 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. |
| 496 const int kChunkSize = 16 * 1024; | 496 const int kChunkSize = 16 * 1024; |
| 497 | 497 |
| 498 // Check the full paragraph instead if the paragraph is short, which saves | 498 // Check the full paragraph instead if the paragraph is short, which saves |
| 499 // the cost on sentence boundary finding. | 499 // the cost on sentence boundary finding. |
| 500 if (fullParagraphToCheck.rangeLength() <= kChunkSize) { | 500 if (fullParagraphToCheck.rangeLength() <= kChunkSize) { |
| 501 SpellCheckRequest* request = SpellCheckRequest::create(resolveTextChecki
ngTypeMask(textCheckingOptions), TextCheckingProcessBatch, paragraphRange, parag
raphRange, 0); | 501 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingTypeS
pelling, TextCheckingProcessBatch, paragraphRange, paragraphRange, 0); |
| 502 if (request) | 502 if (request) |
| 503 m_spellCheckRequester->requestCheckingFor(request); | 503 m_spellCheckRequester->requestCheckingFor(request); |
| 504 return; | 504 return; |
| 505 } | 505 } |
| 506 | 506 |
| 507 CharacterIterator checkRangeIterator(fullParagraphToCheck.checkingRange(), T
extIteratorEmitsObjectReplacementCharacter); | 507 CharacterIterator checkRangeIterator(fullParagraphToCheck.checkingRange(), T
extIteratorEmitsObjectReplacementCharacter); |
| 508 for (int requestNum = 0; !checkRangeIterator.atEnd(); requestNum++) { | 508 for (int requestNum = 0; !checkRangeIterator.atEnd(); requestNum++) { |
| 509 EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrang
e(0, kChunkSize); | 509 EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrang
e(0, kChunkSize); |
| 510 EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chu
nkRange) : expandRangeToSentenceBoundary(chunkRange); | 510 EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chu
nkRange) : expandRangeToSentenceBoundary(chunkRange); |
| 511 | 511 |
| 512 SpellCheckRequest* request = SpellCheckRequest::create(resolveTextChecki
ngTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkRange, paragraph
Range, requestNum); | 512 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingTypeS
pelling, TextCheckingProcessBatch, checkRange, paragraphRange, requestNum); |
| 513 if (request) | 513 if (request) |
| 514 m_spellCheckRequester->requestCheckingFor(request); | 514 m_spellCheckRequester->requestCheckingFor(request); |
| 515 | 515 |
| 516 if (!checkRangeIterator.atEnd()) { | 516 if (!checkRangeIterator.atEnd()) { |
| 517 checkRangeIterator.advance(1); | 517 checkRangeIterator.advance(1); |
| 518 // The layout should be already update due to the initialization of
checkRangeIterator, | 518 // The layout should be already update due to the initialization of
checkRangeIterator, |
| 519 // so comparePositions can be directly called. | 519 // so comparePositions can be directly called. |
| 520 if (comparePositions(chunkRange.endPosition(), checkRange.endPositio
n()) < 0) | 520 if (comparePositions(chunkRange.endPosition(), checkRange.endPositio
n()) < 0) |
| 521 checkRangeIterator.advance(TextIterator::rangeLength(chunkRange.
endPosition(), checkRange.endPosition())); | 521 checkRangeIterator.advance(TextIterator::rangeLength(chunkRange.
endPosition(), checkRange.endPosition())); |
| 522 } | 522 } |
| (...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 884 } | 884 } |
| 885 | 885 |
| 886 return false; | 886 return false; |
| 887 } | 887 } |
| 888 | 888 |
| 889 bool SpellChecker::selectionStartHasSpellingMarkerFor(int from, int length) cons
t | 889 bool SpellChecker::selectionStartHasSpellingMarkerFor(int from, int length) cons
t |
| 890 { | 890 { |
| 891 return selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length); | 891 return selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length); |
| 892 } | 892 } |
| 893 | 893 |
| 894 TextCheckingTypeMask SpellChecker::resolveTextCheckingTypeMask(TextCheckingTypeM
ask textCheckingOptions) | |
| 895 { | |
| 896 bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling; | |
| 897 bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar; | |
| 898 | |
| 899 TextCheckingTypeMask checkingTypes = 0; | |
| 900 if (shouldMarkSpelling) | |
| 901 checkingTypes |= TextCheckingTypeSpelling; | |
| 902 if (shouldMarkGrammar) | |
| 903 checkingTypes |= TextCheckingTypeGrammar; | |
| 904 | |
| 905 return checkingTypes; | |
| 906 } | |
| 907 | |
| 908 void SpellChecker::removeMarkers(const VisibleSelection& selection, DocumentMark
er::MarkerTypes markerTypes) | 894 void SpellChecker::removeMarkers(const VisibleSelection& selection, DocumentMark
er::MarkerTypes markerTypes) |
| 909 { | 895 { |
| 910 const EphemeralRange range = selection.toNormalizedEphemeralRange(); | 896 const EphemeralRange range = selection.toNormalizedEphemeralRange(); |
| 911 if (range.isNull()) | 897 if (range.isNull()) |
| 912 return; | 898 return; |
| 913 frame().document()->markers().removeMarkers(range, markerTypes); | 899 frame().document()->markers().removeMarkers(range, markerTypes); |
| 914 } | 900 } |
| 915 | 901 |
| 916 bool SpellChecker::unifiedTextCheckerEnabled() const | 902 bool SpellChecker::unifiedTextCheckerEnabled() const |
| 917 { | 903 { |
| (...skipping 16 matching lines...) Expand all Loading... |
| 934 visitor->trace(m_frame); | 920 visitor->trace(m_frame); |
| 935 visitor->trace(m_spellCheckRequester); | 921 visitor->trace(m_spellCheckRequester); |
| 936 } | 922 } |
| 937 | 923 |
| 938 void SpellChecker::prepareForLeakDetection() | 924 void SpellChecker::prepareForLeakDetection() |
| 939 { | 925 { |
| 940 m_spellCheckRequester->prepareForLeakDetection(); | 926 m_spellCheckRequester->prepareForLeakDetection(); |
| 941 } | 927 } |
| 942 | 928 |
| 943 } // namespace blink | 929 } // namespace blink |
| OLD | NEW |