Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(351)

Side by Side Diff: Source/core/editing/Editor.cpp

Issue 21130005: Trigger spell check/remove markers if spell checker gets enabled/disabled. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: copy&paste bug fixed Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 static const int chunkSize = 8 * 1024;
tony 2013/08/12 19:45:15 Nit: kChunkSize. Also, I'm not sure static buys y
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 + chunkSize - 1) / (chunkSize);
1520 int currentChunkStart = start;
1521 for (int iter = 0; iter < loopNum; ++iter) {
1522 RefPtr<Range> checkRange = fullParagraphToCheck.subrange(currentChunkSta rt, chunkSize);
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();
1517 m_spellChecker->requestCheckingFor(request); 1530
1531 RefPtr<SpellCheckRequest> request = SpellCheckRequest::create(resolveTex tCheckingTypeMask(textCheckingOptions), TextCheckingProcessBatch, checkRange, ch eckRange, 0/*iter*/);
tony 2013/08/12 19:45:15 I don't think you need to pass in the last paramet
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);
1540 markAndReplaceFor(request, results);
1518 return; 1541 return;
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698