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 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 |