Changeset 63039 in webkit


Ignore:
Timestamp:
Jul 9, 2010 9:20:50 PM (14 years ago)
Author:
tony@chromium.org
Message:

2010-07-09 Tony Chang <tony@chromium.org>

Reviewed by Ojan Vafai.

crash in WebCore::CompositeEditCommand::splitTreeToNode when indenting pre
https://bugs.webkit.org/show_bug.cgi?id=38231

  • editing/execCommand/indent-pre-expected.txt: Added.
  • editing/execCommand/indent-pre.html: Added.

2010-07-09 Tony Chang <tony@chromium.org>

Reviewed by Ojan Vafai.

crash in WebCore::CompositeEditCommand::splitTreeToNode when indenting pre
https://bugs.webkit.org/show_bug.cgi?id=38231

Test: editing/execCommand/indent-pre.html

  • editing/IndentOutdentCommand.cpp: (WebCore::countParagraphs): (WebCore::IndentOutdentCommand::indentRegion): Split text nodes into one node per paragraph

so moveParagraph doesn't get confused.

(WebCore::IndentOutdentCommand::splitTextNodes):

  • editing/IndentOutdentCommand.h:
Location:
trunk
Files:
2 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r63038 r63039  
     12010-07-09  Tony Chang  <tony@chromium.org>
     2
     3        Reviewed by Ojan Vafai.
     4
     5        crash in WebCore::CompositeEditCommand::splitTreeToNode when indenting pre
     6        https://bugs.webkit.org/show_bug.cgi?id=38231
     7
     8        * editing/execCommand/indent-pre-expected.txt: Added.
     9        * editing/execCommand/indent-pre.html: Added.
     10
    1112010-07-09  Erik Arvidsson  <arv@chromium.org>
    212
  • trunk/WebCore/ChangeLog

    r63038 r63039  
     12010-07-09  Tony Chang  <tony@chromium.org>
     2
     3        Reviewed by Ojan Vafai.
     4
     5        crash in WebCore::CompositeEditCommand::splitTreeToNode when indenting pre
     6        https://bugs.webkit.org/show_bug.cgi?id=38231
     7
     8        Test: editing/execCommand/indent-pre.html
     9
     10        * editing/IndentOutdentCommand.cpp:
     11        (WebCore::countParagraphs):
     12        (WebCore::IndentOutdentCommand::indentRegion): Split text nodes into one node per paragraph
     13                                                       so moveParagraph doesn't get confused.
     14        (WebCore::IndentOutdentCommand::splitTextNodes):
     15        * editing/IndentOutdentCommand.h:
     16
    1172010-07-09  Erik Arvidsson  <arv@chromium.org>
    218
  • trunk/WebCore/editing/IndentOutdentCommand.cpp

    r60342 r63039  
    3535#include "Range.h"
    3636#include "SplitElementCommand.h"
     37#include "Text.h"
    3738#include "TextIterator.h"
    3839#include "htmlediting.h"
     
    6162{
    6263    return node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(blockquoteTag));
     64}
     65
     66// This function can return -1 if we are unable to count the paragraphs between |start| and |end|.
     67static int countParagraphs(const VisiblePosition& endOfFirstParagraph, const VisiblePosition& endOfLastParagraph)
     68{
     69    int count = 0;
     70    VisiblePosition cur = endOfFirstParagraph;
     71    while (cur != endOfLastParagraph) {
     72        ++count;
     73        cur = endOfParagraph(cur.next());
     74        // If start is before a table and end is inside a table, we will never hit end because the
     75        // whole table is considered a single paragraph.
     76        if (cur.isNull())
     77            return -1;
     78    }
     79    return count;
    6380}
    6481
     
    148165    VisiblePosition endOfCurrentParagraph = endOfParagraph(startOfSelection);
    149166    VisiblePosition endAfterSelection = endOfParagraph(endOfParagraph(endOfSelection).next());
     167    int endOfCurrentParagraphIndex = indexForVisiblePosition(endOfCurrentParagraph);
     168    int endAfterSelectionIndex = indexForVisiblePosition(endAfterSelection);
     169
     170    // When indenting within a <pre> tag, we need to split each paragraph into a separate node for moveParagraphWithClones to work.
     171    // However, splitting text nodes can cause endOfCurrentParagraph and endAfterSelection to point to an invalid position if we
     172    // changed the text node it was pointing at.  So we have to reset these positions.
     173    int numParagraphs = countParagraphs(endOfCurrentParagraph, endAfterSelection);
     174    if (splitTextNodes(startOfParagraph(startOfSelection), numParagraphs + 1)) {
     175        RefPtr<Range> endOfCurrentParagraphRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), endOfCurrentParagraphIndex, 0, true);
     176        RefPtr<Range> endAfterSelectionRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), endAfterSelectionIndex, 0, true);
     177        if (!endOfCurrentParagraphRange.get() || !endAfterSelectionRange.get()) {
     178            ASSERT_NOT_REACHED();
     179            return;
     180        }
     181        endOfCurrentParagraph = VisiblePosition(endOfCurrentParagraphRange->startPosition(), DOWNSTREAM);
     182        endAfterSelection = VisiblePosition(endAfterSelectionRange->startPosition(), DOWNSTREAM);
     183    }
     184
    150185    while (endOfCurrentParagraph != endAfterSelection) {
    151186        // Iterate across the selected paragraphs...
     
    169204        endOfCurrentParagraph = endOfNextParagraph;
    170205    }   
     206}
     207
     208// Returns true if at least one text node was split.
     209bool IndentOutdentCommand::splitTextNodes(const VisiblePosition& start, int numParagraphs)
     210{
     211    VisiblePosition currentParagraphStart = start;
     212    bool hasSplit = false;
     213    int paragraphCount;
     214    for (paragraphCount = 0; paragraphCount < numParagraphs; ++paragraphCount) {
     215        // If there are multiple paragraphs in a single text node, we split the text node into a separate node for each paragraph.
     216        if (currentParagraphStart.deepEquivalent().node()->isTextNode() && currentParagraphStart.deepEquivalent().node() == startOfParagraph(currentParagraphStart.previous()).deepEquivalent().node()) {
     217            Text* textNode = static_cast<Text *>(currentParagraphStart.deepEquivalent().node());
     218            int offset = currentParagraphStart.deepEquivalent().offsetInContainerNode();
     219            splitTextNode(textNode, offset);
     220            currentParagraphStart = VisiblePosition(textNode, 0, VP_DEFAULT_AFFINITY);
     221            hasSplit = true;
     222        }
     223        VisiblePosition nextParagraph = startOfParagraph(endOfParagraph(currentParagraphStart).next());
     224        if (nextParagraph.isNull())
     225            break;
     226        currentParagraphStart = nextParagraph;
     227    }
     228    return hasSplit;
    171229}
    172230
  • trunk/WebCore/editing/IndentOutdentCommand.h

    r50536 r63039  
    5252    bool tryIndentingAsListItem(const VisiblePosition&);
    5353    void indentIntoBlockquote(const VisiblePosition&, const VisiblePosition&, RefPtr<Element>&);
     54    bool splitTextNodes(const VisiblePosition& start, int numParagraphs);
    5455
    5556    EIndentType m_typeOfAction;
Note: See TracChangeset for help on using the changeset viewer.