Changeset 96353 in webkit


Ignore:
Timestamp:
Sep 29, 2011 1:31:41 PM (13 years ago)
Author:
rniwa@webkit.org
Message:

Remove direct reads to m_firstNodeInserted and m_lastLeafInserted in ReplaceSelectionCommand
https://bugs.webkit.org/show_bug.cgi?id=69023

Reviewed by Enrica Casucci.

Converted to removeUnrenderedTextNodesAtEnds to use InsertedNodes instead of m_firstNodeInserted
and m_lastLeafInserted. Extracted the logic to update nodes as InsertedNodes::willRemoveNode
(old one was renamed to InsertedNodes::willRemoveNodePreservingChildren).

Also extracted shouldPerformSmartReplace and addSpacesForSmartReplace out of doApply,
and rewrote the logic to obtain endNode and startNode using startOfInsertedContent and
endOfInsertedContent instead of m_firstNodeInserted and m_lastLeafInserted.

Finally, replaced the nullity checks of m_firstNodeInserted and m_lastLeafInserted in
completeHTMLReplacement by nullity checks of start and end positions.

  • dom/Node.cpp:

(WebCore::Node::traversePreviousSibling): Added.

  • dom/Node.h:
  • editing/ReplaceSelectionCommand.cpp:

(WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChildren): Renamed from
willRemoveNode.
(WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNode): Extracted from
removeUnrenderedTextNodesAtEnds.
(WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline):
(WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds):
(WebCore::ReplaceSelectionCommand::positionAtEndOfInsertedContent): Made const.
(WebCore::ReplaceSelectionCommand::positionAtStartOfInsertedContent): Made const.
(WebCore::ReplaceSelectionCommand::handleStyleSpans): Takes firstNodeInserted instead of directly
accessing m_firstNodeInserted.
(WebCore::ReplaceSelectionCommand::doApply):
(WebCore::ReplaceSelectionCommand::shouldPerformSmartReplace):
(WebCore::ReplaceSelectionCommand::addSpacesForSmartReplace):
(WebCore::ReplaceSelectionCommand::completeHTMLReplacement):

  • editing/ReplaceSelectionCommand.h:
