diff options
author | Steve Block <steveblock@google.com> | 2009-11-05 09:23:40 +0000 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2009-11-10 22:41:12 +0000 |
commit | cac0f67c402d107cdb10971b95719e2ff9c7c76b (patch) | |
tree | d182c7f87211c6f201a5f038e332336493ebdbe7 /WebCore/editing/IndentOutdentCommand.cpp | |
parent | 4b2ef0f288e7c6c4602f621b7a0e9feed304b70e (diff) | |
download | external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.zip external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.gz external_webkit-cac0f67c402d107cdb10971b95719e2ff9c7c76b.tar.bz2 |
Merge webkit.org at r50258 : Initial merge by git.
Change-Id: I1a9e1dc4ed654b69174ad52a4f031a07240f37b0
Diffstat (limited to 'WebCore/editing/IndentOutdentCommand.cpp')
-rw-r--r-- | WebCore/editing/IndentOutdentCommand.cpp | 115 |
1 files changed, 31 insertions, 84 deletions
diff --git a/WebCore/editing/IndentOutdentCommand.cpp b/WebCore/editing/IndentOutdentCommand.cpp index 308ba74..808a2f8 100644 --- a/WebCore/editing/IndentOutdentCommand.cpp +++ b/WebCore/editing/IndentOutdentCommand.cpp @@ -33,7 +33,6 @@ #include "InsertLineBreakCommand.h" #include "InsertListCommand.h" #include "Range.h" -#include "DocumentFragment.h" #include "SplitElementCommand.h" #include "TextIterator.h" #include "htmlediting.h" @@ -81,14 +80,15 @@ bool IndentOutdentCommand::tryIndentingAsListItem(const VisiblePosition& endOfCu // FIXME: we need to deal with the case where there is no li (malformed HTML) if (!selectedListItem->hasTagName(liTag)) return false; - + // FIXME: previousElementSibling does not ignore non-rendered content like <span></span>. Should we? Element* previousList = selectedListItem->previousElementSibling(); Element* nextList = selectedListItem->nextElementSibling(); RefPtr<Element> newList = document()->createElement(listNode->tagQName(), false); insertNodeBefore(newList, selectedListItem); - appendParagraphIntoNode(visiblePositionBeforeNode(selectedListItem), visiblePositionAfterNode(selectedListItem), newList.get()); + + moveParagraphWithClones(startOfParagraph(endOfCurrentParagraph), endOfCurrentParagraph, newList.get(), selectedListItem); if (canMergeLists(previousList, newList.get())) mergeIdenticalElements(previousList, newList); @@ -98,87 +98,44 @@ bool IndentOutdentCommand::tryIndentingAsListItem(const VisiblePosition& endOfCu return true; } -void IndentOutdentCommand::indentIntoBlockquote(const VisiblePosition& startOfCurrentParagraph, const VisiblePosition& endOfCurrentParagraph, RefPtr<Element>& targetBlockquote, Node* nodeToSplitTo) +void IndentOutdentCommand::indentIntoBlockquote(const VisiblePosition& endOfCurrentParagraph, const VisiblePosition& endOfNextParagraph, RefPtr<Element>& targetBlockquote) { Node* enclosingCell = 0; + Position start = startOfParagraph(endOfCurrentParagraph).deepEquivalent(); + enclosingCell = enclosingNodeOfType(start, &isTableCell); + Node* nodeToSplitTo; + if (enclosingCell) + nodeToSplitTo = enclosingCell; + else if (enclosingList(start.node())) + nodeToSplitTo = enclosingBlock(start.node()); + else + nodeToSplitTo = editableRootForPosition(start); + + RefPtr<Node> outerBlock = splitTreeToNode(start.node(), nodeToSplitTo); + if (!targetBlockquote) { - // Create a new blockquote and insert it as a child of the enclosing block element. We accomplish + // Create a new blockquote and insert it as a child of the root editable element. We accomplish // this by splitting all parents of the current paragraph up to that point. targetBlockquote = createIndentBlockquoteElement(document()); - if (isTableCell(nodeToSplitTo)) - enclosingCell = nodeToSplitTo; - RefPtr<Node> startOfNewBlock = splitTreeToNode(startOfCurrentParagraph.deepEquivalent().node(), nodeToSplitTo); - insertNodeBefore(targetBlockquote, startOfNewBlock); + insertNodeBefore(targetBlockquote, outerBlock); } - VisiblePosition endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next()); - appendParagraphIntoNode(startOfCurrentParagraph, endOfCurrentParagraph, targetBlockquote.get()); - + moveParagraphWithClones(startOfParagraph(endOfCurrentParagraph), endOfCurrentParagraph, targetBlockquote.get(), outerBlock.get()); + // Don't put the next paragraph in the blockquote we just created for this paragraph unless // the next paragraph is in the same cell. if (enclosingCell && enclosingCell != enclosingNodeOfType(endOfNextParagraph.deepEquivalent(), &isTableCell)) targetBlockquote = 0; } -// Enclose all nodes between start and end by newParent, which is a sibling node of nodes between start and end -// FIXME: moveParagraph is overly complicated. We need to clean up moveParagraph so that it uses appendParagraphIntoNode -// or prepare more specialized functions and delete moveParagraph -void IndentOutdentCommand::appendParagraphIntoNode(const VisiblePosition& start, const VisiblePosition& end, Node* newParent) -{ - ASSERT(newParent); - ASSERT(newParent->isContentEditable()); - ASSERT(isStartOfParagraph(start) && isEndOfParagraph(end)); - - Position endOfParagraph = end.deepEquivalent().downstream(); - Node* insertionPoint = newParent->lastChild();// Remember the place to put br later - // Look for the beginning of the last paragraph in newParent - Node* startOfLastParagraph = startOfParagraph(Position(newParent, newParent->childNodeCount())).deepEquivalent().node(); - if (startOfLastParagraph && !startOfLastParagraph->isDescendantOf(newParent)) - startOfLastParagraph = 0; - - // Extend the range so that we can append wrapping nodes as well if they're containd within the paragraph - ExceptionCode ec = 0; - RefPtr<Range> selectedRange = createRange(document(), start, end, ec); - RefPtr<Range> extendedRange = extendRangeToWrappingNodes(selectedRange, selectedRange.get(), newParent->parentNode()); - newParent->appendChild(extendedRange->extractContents(ec), ec); - - // If the start of paragraph didn't change by appending nodes, we should insert br to seperate the paragraphs. - Node* startOfNewParagraph = startOfParagraph(Position(newParent, newParent->childNodeCount())).deepEquivalent().node(); - if (startOfNewParagraph == startOfLastParagraph) { - if (insertionPoint) - newParent->insertBefore(createBreakElement(document()), insertionPoint->nextSibling(), ec); - else - newParent->appendChild(createBreakElement(document()), ec); - } - - // Remove unnecessary br from the place where we moved the paragraph from - removeUnnecessaryLineBreakAt(endOfParagraph); -} - -void IndentOutdentCommand::removeUnnecessaryLineBreakAt(const Position& endOfParagraph) -{ - // If there is something in this paragraph, then don't remove br. - if (!isStartOfParagraph(endOfParagraph) || !isEndOfParagraph(endOfParagraph)) - return; - - // We only care about br at the end of paragraph - Node* br = endOfParagraph.node(); - Node* parentNode = br->parentNode(); - - // If the node isn't br or the parent node is empty, then don't remove. - if (!br->hasTagName(brTag) || isVisiblyAdjacent(positionInParentBeforeNode(parentNode), positionInParentAfterNode(parentNode))) - return; - - removeNodeAndPruneAncestors(br); -} - void IndentOutdentCommand::indentRegion() { VisibleSelection selection = selectionForParagraphIteration(endingSelection()); VisiblePosition startOfSelection = selection.visibleStart(); VisiblePosition endOfSelection = selection.visibleEnd(); - RefPtr<Range> selectedRange = selection.firstRange(); + int startIndex = indexForVisiblePosition(startOfSelection); + int endIndex = indexForVisiblePosition(endOfSelection); ASSERT(!startOfSelection.isNull()); ASSERT(!endOfSelection.isNull()); @@ -203,24 +160,8 @@ void IndentOutdentCommand::indentRegion() VisiblePosition endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next()); if (tryIndentingAsListItem(endOfCurrentParagraph)) blockquoteForNextIndent = 0; - else { - VisiblePosition startOfCurrentParagraph = startOfParagraph(endOfCurrentParagraph); - Node* blockNode = enclosingBlock(endOfCurrentParagraph.deepEquivalent().node()->parentNode()); - // extend the region so that it contains all the ancestor blocks within the selection - ExceptionCode ec; - Element* unsplittableNode = unsplittableElementForPosition(endOfCurrentParagraph.deepEquivalent()); - RefPtr<Range> originalRange = createRange(document(), endOfCurrentParagraph, endOfCurrentParagraph, ec); - RefPtr<Range> extendedRange = extendRangeToWrappingNodes(originalRange, selectedRange.get(), unsplittableNode); - if (originalRange != extendedRange) { - ExceptionCode ec = 0; - endOfCurrentParagraph = endOfParagraph(extendedRange->endPosition().previous()); - blockNode = enclosingBlock(extendedRange->commonAncestorContainer(ec)); - } - - endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next()); - indentIntoBlockquote(startOfCurrentParagraph, endOfCurrentParagraph, blockquoteForNextIndent, blockNode); - // blockquoteForNextIndent will be updated in the function - } + else + indentIntoBlockquote(endOfCurrentParagraph, endOfNextParagraph, blockquoteForNextIndent); // Sanity check: Make sure our moveParagraph calls didn't remove endOfNextParagraph.deepEquivalent().node() // If somehow we did, return to prevent crashes. if (endOfNextParagraph.isNotNull() && !endOfNextParagraph.deepEquivalent().node()->inDocument()) { @@ -229,7 +170,13 @@ void IndentOutdentCommand::indentRegion() } endOfCurrentParagraph = endOfNextParagraph; } - + + updateLayout(); + + RefPtr<Range> startRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, 0, true); + RefPtr<Range> endRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), endIndex, 0, true); + if (startRange && endRange) + setEndingSelection(VisibleSelection(startRange->startPosition(), endRange->startPosition(), DOWNSTREAM)); } void IndentOutdentCommand::outdentParagraph() |