Changeset 70826 in webkit


Ignore:
Timestamp:
Oct 28, 2010 4:45:26 PM (13 years ago)
Author:
commit-queue@webkit.org
Message:

2010-10-28 Jia Pu <jpu@apple.com>

Reviewed by Dan Bernstein.

Editing a word with misspell or autocorrection underline should remove the underline when the editing changes the word.
https://bugs.webkit.org/show_bug.cgi?id=48078
<rdar://problem/8579155>

  • platform/mac-leopard/Skipped: New tests don't apply to this platform.
  • platform/mac-snowleopard/Skipped: Ditto.
  • platform/mac-tiger/Skipped: Ditto.
  • platform/mac-wk2/Skipped: Ditto.
  • platform/mac/editing/spelling/autocorrection-delete-expected.checksum: Updated expected test result.
  • platform/mac/editing/spelling/autocorrection-delete-expected.png: Ditto.
  • platform/mac/editing/spelling/editing-multiple-words-with-markers-expected.txt: Added.
  • platform/mac/editing/spelling/editing-multiple-words-with-markers.html: Added.
  • platform/mac/editing/spelling/editing-word-with-marker-1-expected.txt: Added.
  • platform/mac/editing/spelling/editing-word-with-marker-1.html: Added.
  • platform/mac/editing/spelling/editing-word-with-marker-2-expected.txt: Added.
  • platform/mac/editing/spelling/editing-word-with-marker-2.html: Added.

2010-10-28 Jia Pu <jpu@apple.com>

Reviewed by Dan Bernstein.

Editing a word with misspell or autocorrection underline should remove the underline when the editing changes the word.
https://bugs.webkit.org/show_bug.cgi?id=48078
<rdar://problem/8579155>

Tests: platform/mac/editing/spelling/editing-multiple-words-with-markers.html

platform/mac/editing/spelling/editing-word-with-marker-1.html
platform/mac/editing/spelling/editing-word-with-marker-2.html

