15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2005, 2006 Apple Computer, Inc.  All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/InsertParagraphSeparatorCommand.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295d92fedcae5e801a8b224de090094f2d9df0b54aTorne (Richard Coles)#include "core/HTMLNames.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/NodeTraversal.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Text.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/EditingStyle.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/InsertLineBreakCommand.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/VisibleUnits.h"
3653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/editing/htmlediting.h"
37c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/html/HTMLBRElement.h"
3853e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/html/HTMLElement.h"
39c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/html/HTMLQuoteElement.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h"
41c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)#include "core/rendering/RenderText.h"
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
43c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)using namespace HTMLNames;
465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// When inserting a new line, we want to avoid nesting empty divs if we can.  Otherwise, when
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// pasting, it's easy to have each new line be a div deeper than the previous.  E.g., in the case
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// below, we want to insert at ^ instead of |.
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// <div>foo<div>bar</div>|</div>^
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Element* highestVisuallyEquivalentDivBelowRoot(Element* startBlock)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Element* curBlock = startBlock;
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // We don't want to return a root node (if it happens to be a div, e.g., in a document fragment) because there are no
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // siblings for us to append to.
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (!curBlock->nextSibling() && isHTMLDivElement(*curBlock->parentElement()) && curBlock->parentElement()->parentElement()) {
575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (curBlock->parentElement()->hasAttributes())
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            break;
595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        curBlock = curBlock->parentElement();
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return curBlock;
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
64c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)InsertParagraphSeparatorCommand::InsertParagraphSeparatorCommand(Document& document, bool mustUseDefaultParagraphElement, bool pasteBlockquoteIntoUnquotedArea)
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : CompositeEditCommand(document)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_mustUseDefaultParagraphElement(mustUseDefaultParagraphElement)
67c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    , m_pasteBlockquoteIntoUnquotedArea(pasteBlockquoteIntoUnquotedArea)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool InsertParagraphSeparatorCommand::preservesTypingStyle() const
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InsertParagraphSeparatorCommand::calculateStyleBeforeInsertion(const Position &pos)
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // It is only important to set a style to apply later if we're at the boundaries of
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // a paragraph. Otherwise, content that is moved as part of the work of the command
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // will lend their styles to the new paragraph without any extra work needed.
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisiblePosition visiblePos(pos, VP_DEFAULT_AFFINITY);
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isStartOfParagraph(visiblePos) && !isEndOfParagraph(visiblePos))
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(pos.isNotNull());
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_style = EditingStyle::create(pos);
878abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    m_style->mergeTypingStyle(pos.document());
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
90c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void InsertParagraphSeparatorCommand::applyStyleAfterInsertion(Element* originalEnclosingBlock)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Not only do we break out of header tags, but we also do not preserve the typing style,
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // in order to match other browsers.
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (originalEnclosingBlock->hasTagName(h1Tag) ||
955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        originalEnclosingBlock->hasTagName(h2Tag) ||
965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        originalEnclosingBlock->hasTagName(h3Tag) ||
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        originalEnclosingBlock->hasTagName(h4Tag) ||
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        originalEnclosingBlock->hasTagName(h5Tag))
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_style)
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_style->prepareToApplyAt(endingSelection().start());
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!m_style->isEmpty())
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        applyStyle(m_style.get());
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
109c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool InsertParagraphSeparatorCommand::shouldUseDefaultParagraphElement(Element* enclosingBlock) const
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_mustUseDefaultParagraphElement)
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return true;
11302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Assumes that if there was a range selection, it was already deleted.
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!isEndOfBlock(endingSelection().visibleStart()))
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return enclosingBlock->hasTagName(h1Tag) ||
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           enclosingBlock->hasTagName(h2Tag) ||
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           enclosingBlock->hasTagName(h3Tag) ||
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           enclosingBlock->hasTagName(h4Tag) ||
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)           enclosingBlock->hasTagName(h5Tag);
1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
125f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void InsertParagraphSeparatorCommand::getAncestorsInsideBlock(const Node* insertionNode, Element* outerBlock, WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors)
1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ancestors.clear();
12802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Build up list of ancestors elements between the insertion node and the outer block.
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (insertionNode != outerBlock) {
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        for (Element* n = insertionNode->parentElement(); n && n != outerBlock; n = n->parentElement())
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ancestors.append(n);
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
136f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)PassRefPtrWillBeRawPtr<Element> InsertParagraphSeparatorCommand::cloneHierarchyUnderNewBlock(const WillBeHeapVector<RefPtrWillBeMember<Element> >& ancestors, PassRefPtrWillBeRawPtr<Element> blockToInsert)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make clones of ancestors in between the start node and the start block.
139f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> parent = blockToInsert;
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    for (size_t i = ancestors.size(); i != 0; --i) {
141f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeRawPtr<Element> child = ancestors[i - 1]->cloneElementWithoutChildren();
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // It should always be okay to remove id from the cloned elements, since the originals are not deleted.
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        child->removeAttribute(idAttr);
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNode(child, parent);
1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        parent = child.release();
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
14702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return parent.release();
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void InsertParagraphSeparatorCommand::doApply()
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!endingSelection().isNonOrphanedCaretOrRange())
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
15502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position insertionPosition = endingSelection().start();
15702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    EAffinity affinity = endingSelection().affinity();
15902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Delete the current selection.
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (endingSelection().isRange()) {
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        calculateStyleBeforeInsertion(insertionPosition);
1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        deleteSelection(false, true);
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertionPosition = endingSelection().start();
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        affinity = endingSelection().affinity();
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
16702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: The parentAnchoredEquivalent conversion needs to be moved into enclosingBlock.
169f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode());
17006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    Node* listChildNode = enclosingListChild(insertionPosition.parentAnchoredEquivalent().containerNode());
171c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    RefPtrWillBeRawPtr<HTMLElement> listChild = listChildNode && listChildNode->isHTMLElement() ? toHTMLElement(listChildNode) : 0;
1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent();
1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!startBlock
1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || !startBlock->nonShadowBoundaryParentNode()
1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        || isTableCell(startBlock.get())
176d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        || isHTMLFormElement(*startBlock)
1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342
178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        || (!canonicalPos.isNull() && isRenderedTableElement(canonicalPos.deprecatedNode()))
179d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.deprecatedNode()))) {
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        applyCommandToComposite(InsertLineBreakCommand::create(document()));
1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
18302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Use the leftmost candidate.
1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    insertionPosition = insertionPosition.upstream();
1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!insertionPosition.isCandidate())
1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertionPosition = insertionPosition.downstream();
1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Adjust the insertion position after the delete
1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    insertionPosition = positionAvoidingSpecialElementBoundary(insertionPosition);
1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    VisiblePosition visiblePos(insertionPosition, affinity);
1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    calculateStyleBeforeInsertion(insertionPosition);
1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //---------------------------------------------------------------------
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle special case of typing return on an empty list item
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (breakOutOfEmptyListItem())
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //---------------------------------------------------------------------
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Prepare for more general cases.
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isFirstInBlock = isStartOfBlock(visiblePos);
2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool isLastInBlock = isEndOfBlock(visiblePos);
2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    bool nestNewBlock = false;
2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Create block to be inserted.
207f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    RefPtrWillBeRawPtr<Element> blockToInsert = nullptr;
2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (startBlock->isRootEditableElement()) {
2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockToInsert = createDefaultParagraphElement(document());
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        nestNewBlock = true;
2118abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    } else if (shouldUseDefaultParagraphElement(startBlock.get())) {
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockToInsert = createDefaultParagraphElement(document());
2138abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    } else {
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        blockToInsert = startBlock->cloneElementWithoutChildren();
2158abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    }
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //---------------------------------------------------------------------
2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle case when position is in the last visible position in its block,
21902772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // including when the block is empty.
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isLastInBlock) {
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (nestNewBlock) {
2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (isFirstInBlock && !lineBreakExistsAtVisiblePosition(visiblePos)) {
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // The block is empty.  Create an empty block to
2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                // represent the paragraph that we're leaving.
225c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                RefPtrWillBeRawPtr<HTMLElement> extraBlock = createDefaultParagraphElement(document());
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                appendNode(extraBlock, startBlock);
2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                appendBlockPlaceholder(extraBlock);
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            appendNode(blockToInsert, startBlock);
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else {
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // We can get here if we pasted a copied portion of a blockquote with a newline at the end and are trying to paste it
2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // into an unquoted area. We then don't want the newline within the blockquote or else it will also be quoted.
233c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            if (m_pasteBlockquoteIntoUnquotedArea) {
234c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                if (HTMLQuoteElement* highestBlockquote = toHTMLQuoteElement(highestEnclosingNodeOfType(canonicalPos, &isMailHTMLBlockquoteElement)))
235c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                    startBlock = highestBlockquote;
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
23806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (listChild && listChild != startBlock) {
239f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
24006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                appendNode(blockToInsert, listChildToInsert.get());
24106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                insertNodeAfter(listChildToInsert.get(), listChild);
24206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            } else {
24306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists). However,
24406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                // for div nodes, this can result in nested div tags that are hard to break out of.
245c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                Element* siblingElement = startBlock.get();
246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                if (isHTMLDivElement(*blockToInsert))
247c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                    siblingElement = highestVisuallyEquivalentDivBelowRoot(startBlock.get());
248c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)                insertNodeAfter(blockToInsert, siblingElement);
24906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Recreate the same structure in the new paragraph.
25302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
254f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors;
25502772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch        getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock.get(), ancestors);
256f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeRawPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);
25702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendBlockPlaceholder(parent);
2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setEndingSelection(VisibleSelection(firstPositionInNode(parent.get()), DOWNSTREAM, endingSelection().isDirectional()));
2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
26302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //---------------------------------------------------------------------
2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle case when position is in the first visible position in its block, and
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // similar case where previous position is in another, presumeably nested, block.
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isFirstInBlock || !inSameBlock(visiblePos, visiblePos.previous())) {
26906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        Node* refNode = 0;
2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertionPosition = positionOutsideTabSpan(insertionPosition);
2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
27206f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (isFirstInBlock && !nestNewBlock) {
27306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            if (listChild && listChild != startBlock) {
274f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)                RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
27506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                appendNode(blockToInsert, listChildToInsert.get());
27606f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                insertNodeBefore(listChildToInsert.get(), listChild);
27706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            } else {
27806f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)                refNode = startBlock.get();
27906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            }
28006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        } else if (isFirstInBlock && nestNewBlock) {
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // startBlock should always have children, otherwise isLastInBlock would be true and it's handled above.
282c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            ASSERT(startBlock->hasChildren());
2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            refNode = startBlock->firstChild();
2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else if (insertionPosition.deprecatedNode() == startBlock && nestNewBlock) {
286c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)            refNode = NodeTraversal::childAt(*startBlock, insertionPosition.deprecatedEditingOffset());
2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(refNode); // must be true or we'd be in the end of block case
2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        } else
2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            refNode = insertionPosition.deprecatedNode();
2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // find ending selection position easily before inserting the paragraph
2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertionPosition = insertionPosition.downstream();
29302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
29406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        if (refNode)
29506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)            insertNodeBefore(blockToInsert, refNode);
2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // Recreate the same structure in the new paragraph.
2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
299f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        WillBeHeapVector<RefPtrWillBeMember<Element> > ancestors;
3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock.get(), ancestors);
30102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToInsert));
30302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // In this case, we need to set the new ending selection.
3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        setEndingSelection(VisibleSelection(insertionPosition, DOWNSTREAM, endingSelection().isDirectional()));
3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    //---------------------------------------------------------------------
3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle the (more complicated) general case,
3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // All of the content in the current block after visiblePos is
31302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // about to be wrapped in a new paragraph element.  Add a br before
31402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // it if visiblePos is at the start of a paragraph so that the
3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // content will move down a line.
3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isStartOfParagraph(visiblePos)) {
317c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        RefPtrWillBeRawPtr<HTMLBRElement> br = createBreakElement(document());
3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertNodeAt(br.get(), insertionPosition);
319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        insertionPosition = positionInParentAfterNode(*br);
3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // If the insertion point is a break element, there is nothing else
3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        // we need to do.
3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (visiblePos.deepEquivalent().anchorNode()->renderer()->isBR()) {
3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            setEndingSelection(VisibleSelection(insertionPosition, DOWNSTREAM, endingSelection().isDirectional()));
3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            return;
3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
32702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
32802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // Move downstream. Typing style code will take care of carrying along the
3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // style of the upstream position.
3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    insertionPosition = insertionPosition.downstream();
3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // At this point, the insertionPosition's node could be a container, and we want to make sure we include
3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // all of the correct nodes when building the ancestor list.  So this needs to be the deepest representation of the position
3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // before we walk the DOM tree.
3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    insertionPosition = positionOutsideTabSpan(VisiblePosition(insertionPosition).deepEquivalent());
3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
337e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // If the returned position lies either at the end or at the start of an element that is ignored by editing
338e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    // we should move to its upstream or downstream position.
339e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    if (editingIgnoresContent(insertionPosition.deprecatedNode())) {
340e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        if (insertionPosition.atLastEditingPositionForNode())
341e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            insertionPosition = insertionPosition.downstream();
342e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch        else if (insertionPosition.atFirstEditingPositionForNode())
343e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch            insertionPosition = insertionPosition.upstream();
344e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    }
345e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch
3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Make sure we do not cause a rendered space to become unrendered.
3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: We need the affinity for pos, but pos.downstream() does not give it
348197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    Position leadingWhitespace = leadingWhitespacePosition(insertionPosition, VP_DEFAULT_AFFINITY);
3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: leadingWhitespacePosition is returning the position before preserved newlines for positions
3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // after the preserved newline, causing the newline to be turned into a nbsp.
3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (leadingWhitespace.isNotNull() && leadingWhitespace.deprecatedNode()->isTextNode()) {
3525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Text* textNode = toText(leadingWhitespace.deprecatedNode());
3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        replaceTextInNodePreservingMarkers(textNode, leadingWhitespace.deprecatedEditingOffset(), 1, nonBreakingSpaceString());
3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
35602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch
3575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Split at pos if in the middle of a text node.
3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    Position positionAfterSplit;
3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (insertionPosition.anchorType() == Position::PositionIsOffsetInAnchor && insertionPosition.containerNode()->isTextNode()) {
360d6cdb82654e8f3343a693ca752d5c4cee0324e17Torne (Richard Coles)        RefPtrWillBeRawPtr<Text> textNode = toText(insertionPosition.containerNode());
3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        bool atEnd = static_cast<unsigned>(insertionPosition.offsetInContainerNode()) >= textNode->length();
3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (insertionPosition.deprecatedEditingOffset() > 0 && !atEnd) {
3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            splitTextNode(textNode, insertionPosition.offsetInContainerNode());
3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            positionAfterSplit = firstPositionInNode(textNode.get());
3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            insertionPosition.moveToPosition(textNode->previousSibling(), insertionPosition.offsetInContainerNode());
3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            visiblePos = VisiblePosition(insertionPosition);
3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If we got detached due to mutation events, just bail out.
3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (!startBlock->parentNode())
3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Put the added block in the tree.
37506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    if (nestNewBlock) {
3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNode(blockToInsert.get(), startBlock);
37706f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    } else if (listChild && listChild != startBlock) {
378f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)        RefPtrWillBeRawPtr<Element> listChildToInsert = listChild->cloneElementWithoutChildren();
37906f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        appendNode(blockToInsert.get(), listChildToInsert.get());
38006f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)        insertNodeAfter(listChildToInsert.get(), listChild);
38106f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    } else {
3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        insertNodeAfter(blockToInsert.get(), startBlock);
38306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)    }
3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3858abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)    document().updateLayoutIgnorePendingStylesheets();
3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // If the paragraph separator was inserted at the end of a paragraph, an empty line must be
38802772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    // created.  All of the nodes, starting at visiblePos, are about to be added to the new paragraph
3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // element.  If the first node to be inserted won't be one that will hold an empty line open, add a br.
3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (isEndOfParagraph(visiblePos) && !lineBreakExistsAtVisiblePosition(visiblePos))
3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        appendNode(createBreakElement(document()).get(), blockToInsert.get());
3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Move the start node and the siblings of the start node.
3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (VisiblePosition(insertionPosition) != VisiblePosition(positionBeforeNode(blockToInsert.get()))) {
3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        Node* n;
3965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (insertionPosition.containerNode() == startBlock)
3975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            n = insertionPosition.computeNodeAfterPosition();
3985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        else {
3995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            Node* splitTo = insertionPosition.containerNode();
4005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (splitTo->isTextNode() && insertionPosition.offsetInContainerNode() >= caretMaxOffset(splitTo))
40151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)                splitTo = NodeTraversal::next(*splitTo, startBlock.get());
4025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(splitTo);
4035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            splitTreeToNode(splitTo, startBlock.get());
4045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            for (n = startBlock->firstChild(); n; n = n->nextSibling()) {
406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                VisiblePosition beforeNodePosition(positionBeforeNode(n));
40753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)                if (!beforeNodePosition.isNull() && comparePositions(VisiblePosition(insertionPosition), beforeNodePosition) <= 0)
4085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                    break;
4095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            }
4105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        moveRemainingSiblingsToNewParent(n, blockToInsert.get(), blockToInsert);
41302772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch    }
4145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Handle whitespace that occurs after the split
4165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (positionAfterSplit.isNotNull()) {
4178abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)        document().updateLayoutIgnorePendingStylesheets();
4185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        if (!positionAfterSplit.isRenderedCharacter()) {
4195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            // Clear out all whitespace and insert one non-breaking space
4205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            ASSERT(!positionAfterSplit.containerNode()->renderer() || positionAfterSplit.containerNode()->renderer()->style()->collapseWhiteSpace());
4215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            deleteInsignificantTextDownstream(positionAfterSplit);
4225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)            if (positionAfterSplit.deprecatedNode()->isTextNode())
4235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)                insertTextIntoNode(toText(positionAfterSplit.containerNode()), 0, nonBreakingSpaceString());
4245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        }
4255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
4265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
4275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    setEndingSelection(VisibleSelection(firstPositionInNode(blockToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
4285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    applyStyleAfterInsertion(startBlock.get());
4295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
4305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
431f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)void InsertParagraphSeparatorCommand::trace(Visitor *visitor)
432f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles){
433f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    visitor->trace(m_style);
434f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)    CompositeEditCommand::trace(visitor);
435f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)}
436f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
437f6b7aed3f7ce69aca0d7a032d144cbd088b04393Torne (Richard Coles)
438c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
439