summaryrefslogtreecommitdiffstats
path: root/WebCore/editing/ReplaceSelectionCommand.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/editing/ReplaceSelectionCommand.cpp')
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.cpp45
1 files changed, 31 insertions, 14 deletions
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 49bdaca..056ab70 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -76,9 +76,9 @@ public:
void removeNodePreservingChildren(Node*);
private:
- PassRefPtr<Node> insertFragmentForTestRendering(Node* context);
+ PassRefPtr<StyledElement> insertFragmentForTestRendering(Node* context);
void removeUnrenderedNodes(Node*);
- void restoreTestRenderingNodesToFragment(Node*);
+ void restoreTestRenderingNodesToFragment(StyledElement*);
void removeInterchangeNodes(Node*);
void insertNodeBefore(PassRefPtr<Node> node, Node* refNode);
@@ -150,7 +150,7 @@ ReplacementFragment::ReplacementFragment(Document* document, DocumentFragment* f
}
Node* styleNode = selection.base().node();
- RefPtr<Node> holder = insertFragmentForTestRendering(styleNode);
+ RefPtr<StyledElement> holder = insertFragmentForTestRendering(styleNode);
RefPtr<Range> range = VisibleSelection::selectionFromContentsOfNode(holder.get()).toNormalizedRange();
String text = plainText(range.get());
@@ -208,7 +208,7 @@ void ReplacementFragment::removeNode(PassRefPtr<Node> node)
if (!node)
return;
- Node *parent = node->parentNode();
+ ContainerNode* parent = node->parentNode();
if (!parent)
return;
@@ -222,7 +222,7 @@ void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode)
if (!node || !refNode)
return;
- Node* parent = refNode->parentNode();
+ ContainerNode* parent = refNode->parentNode();
if (!parent)
return;
@@ -231,9 +231,9 @@ void ReplacementFragment::insertNodeBefore(PassRefPtr<Node> node, Node* refNode)
ASSERT(ec == 0);
}
-PassRefPtr<Node> ReplacementFragment::insertFragmentForTestRendering(Node* context)
+PassRefPtr<StyledElement> ReplacementFragment::insertFragmentForTestRendering(Node* context)
{
- Node* body = m_document->body();
+ HTMLElement* body = m_document->body();
if (!body)
return 0;
@@ -266,7 +266,7 @@ PassRefPtr<Node> ReplacementFragment::insertFragmentForTestRendering(Node* conte
return holder.release();
}
-void ReplacementFragment::restoreTestRenderingNodesToFragment(Node *holder)
+void ReplacementFragment::restoreTestRenderingNodesToFragment(StyledElement* holder)
{
if (!holder)
return;
@@ -628,7 +628,7 @@ void ReplaceSelectionCommand::handleStyleSpans()
return;
RefPtr<CSSMutableStyleDeclaration> sourceDocumentStyle = static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()->copy();
- Node* context = sourceDocumentStyleSpan->parentNode();
+ ContainerNode* context = sourceDocumentStyleSpan->parentNode();
// If Mail wraps the fragment with a Paste as Quotation blockquote, or if you're pasting into a quoted region,
// styles from blockquoteNode are allowed to override those from the source document, see <rdar://problem/4930986> and <rdar://problem/5089327>.
@@ -710,13 +710,15 @@ void ReplaceSelectionCommand::copyStyleToChildren(Node* parentNode, const CSSMut
for (Node* childNode = parentNode->firstChild(); childNode; childNode = childNode->nextSibling()) {
if (childNode->isTextNode() || !isBlock(childNode) || childNode->hasTagName(preTag)) {
// In this case, put a span tag around the child node.
- RefPtr<Node> newSpan = parentNode->cloneNode(false);
- setNodeAttribute(static_cast<Element*>(newSpan.get()), styleAttr, parentStyle->cssText());
+ RefPtr<Node> newNode = parentNode->cloneNode(false);
+ ASSERT(newNode->hasTagName(spanTag));
+ HTMLElement* newSpan = static_cast<HTMLElement*>(newNode.get());
+ setNodeAttribute(newSpan, styleAttr, parentStyle->cssText());
insertNodeAfter(newSpan, childNode);
ExceptionCode ec = 0;
newSpan->appendChild(childNode, ec);
ASSERT(!ec);
- childNode = newSpan.get();
+ childNode = newSpan;
} else if (childNode->isHTMLElement()) {
// Copy the style attribute and merge them into the child node. We don't want to override
// existing styles, so don't clobber on merge.
@@ -777,6 +779,21 @@ void ReplaceSelectionCommand::mergeEndIfNeeded()
}
}
+static Node* enclosingInline(Node* node)
+{
+ while (ContainerNode* parent = node->parentNode()) {
+ if (parent->isBlockFlow() || parent->hasTagName(bodyTag))
+ return node;
+ // Stop if any previous sibling is a block.
+ for (Node* sibling = node->previousSibling(); sibling; sibling = sibling->previousSibling()) {
+ if (sibling->isBlockFlow())
+ return node;
+ }
+ node = parent;
+ }
+ return node;
+}
+
void ReplaceSelectionCommand::doApply()
{
VisibleSelection selection = endingSelection();
@@ -996,7 +1013,7 @@ void ReplaceSelectionCommand::doApply()
// but our destination node is inside an inline that is the last in the block.
// We insert a placeholder before the newly inserted content to avoid being merged into the inline.
Node* destinationNode = destination.deepEquivalent().node();
- if (m_shouldMergeEnd && destinationNode != destinationNode->enclosingInlineElement() && destinationNode->enclosingInlineElement()->nextSibling())
+ if (m_shouldMergeEnd && destinationNode != enclosingInline(destinationNode) && enclosingInline(destinationNode)->nextSibling())
insertNodeBefore(createBreakElement(document()), refNode.get());
// Merging the the first paragraph of inserted content with the content that came
@@ -1211,7 +1228,7 @@ Node* ReplaceSelectionCommand::insertAsListItems(PassRefPtr<Node> listElement, N
while (RefPtr<Node> listItem = listElement->firstChild()) {
ExceptionCode ec = 0;
- listElement->removeChild(listItem.get(), ec);
+ toContainerNode(listElement.get())->removeChild(listItem.get(), ec);
ASSERT(!ec);
if (isStart || isMiddle)
insertNodeBefore(listItem, lastNode);