summaryrefslogtreecommitdiffstats
path: root/WebCore/editing/ReplaceSelectionCommand.cpp
diff options
context:
space:
mode:
authorTeng-Hui Zhu <ztenghui@google.com>2010-11-10 15:31:59 -0800
committerTeng-Hui Zhu <ztenghui@google.com>2010-11-17 13:35:59 -0800
commit28040489d744e0c5d475a88663056c9040ed5320 (patch)
treec463676791e4a63e452a95f0a12b2a8519730693 /WebCore/editing/ReplaceSelectionCommand.cpp
parenteff9be92c41913c92fb1d3b7983c071f3e718678 (diff)
downloadexternal_webkit-28040489d744e0c5d475a88663056c9040ed5320.zip
external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.gz
external_webkit-28040489d744e0c5d475a88663056c9040ed5320.tar.bz2
Merge WebKit at r71558: Initial merge by git.
Change-Id: Ib345578fa29df7e4bc72b4f00e4a6fddcb754c4c
Diffstat (limited to 'WebCore/editing/ReplaceSelectionCommand.cpp')
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.cpp92
1 files changed, 36 insertions, 56 deletions
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 056ab70..fb52e56 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -31,7 +31,6 @@
#include "BreakBlockquoteCommand.h"
#include "CSSComputedStyleDeclaration.h"
#include "CSSMutableStyleDeclaration.h"
-#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Document.h"
@@ -484,17 +483,6 @@ void ReplaceSelectionCommand::negateStyleRulesThatAffectAppearance()
e->getInlineStyleDecl()->setProperty(CSSPropertyDisplay, CSSValueInline);
if (e->renderer() && e->renderer()->style()->floating() != FNONE)
e->getInlineStyleDecl()->setProperty(CSSPropertyFloat, CSSValueNone);
-
- // Undo the effects of page zoom if we have an absolute font size. When we copy, we
- // compute the new font size as an absolute size so pasting will cause the zoom to be
- // applied twice.
- if (e->renderer() && e->renderer()->style() && e->renderer()->style()->effectiveZoom() != 1.0
- && e->renderer()->style()->fontDescription().isAbsoluteSize()) {
- float newSize = e->renderer()->style()->fontDescription().specifiedSize() / e->renderer()->style()->effectiveZoom();
- ExceptionCode ec = 0;
- e->style()->setProperty(CSSPropertyFontSize, String::number(newSize), false, ec);
- ASSERT(!ec);
- }
}
if (node == m_lastLeafInserted)
break;
@@ -563,35 +551,36 @@ VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent()
static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos)
{
Node* topNode = fragment.firstChild();
-
+
// Handling the case where we are doing Paste as Quotation or pasting into quoted content is more complicated (see handleStyleSpans)
// and doesn't receive the optimization.
if (isMailPasteAsQuotationNode(topNode) || nearestMailBlockquote(topNode))
return false;
-
+
// Either there are no style spans in the fragment or a WebKit client has added content to the fragment
// before inserting it. Look for and handle style spans after insertion.
if (!isStyleSpan(topNode))
return false;
-
+
Node* sourceDocumentStyleSpan = topNode;
RefPtr<Node> copiedRangeStyleSpan = sourceDocumentStyleSpan->firstChild();
- RefPtr<CSSMutableStyleDeclaration> styleAtInsertionPos = ApplyStyleCommand::editingStyleAtPosition(rangeCompliantEquivalent(insertionPos));
+ RefPtr<EditingStyle> styleAtInsertionPos = EditingStyle::create(rangeCompliantEquivalent(insertionPos));
+ String styleText = styleAtInsertionPos->style()->cssText();
- String styleText = styleAtInsertionPos->cssText();
-
+ // FIXME: This string comparison is a naive way of comparing two styles.
+ // We should be taking the diff and check that the diff is empty.
if (styleText == static_cast<Element*>(sourceDocumentStyleSpan)->getAttribute(styleAttr)) {
fragment.removeNodePreservingChildren(sourceDocumentStyleSpan);
if (!isStyleSpan(copiedRangeStyleSpan.get()))
return true;
}
-
+
if (isStyleSpan(copiedRangeStyleSpan.get()) && styleText == static_cast<Element*>(copiedRangeStyleSpan.get())->getAttribute(styleAttr)) {
fragment.removeNodePreservingChildren(copiedRangeStyleSpan.get());
return true;
}
-
+
return false;
}
@@ -626,29 +615,20 @@ void ReplaceSelectionCommand::handleStyleSpans()
// we are here because of a document.execCommand("InsertHTML", ...) call.
if (!sourceDocumentStyleSpan)
return;
-
- RefPtr<CSSMutableStyleDeclaration> sourceDocumentStyle = static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()->copy();
+
+ RefPtr<EditingStyle> sourceDocumentStyle = EditingStyle::create(static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl());
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>.
Node* blockquoteNode = isMailPasteAsQuotationNode(context) ? context : nearestMailBlockquote(context);
if (blockquoteNode) {
- RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode, 0));
- RefPtr<CSSMutableStyleDeclaration> parentStyle = ApplyStyleCommand::editingStyleAtPosition(Position(blockquoteNode->parentNode(), 0));
- parentStyle->diff(blockquoteStyle.get());
-
- CSSMutableStyleDeclaration::const_iterator end = blockquoteStyle->end();
- for (CSSMutableStyleDeclaration::const_iterator it = blockquoteStyle->begin(); it != end; ++it) {
- const CSSProperty& property = *it;
- sourceDocumentStyle->removeProperty(property.id());
- }
-
+ sourceDocumentStyle->removeStyleConflictingWithStyleOfNode(blockquoteNode);
context = blockquoteNode->parentNode();
}
// This operation requires that only editing styles to be removed from sourceDocumentStyle.
- prepareEditingStyleToApplyAt(sourceDocumentStyle.get(), Position(context, 0));
+ sourceDocumentStyle->prepareToApplyAt(firstPositionInNode(context));
// Remove block properties in the span's style. This prevents properties that probably have no effect
// currently from affecting blocks later if the style is cloned for a new block element during a future
@@ -656,49 +636,44 @@ void ReplaceSelectionCommand::handleStyleSpans()
// FIXME: They *can* have an effect currently if blocks beneath the style span aren't individually marked
// with block styles by the editing engine used to style them. WebKit doesn't do this, but others might.
sourceDocumentStyle->removeBlockProperties();
-
+
// The styles on sourceDocumentStyleSpan are all redundant, and there is no copiedRangeStyleSpan
// to consider. We're finished.
- if (sourceDocumentStyle->length() == 0 && !copiedRangeStyleSpan) {
+ if (sourceDocumentStyle->isEmpty() && !copiedRangeStyleSpan) {
removeNodePreservingChildren(sourceDocumentStyleSpan);
return;
}
-
+
// There are non-redundant styles on sourceDocumentStyleSpan, but there is no
// copiedRangeStyleSpan. Remove the span, because it could be surrounding block elements,
// and apply the styles to its children.
- if (sourceDocumentStyle->length() > 0 && !copiedRangeStyleSpan) {
- copyStyleToChildren(sourceDocumentStyleSpan, sourceDocumentStyle.get());
+ if (!sourceDocumentStyle->isEmpty() && !copiedRangeStyleSpan) {
+ copyStyleToChildren(sourceDocumentStyleSpan, sourceDocumentStyle->style());
removeNodePreservingChildren(sourceDocumentStyleSpan);
return;
}
- RefPtr<CSSMutableStyleDeclaration> copiedRangeStyle = static_cast<HTMLElement*>(copiedRangeStyleSpan)->getInlineStyleDecl()->copy();
-
+ RefPtr<EditingStyle> copiedRangeStyle = EditingStyle::create(static_cast<HTMLElement*>(copiedRangeStyleSpan)->getInlineStyleDecl());
+
// We're going to put sourceDocumentStyleSpan's non-redundant styles onto copiedRangeStyleSpan,
// as long as they aren't overridden by ones on copiedRangeStyleSpan.
- sourceDocumentStyle->merge(copiedRangeStyle.get(), true);
- copiedRangeStyle = sourceDocumentStyle;
-
+ copiedRangeStyle->style()->merge(sourceDocumentStyle->style(), false);
+
removeNodePreservingChildren(sourceDocumentStyleSpan);
-
+
// Remove redundant styles.
context = copiedRangeStyleSpan->parentNode();
- prepareEditingStyleToApplyAt(copiedRangeStyle.get(), Position(context, 0));
-
- // See the comments above about removing block properties.
+ copiedRangeStyle->prepareToApplyAt(firstPositionInNode(context));
copiedRangeStyle->removeBlockProperties();
-
- // All the styles on copiedRangeStyleSpan are redundant, remove it.
- if (copiedRangeStyle->length() == 0) {
+ if (copiedRangeStyle->isEmpty()) {
removeNodePreservingChildren(copiedRangeStyleSpan);
return;
}
-
+
// Clear the redundant styles from the span's style attribute.
// FIXME: If font-family:-webkit-monospace is non-redundant, then the font-size should stay, even if it
// appears redundant.
- setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, copiedRangeStyle->cssText());
+ setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, copiedRangeStyle->style()->cssText());
}
// Take the style attribute of a span and apply it to it's children instead. This allows us to
@@ -810,9 +785,14 @@ void ReplaceSelectionCommand::doApply()
if (performTrivialReplace(fragment))
return;
- if (m_matchStyle)
- m_insertionStyle = ApplyStyleCommand::editingStyleAtPosition(selection.start(), IncludeTypingStyle);
+ // We can skip matching the style if the selection is plain text.
+ if ((selection.start().node()->renderer() && selection.start().node()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY) &&
+ (selection.end().node()->renderer() && selection.end().node()->renderer()->style()->userModify() == READ_WRITE_PLAINTEXT_ONLY))
+ m_matchStyle = false;
+ if (m_matchStyle)
+ m_insertionStyle = editingStyleIncludingTypingStyle(selection.start());
+
VisiblePosition visibleStart = selection.visibleStart();
VisiblePosition visibleEnd = selection.visibleEnd();
@@ -1163,7 +1143,7 @@ void ReplaceSelectionCommand::completeHTMLReplacement(const Position &lastPositi
if (m_matchStyle) {
ASSERT(m_insertionStyle);
- applyStyle(m_insertionStyle.get(), start, end);
+ applyStyle(m_insertionStyle->style(), start, end);
}
if (lastPositionToSelect.isNotNull())