This source file includes following definitions.
- doApply
#include "config.h"
#include "core/editing/BreakBlockquoteCommand.h"
#include "HTMLNames.h"
#include "core/dom/NodeTraversal.h"
#include "core/dom/Text.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/htmlediting.h"
#include "core/html/HTMLElement.h"
#include "core/rendering/RenderListItem.h"
namespace WebCore {
using namespace HTMLNames;
BreakBlockquoteCommand::BreakBlockquoteCommand(Document& document)
: CompositeEditCommand(document)
{
}
void BreakBlockquoteCommand::doApply()
{
if (endingSelection().isNone())
return;
if (endingSelection().isRange())
deleteSelection(false, false);
ASSERT(!endingSelection().isNone());
if (endingSelection().isNone())
return;
VisiblePosition visiblePos = endingSelection().visibleStart();
Position pos = endingSelection().start().downstream();
Node* topBlockquote = highestEnclosingNodeOfType(pos, isMailBlockquote);
if (!topBlockquote || !topBlockquote->parentNode() || !topBlockquote->isElementNode())
return;
RefPtr<Element> breakNode = createBreakElement(document());
bool isLastVisPosInNode = isLastVisiblePositionInNode(visiblePos, topBlockquote);
if (isFirstVisiblePositionInNode(visiblePos, topBlockquote) && !isLastVisPosInNode) {
insertNodeBefore(breakNode.get(), topBlockquote);
setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM, endingSelection().isDirectional()));
rebalanceWhitespace();
return;
}
insertNodeAfter(breakNode.get(), topBlockquote);
if (isLastVisPosInNode) {
setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM, endingSelection().isDirectional()));
rebalanceWhitespace();
return;
}
if (lineBreakExistsAtVisiblePosition(visiblePos))
pos = pos.next();
while (isFirstVisiblePositionInNode(VisiblePosition(pos), enclosingNodeOfType(pos, isMailBlockquote)))
pos = pos.previous();
Node* startNode = pos.deprecatedNode();
ASSERT(startNode);
if (startNode->isTextNode()) {
Text* textNode = toText(startNode);
if ((unsigned)pos.deprecatedEditingOffset() >= textNode->length()) {
startNode = NodeTraversal::next(*startNode);
ASSERT(startNode);
} else if (pos.deprecatedEditingOffset() > 0)
splitTextNode(textNode, pos.deprecatedEditingOffset());
} else if (pos.deprecatedEditingOffset() > 0) {
Node* childAtOffset = startNode->traverseToChildAt(pos.deprecatedEditingOffset());
startNode = childAtOffset ? childAtOffset : NodeTraversal::next(*startNode);
ASSERT(startNode);
}
if (!startNode->isDescendantOf(topBlockquote)) {
setEndingSelection(VisibleSelection(VisiblePosition(firstPositionInOrBeforeNode(startNode)), endingSelection().isDirectional()));
return;
}
Vector<RefPtr<Element> > ancestors;
for (Element* node = startNode->parentElement(); node && node != topBlockquote; node = node->parentElement())
ancestors.append(node);
RefPtr<Element> clonedBlockquote = toElement(topBlockquote)->cloneElementWithoutChildren();
insertNodeAfter(clonedBlockquote.get(), breakNode.get());
RefPtr<Element> clonedAncestor = clonedBlockquote;
for (size_t i = ancestors.size(); i != 0; --i) {
RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
if (isHTMLOListElement(*clonedChild)) {
Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode;
while (listChildNode && !isHTMLLIElement(*listChildNode))
listChildNode = listChildNode->nextSibling();
if (listChildNode && listChildNode->renderer() && listChildNode->renderer()->isListItem())
setNodeAttribute(clonedChild, startAttr, AtomicString::number(toRenderListItem(listChildNode->renderer())->value()));
}
appendNode(clonedChild.get(), clonedAncestor.get());
clonedAncestor = clonedChild;
}
moveRemainingSiblingsToNewParent(startNode, 0, clonedAncestor);
if (!ancestors.isEmpty()) {
RefPtr<Element> ancestor;
RefPtr<Element> clonedParent;
for (ancestor = ancestors.first(), clonedParent = clonedAncestor->parentElement();
ancestor && ancestor != topBlockquote;
ancestor = ancestor->parentElement(), clonedParent = clonedParent->parentElement())
moveRemainingSiblingsToNewParent(ancestor->nextSibling(), 0, clonedParent);
Node* originalParent = ancestors.first().get();
if (!originalParent->hasChildren())
removeNode(originalParent);
}
addBlockPlaceholderIfNeeded(clonedBlockquote.get());
setEndingSelection(VisibleSelection(positionBeforeNode(breakNode.get()), DOWNSTREAM, endingSelection().isDirectional()));
rebalanceWhitespace();
}
}