diff options
Diffstat (limited to 'WebCore/editing')
-rw-r--r-- | WebCore/editing/DeleteSelectionCommand.cpp | 4 | ||||
-rw-r--r-- | WebCore/editing/InsertLineBreakCommand.cpp | 5 | ||||
-rw-r--r-- | WebCore/editing/InsertListCommand.cpp | 99 | ||||
-rw-r--r-- | WebCore/editing/InsertListCommand.h | 2 | ||||
-rw-r--r-- | WebCore/editing/InsertParagraphSeparatorCommand.cpp | 6 |
5 files changed, 56 insertions, 60 deletions
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp index 623b188..c37b0fc 100644 --- a/WebCore/editing/DeleteSelectionCommand.cpp +++ b/WebCore/editing/DeleteSelectionCommand.cpp @@ -537,12 +537,12 @@ void DeleteSelectionCommand::fixupWhitespace() { updateLayout(); // FIXME: isRenderedCharacter should be removed, and we should use VisiblePosition::characterAfter and VisiblePosition::characterBefore - if (m_leadingWhitespace.isNotNull() && !m_leadingWhitespace.isRenderedCharacter()) { + if (m_leadingWhitespace.isNotNull() && !m_leadingWhitespace.isRenderedCharacter() && m_leadingWhitespace.node()->isTextNode()) { Text* textNode = static_cast<Text*>(m_leadingWhitespace.node()); ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace()); replaceTextInNode(textNode, m_leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); } - if (m_trailingWhitespace.isNotNull() && !m_trailingWhitespace.isRenderedCharacter()) { + if (m_trailingWhitespace.isNotNull() && !m_trailingWhitespace.isRenderedCharacter() && m_trailingWhitespace.node()->isTextNode()) { Text* textNode = static_cast<Text*>(m_trailingWhitespace.node()); ASSERT(!textNode->renderer() ||textNode->renderer()->style()->collapseWhiteSpace()); replaceTextInNode(textNode, m_trailingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); diff --git a/WebCore/editing/InsertLineBreakCommand.cpp b/WebCore/editing/InsertLineBreakCommand.cpp index d805acf..f815d98 100644 --- a/WebCore/editing/InsertLineBreakCommand.cpp +++ b/WebCore/editing/InsertLineBreakCommand.cpp @@ -136,11 +136,8 @@ void InsertLineBreakCommand::doApply() } else if (pos.deprecatedEditingOffset() >= caretMaxOffset(pos.node()) || !pos.node()->isTextNode()) { insertNodeAt(nodeToInsert.get(), pos); setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), DOWNSTREAM)); - } else { + } else if (pos.node()->isTextNode()) { // Split a text node - ASSERT(pos.node()->isTextNode()); - - // Do the split Text* textNode = static_cast<Text*>(pos.node()); splitTextNode(textNode, pos.deprecatedEditingOffset()); insertNodeBefore(nodeToInsert, textNode); diff --git a/WebCore/editing/InsertListCommand.cpp b/WebCore/editing/InsertListCommand.cpp index 0f7dc77..06162c9 100644 --- a/WebCore/editing/InsertListCommand.cpp +++ b/WebCore/editing/InsertListCommand.cpp @@ -55,55 +55,10 @@ HTMLElement* InsertListCommand::fixOrphanedListChild(Node* node) } InsertListCommand::InsertListCommand(Document* document, Type type) - : CompositeEditCommand(document), m_type(type), m_forceCreateList(false) + : CompositeEditCommand(document), m_type(type) { } -bool InsertListCommand::modifyRange() -{ - VisibleSelection selection = selectionForParagraphIteration(endingSelection()); - ASSERT(selection.isRange()); - VisiblePosition startOfSelection = selection.visibleStart(); - VisiblePosition endOfSelection = selection.visibleEnd(); - VisiblePosition startOfLastParagraph = startOfParagraph(endOfSelection); - - if (startOfParagraph(startOfSelection) == startOfLastParagraph) - return false; - - Node* startList = enclosingList(startOfSelection.deepEquivalent().node()); - Node* endList = enclosingList(endOfSelection.deepEquivalent().node()); - if (!startList || startList != endList) - m_forceCreateList = true; - - setEndingSelection(startOfSelection); - doApply(); - // Fetch the start of the selection after moving the first paragraph, - // because moving the paragraph will invalidate the original start. - // We'll use the new start to restore the original selection after - // we modified all selected paragraphs. - startOfSelection = endingSelection().visibleStart(); - VisiblePosition startOfCurrentParagraph = startOfNextParagraph(startOfSelection); - while (startOfCurrentParagraph != startOfLastParagraph) { - // doApply() may operate on and remove the last paragraph of the selection from the document - // if it's in the same list item as startOfCurrentParagraph. Return early to avoid an - // infinite loop and because there is no more work to be done. - // FIXME(<rdar://problem/5983974>): The endingSelection() may be incorrect here. Compute - // the new location of endOfSelection and use it as the end of the new selection. - if (!startOfLastParagraph.deepEquivalent().node()->inDocument()) - return true; - setEndingSelection(startOfCurrentParagraph); - doApply(); - startOfCurrentParagraph = startOfNextParagraph(endingSelection().visibleStart()); - } - setEndingSelection(endOfSelection); - doApply(); - // Fetch the end of the selection, for the reason mentioned above. - endOfSelection = endingSelection().visibleEnd(); - setEndingSelection(VisibleSelection(startOfSelection, endOfSelection)); - m_forceCreateList = false; - return true; -} - void InsertListCommand::doApply() { if (endingSelection().isNone()) @@ -125,9 +80,53 @@ void InsertListCommand::doApply() if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd)) setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(true))); - if (endingSelection().isRange() && modifyRange()) - return; - + if (endingSelection().isRange()) { + VisibleSelection selection = selectionForParagraphIteration(endingSelection()); + ASSERT(selection.isRange()); + VisiblePosition startOfSelection = selection.visibleStart(); + VisiblePosition endOfSelection = selection.visibleEnd(); + VisiblePosition startOfLastParagraph = startOfParagraph(endOfSelection); + + if (startOfParagraph(startOfSelection) != startOfLastParagraph) { + Node* startList = enclosingList(startOfSelection.deepEquivalent().node()); + Node* endList = enclosingList(endOfSelection.deepEquivalent().node()); + bool forceCreateList = !startList || startList != endList; + + VisiblePosition startOfCurrentParagraph = startOfSelection; + while (startOfCurrentParagraph != startOfLastParagraph) { + // doApply() may operate on and remove the last paragraph of the selection from the document + // if it's in the same list item as startOfCurrentParagraph. Return early to avoid an + // infinite loop and because there is no more work to be done. + // FIXME(<rdar://problem/5983974>): The endingSelection() may be incorrect here. Compute + // the new location of endOfSelection and use it as the end of the new selection. + if (!startOfLastParagraph.deepEquivalent().node()->inDocument()) + return; + setEndingSelection(startOfCurrentParagraph); + doApplyForSingleParagraph(forceCreateList); + + // Fetch the start of the selection after moving the first paragraph, + // because moving the paragraph will invalidate the original start. + // We'll use the new start to restore the original selection after + // we modified all selected paragraphs. + if (startOfCurrentParagraph == startOfSelection) + startOfSelection = endingSelection().visibleStart(); + + startOfCurrentParagraph = startOfNextParagraph(endingSelection().visibleStart()); + } + setEndingSelection(endOfSelection); + doApplyForSingleParagraph(forceCreateList); + // Fetch the end of the selection, for the reason mentioned above. + endOfSelection = endingSelection().visibleEnd(); + setEndingSelection(VisibleSelection(startOfSelection, endOfSelection)); + return; + } + } + + doApplyForSingleParagraph(false); +} + +void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList) +{ // FIXME: This will produce unexpected results for a selection that starts just before a // table and ends inside the first cell, selectionForParagraphIteration should probably // be renamed and deployed inside setEndingSelection(). @@ -147,7 +146,7 @@ void InsertListCommand::doApply() unlistifyParagraph(endingSelection().visibleStart(), listNode, listChildNode); } - if (!listChildNode || switchListType || m_forceCreateList) + if (!listChildNode || switchListType || forceCreateList) m_listElement = listifyParagraph(endingSelection().visibleStart(), listTag); } diff --git a/WebCore/editing/InsertListCommand.h b/WebCore/editing/InsertListCommand.h index 7f3b07d..7fbf936 100644 --- a/WebCore/editing/InsertListCommand.h +++ b/WebCore/editing/InsertListCommand.h @@ -53,11 +53,11 @@ private: HTMLElement* fixOrphanedListChild(Node*); bool modifyRange(); + void doApplyForSingleParagraph(bool forceCreateList); void unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode); PassRefPtr<HTMLElement> listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag); RefPtr<HTMLElement> m_listElement; Type m_type; - bool m_forceCreateList; }; } // namespace WebCore diff --git a/WebCore/editing/InsertParagraphSeparatorCommand.cpp b/WebCore/editing/InsertParagraphSeparatorCommand.cpp index d8aa98f..a3dfa83 100644 --- a/WebCore/editing/InsertParagraphSeparatorCommand.cpp +++ b/WebCore/editing/InsertParagraphSeparatorCommand.cpp @@ -312,7 +312,7 @@ void InsertParagraphSeparatorCommand::doApply() Position leadingWhitespace = insertionPosition.leadingWhitespacePosition(VP_DEFAULT_AFFINITY); // FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions // after the preserved newline, causing the newline to be turned into a nbsp. - if (leadingWhitespace.isNotNull()) { + if (leadingWhitespace.isNotNull() && leadingWhitespace.node()->isTextNode()) { Text* textNode = static_cast<Text*>(leadingWhitespace.node()); ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace()); replaceTextInNode(textNode, leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString()); @@ -385,10 +385,10 @@ void InsertParagraphSeparatorCommand::doApply() insertionPosition = Position(insertionPosition.node(), 0); if (!insertionPosition.isRenderedCharacter()) { // Clear out all whitespace and insert one non-breaking space - ASSERT(insertionPosition.node()->isTextNode()); ASSERT(!insertionPosition.node()->renderer() || insertionPosition.node()->renderer()->style()->collapseWhiteSpace()); deleteInsignificantTextDownstream(insertionPosition); - insertTextIntoNode(static_cast<Text*>(insertionPosition.node()), 0, nonBreakingSpaceString()); + if (insertionPosition.node()->isTextNode()) + insertTextIntoNode(static_cast<Text*>(insertionPosition.node()), 0, nonBreakingSpaceString()); } } |