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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 applyCommand(ReplaceSelectionCommand::create(m_frame->document(), fragment, options, EditActionPaste)); | 414 applyCommand(ReplaceSelectionCommand::create(m_frame->document(), fragment, options, EditActionPaste)); |
415 revealSelectionAfterEditingOperation(); | 415 revealSelectionAfterEditingOperation(); |
416 | 416 |
417 if (m_frame->selection()->isInPasswordField() || !isContinuousSpellCheckingE nabled()) | 417 if (m_frame->selection()->isInPasswordField() || !isContinuousSpellCheckingE nabled()) |
418 return; | 418 return; |
419 Node* nodeToCheck = m_frame->selection()->rootEditableElement(); | 419 Node* nodeToCheck = m_frame->selection()->rootEditableElement(); |
420 if (!nodeToCheck) | 420 if (!nodeToCheck) |
421 return; | 421 return; |
422 | 422 |
423 RefPtr<Range> rangeToCheck = Range::create(m_frame->document(), firstPositio nInNode(nodeToCheck), lastPositionInNode(nodeToCheck)); | 423 RefPtr<Range> rangeToCheck = Range::create(m_frame->document(), firstPositio nInNode(nodeToCheck), lastPositionInNode(nodeToCheck)); |
424 m_spellChecker->requestCheckingFor(SpellCheckRequest::create(resolveTextChec kingTypeMask(TextCheckingTypeSpelling | TextCheckingTypeGrammar), TextCheckingPr ocessBatch, rangeToCheck, rangeToCheck)); | 424 markAllMisspellingsAndBadGrammarInRanges(resolveTextCheckingTypeMask(TextChe ckingTypeSpelling | TextCheckingTypeGrammar), rangeToCheck.get(), rangeToCheck.g et()); |
425 } | 425 } |
426 | 426 |
427 void Editor::replaceSelectionWithText(const String& text, bool selectReplacement , bool smartReplace) | 427 void Editor::replaceSelectionWithText(const String& text, bool selectReplacement , bool smartReplace) |
428 { | 428 { |
429 replaceSelectionWithFragment(createFragmentFromText(selectedRange().get(), t ext), selectReplacement, smartReplace, true); | 429 replaceSelectionWithFragment(createFragmentFromText(selectedRange().get(), t ext), selectReplacement, smartReplace, true); |
430 } | 430 } |
431 | 431 |
432 PassRefPtr<Range> Editor::selectedRange() | 432 PassRefPtr<Range> Editor::selectedRange() |
433 { | 433 { |
434 if (!m_frame) | 434 if (!m_frame) |
(...skipping 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1479 | 1479 |
1480 void Editor::markBadGrammar(const VisibleSelection& selection) | 1480 void Editor::markBadGrammar(const VisibleSelection& selection) |
1481 { | 1481 { |
1482 RefPtr<Range> firstMisspellingRange; | 1482 RefPtr<Range> firstMisspellingRange; |
1483 markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange); | 1483 markMisspellingsOrBadGrammar(selection, false, firstMisspellingRange); |
1484 } | 1484 } |
1485 | 1485 |
1486 void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textC heckingOptions, Range* spellingRange, Range* grammarRange) | 1486 void Editor::markAllMisspellingsAndBadGrammarInRanges(TextCheckingTypeMask textC heckingOptions, Range* spellingRange, Range* grammarRange) |
1487 { | 1487 { |
1488 ASSERT(m_frame); | 1488 ASSERT(m_frame); |
1489 ASSERT(unifiedTextCheckerEnabled()); | |
1490 | 1489 |
1491 bool shouldMarkGrammar = textCheckingOptions & TextCheckingTypeGrammar; | 1490 bool shouldMarkGrammar = (textCheckingOptions & TextCheckingTypeGrammar) && isGrammarCheckingEnabled(); |
1491 bool shouldMarkSpellling = (textCheckingOptions & TextCheckingTypeSpelling) && isContinuousSpellCheckingEnabled(); | |
1492 | |
1493 if (!shouldMarkSpellling && !shouldMarkGrammar) | |
1494 return; | |
1492 | 1495 |
1493 // This function is called with selections already expanded to word boundari es. | 1496 // This function is called with selections already expanded to word boundari es. |
1494 if (!client() || !spellingRange || (shouldMarkGrammar && !grammarRange)) | 1497 if (!client() || !spellingRange || (shouldMarkGrammar && !grammarRange)) |
1495 return; | 1498 return; |
1496 | 1499 |
1497 // If we're not in an editable node, bail. | 1500 // If we're not in an editable node, bail. |
1498 Node* editableNode = spellingRange->startContainer(); | 1501 Node* editableNode = spellingRange->startContainer(); |
1499 if (!editableNode || !editableNode->rendererIsEditable()) | 1502 if (!editableNode || !editableNode->rendererIsEditable()) |
1500 return; | 1503 return; |
1501 | 1504 |
1502 if (!isSpellCheckingEnabledFor(editableNode)) | 1505 if (!isSpellCheckingEnabledFor(editableNode)) |
1503 return; | 1506 return; |
1504 | 1507 |
1505 Range* rangeToCheck = shouldMarkGrammar ? grammarRange : spellingRange; | 1508 Range* rangeToCheck = shouldMarkGrammar ? grammarRange : spellingRange; |
1506 TextCheckingParagraph paragraphToCheck(rangeToCheck); | 1509 TextCheckingParagraph fullParagraphToCheck(rangeToCheck); |
1507 if (paragraphToCheck.isRangeEmpty() || paragraphToCheck.isEmpty()) | 1510 if (fullParagraphToCheck.isRangeEmpty() || fullParagraphToCheck.isEmpty()) |
1508 return; | 1511 return; |
1509 RefPtr<Range> paragraphRange = paragraphToCheck.paragraphRange(); | |
1510 | 1512 |
1511 bool asynchronous = m_frame && m_frame->settings() && m_frame->settings()->a synchronousSpellCheckingEnabled(); | 1513 // Since the text may be quite big chunk it up and adjust to the sentence bo undary. |
1514 const int kChunkSize = 16 * 1024; | |
1515 int start = fullParagraphToCheck.checkingStart(); | |
1516 int end = fullParagraphToCheck.checkingEnd(); | |
1517 start = std::min(start, end); | |
1518 end = std::max(start, end); | |
1519 const int loopNum = (end - start + kChunkSize - 1) / (kChunkSize); | |
please use gerrit instead
2013/08/13 21:54:21
Nit: rename loopNum to "numChunksToCheck". (Number
| |
1520 int currentChunkStart = start; | |
1521 for (int iter = 0; iter < loopNum; ++iter) { | |
1522 RefPtr<Range> checkRange = fullParagraphToCheck.subrange(currentChunkSta rt, kChunkSize); | |
1523 setStart(checkRange.get(), startOfSentence(checkRange->startPosition())) ; | |
1524 setEnd(checkRange.get(), endOfSentence(checkRange->endPosition())); | |
1525 TextCheckingParagraph sentenceToCheck(checkRange, checkRange); | |
1512 | 1526 |
1513 // In asynchronous mode, we intentionally check paragraph-wide sentence. | 1527 currentChunkStart += sentenceToCheck.checkingLength(); |
1514 RefPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTextChe ckingTypeMask(textCheckingOptions), TextCheckingProcessIncremental, asynchronous ? paragraphRange : rangeToCheck, paragraphRange); | |
1515 | 1528 |
1516 if (asynchronous) { | 1529 bool asynchronous = m_frame && m_frame->settings() && m_frame->settings( )->asynchronousSpellCheckingEnabled(); |
please use gerrit instead
2013/08/13 21:54:21
The "asynchronous" variable can live outside of th
| |
1517 m_spellChecker->requestCheckingFor(request); | 1530 |
1531 RefPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTex tCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkRange, ch eckRange, iter); | |
1532 | |
1533 if (asynchronous) { | |
1534 m_spellChecker->requestCheckingFor(request); | |
1535 continue; | |
1536 } | |
1537 | |
1538 Vector<TextCheckingResult> results; | |
1539 checkTextOfParagraph(textChecker(), sentenceToCheck.text(), resolveTextC heckingTypeMask(textCheckingOptions), results); | |
please use gerrit instead
2013/08/13 21:54:21
If you're splitting up the spellcheck requests for
| |
1540 markAndReplaceFor(request, results); | |
1518 return; | 1541 return; |
please use gerrit instead
2013/08/13 21:54:21
It's not clear from this code that you spellcheck
| |
1519 } | 1542 } |
1520 | |
1521 Vector<TextCheckingResult> results; | |
1522 checkTextOfParagraph(textChecker(), paragraphToCheck.text(), resolveTextChec kingTypeMask(textCheckingOptions), results); | |
1523 markAndReplaceFor(request, results); | |
1524 } | 1543 } |
1525 | 1544 |
1526 void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect or<TextCheckingResult>& results) | 1545 void Editor::markAndReplaceFor(PassRefPtr<SpellCheckRequest> request, const Vect or<TextCheckingResult>& results) |
1527 { | 1546 { |
1528 ASSERT(request); | 1547 ASSERT(request); |
1529 | 1548 |
1530 TextCheckingTypeMask textCheckingOptions = request->data().mask(); | 1549 TextCheckingTypeMask textCheckingOptions = request->data().mask(); |
1531 TextCheckingParagraph paragraph(request->checkingRange(), request->paragraph Range()); | 1550 TextCheckingParagraph paragraph(request->checkingRange(), request->paragraph Range()); |
1532 | 1551 |
1533 bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling; | 1552 bool shouldMarkSpelling = textCheckingOptions & TextCheckingTypeSpelling; |
(...skipping 15 matching lines...) Expand all Loading... | |
1549 if (selectionOffset > 0 && (static_cast<unsigned>(selectionOffset) > paragraph.text().length() || paragraph.textCharAt(selectionOffset - 1) == newli neCharacter)) | 1568 if (selectionOffset > 0 && (static_cast<unsigned>(selectionOffset) > paragraph.text().length() || paragraph.textCharAt(selectionOffset - 1) == newli neCharacter)) |
1550 adjustSelectionForParagraphBoundaries = true; | 1569 adjustSelectionForParagraphBoundaries = true; |
1551 if (selectionOffset > 0 && static_cast<unsigned>(selectionOffset) <= paragraph.text().length() && isAmbiguousBoundaryCharacter(paragraph.textCharAt( selectionOffset - 1))) | 1570 if (selectionOffset > 0 && static_cast<unsigned>(selectionOffset) <= paragraph.text().length() && isAmbiguousBoundaryCharacter(paragraph.textCharAt( selectionOffset - 1))) |
1552 ambiguousBoundaryOffset = selectionOffset - 1; | 1571 ambiguousBoundaryOffset = selectionOffset - 1; |
1553 } | 1572 } |
1554 } | 1573 } |
1555 | 1574 |
1556 for (unsigned i = 0; i < results.size(); i++) { | 1575 for (unsigned i = 0; i < results.size(); i++) { |
1557 int spellingRangeEndOffset = paragraph.checkingEnd(); | 1576 int spellingRangeEndOffset = paragraph.checkingEnd(); |
1558 const TextCheckingResult* result = &results[i]; | 1577 const TextCheckingResult* result = &results[i]; |
1559 int resultLocation = result->location; | 1578 int resultLocation = result->location + paragraph.checkingStart(); |
1560 int resultLength = result->length; | 1579 int resultLength = result->length; |
1561 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res ultLocation + resultLength == ambiguousBoundaryOffset; | 1580 bool resultEndsAtAmbiguousBoundary = ambiguousBoundaryOffset >= 0 && res ultLocation + resultLength == ambiguousBoundaryOffset; |
1562 | 1581 |
1563 // Only mark misspelling if: | 1582 // Only mark misspelling if: |
1564 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false. | 1583 // 1. Current text checking isn't done for autocorrection, in which case shouldMarkSpelling is false. |
1565 // 2. Result falls within spellingRange. | 1584 // 2. Result falls within spellingRange. |
1566 // 3. The word in question doesn't end at an ambiguous boundary. For ins tance, we would not mark | 1585 // 3. The word in question doesn't end at an ambiguous boundary. For ins tance, we would not mark |
1567 // "wouldn'" as misspelled right after apostrophe is typed. | 1586 // "wouldn'" as misspelled right after apostrophe is typed. |
1568 if (shouldMarkSpelling && result->type == TextCheckingTypeSpelling && re sultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= sp ellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { | 1587 if (shouldMarkSpelling && result->type == TextCheckingTypeSpelling && re sultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= sp ellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) { |
1569 ASSERT(resultLength > 0 && resultLocation >= 0); | 1588 ASSERT(resultLength > 0 && resultLocation >= 0); |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2178 return WebCore::unifiedTextCheckerEnabled(m_frame); | 2197 return WebCore::unifiedTextCheckerEnabled(m_frame); |
2179 } | 2198 } |
2180 | 2199 |
2181 void Editor::toggleOverwriteModeEnabled() | 2200 void Editor::toggleOverwriteModeEnabled() |
2182 { | 2201 { |
2183 m_overwriteModeEnabled = !m_overwriteModeEnabled; | 2202 m_overwriteModeEnabled = !m_overwriteModeEnabled; |
2184 frame()->selection()->setShouldShowBlockCursor(m_overwriteModeEnabled); | 2203 frame()->selection()->setShouldShowBlockCursor(m_overwriteModeEnabled); |
2185 }; | 2204 }; |
2186 | 2205 |
2187 } // namespace WebCore | 2206 } // namespace WebCore |
OLD | NEW |