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 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 320 |
321 const EphemeralRange& range = selection.toNormalizedEphemeralRange(); | 321 const EphemeralRange& range = selection.toNormalizedEphemeralRange(); |
322 if (range.isNull()) | 322 if (range.isNull()) |
323 return; | 323 return; |
324 | 324 |
325 // If we're not in an editable node, bail. | 325 // If we're not in an editable node, bail. |
326 Node* editableNode = range.startPosition().computeContainerNode(); | 326 Node* editableNode = range.startPosition().computeContainerNode(); |
327 if (!editableNode || !hasEditableStyle(*editableNode)) | 327 if (!editableNode || !hasEditableStyle(*editableNode)) |
328 return; | 328 return; |
329 | 329 |
330 chunkAndMarkAllMisspellingsAndBadGrammar(range); | 330 TextCheckingParagraph fullParagraphToCheck(expandRangeToSentenceBoundary(ran
ge)); |
| 331 chunkAndMarkAllMisspellingsAndBadGrammar(fullParagraphToCheck); |
331 } | 332 } |
332 | 333 |
333 void SpellChecker::markMisspellingsAfterApplyingCommand(const CompositeEditComma
nd& cmd) | 334 void SpellChecker::markMisspellingsAfterApplyingCommand(const CompositeEditComma
nd& cmd) |
334 { | 335 { |
335 if (!isSpellCheckingEnabled()) | 336 if (!isSpellCheckingEnabled()) |
336 return; | 337 return; |
337 if (!isSpellCheckingEnabledFor(cmd.endingSelection())) | 338 if (!isSpellCheckingEnabledFor(cmd.endingSelection())) |
338 return; | 339 return; |
339 | 340 |
340 // Use type-based conditioning instead of polymorphism so that all spell | 341 // Use type-based conditioning instead of polymorphism so that all spell |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 const Element* focusedElement = focusedNode->isElementNode() ? toElement(foc
usedNode) : focusedNode->parentElement(); | 409 const Element* focusedElement = focusedNode->isElementNode() ? toElement(foc
usedNode) : focusedNode->parentElement(); |
409 if (!focusedElement) | 410 if (!focusedElement) |
410 return false; | 411 return false; |
411 return focusedElement->isSpellCheckingEnabled(); | 412 return focusedElement->isSpellCheckingEnabled(); |
412 } | 413 } |
413 | 414 |
414 void SpellChecker::markMisspellingsAfterReplaceSelectionCommand(const ReplaceSel
ectionCommand& cmd) | 415 void SpellChecker::markMisspellingsAfterReplaceSelectionCommand(const ReplaceSel
ectionCommand& cmd) |
415 { | 416 { |
416 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterReplaceSelectionCo
mmand"); | 417 TRACE_EVENT0("blink", "SpellChecker::markMisspellingsAfterReplaceSelectionCo
mmand"); |
417 | 418 |
418 chunkAndMarkAllMisspellingsAndBadGrammar(cmd.insertedRange()); | 419 const EphemeralRange& insertedRange = cmd.insertedRange(); |
| 420 if (insertedRange.isNull()) |
| 421 return; |
| 422 |
| 423 Node* node = cmd.endingSelection().rootEditableElement(); |
| 424 if (!node) |
| 425 return; |
| 426 |
| 427 EphemeralRange paragraphRange(Position::firstPositionInNode(node), Position:
:lastPositionInNode(node)); |
| 428 TextCheckingParagraph textToCheck(insertedRange, paragraphRange); |
| 429 chunkAndMarkAllMisspellingsAndBadGrammar(textToCheck); |
419 } | 430 } |
420 | 431 |
421 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(const EphemeralRange
& range) | 432 void SpellChecker::chunkAndMarkAllMisspellingsAndBadGrammar(const TextCheckingPa
ragraph& fullParagraphToCheck) |
422 { | 433 { |
423 if (range.isNull()) | 434 if (fullParagraphToCheck.isEmpty()) |
424 return; | 435 return; |
425 | 436 const EphemeralRange& paragraphRange = fullParagraphToCheck.paragraphRange()
; |
426 Node* rootEditableElement = rootEditableElementOf(range.startPosition()); | |
427 if (!rootEditableElement) | |
428 return; | |
429 | |
430 const EphemeralRange& fullTextRange = EphemeralRange::rangeOfContents(*rootE
ditableElement); | |
431 int fullTextLength = TextIterator::rangeLength(fullTextRange.startPosition()
, fullTextRange.endPosition()); | |
432 if (fullTextLength <= 0) | |
433 return; | |
434 | 437 |
435 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. | 438 // Since the text may be quite big chunk it up and adjust to the sentence bo
undary. |
436 const int kChunkSize = 16 * 1024; | 439 const int kChunkSize = 16 * 1024; |
437 | 440 |
438 // Check the full paragraph instead if the paragraph is short, which saves | 441 // Check the full paragraph instead if the paragraph is short, which saves |
439 // the cost on sentence boundary finding. | 442 // the cost on sentence boundary finding. |
440 if (fullTextLength <= kChunkSize) { | 443 if (fullParagraphToCheck.rangeLength() <= kChunkSize) { |
441 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingProce
ssBatch, fullTextRange, 0); | 444 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingProce
ssBatch, paragraphRange, 0); |
442 if (request) | 445 if (request) |
443 m_spellCheckRequester->requestCheckingFor(request); | 446 m_spellCheckRequester->requestCheckingFor(request); |
444 return; | 447 return; |
445 } | 448 } |
446 | 449 |
447 CharacterIterator checkRangeIterator(range, TextIteratorEmitsObjectReplaceme
ntCharacter); | 450 CharacterIterator checkRangeIterator(fullParagraphToCheck.checkingRange(), T
extIteratorEmitsObjectReplacementCharacter); |
448 for (int requestNum = 0; !checkRangeIterator.atEnd(); requestNum++) { | 451 for (int requestNum = 0; !checkRangeIterator.atEnd(); requestNum++) { |
449 EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrang
e(0, kChunkSize); | 452 EphemeralRange chunkRange = checkRangeIterator.calculateCharacterSubrang
e(0, kChunkSize); |
450 EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chu
nkRange) : expandRangeToSentenceBoundary(chunkRange); | 453 EphemeralRange checkRange = requestNum ? expandEndToSentenceBoundary(chu
nkRange) : expandRangeToSentenceBoundary(chunkRange); |
451 | 454 |
452 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingProce
ssBatch, checkRange, requestNum); | 455 SpellCheckRequest* request = SpellCheckRequest::create(TextCheckingProce
ssBatch, checkRange, requestNum); |
453 if (request) | 456 if (request) |
454 m_spellCheckRequester->requestCheckingFor(request); | 457 m_spellCheckRequester->requestCheckingFor(request); |
455 | 458 |
456 if (!checkRangeIterator.atEnd()) { | 459 if (!checkRangeIterator.atEnd()) { |
457 checkRangeIterator.advance(1); | 460 checkRangeIterator.advance(1); |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
940 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); | 943 VisiblePosition newParagraphStart = startOfNextParagraph(createVisiblePo
sition(paragraphEnd)); |
941 paragraphStart = newParagraphStart.toParentAnchoredPosition(); | 944 paragraphStart = newParagraphStart.toParentAnchoredPosition(); |
942 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); | 945 paragraphEnd = endOfParagraph(newParagraphStart).toParentAnchoredPositio
n(); |
943 firstIteration = false; | 946 firstIteration = false; |
944 totalLengthProcessed += currentLength; | 947 totalLengthProcessed += currentLength; |
945 } | 948 } |
946 return std::make_pair(firstFoundItem, firstFoundOffset); | 949 return std::make_pair(firstFoundItem, firstFoundOffset); |
947 } | 950 } |
948 | 951 |
949 } // namespace blink | 952 } // namespace blink |
OLD | NEW |