This patch is part of on-going improvement of autocorrection feature on Mac OS X. When an editing
occurs, if it affects words (by deleting/inserting characters, spliting word, merging words) that
have Spelling and/or CorrectionIndicator markers, we want to remove the markers. If subsequntial
spelling checking finds spelling error in newlly formed words, it will add the markers back in.

  • dom/DocumentMarker.h: Changed MarkerType to bit masks to make search multiple types easier.
  • dom/DocumentMarkerController.cpp: Refactored two removeMarkers() methods to support remove markers with specific type from a node. (WebCore::DocumentMarkerController::removeMarkers): Changed signature to remove marker with specific type. (WebCore::DocumentMarkerController::removeMarkersFromMarkerMapVectorPair): Refactoring. (WebCore::DocumentMarkerController::hasMarkers): Convenience method to search markers in range.
  • dom/DocumentMarkerController.h: Added new methods and matched new signature of removeMarkers().
  • editing/Editor.cpp: (WebCore::Editor::respondToChangedContents): Remove existing markers if the change formed new word. (WebCore::Editor::cut): Remove markers on words that will be modified by this editing. (WebCore::Editor::paste): Ditto. (WebCore::Editor::pasteAsPlainText): Ditto. (WebCore::Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited): Main logic for removing markers on words affected by editing.
  • editing/Editor.h: Added removeSpellAndCorrectionMarkersFromWordsToBeEdited(). Added REMOVE_MARKERS_UPON_EDITING and SUPPORT_AUTOCORRECTION_PANEL macro to improve readability.
  • editing/TypingCommand.cpp: (WebCore::TypingCommand::insertText): Remove markers on words that will be modified by this editing. (WebCore::TypingCommand::deleteKeyPressed): Ditto. (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
Location:
trunk
Files:
6 added
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r70825 r70826  
     12010-10-28  Jia Pu  <jpu@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        Editing a word with misspell or autocorrection underline should remove the underline when the editing changes the word.
     6        https://bugs.webkit.org/show_bug.cgi?id=48078
     7        <rdar://problem/8579155>
     8
     9        * platform/mac-leopard/Skipped: New tests don't apply to this platform.
     10        * platform/mac-snowleopard/Skipped: Ditto.
     11        * platform/mac-tiger/Skipped: Ditto.
     12        * platform/mac-wk2/Skipped: Ditto.
     13        * platform/mac/editing/spelling/autocorrection-delete-expected.checksum: Updated expected test result.
     14        * platform/mac/editing/spelling/autocorrection-delete-expected.png: Ditto.
     15        * platform/mac/editing/spelling/editing-multiple-words-with-markers-expected.txt: Added.
     16        * platform/mac/editing/spelling/editing-multiple-words-with-markers.html: Added.
     17        * platform/mac/editing/spelling/editing-word-with-marker-1-expected.txt: Added.
     18        * platform/mac/editing/spelling/editing-word-with-marker-1.html: Added.
     19        * platform/mac/editing/spelling/editing-word-with-marker-2-expected.txt: Added.
     20        * platform/mac/editing/spelling/editing-word-with-marker-2.html: Added.
     21
    1222010-10-28  Brian Weinstein  <bweinstein@apple.com>
    223
  • trunk/LayoutTests/platform/mac-leopard/Skipped

    r70803 r70826  
    103103platform/mac/editing/spelling/delete-into-autocorrected-word.html
    104104platform/mac/editing/spelling/delete-into-misspelled-word.html
     105platform/mac/editing/spelling/editing-multiple-words-with-markers.html
     106platform/mac/editing/spelling/editing-word-with-marker-1.html
     107platform/mac/editing/spelling/editing-word-with-marker-2.html
    105108platform/mac/editing/spelling/forward-delete-into-autocorrected-word.html
    106109platform/mac/editing/spelling/move-cursor-around-misspelled-word.html
  • trunk/LayoutTests/platform/mac-snowleopard/Skipped

    r70071 r70826  
    138138platform/mac/editing/spelling/delete-into-autocorrected-word.html
    139139platform/mac/editing/spelling/delete-into-misspelled-word.html
     140platform/mac/editing/spelling/editing-multiple-words-with-markers.html
     141platform/mac/editing/spelling/editing-word-with-marker-1.html
     142platform/mac/editing/spelling/editing-word-with-marker-2.html
    140143platform/mac/editing/spelling/forward-delete-into-autocorrected-word.html
    141144platform/mac/editing/spelling/move-cursor-around-misspelled-word.html
  • trunk/LayoutTests/platform/mac-tiger/Skipped

    r70071 r70826  
    213213platform/mac/editing/spelling/delete-into-autocorrected-word.html
    214214platform/mac/editing/spelling/delete-into-misspelled-word.html
     215platform/mac/editing/spelling/editing-multiple-words-with-markers.html
     216platform/mac/editing/spelling/editing-word-with-marker-1.html
     217platform/mac/editing/spelling/editing-word-with-marker-2.html
    215218platform/mac/editing/spelling/forward-delete-into-autocorrected-word.html
    216219platform/mac/editing/spelling/move-cursor-around-misspelled-word.html
  • trunk/LayoutTests/platform/mac-wk2/Skipped

    r70779 r70826  
    482482platform/mac/editing/spelling/delete-into-autocorrected-word.html
    483483platform/mac/editing/spelling/delete-into-misspelled-word.html
     484platform/mac/editing/spelling/editing-multiple-words-with-markers.html
     485platform/mac/editing/spelling/editing-word-with-marker-1.html
     486platform/mac/editing/spelling/editing-word-with-marker-2.html
    484487platform/mac/editing/spelling/forward-delete-into-autocorrected-word.html
    485488platform/mac/editing/spelling/move-cursor-around-misspelled-word.html
  • trunk/LayoutTests/platform/mac/editing/spelling/autocorrection-delete-expected.checksum

    r70071 r70826  
    1 a7f7bb68b8cb6b37695a4e7b4f69a847
     139685c692f4697ce0b957e38a07a2357
  • trunk/WebCore/ChangeLog

    r70825 r70826  
     12010-10-28  Jia Pu  <jpu@apple.com>
     2
     3        Reviewed by Dan Bernstein.
     4
     5        Editing a word with misspell or autocorrection underline should remove the underline when the editing changes the word.
     6        https://bugs.webkit.org/show_bug.cgi?id=48078
     7        <rdar://problem/8579155>
     8
     9        Tests: platform/mac/editing/spelling/editing-multiple-words-with-markers.html
     10               platform/mac/editing/spelling/editing-word-with-marker-1.html
     11               platform/mac/editing/spelling/editing-word-with-marker-2.html
     12
     13        This patch is part of on-going improvement of autocorrection feature on Mac OS X. When an editing
     14        occurs, if it affects words (by deleting/inserting characters, spliting word, merging words) that
     15        have Spelling and/or CorrectionIndicator markers, we want to remove the markers. If subsequntial
     16        spelling checking finds spelling error in newlly formed words, it will add the markers back in.
     17
     18        * dom/DocumentMarker.h: Changed MarkerType to bit masks to make search multiple types easier.
     19
     20        * dom/DocumentMarkerController.cpp: Refactored two removeMarkers() methods to support remove
     21          markers with specific type from a node.
     22        (WebCore::DocumentMarkerController::removeMarkers): Changed signature to remove marker with specific type.
     23        (WebCore::DocumentMarkerController::removeMarkersFromMarkerMapVectorPair): Refactoring.
     24        (WebCore::DocumentMarkerController::hasMarkers): Convenience method to search markers in range.
     25
     26        * dom/DocumentMarkerController.h: Added new methods and matched new signature of removeMarkers().
     27
     28        * editing/Editor.cpp:
     29        (WebCore::Editor::respondToChangedContents): Remove existing markers if the change formed new word.
     30        (WebCore::Editor::cut): Remove markers on words that will be modified by this editing.
     31        (WebCore::Editor::paste): Ditto.
     32        (WebCore::Editor::pasteAsPlainText): Ditto.
     33        (WebCore::Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited): Main logic for removing
     34          markers on words affected by editing.
     35
     36        * editing/Editor.h: Added removeSpellAndCorrectionMarkersFromWordsToBeEdited().  Added
     37          REMOVE_MARKERS_UPON_EDITING and SUPPORT_AUTOCORRECTION_PANEL macro to improve readability.
     38
     39        * editing/TypingCommand.cpp:
     40        (WebCore::TypingCommand::insertText): Remove markers on words that will be modified by this editing.
     41        (WebCore::TypingCommand::deleteKeyPressed): Ditto.
     42        (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
     43
    1442010-10-28  Brian Weinstein  <bweinstein@apple.com>
    245
  • trunk/WebCore/dom/DocumentMarker.h

    r68243 r70826  
    3434// for all types other than type TextMatch.
    3535struct DocumentMarker {
    36 
    3736    enum MarkerType {
    38         AllMarkers  = -1,
    39         Spelling,
    40         Grammar,
    41         TextMatch,
    42         Replacement,
    43         CorrectionIndicator,
    44         RejectedCorrection
     37        Spelling = 1 << 0,
     38        Grammar = 1 << 1,
     39        TextMatch = 1 << 2,
     40        Replacement = 1 << 3,
     41        CorrectionIndicator = 1 << 4,
     42        RejectedCorrection = 1 << 5,
     43        AllMarkers = Spelling | Grammar | TextMatch | Replacement | CorrectionIndicator | RejectedCorrection
    4544    };
    46 
    4745    MarkerType type;
     46    typedef unsigned MarkerTypes;
    4847    unsigned startOffset;
    4948    unsigned endOffset;
  • trunk/WebCore/dom/DocumentMarkerController.cpp

    r65787 r70826  
    322322}
    323323
    324 void DocumentMarkerController::removeMarkers(Node* node)
    325 {
    326     MarkerMap::iterator i = m_markers.find(node);
    327     if (i != m_markers.end()) {
    328         delete i->second;
    329         m_markers.remove(i);
    330         if (RenderObject* renderer = node->renderer())
    331             renderer->repaint();
    332     }
     324void DocumentMarkerController::removeMarkers(Node* node, DocumentMarker::MarkerType markerType)
     325{
     326    MarkerMap::iterator iterator = m_markers.find(node);
     327    if (iterator != m_markers.end())
     328        removeMarkersFromMarkerMapVectorPair(node, iterator->second, markerType);
    333329}
    334330
     
    340336    for (MarkerMap::iterator i = markerMapCopy.begin(); i != end; ++i) {
    341337        Node* node = i->first.get();
    342         bool nodeNeedsRepaint = false;
    343 
    344         // inner loop: process each marker in the current node
    345338        MarkerMapVectorPair* vectorPair = i->second;
     339        removeMarkersFromMarkerMapVectorPair(node, vectorPair, markerType);
     340    }
     341}
     342
     343// This function may release node and vectorPair.
     344void DocumentMarkerController::removeMarkersFromMarkerMapVectorPair(Node* node, MarkerMapVectorPair* vectorPair, DocumentMarker::MarkerType markerType)
     345{
     346    if (markerType == DocumentMarker::AllMarkers) {
     347        delete vectorPair;
     348        m_markers.remove(node);
     349        if (RenderObject* renderer = node->renderer())
     350            renderer->repaint();
     351    } else {
     352        bool needsRepaint = false;
    346353        Vector<DocumentMarker>& markers = vectorPair->first;
    347354        Vector<IntRect>& rects = vectorPair->second;
     
    351358
    352359            // skip nodes that are not of the specified type
    353             if (marker.type != markerType && markerType != DocumentMarker::AllMarkers) {
     360            if (marker.type != markerType) {
    354361                ++i;
    355362                continue;
     
    359366            markers.remove(i);
    360367            rects.remove(i);
    361             nodeNeedsRepaint = true;
    362             // markerIterator now points to the next node
    363         }
    364 
    365         // Redraw the node if it changed. Do this before the node is removed from m_markers, since 
     368            needsRepaint = true;
     369            // i now is the index of the next marker
     370        }
     371
     372        // Redraw the node if it changed. Do this before the node is removed from m_markers, since
    366373        // m_markers might contain the last reference to the node.
    367         if (nodeNeedsRepaint) {
     374        if (needsRepaint) {
    368375            RenderObject* renderer = node->renderer();
    369376            if (renderer)
     
    525532}
    526533
     534bool DocumentMarkerController::hasMarkers(Range* range, DocumentMarker::MarkerTypes markerTypes)
     535{
     536    if (m_markers.isEmpty())
     537        return false;
     538
     539    Node* startContainer = range->startContainer();
     540    ASSERT(startContainer);
     541    Node* endContainer = range->endContainer();
     542    ASSERT(endContainer);
     543
     544    Node* pastLastNode = range->pastLastNode();
     545    for (Node* node = range->firstNode(); node != pastLastNode; node = node->traverseNextNode()) {
     546        Vector<DocumentMarker> markers = markersForNode(node);
     547        Vector<DocumentMarker>::const_iterator end = markers.end();
     548        for (Vector<DocumentMarker>::const_iterator it = markers.begin(); it != end; ++it) {
     549            if (!(markerTypes & it->type))
     550                continue;
     551            if (node == startContainer && node == endContainer) {
     552                // The range spans only one node.
     553                if (it->endOffset > static_cast<unsigned>(range->startOffset()) && it->startOffset < static_cast<unsigned>(range->endOffset()))
     554                    return true;
     555            } else {
     556                if (node == startContainer) {
     557                    if (it->endOffset > static_cast<unsigned>(range->startOffset()))
     558                        return true;
     559                } else if (node == endContainer) {
     560                    if (it->startOffset < static_cast<unsigned>(range->endOffset()))
     561                        return true;
     562                } else
     563                    return true;
     564            }
     565        }
     566    }
     567    return false;
     568}
     569
    527570} // namespace WebCore
  • trunk/WebCore/dom/DocumentMarkerController.h

    r65787 r70826  
    4747    void addMarker(Node*, DocumentMarker);
    4848    void copyMarkers(Node* srcNode, unsigned startOffset, int length, Node* dstNode, int delta, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
     49    bool hasMarkers(Range*, DocumentMarker::MarkerTypes = DocumentMarker::AllMarkers);
    4950    void removeMarkers(Range*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
    5051    void removeMarkers(Node*, unsigned startOffset, int length, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
    5152    void removeMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
    52     void removeMarkers(Node*);
     53    void removeMarkers(Node*, DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
    5354    void repaintMarkers(DocumentMarker::MarkerType = DocumentMarker::AllMarkers);
    5455    void setRenderedRectForMarker(Node*, const DocumentMarker&, const IntRect&);
     
    6667    typedef HashMap<RefPtr<Node>, MarkerMapVectorPair*> MarkerMap;
    6768    MarkerMap m_markers;
     69    void removeMarkersFromMarkerMapVectorPair(Node*, MarkerMapVectorPair*, DocumentMarker::MarkerType);
    6870};
    6971
  • trunk/WebCore/editing/Editor.cpp

    r70598 r70826  
    469469            m_frame->document()->axObjectCache()->postNotification(node->renderer(), AXObjectCache::AXValueChanged, false);
    470470    }
    471    
     471
     472#if REMOVE_MARKERS_UPON_EDITING
     473    removeSpellAndCorrectionMarkersFromWordsToBeEdited(true);
     474#endif
     475
    472476    if (client())
    473         client()->respondToChangedContents(); 
     477        client()->respondToChangedContents();
    474478}
    475479
     
    11551159    RefPtr<Range> selection = selectedRange();
    11561160    if (shouldDeleteRange(selection.get())) {
     1161#if REMOVE_MARKERS_UPON_EDITING
     1162        removeSpellAndCorrectionMarkersFromWordsToBeEdited(true);
     1163#endif
    11571164        if (isNodeInTextFormControl(m_frame->selection()->start().node()))
    11581165            Pasteboard::generalPasteboard()->writePlainText(selectedText());
     
    11931200    if (!canPaste())
    11941201        return;
     1202#if REMOVE_MARKERS_UPON_EDITING
     1203    removeSpellAndCorrectionMarkersFromWordsToBeEdited(false);
     1204#endif
    11951205    CachedResourceLoader* loader = m_frame->document()->cachedResourceLoader();
    11961206    loader->setAllowStaleResources(true);
     
    12081218    if (!canPaste())
    12091219        return;
     1220#if REMOVE_MARKERS_UPON_EDITING
     1221    removeSpellAndCorrectionMarkersFromWordsToBeEdited(false);
     1222#endif
    12101223    pasteAsPlainTextWithPasteboard(Pasteboard::generalPasteboard());
    12111224}
     
    29032916}
    29042917
     2918void Editor::removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary)
     2919{
     2920    // We want to remove the markers from a word if an editing command will change the word. This can happen in one of
     2921    // several scenarios:
     2922    // 1. Insert in the middle of a word.
     2923    // 2. Appending non whitespace at the beginning of word.
     2924    // 3. Appending non whitespace at the end of word.
     2925    // Note that, appending only whitespaces at the beginning or end of word won't change the word, so we don't need to
     2926    // remove the markers on that word.
     2927    // Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
     2928    // selection, and remove words between the selection boundaries.
     2929    //
     2930    VisiblePosition startOfSelection = frame()->selection()->selection().start();
     2931    VisiblePosition endOfSelection = frame()->selection()->selection().end();
     2932    if (startOfSelection.isNull())
     2933        return;
     2934    // First word is the word that ends after or on the start of selection.
     2935    VisiblePosition startOfFirstWord = startOfWord(startOfSelection, LeftWordIfOnBoundary);
     2936    VisiblePosition endOfFirstWord = endOfWord(startOfSelection, LeftWordIfOnBoundary);
     2937    // Last word is the word that begins before or on the end of selection
     2938    VisiblePosition startOfLastWord = startOfWord(endOfSelection, RightWordIfOnBoundary);
     2939    VisiblePosition endOfLastWord = endOfWord(endOfSelection, RightWordIfOnBoundary);
     2940
     2941    // This can be the case if the end of selection is at the end of document.
     2942    if (endOfLastWord.deepEquivalent().anchorType() != Position::PositionIsOffsetInAnchor) {
     2943        startOfLastWord = startOfWord(frame()->selection()->selection().start(), LeftWordIfOnBoundary);
     2944        endOfLastWord = endOfWord(frame()->selection()->selection().start(), LeftWordIfOnBoundary);
     2945    }
     2946
     2947    // If doNotRemoveIfSelectionAtWordBoundary is true, and first word ends at the start of selection,
     2948    // we choose next word as the first word.
     2949    if (doNotRemoveIfSelectionAtWordBoundary && endOfFirstWord == startOfSelection) {
     2950        startOfFirstWord = nextWordPosition(startOfFirstWord);
     2951        if (startOfFirstWord == endOfSelection)
     2952            return;
     2953        endOfFirstWord = endOfWord(startOfFirstWord, RightWordIfOnBoundary);
     2954        if (endOfFirstWord.deepEquivalent().anchorType() != Position::PositionIsOffsetInAnchor)
     2955            return;
     2956    }
     2957
     2958    // If doNotRemoveIfSelectionAtWordBoundary is true, and last word begins at the end of selection,
     2959    // we choose previous word as the last word.
     2960    if (doNotRemoveIfSelectionAtWordBoundary && startOfLastWord == endOfSelection) {
     2961        startOfLastWord = previousWordPosition(startOfLastWord);
     2962        endOfLastWord = endOfWord(startOfLastWord, RightWordIfOnBoundary);
     2963        if (endOfLastWord == startOfFirstWord)
     2964            return;
     2965    }
     2966
     2967    // Now we remove markers on everything between startOfFirstWord and endOfLastWord.
     2968    // However, if an autocorrection change a single word to multiple words, we want to remove correction mark from all the
     2969    // resulted words even we only edit one of them. For example, assuming autocorrection changes "avantgarde" to "avant
     2970    // garde", we will have CorrectionIndicator marker on both words and on the whitespace between them. If we then edit garde,
     2971    // we would like to remove the marker from word "avant" and whitespace as well. So we need to get the continous range of
     2972    // of marker that contains the word in question, and remove marker on that whole range.
     2973    Document* document = m_frame->document();
     2974    RefPtr<Range> wordRange = Range::create(document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
     2975    RefPtr<Range> rangeOfFirstWord = Range::create(document, startOfFirstWord.deepEquivalent(), endOfFirstWord.deepEquivalent());
     2976    RefPtr<Range> rangeOfLastWord = Range::create(document, startOfLastWord.deepEquivalent(), endOfLastWord.deepEquivalent());
     2977
     2978    typedef pair<RefPtr<Range>, DocumentMarker::MarkerType> RangeMarkerPair;
     2979    // It's probably unsafe to remove marker while iterating a vector of markers. So we store the markers and ranges that we want to remove temporarily. Then remove them at the end of function.
     2980    // To avoid allocation on the heap, Give markersToRemove a small inline capacity
     2981    Vector<RangeMarkerPair, 16> markersToRemove;
     2982    for (TextIterator textIterator(wordRange.get()); !textIterator.atEnd(); textIterator.advance()) {
     2983        Node* node = textIterator.node();
     2984        if (node == startOfFirstWord.deepEquivalent().containerNode() || node == endOfLastWord.deepEquivalent().containerNode()) {
     2985            // First word and last word can belong to the same node
     2986            bool processFirstWord = node == startOfFirstWord.deepEquivalent().containerNode() && document->markers()->hasMarkers(rangeOfFirstWord.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator);
     2987            bool processLastWord = node == endOfLastWord.deepEquivalent().containerNode() && document->markers()->hasMarkers(rangeOfLastWord.get(), DocumentMarker::Spelling | DocumentMarker::CorrectionIndicator);
     2988            // Take note on the markers whose range overlaps with the range of the first word or the last word.
     2989            Vector<DocumentMarker> markers = document->markers()->markersForNode(node);
     2990            for (size_t i = 0; i < markers.size(); ++i) {
     2991                DocumentMarker marker = markers[i];
     2992                if (processFirstWord && static_cast<int>(marker.endOffset) > startOfFirstWord.deepEquivalent().offsetInContainerNode() && (marker.type == DocumentMarker::Spelling || marker.type == DocumentMarker::CorrectionIndicator)) {
     2993                    RefPtr<Range> markerRange = Range::create(document, node, marker.startOffset, node, marker.endOffset);
     2994                    markersToRemove.append(std::make_pair(markerRange, marker.type));
     2995                }
     2996                if (processLastWord && static_cast<int>(marker.startOffset) <= endOfLastWord.deepEquivalent().offsetInContainerNode() && (marker.type == DocumentMarker::Spelling || marker.type == DocumentMarker::CorrectionIndicator)) {
     2997                    RefPtr<Range> markerRange = Range::create(document, node, marker.startOffset, node, marker.endOffset);
     2998                    markersToRemove.append(std::make_pair(markerRange, marker.type));
     2999                }
     3000            }
     3001        } else {
     3002            document->markers()->removeMarkers(node, DocumentMarker::Spelling);
     3003            document->markers()->removeMarkers(node, DocumentMarker::CorrectionIndicator);
     3004        }
     3005    }
     3006
     3007    // Actually remove the markers.
     3008    Vector<RangeMarkerPair>::const_iterator pairEnd = markersToRemove.end();
     3009    for (Vector<RangeMarkerPair>::const_iterator pairIterator = markersToRemove.begin(); pairIterator != pairEnd; ++pairIterator)
     3010        document->markers()->removeMarkers(pairIterator->first.get(), pairIterator->second);
     3011}
     3012
    29053013PassRefPtr<Range> Editor::rangeForPoint(const IntPoint& windowPoint)
    29063014{
  • trunk/WebCore/editing/Editor.h

    r70598 r70826  
    3434#include "EditorInsertAction.h"
    3535#include "SelectionController.h"
     36
     37#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD)
     38// Some platforms provide UI for suggesting autocorrection.
     39#define SUPPORT_AUTOCORRECTION_PANEL 1
     40// Some platforms use spelling and autocorrection markers to provide visual cue.
     41// On such platform, if word with marker is edited, we need to remove the marker.
     42#define REMOVE_MARKERS_UPON_EDITING 1
     43#else
     44#define SUPPORT_AUTOCORRECTION_PANEL 0
     45#define REMOVE_MARKERS_UPON_EDITING 0
     46#endif /* #if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) */
    3647
    3748#if PLATFORM(MAC) && !defined(__OBJC__)
     
    363374
    364375    bool selectionStartHasSpellingMarkerFor(int from, int length) const;
     376    void removeSpellAndCorrectionMarkersFromWordsToBeEdited(bool doNotRemoveIfSelectionAtWordBoundary);
    365377
    366378private:
  • trunk/WebCore/editing/TypingCommand.cpp

    r68613 r70826  
    132132void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
    133133{
    134     ASSERT(document);
    135    
     134#if REMOVE_MARKERS_UPON_EDITING
     135    if (!text.isEmpty())
     136        document->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(isSpaceOrNewline(text.characters()[0]));
     137#endif
     138
     139    ASSERT(document);
     140
    136141    RefPtr<Frame> frame = document->frame();
    137142    ASSERT(frame);
    138    
     143
    139144    VisibleSelection currentSelection = frame->selection()->selection();
    140145    bool changeSelection = currentSelection != selectionForInsertion;
    141    
    142146    String newText = text;
    143147    Node* startNode = selectionForInsertion.start().node();
     
    420424void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
    421425{
     426#if REMOVE_MARKERS_UPON_EDITING
     427    document()->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(false);
     428#endif
    422429    VisibleSelection selectionToDelete;
    423430    VisibleSelection selectionAfterUndo;
    424    
     431
    425432    switch (endingSelection().selectionType()) {
    426433    case VisibleSelection::RangeSelection:
     
    516523void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
    517524{
     525#if REMOVE_MARKERS_UPON_EDITING
     526    document()->frame()->editor()->removeSpellAndCorrectionMarkersFromWordsToBeEdited(false);
     527#endif
    518528    VisibleSelection selectionToDelete;
    519529    VisibleSelection selectionAfterUndo;
Note: See TracChangeset for help on using the changeset viewer.