Location:
trunk/Source/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r96352 r96353  
     12011-09-29  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Remove direct reads to m_firstNodeInserted and m_lastLeafInserted in ReplaceSelectionCommand
     4        https://bugs.webkit.org/show_bug.cgi?id=69023
     5
     6        Reviewed by Enrica Casucci.
     7
     8        Converted to removeUnrenderedTextNodesAtEnds to use InsertedNodes instead of m_firstNodeInserted
     9        and m_lastLeafInserted. Extracted the logic to update nodes as InsertedNodes::willRemoveNode
     10        (old one was renamed to InsertedNodes::willRemoveNodePreservingChildren).
     11
     12        Also extracted shouldPerformSmartReplace and addSpacesForSmartReplace out of doApply,
     13        and rewrote the logic to obtain endNode and startNode using startOfInsertedContent and
     14        endOfInsertedContent instead of m_firstNodeInserted and m_lastLeafInserted.
     15
     16        Finally, replaced the nullity checks of m_firstNodeInserted and m_lastLeafInserted in
     17        completeHTMLReplacement by nullity checks of start and end positions.
     18
     19        * dom/Node.cpp:
     20        (WebCore::Node::traversePreviousSibling): Added.
     21        * dom/Node.h:
     22        * editing/ReplaceSelectionCommand.cpp:
     23        (WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChildren): Renamed from
     24        willRemoveNode.
     25        (WebCore::ReplaceSelectionCommand::InsertedNodes::willRemoveNode): Extracted from
     26        removeUnrenderedTextNodesAtEnds.
     27        (WebCore::ReplaceSelectionCommand::removeRedundantStylesAndKeepStyleSpanInline):
     28        (WebCore::ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds):
     29        (WebCore::ReplaceSelectionCommand::positionAtEndOfInsertedContent): Made const.
     30        (WebCore::ReplaceSelectionCommand::positionAtStartOfInsertedContent): Made const.
     31        (WebCore::ReplaceSelectionCommand::handleStyleSpans): Takes firstNodeInserted instead of directly
     32        accessing m_firstNodeInserted.
     33        (WebCore::ReplaceSelectionCommand::doApply):
     34        (WebCore::ReplaceSelectionCommand::shouldPerformSmartReplace):
     35        (WebCore::ReplaceSelectionCommand::addSpacesForSmartReplace):
     36        (WebCore::ReplaceSelectionCommand::completeHTMLReplacement):
     37        * editing/ReplaceSelectionCommand.h:
     38
    1392011-09-29  Andreas Kling  <kling@webkit.org>
    240
  • trunk/Source/WebCore/dom/Node.cpp

    r95372 r96353  
    11941194}
    11951195
     1196Node* Node::traversePreviousSibling(const Node* stayWithin) const
     1197{
     1198    if (this == stayWithin)
     1199        return 0;
     1200    if (previousSibling())
     1201        return previousSibling();
     1202    const Node *n = this;
     1203    while (n && !n->previousSibling() && (!stayWithin || n->parentNode() != stayWithin))
     1204        n = n->parentNode();
     1205    if (n)
     1206        return n->previousSibling();
     1207    return 0;
     1208}
     1209
    11961210Node* Node::traversePreviousNodePostOrder(const Node* stayWithin) const
    11971211{
  • trunk/Source/WebCore/dom/Node.h

    r94659 r96353  
    400400    Node* traversePreviousNode(const Node* stayWithin = 0) const;
    401401
     402    // Like traversePreviousNode, but skips children and starts with the next sibling.
     403    Node* traversePreviousSibling(const Node* stayWithin = 0) const;
     404
    402405    // Like traverseNextNode, but visits parents after their children.
    403406    Node* traverseNextNodePostOrder() const;
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.cpp

    r96187 r96353  
    360360}
    361361
    362 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node* node)
     362inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNodePreservingChildren(Node* node)
    363363{
    364364    if (m_firstNodeInserted == node)
     
    366366    if (m_lastNodeInserted == node)
    367367        m_lastNodeInserted = node->lastChild() ? node->lastChild() : node->traverseNextSibling();
     368}
     369
     370inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node* node)
     371{
     372    if (m_firstNodeInserted == node && m_lastNodeInserted == node) {
     373        m_firstNodeInserted = 0;
     374        m_lastNodeInserted = 0;
     375    } else if (m_firstNodeInserted == node)
     376        m_firstNodeInserted = m_firstNodeInserted->traverseNextSibling();
     377    else if (m_lastNodeInserted == node)
     378        m_lastNodeInserted = m_lastNodeInserted->traversePreviousSibling();
    368379}
    369380
     
    526537        if (!inlineStyle || newInlineStyle->isEmpty()) {
    527538            if (isStyleSpanOrSpanWithOnlyStyleAttribute(element)) {
    528                 insertedNodes.willRemoveNode(element);
     539                insertedNodes.willRemoveNodePreservingChildren(element);
    529540                removeNodePreservingChildren(element);
    530541            } else
     
    537548        if (isLegacyAppleStyleSpan(element)) {
    538549            if (!element->firstChild()) {
    539                 insertedNodes.willRemoveNode(element);
     550                insertedNodes.willRemoveNodePreservingChildren(element);
    540551                removeNodePreservingChildren(element);
    541552                continue;
     
    560571}
    561572
    562 void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds()
     573void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds(InsertedNodes& insertedNodes)
    563574{
    564575    document()->updateLayoutIgnorePendingStylesheets();
    565     if (m_lastLeafInserted->isTextNode() && !nodeHasVisibleRenderText(static_cast<Text*>(m_lastLeafInserted.get()))
    566         && !enclosingNodeWithTag(firstPositionInOrBeforeNode(m_lastLeafInserted.get()), selectTag)
    567         && !enclosingNodeWithTag(firstPositionInOrBeforeNode(m_lastLeafInserted.get()), scriptTag)) {
    568         if (m_firstNodeInserted == m_lastLeafInserted) {
    569             removeNode(m_lastLeafInserted.get());
    570             m_lastLeafInserted = 0;
    571             m_firstNodeInserted = 0;
    572             return;
    573         }
    574         RefPtr<Node> previous = m_lastLeafInserted->traversePreviousNode();
    575         removeNode(m_lastLeafInserted.get());
    576         m_lastLeafInserted = previous;
    577     }
    578    
     576
     577    Node* lastLeafInserted = insertedNodes.lastLeafInserted();
     578    if (lastLeafInserted && lastLeafInserted->isTextNode() && !nodeHasVisibleRenderText(static_cast<Text*>(lastLeafInserted))
     579        && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), selectTag)
     580        && !enclosingNodeWithTag(firstPositionInOrBeforeNode(lastLeafInserted), scriptTag)) {
     581        insertedNodes.willRemoveNode(lastLeafInserted);
     582        removeNode(lastLeafInserted);
     583    }
     584
    579585    // We don't have to make sure that m_firstNodeInserted isn't inside a select or script element, because
    580586    // it is a top level node in the fragment and the user can't insert into those elements.
    581     if (m_firstNodeInserted->isTextNode() && !nodeHasVisibleRenderText(static_cast<Text*>(m_firstNodeInserted.get()))) {
    582         if (m_firstNodeInserted == m_lastLeafInserted) {
    583             removeNode(m_firstNodeInserted.get());
    584             m_firstNodeInserted = 0;
    585             m_lastLeafInserted = 0;
    586             return;
    587         }
    588         RefPtr<Node> next = m_firstNodeInserted->traverseNextSibling();
    589         removeNode(m_firstNodeInserted.get());
    590         m_firstNodeInserted = next;
    591     }
    592 }
    593 
    594 void ReplaceSelectionCommand::handlePasteAsQuotationNode()
    595 {
    596     Node* node = m_firstNodeInserted.get();
    597     if (isMailPasteAsQuotationNode(node))
    598         removeNodeAttribute(static_cast<Element*>(node), classAttr);
    599 }
    600 
    601 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent()
     587    Node* firstNodeInserted = insertedNodes.firstNodeInserted();
     588    lastLeafInserted = insertedNodes.lastLeafInserted();
     589    if (firstNodeInserted && firstNodeInserted->isTextNode() && !nodeHasVisibleRenderText(static_cast<Text*>(firstNodeInserted))) {
     590        insertedNodes.willRemoveNode(firstNodeInserted);
     591        removeNode(firstNodeInserted);
     592    }
     593}
     594
     595VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent() const
    602596{
    603597    Node* lastNode = m_lastLeafInserted.get();
     
    609603}
    610604
    611 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent()
     605VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() const
    612606{
    613607    return firstPositionInOrBeforeNode(m_firstNodeInserted.get());
     
    667661// We should remove styles from spans that are overridden by all of their children, either here
    668662// or at copy time.
    669 void ReplaceSelectionCommand::handleStyleSpans()
     663void ReplaceSelectionCommand::handleStyleSpans(Node* firstNodeInserted)
    670664{
    671665    HTMLElement* wrappingStyleSpan = 0;
     
    673667    // the top of the fragment, but Mail sometimes adds a wrapper (for Paste As Quotation),
    674668    // so search for the top level style span instead of assuming it's at the top.
    675     for (Node* node = m_firstNodeInserted.get(); node; node = node->traverseNextNode()) {
     669    for (Node* node = firstNodeInserted; node; node = node->traverseNextNode()) {
    676670        if (isLegacyAppleStyleSpan(node)) {
    677671            wrappingStyleSpan = toHTMLElement(node);
     
    836830    if (!selection.isNonOrphanedCaretOrRange() || !selection.start().deprecatedNode())
    837831        return;
    838    
    839     bool selectionIsPlainText = !selection.isContentRichlyEditable();
    840    
    841     Element* currentRoot = selection.rootEditableElement();
     832
    842833    ReplacementFragment fragment(document(), m_documentFragment.get(), m_matchStyle, selection);
    843    
    844834    if (performTrivialReplace(fragment))
    845835        return;
     
    865855    Position insertionPos = selection.start();
    866856    bool startIsInsideMailBlockquote = enclosingNodeOfType(insertionPos, isMailBlockquote, CanCrossEditingBoundary);
     857    bool selectionIsPlainText = !selection.isContentRichlyEditable();
     858    Element* currentRoot = selection.rootEditableElement();
    867859
    868860    if ((selectionStartWasStartOfParagraph && selectionEndWasEndOfParagraph && !startIsInsideMailBlockquote) ||
     
    10511043    removeRedundantStylesAndKeepStyleSpanInline(insertedNodes);
    10521044
     1045    removeUnrenderedTextNodesAtEnds(insertedNodes);
     1046   
    10531047    m_firstNodeInserted = insertedNodes.firstNodeInserted();
    10541048    m_lastLeafInserted = insertedNodes.lastLeafInserted();
    10551049
    1056     removeUnrenderedTextNodesAtEnds();
    1057 
    10581050    if (!handledStyleSpans)
    1059         handleStyleSpans();
    1060    
     1051        handleStyleSpans(m_firstNodeInserted.get());
     1052
    10611053    // Mutation events (bug 20161) may have already removed the inserted content
    10621054    if (!m_firstNodeInserted || !m_firstNodeInserted->inDocument())
     
    10701062    if (startBlock && insertionPos.deprecatedNode() == startBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < startBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
    10711063        insertNodeAt(createBreakElement(document()).get(), startOfInsertedContent.deepEquivalent());
    1072    
    1073     Position lastPositionToSelect;
    1074    
     1064
    10751065    bool interchangeNewlineAtEnd = fragment.hasInterchangeNewlineAtEnd();
    10761066
     
    11171107    endOfInsertedContent = positionAtEndOfInsertedContent();
    11181108    startOfInsertedContent = positionAtStartOfInsertedContent();
    1119    
     1109
     1110    Position lastPositionToSelect;
    11201111    if (interchangeNewlineAtEnd) {
    11211112        VisiblePosition next = endOfInsertedContent.next(CannotCrossEditingBoundary);
     
    11451136    } else
    11461137        mergeEndIfNeeded();
    1147    
    1148     handlePasteAsQuotationNode();
    1149    
    1150     endOfInsertedContent = positionAtEndOfInsertedContent();
    1151     startOfInsertedContent = positionAtStartOfInsertedContent();
    1152    
    1153     // Add spaces for smart replace.
    1154     if (m_smartReplace && currentRoot) {
    1155         Element* textControl = enclosingTextFormControl(firstPositionInNode(currentRoot));
    1156         if (textControl && textControl->hasTagName(inputTag) && static_cast<HTMLInputElement*>(textControl)->isPasswordField())
    1157             m_smartReplace = false; // Disable smart replace for password fields.
    1158     }
    1159     if (m_smartReplace) {
    1160         bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) &&
    1161                                   !isCharacterSmartReplaceExempt(endOfInsertedContent.characterAfter(), false);
    1162         if (needsTrailingSpace) {
    1163             RenderObject* renderer = m_lastLeafInserted->renderer();
    1164             bool collapseWhiteSpace = !renderer || renderer->style()->collapseWhiteSpace();
    1165             Node* endNode = positionAtEndOfInsertedContent().deepEquivalent().upstream().deprecatedNode();
    1166             if (endNode->isTextNode()) {
    1167                 Text* text = static_cast<Text*>(endNode);
    1168                 insertTextIntoNode(text, text->length(), collapseWhiteSpace ? nonBreakingSpaceString() : " ");
    1169             } else {
    1170                 RefPtr<Node> node = document()->createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
    1171                 insertNodeAfter(node, endNode);
    1172                 updateNodesInserted(node.get());
    1173             }
    1174         }
    1175    
    1176         bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) &&
    1177                                  !isCharacterSmartReplaceExempt(startOfInsertedContent.previous().characterAfter(), true);
    1178         if (needsLeadingSpace) {
    1179             RenderObject* renderer = m_lastLeafInserted->renderer();
    1180             bool collapseWhiteSpace = !renderer || renderer->style()->collapseWhiteSpace();
    1181             Node* startNode = positionAtStartOfInsertedContent().deepEquivalent().downstream().deprecatedNode();
    1182             if (startNode->isTextNode()) {
    1183                 Text* text = static_cast<Text*>(startNode);
    1184                 insertTextIntoNode(text, 0, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
    1185             } else {
    1186                 RefPtr<Node> node = document()->createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
    1187                 // Don't updateNodesInserted.  Doing so would set m_lastLeafInserted to be the node containing the
    1188                 // leading space, but m_lastLeafInserted is supposed to mark the end of pasted content.
    1189                 insertNodeBefore(node, startNode);
    1190                 // FIXME: Use positions to track the start/end of inserted content.
    1191                 m_firstNodeInserted = node;
    1192             }
    1193         }
    1194     }
    1195    
     1138
     1139    if (Node* mailBlockquote = enclosingNodeOfType(positionAtStartOfInsertedContent().deepEquivalent(), isMailPasteAsQuotationNode))
     1140        removeNodeAttribute(static_cast<Element*>(mailBlockquote), classAttr);
     1141
     1142    if (shouldPerformSmartReplace())
     1143        addSpacesForSmartReplace();
     1144
    11961145    // If we are dealing with a fragment created from plain text
    11971146    // no style matching is necessary.
     
    12221171}
    12231172
     1173bool ReplaceSelectionCommand::shouldPerformSmartReplace() const
     1174{
     1175    if (!m_smartReplace)
     1176        return false;
     1177
     1178    Element* textControl = enclosingTextFormControl(positionAtStartOfInsertedContent().deepEquivalent());
     1179    if (textControl && textControl->hasTagName(inputTag) && static_cast<HTMLInputElement*>(textControl)->isPasswordField())
     1180        return false; // Disable smart replace for password fields.
     1181
     1182    return true;
     1183}
     1184
     1185void ReplaceSelectionCommand::addSpacesForSmartReplace()
     1186{
     1187    VisiblePosition startOfInsertedContent = positionAtStartOfInsertedContent();
     1188    VisiblePosition endOfInsertedContent = positionAtEndOfInsertedContent();
     1189
     1190    Position endUpstream = endOfInsertedContent.deepEquivalent().upstream();
     1191    Node* endNode = endUpstream.computeNodeBeforePosition();
     1192    if (endUpstream.anchorType() == Position::PositionIsOffsetInAnchor)
     1193        endNode = endUpstream.containerNode();
     1194
     1195    bool needsTrailingSpace = !isEndOfParagraph(endOfInsertedContent) && !isCharacterSmartReplaceExempt(endOfInsertedContent.characterAfter(), false);
     1196    if (needsTrailingSpace && endNode) {
     1197        bool collapseWhiteSpace = !endNode->renderer() || endNode->renderer()->style()->collapseWhiteSpace();
     1198        if (endNode->isTextNode()) {
     1199            Text* text = static_cast<Text*>(endNode);
     1200            insertTextIntoNode(text, text->length(), collapseWhiteSpace ? nonBreakingSpaceString() : " ");
     1201        } else {
     1202            RefPtr<Node> node = document()->createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
     1203            insertNodeAfter(node, endNode);
     1204            updateNodesInserted(node.get());
     1205        }
     1206    }
     1207
     1208    Position startDownstream = startOfInsertedContent.deepEquivalent().downstream();
     1209    Node* startNode = startDownstream.computeNodeAfterPosition();
     1210    if (startDownstream.anchorType() == Position::PositionIsOffsetInAnchor)
     1211        startNode = startDownstream.containerNode();
     1212
     1213    bool needsLeadingSpace = !isStartOfParagraph(startOfInsertedContent) && !isCharacterSmartReplaceExempt(startOfInsertedContent.previous().characterAfter(), true);
     1214    if (needsLeadingSpace && startNode) {
     1215        bool collapseWhiteSpace = !startNode->renderer() || startNode->renderer()->style()->collapseWhiteSpace();
     1216        if (startNode->isTextNode()) {
     1217            Text* text = static_cast<Text*>(startNode);
     1218            insertTextIntoNode(text, 0, collapseWhiteSpace ? nonBreakingSpaceString() : " ");
     1219        } else {
     1220            RefPtr<Node> node = document()->createEditingTextNode(collapseWhiteSpace ? nonBreakingSpaceString() : " ");
     1221            // Don't updateNodesInserted. Doing so would set m_lastLeafInserted to be the node containing the leading space,
     1222            // but m_lastLeafInserted is supposed to mark the end of pasted content.
     1223            insertNodeBefore(node, startNode);
     1224            // FIXME: Use positions to track the start/end of inserted content.
     1225            m_firstNodeInserted = node;
     1226        }
     1227    }
     1228}
     1229
    12241230void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositionToSelect)
    12251231{
    1226     Position start;
    1227     Position end;
    1228 
    1229     // FIXME: This should never not be the case.
    1230     if (m_firstNodeInserted && m_firstNodeInserted->inDocument() && m_lastLeafInserted && m_lastLeafInserted->inDocument()) {
    1231        
    1232         start = positionAtStartOfInsertedContent().deepEquivalent();
    1233         end = positionAtEndOfInsertedContent().deepEquivalent();
    1234        
     1232    Position start = positionAtStartOfInsertedContent().deepEquivalent();
     1233    Position end = positionAtEndOfInsertedContent().deepEquivalent();
     1234
     1235    // Mutation events may have deleted start or end
     1236    if (start.isNotNull() && !start.isOrphan() && end.isNotNull() && !end.isOrphan()) {
    12351237        // FIXME (11475): Remove this and require that the creator of the fragment to use nbsps.
    12361238        rebalanceWhitespaceAt(start);
     
    12411243            applyStyle(m_insertionStyle.get(), start, end);
    12421244        }   
    1243        
     1245
    12441246        if (lastPositionToSelect.isNotNull())
    12451247            end = lastPositionToSelect;
     
    12481250    else
    12491251        return;
    1250    
     1252
    12511253    if (m_selectReplacement)
    12521254        setEndingSelection(VisibleSelection(start, end, SEL_DEFAULT_AFFINITY, endingSelection().isDirectional()));
  • trunk/Source/WebCore/editing/ReplaceSelectionCommand.h

    r96084 r96353  
    5959    virtual void doApply();
    6060    virtual EditAction editingAction() const;
    61 
    62     void completeHTMLReplacement(const Position& lastPositionToSelect);
    6361   
    6462    class InsertedNodes {
    6563    public:
    66         void respondToNodeInsertion(Node* node);
    67         void willRemoveNode(Node* node);
     64        void respondToNodeInsertion(Node*);
     65        void willRemoveNodePreservingChildren(Node*);
     66        void willRemoveNode(Node*);
     67
    6868        Node* firstNodeInserted() const { return m_firstNodeInserted.get(); }
    6969        Node* lastLeafInserted() const { return m_lastNodeInserted->lastDescendant(); }
     
    8686    void mergeEndIfNeeded();
    8787   
    88     void removeUnrenderedTextNodesAtEnds();
     88    void removeUnrenderedTextNodesAtEnds(InsertedNodes&);
    8989   
    9090    void removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes&);
    91     void handleStyleSpans();
     91    void handleStyleSpans(Node* firstNodeInserted);
    9292    void copyStyleToChildren(Node* parentNode, const CSSMutableStyleDeclaration* parentStyle);
    9393    void handlePasteAsQuotationNode();
     
    9696    virtual void removeNodeAndPruneAncestors(Node*);
    9797   
    98     VisiblePosition positionAtStartOfInsertedContent();
    99     VisiblePosition positionAtEndOfInsertedContent();
    100    
     98    VisiblePosition positionAtStartOfInsertedContent() const;
     99    VisiblePosition positionAtEndOfInsertedContent() const;
     100
     101    bool shouldPerformSmartReplace() const;
     102    void addSpacesForSmartReplace();
     103    void completeHTMLReplacement(const Position& lastPositionToSelect);
     104
    101105    bool performTrivialReplace(const ReplacementFragment&);
    102106
Note: See TracChangeset for help on using the changeset viewer.