summaryrefslogtreecommitdiffstats
path: root/WebCore/editing
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit9364f22aed35e1a1e9d07c121510f80be3ab0502 (patch)
treed49911209b132da58d838efa852daf28d516df21 /WebCore/editing
parent87eb0cb35bad8784770ebc807e6c982432e47107 (diff)
downloadexternal_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.zip
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.gz
external_webkit-9364f22aed35e1a1e9d07c121510f80be3ab0502.tar.bz2
Initial Contribution
Diffstat (limited to 'WebCore/editing')
-rw-r--r--WebCore/editing/DeleteSelectionCommand.cpp37
-rw-r--r--WebCore/editing/EditCommand.cpp3
-rw-r--r--WebCore/editing/HTMLInterchange.cpp69
-rw-r--r--WebCore/editing/HTMLInterchange.h6
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.cpp233
-rw-r--r--WebCore/editing/ReplaceSelectionCommand.h3
-rw-r--r--WebCore/editing/Selection.cpp10
-rw-r--r--WebCore/editing/SelectionController.cpp18
-rw-r--r--WebCore/editing/TextIterator.cpp20
-rw-r--r--WebCore/editing/TextIterator.h14
-rw-r--r--WebCore/editing/TypingCommand.cpp2
-rw-r--r--WebCore/editing/VisiblePosition.cpp6
-rw-r--r--WebCore/editing/htmlediting.cpp10
-rw-r--r--WebCore/editing/markup.cpp220
14 files changed, 276 insertions, 375 deletions
diff --git a/WebCore/editing/DeleteSelectionCommand.cpp b/WebCore/editing/DeleteSelectionCommand.cpp
index 28eca34..6bedd69 100644
--- a/WebCore/editing/DeleteSelectionCommand.cpp
+++ b/WebCore/editing/DeleteSelectionCommand.cpp
@@ -120,7 +120,7 @@ void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
if (!m_expandForSpecialElements)
return;
- while (1) {
+ while (VisiblePosition(start) == m_selectionToDelete.visibleStart() && VisiblePosition(end) == m_selectionToDelete.visibleEnd()) {
startSpecialContainer = 0;
endSpecialContainer = 0;
@@ -129,9 +129,6 @@ void DeleteSelectionCommand::initializeStartEnd(Position& start, Position& end)
if (!startSpecialContainer && !endSpecialContainer)
break;
-
- if (VisiblePosition(start) != m_selectionToDelete.visibleStart() || VisiblePosition(end) != m_selectionToDelete.visibleEnd())
- break;
// If we're going to expand to include the startSpecialContainer, it must be fully selected.
if (startSpecialContainer && !endSpecialContainer && Range::compareBoundaryPoints(positionAfterNode(startSpecialContainer), end) > -1)
@@ -233,16 +230,6 @@ void DeleteSelectionCommand::initializePositionData()
void DeleteSelectionCommand::saveTypingStyleState()
{
- // A common case is deleting characters that are all from the same text node. In
- // that case, the style at the start of the selection before deletion will be the
- // same as the style at the start of the selection after deletion (since those
- // two positions will be identical). Therefore there is no need to save the
- // typing style at the start of the selection, nor is there a reason to
- // compute the style at the start of the selection after deletion (see the
- // early return in calculateTypingStyleAfterDelete).
- if (m_upstreamStart.node() == m_downstreamEnd.node() && m_upstreamStart.node()->isTextNode())
- return;
-
// Figure out the typing style in effect before the delete is done.
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
@@ -613,9 +600,6 @@ void DeleteSelectionCommand::removePreviouslySelectedEmptyTableRows()
void DeleteSelectionCommand::calculateTypingStyleAfterDelete(Node *insertedPlaceholder)
{
- if (!m_typingStyle)
- return;
-
// Compute the difference between the style before the delete and the style now
// after the delete has been done. Set this style on the frame, so other editing
// commands being composed with this one will work, and also cache it on the command,
@@ -664,21 +648,12 @@ void DeleteSelectionCommand::clearTransientState()
void DeleteSelectionCommand::saveFullySelectedAnchor()
{
- // If deleting an anchor element, save it away so that it can be restored
+ // If we're deleting an entire anchor element, save it away so that it can be restored
// when the user begins entering text.
-
- Position start = m_selectionToDelete.start();
- Node* startAnchor = enclosingNodeWithTag(start.downstream(), aTag);
- if (!startAnchor)
- return;
-
- Position end = m_selectionToDelete.end();
- Node* endAnchor = enclosingNodeWithTag(end.upstream(), aTag);
- if (startAnchor != endAnchor)
- return;
-
- VisiblePosition visibleStart(m_selectionToDelete.visibleStart());
- VisiblePosition visibleEnd(m_selectionToDelete.visibleEnd());
+ VisiblePosition visibleStart = m_selectionToDelete.visibleStart();
+ VisiblePosition visibleEnd = m_selectionToDelete.visibleEnd();
+ Node* startAnchor = enclosingNodeWithTag(visibleStart.deepEquivalent().downstream(), aTag);
+ Node* endAnchor = enclosingNodeWithTag(visibleEnd.deepEquivalent().upstream(), aTag);
Node* beforeStartAnchor = enclosingNodeWithTag(visibleStart.previous().deepEquivalent().downstream(), aTag);
Node* afterEndAnchor = enclosingNodeWithTag(visibleEnd.next().deepEquivalent().upstream(), aTag);
diff --git a/WebCore/editing/EditCommand.cpp b/WebCore/editing/EditCommand.cpp
index a7c7ed0..7a5d752 100644
--- a/WebCore/editing/EditCommand.cpp
+++ b/WebCore/editing/EditCommand.cpp
@@ -44,8 +44,7 @@ namespace WebCore {
using namespace EventNames;
EditCommand::EditCommand(Document* document)
- : RefCounted<EditCommand>(0)
- , m_document(document)
+ : m_document(document)
, m_parent(0)
{
ASSERT(m_document);
diff --git a/WebCore/editing/HTMLInterchange.cpp b/WebCore/editing/HTMLInterchange.cpp
index 024ac9f..e17f32e 100644
--- a/WebCore/editing/HTMLInterchange.cpp
+++ b/WebCore/editing/HTMLInterchange.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -27,6 +27,7 @@
#include "HTMLInterchange.h"
#include "CharacterNames.h"
+#include "Document.h"
#include "Text.h"
#include "TextIterator.h"
@@ -34,14 +35,14 @@ namespace WebCore {
namespace {
-String convertedSpaceString()
+DeprecatedString convertedSpaceString()
{
- static String convertedSpaceString;
- if (convertedSpaceString.isNull()) {
+ static DeprecatedString convertedSpaceString;
+ if (convertedSpaceString.length() == 0) {
convertedSpaceString = "<span class=\"";
convertedSpaceString += AppleConvertedSpace;
convertedSpaceString += "\">";
- convertedSpaceString.append(noBreakSpace);
+ convertedSpaceString += DeprecatedChar(noBreakSpace);
convertedSpaceString += "</span>";
}
return convertedSpaceString;
@@ -49,63 +50,67 @@ String convertedSpaceString()
} // end anonymous namespace
-String convertHTMLTextToInterchangeFormat(const String& in, const Text* node)
+DeprecatedString convertHTMLTextToInterchangeFormat(const DeprecatedString& in, const Text* node)
{
// Assume all the text comes from node.
if (node->renderer() && node->renderer()->style()->preserveNewline())
return in;
+
+ DeprecatedString s;
- Vector<UChar> s;
-
- unsigned i = 0;
- unsigned consumed = 0;
+ unsigned int i = 0;
+ unsigned int consumed = 0;
while (i < in.length()) {
consumed = 1;
- if (isCollapsibleWhitespace(in[i])) {
+ if (isCollapsibleWhitespace(in[i].unicode())) {
// count number of adjoining spaces
- unsigned j = i + 1;
- while (j < in.length() && isCollapsibleWhitespace(in[j]))
+ unsigned int j = i + 1;
+ while (j < in.length() && isCollapsibleWhitespace(in[j].unicode()))
j++;
- unsigned count = j - i;
+ unsigned int count = j - i;
consumed = count;
while (count) {
- unsigned add = count % 3;
+ unsigned int add = count % 3;
switch (add) {
case 0:
- append(s, convertedSpaceString());
- s.append(' ');
- append(s, convertedSpaceString());
+ s += convertedSpaceString();
+ s += ' ';
+ s += convertedSpaceString();
add = 3;
break;
case 1:
if (i == 0 || i + 1 == in.length()) // at start or end of string
- append(s, convertedSpaceString());
+ s += convertedSpaceString();
else
- s.append(' ');
+ s += ' ';
break;
case 2:
if (i == 0) {
// at start of string
- append(s, convertedSpaceString());
- s.append(' ');
- } else if (i + 2 == in.length()) {
+ s += convertedSpaceString();
+ s += ' ';
+ }
+ else if (i + 2 == in.length()) {
// at end of string
- append(s, convertedSpaceString());
- append(s, convertedSpaceString());
- } else {
- append(s, convertedSpaceString());
- s.append(' ');
+ s += convertedSpaceString();
+ s += convertedSpaceString();
+ }
+ else {
+ s += convertedSpaceString();
+ s += ' ';
}
break;
}
count -= add;
}
- } else
- s.append(in[i]);
+ }
+ else {
+ s += in[i];
+ }
i += consumed;
}
- return String::adopt(s);
+ return s;
}
-} // namespace WebCore
+}
diff --git a/WebCore/editing/HTMLInterchange.h b/WebCore/editing/HTMLInterchange.h
index 3b68efb..c840231 100644
--- a/WebCore/editing/HTMLInterchange.h
+++ b/WebCore/editing/HTMLInterchange.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -28,7 +28,7 @@
namespace WebCore {
-class String;
+class DeprecatedString;
class Text;
#define AppleInterchangeNewline "Apple-interchange-newline"
@@ -39,7 +39,7 @@ class Text;
enum EAnnotateForInterchange { DoNotAnnotateForInterchange, AnnotateForInterchange };
-String convertHTMLTextToInterchangeFormat(const String&, const Text*);
+DeprecatedString convertHTMLTextToInterchangeFormat(const DeprecatedString&, const Text*);
}
diff --git a/WebCore/editing/ReplaceSelectionCommand.cpp b/WebCore/editing/ReplaceSelectionCommand.cpp
index 1f66de4..a110480 100644
--- a/WebCore/editing/ReplaceSelectionCommand.cpp
+++ b/WebCore/editing/ReplaceSelectionCommand.cpp
@@ -29,7 +29,6 @@
#include "ApplyStyleCommand.h"
#include "BeforeTextInsertedEvent.h"
#include "CSSComputedStyleDeclaration.h"
-#include "CSSProperty.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "Document.h"
@@ -414,11 +413,84 @@ void ReplaceSelectionCommand::removeUnrenderedTextNodesAtEnds()
}
}
+void ReplaceSelectionCommand::removeRedundantStyles(Node* mailBlockquoteEnclosingSelectionStart)
+{
+ // There's usually a top level style span that holds the document's default style, push it down.
+ Node* node = m_firstNodeInserted.get();
+ if (isStyleSpan(node) && mailBlockquoteEnclosingSelectionStart) {
+ // Calculate the document default style.
+ RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = Position(mailBlockquoteEnclosingSelectionStart, 0).computedStyle()->copyInheritableProperties();
+ RefPtr<CSSMutableStyleDeclaration> spanStyle = static_cast<HTMLElement*>(node)->inlineStyleDecl();
+ spanStyle->merge(blockquoteStyle.get());
+ }
+
+ // Compute and save the non-redundant styles for all HTML elements.
+ // Don't do any mutation here, because that would cause the diffs to trigger layouts.
+ Vector<RefPtr<CSSMutableStyleDeclaration> > styles;
+ Vector<RefPtr<HTMLElement> > elements;
+ for (node = m_firstNodeInserted.get(); node; node = node->traverseNextNode()) {
+ if (node->isHTMLElement() && isStyleSpan(node)) {
+ elements.append(static_cast<HTMLElement*>(node));
+
+ RefPtr<CSSMutableStyleDeclaration> parentStyle = computedStyle(node->parentNode())->copyInheritableProperties();
+ RefPtr<CSSMutableStyleDeclaration> style = computedStyle(node)->copyInheritableProperties();
+ parentStyle->diff(style.get());
+
+ // Remove any inherited block properties that are now in the span's style. This cuts out meaningless properties
+ // and prevents properties from magically affecting blocks later if the style is cloned for a new block element
+ // during a future editing operation.
+ style->removeBlockProperties();
+
+ styles.append(style.release());
+ }
+ if (node == m_lastLeafInserted)
+ break;
+ }
+
+ size_t count = styles.size();
+ for (size_t i = 0; i < count; ++i) {
+ HTMLElement* element = elements[i].get();
+
+ // Handle case where the element was already removed by earlier processing.
+ // It's possible this no longer occurs, but it did happen in an earlier version
+ // that processed elements in a less-determistic order, and I can't prove it
+ // does not occur.
+ if (!element->inDocument())
+ continue;
+
+ // Remove empty style spans.
+ if (isStyleSpan(element) && !element->hasChildNodes()) {
+ removeNodeAndPruneAncestors(element);
+ continue;
+ }
+
+ // Remove redundant style tags and style spans.
+ CSSMutableStyleDeclaration* style = styles[i].get();
+ if (style->length() == 0
+ && (isStyleSpan(element)
+ || element->hasTagName(bTag)
+ || element->hasTagName(fontTag)
+ || element->hasTagName(iTag)
+ || element->hasTagName(uTag))) {
+ removeNodePreservingChildren(element);
+ continue;
+ }
+
+ // Clear redundant styles from elements.
+ CSSMutableStyleDeclaration* inlineStyleDecl = element->inlineStyleDecl();
+ if (inlineStyleDecl) {
+ CSSComputedStyleDeclaration::removeComputedInheritablePropertiesFrom(inlineStyleDecl);
+ inlineStyleDecl->merge(style, true);
+ setNodeAttribute(element, styleAttr, inlineStyleDecl->cssText());
+ }
+ }
+}
+
void ReplaceSelectionCommand::handlePasteAsQuotationNode()
{
Node* node = m_firstNodeInserted.get();
if (isMailPasteAsQuotationNode(node))
- removeNodeAttribute(static_cast<Element*>(node), classAttr);
+ static_cast<Element*>(node)->setAttribute(classAttr, "");
}
VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent()
@@ -436,146 +508,6 @@ VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent()
return VisiblePosition(nextCandidate(positionBeforeNode(m_firstNodeInserted.get())));
}
-// Remove style spans before insertion if they are unnecessary. It's faster because we'll
-// avoid doing a layout.
-static bool handleStyleSpansBeforeInsertion(ReplacementFragment& fragment, const Position& insertionPos)
-{
- Node* topNode = fragment.firstChild();
-
- // Handling this case is more complicated (see handleStyleSpans) and doesn't receive the optimization.
- if (isMailPasteAsQuotationNode(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 = rangeCompliantEquivalent(insertionPos).computedStyle()->copyInheritableProperties();
- String styleText = styleAtInsertionPos->cssText();
-
- 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;
-}
-
-// At copy time, WebKit wraps copied content in a span that contains the source document's
-// default styles. If the copied Range inherits any other styles from its ancestors, we put
-// those styles on a second span.
-// This function removes redundant styles from those spans, and removes the spans if all their
-// styles are redundant.
-// We should remove the Apple-style-span class when we're done, see <rdar://problem/5685600>.
-// We should remove styles from spans that are overridden by all of their children, either here
-// or at copy time.
-void ReplaceSelectionCommand::handleStyleSpans()
-{
- Node* sourceDocumentStyleSpan = 0;
- Node* copiedRangeStyleSpan = 0;
- // The style span that contains the source document's default style should be at
- // the top of the fragment, but Mail sometimes adds a wrapper (for Paste As Quotation),
- // so search for the top level style span instead of assuming it's at the top.
- for (Node* node = m_firstNodeInserted.get(); node; node = node->traverseNextNode()) {
- if (isStyleSpan(node)) {
- sourceDocumentStyleSpan = node;
- // If the copied Range's common ancestor had user applied inheritable styles
- // on it, they'll be on a second style span, just below the one that holds the
- // document defaults.
- if (isStyleSpan(node->firstChild()))
- copiedRangeStyleSpan = node->firstChild();
- break;
- }
- }
-
- // There might not be any style spans if we're pasting from another application or if
- // we are here because of a document.execCommand("InsertHTML", ...) call.
- if (!sourceDocumentStyleSpan)
- return;
-
- RefPtr<CSSMutableStyleDeclaration> sourceDocumentStyle = static_cast<HTMLElement*>(sourceDocumentStyleSpan)->getInlineStyleDecl()->copy();
- Node* context = sourceDocumentStyleSpan->parentNode();
-
- // If Mail wraps the fragment with a Paste as Quotation blockquote, styles from that element are
- // allowed to override those from the source document, see <rdar://problem/4930986>.
- if (isMailPasteAsQuotationNode(context)) {
- RefPtr<CSSMutableStyleDeclaration> blockquoteStyle = computedStyle(context)->copyInheritableProperties();
- RefPtr<CSSMutableStyleDeclaration> parentStyle = computedStyle(context->parentNode())->copyInheritableProperties();
- parentStyle->diff(blockquoteStyle.get());
-
- DeprecatedValueListConstIterator<CSSProperty> end;
- for (DeprecatedValueListConstIterator<CSSProperty> it = blockquoteStyle->valuesIterator(); it != end; ++it) {
- const CSSProperty& property = *it;
- sourceDocumentStyle->removeProperty(property.id());
- }
-
- context = context->parentNode();
- }
-
- RefPtr<CSSMutableStyleDeclaration> contextStyle = computedStyle(context)->copyInheritableProperties();
- String contextStyleText = contextStyle->cssText();
- String sourceDocumentStyleText = sourceDocumentStyle->cssText();
- contextStyle->diff(sourceDocumentStyle.get());
-
- // 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
- // editing operation.
- // 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) {
- removeNodePreservingChildren(sourceDocumentStyleSpan);
- return;
- }
-
- // There are non-redundant styles on sourceDocumentStyleSpan, but there is no
- // copiedRangeStyleSpan. Clear the redundant styles from sourceDocumentStyleSpan
- // and return.
- if (sourceDocumentStyle->length() > 0 && !copiedRangeStyleSpan) {
- setNodeAttribute(static_cast<Element*>(sourceDocumentStyleSpan), styleAttr, sourceDocumentStyle->cssText());
- return;
- }
-
- RefPtr<CSSMutableStyleDeclaration> copiedRangeStyle = static_cast<HTMLElement*>(copiedRangeStyleSpan)->getInlineStyleDecl()->copy();
-
- // 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;
-
- removeNodePreservingChildren(sourceDocumentStyleSpan);
-
- // Remove redundant styles.
- context = copiedRangeStyleSpan->parentNode();
- contextStyle = computedStyle(context)->copyInheritableProperties();
- contextStyle->diff(copiedRangeStyle.get());
-
- // See the comments above about removing block properties.
- copiedRangeStyle->removeBlockProperties();
-
- // All the styles on copiedRangeStyleSpan are redundant, remove it.
- if (copiedRangeStyle->length() == 0) {
- removeNodePreservingChildren(copiedRangeStyleSpan);
- return;
- }
-
- // Clear the redundant styles from the span's style attribute.
- setNodeAttribute(static_cast<Element*>(copiedRangeStyleSpan), styleAttr, copiedRangeStyle->cssText());
-}
-
void ReplaceSelectionCommand::doApply()
{
Selection selection = endingSelection();
@@ -597,6 +529,7 @@ void ReplaceSelectionCommand::doApply()
bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd);
bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart);
+ Node* mailBlockquoteEnclosingSelectionStart = nearestMailBlockquote(visibleStart.deepEquivalent().node());
Node* startBlock = enclosingBlock(visibleStart.deepEquivalent().node());
@@ -680,9 +613,16 @@ void ReplaceSelectionCommand::doApply()
// FIXME: Improve typing style.
// See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
frame->clearTypingStyle();
- setTypingStyle(0);
-
- bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
+ setTypingStyle(0);
+
+ // Remove the top level style span if its unnecessary before inserting it into the document, its faster.
+ RefPtr<CSSMutableStyleDeclaration> styleAtInsertionPos = insertionPos.computedStyle()->copyInheritableProperties();
+ if (isStyleSpan(fragment.firstChild())) {
+ Node* styleSpan = fragment.firstChild();
+ String styleText = static_cast<Element*>(styleSpan)->getAttribute(styleAttr);
+ if (styleText == styleAtInsertionPos->cssText())
+ fragment.removeNodePreservingChildren(styleSpan);
+ }
// We're finished if there is nothing to add.
if (fragment.isEmpty() || !fragment.firstChild())
@@ -718,8 +658,7 @@ void ReplaceSelectionCommand::doApply()
negateStyleRulesThatAffectAppearance();
- if (!handledStyleSpans)
- handleStyleSpans();
+ removeRedundantStyles(mailBlockquoteEnclosingSelectionStart);
if (!m_firstNodeInserted)
return;
diff --git a/WebCore/editing/ReplaceSelectionCommand.h b/WebCore/editing/ReplaceSelectionCommand.h
index d900c71..679a90e 100644
--- a/WebCore/editing/ReplaceSelectionCommand.h
+++ b/WebCore/editing/ReplaceSelectionCommand.h
@@ -92,7 +92,8 @@ private:
void removeUnrenderedTextNodesAtEnds();
void negateStyleRulesThatAffectAppearance();
- void handleStyleSpans();
+ void removeRedundantStyles(Node*);
+
void handlePasteAsQuotationNode();
virtual void removeNodePreservingChildren(Node*);
diff --git a/WebCore/editing/Selection.cpp b/WebCore/editing/Selection.cpp
index d29ac40..32f6500 100644
--- a/WebCore/editing/Selection.cpp
+++ b/WebCore/editing/Selection.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "Selection.h"
-#include "CString.h"
#include "Document.h"
#include "Element.h"
#include "htmlediting.h"
@@ -34,7 +33,6 @@
#include "visible_units.h"
#include "Range.h"
#include <wtf/Assertions.h>
-#include <stdio.h>
namespace WebCore {
@@ -526,13 +524,13 @@ void Selection::debugPosition() const
if (m_start == m_end) {
Position pos = m_start;
- fprintf(stderr, "pos: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "pos: %s %p:%d\n", pos.node()->nodeName().deprecatedString().latin1(), pos.node(), pos.offset());
} else {
Position pos = m_start;
- fprintf(stderr, "start: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "start: %s %p:%d\n", pos.node()->nodeName().deprecatedString().latin1(), pos.node(), pos.offset());
fprintf(stderr, "-----------------------------------\n");
pos = m_end;
- fprintf(stderr, "end: %s %p:%d\n", pos.node()->nodeName().utf8().data(), pos.node(), pos.offset());
+ fprintf(stderr, "end: %s %p:%d\n", pos.node()->nodeName().deprecatedString().latin1(), pos.node(), pos.offset());
fprintf(stderr, "-----------------------------------\n");
}
@@ -559,7 +557,7 @@ void Selection::formatForDebugger(char* buffer, unsigned length) const
result += s;
}
- strncpy(buffer, result.utf8().data(), length - 1);
+ strncpy(buffer, result.deprecatedString().latin1(), length - 1);
}
void Selection::showTreeForThis() const
diff --git a/WebCore/editing/SelectionController.cpp b/WebCore/editing/SelectionController.cpp
index cd6286a..6e1d6bf 100644
--- a/WebCore/editing/SelectionController.cpp
+++ b/WebCore/editing/SelectionController.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -26,7 +26,6 @@
#include "config.h"
#include "SelectionController.h"
-#include "CString.h"
#include "DeleteSelectionCommand.h"
#include "Document.h"
#include "Editor.h"
@@ -51,7 +50,6 @@
#include "TypingCommand.h"
#include "htmlediting.h"
#include "visible_units.h"
-#include <stdio.h>
#define EDIT_DEBUG 0
@@ -793,7 +791,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
{
if (r->node()->isElementNode()) {
Element *element = static_cast<Element *>(r->node());
- fprintf(stderr, "%s%s\n", selected ? "==> " : " ", element->localName().string().utf8().data());
+ fprintf(stderr, "%s%s\n", selected ? "==> " : " ", element->localName().deprecatedString().latin1());
}
else if (r->isText()) {
RenderText* textRenderer = static_cast<RenderText*>(r);
@@ -803,7 +801,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
}
static const int max = 36;
- String text = textRenderer->text();
+ DeprecatedString text = String(textRenderer->text()).deprecatedString();
int textLength = text.length();
if (selected) {
int offset = 0;
@@ -814,9 +812,9 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
int pos;
InlineTextBox *box = textRenderer->findNextInlineTextBox(offset, pos);
- text = text.substring(box->m_start, box->m_len);
+ text = text.mid(box->m_start, box->m_len);
- String show;
+ DeprecatedString show;
int mid = max / 2;
int caret = 0;
@@ -834,7 +832,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
// enough characters on each side
else if (pos - mid >= 0 && pos + mid <= textLength) {
- show = "..." + text.substring(pos - mid + 3, max - 6) + "...";
+ show = "..." + text.mid(pos - mid + 3, max - 6) + "...";
caret = mid;
}
@@ -846,7 +844,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
show.replace('\n', ' ');
show.replace('\r', ' ');
- fprintf(stderr, "==> #text : \"%s\" at offset %d\n", show.utf8().data(), pos);
+ fprintf(stderr, "==> #text : \"%s\" at offset %d\n", show.latin1(), pos);
fprintf(stderr, " ");
for (int i = 0; i < caret; i++)
fprintf(stderr, " ");
@@ -857,7 +855,7 @@ void SelectionController::debugRenderer(RenderObject *r, bool selected) const
text = text.left(max - 3) + "...";
else
text = text.left(max);
- fprintf(stderr, " #text : \"%s\"\n", text.utf8().data());
+ fprintf(stderr, " #text : \"%s\"\n", text.latin1());
}
}
}
diff --git a/WebCore/editing/TextIterator.cpp b/WebCore/editing/TextIterator.cpp
index 233361e..c6f1928 100644
--- a/WebCore/editing/TextIterator.cpp
+++ b/WebCore/editing/TextIterator.cpp
@@ -962,17 +962,17 @@ void CharacterIterator::advance(int count)
m_runOffset = 0;
}
-String CharacterIterator::string(int numChars)
+DeprecatedString CharacterIterator::string(int numChars)
{
- Vector<UChar> result;
- result.reserveCapacity(numChars);
+ DeprecatedString result;
+ result.reserve(numChars);
while (numChars > 0 && !atEnd()) {
int runSize = min(numChars, length());
- result.append(characters(), runSize);
+ result.append(reinterpret_cast<const DeprecatedChar*>(characters()), runSize);
numChars -= runSize;
advance(runSize);
}
- return String::adopt(result);
+ return result;
}
// --------
@@ -1001,7 +1001,7 @@ WordAwareIterator::WordAwareIterator(const Range *r)
void WordAwareIterator::advance()
{
m_previousText = 0;
- m_buffer.clear(); // toss any old buffer we built up
+ m_buffer = ""; // toss any old buffer we built up
// If last time we did a look-ahead, start with that looked-ahead chunk now
if (!m_didLookAhead) {
@@ -1038,10 +1038,10 @@ void WordAwareIterator::advance()
if (m_buffer.isEmpty()) {
// Start gobbling chunks until we get to a suitable stopping point
- m_buffer.append(m_previousText, m_previousLength);
+ m_buffer.append(reinterpret_cast<const DeprecatedChar*>(m_previousText), m_previousLength);
m_previousText = 0;
}
- m_buffer.append(m_textIterator.characters(), m_textIterator.length());
+ m_buffer.append(reinterpret_cast<const DeprecatedChar*>(m_textIterator.characters()), m_textIterator.length());
int exception = 0;
m_range->setEnd(m_textIterator.range()->endContainer(exception), m_textIterator.range()->endOffset(exception), exception);
}
@@ -1050,7 +1050,7 @@ void WordAwareIterator::advance()
int WordAwareIterator::length() const
{
if (!m_buffer.isEmpty())
- return m_buffer.size();
+ return m_buffer.length();
if (m_previousText)
return m_previousLength;
return m_textIterator.length();
@@ -1059,7 +1059,7 @@ int WordAwareIterator::length() const
const UChar* WordAwareIterator::characters() const
{
if (!m_buffer.isEmpty())
- return m_buffer.data();
+ return reinterpret_cast<const UChar*>(m_buffer.unicode());
if (m_previousText)
return m_previousText;
return m_textIterator.characters();
diff --git a/WebCore/editing/TextIterator.h b/WebCore/editing/TextIterator.h
index 56f42be..5f36468 100644
--- a/WebCore/editing/TextIterator.h
+++ b/WebCore/editing/TextIterator.h
@@ -26,6 +26,7 @@
#ifndef TextIterator_h
#define TextIterator_h
+#include "DeprecatedString.h"
#include "InlineTextBox.h"
#include "Range.h"
#include <wtf/Vector.h>
@@ -33,7 +34,8 @@
namespace WebCore {
// FIXME: Can't really answer this question correctly without knowing the white-space mode.
-// FIXME: Move this somewhere else in the editing directory. It doesn't belong here.
+// FIXME: Move this along with the white-space position functions above
+// somewhere else in the editing directory. It doesn't belong here.
inline bool isCollapsibleWhitespace(UChar c)
{
switch (c) {
@@ -53,7 +55,8 @@ PassRefPtr<Range> findPlainText(const Range*, const String&, bool forward, bool
// at points where replaced elements break up the text flow. The text comes back in
// chunks so as to optimize for performance of the iteration.
-class TextIterator {
+class TextIterator
+{
public:
TextIterator();
explicit TextIterator(const Range*, bool emitCharactersBetweenAllVisiblePositions = false);
@@ -132,7 +135,8 @@ private:
// Iterates through the DOM range, returning all the text, and 0-length boundaries
// at points where replaced elements break up the text flow. The text comes back in
// chunks so as to optimize for performance of the iteration.
-class SimplifiedBackwardsTextIterator {
+class SimplifiedBackwardsTextIterator
+{
public:
SimplifiedBackwardsTextIterator();
explicit SimplifiedBackwardsTextIterator(const Range *);
@@ -198,7 +202,7 @@ public:
int length() const { return m_textIterator.length() - m_runOffset; }
const UChar* characters() const { return m_textIterator.characters() + m_runOffset; }
- String string(int numChars);
+ DeprecatedString string(int numChars);
int characterOffset() const { return m_offset; }
PassRefPtr<Range> range() const;
@@ -233,7 +237,7 @@ private:
int m_previousLength;
// many chunks from textIterator concatenated
- Vector<UChar> m_buffer;
+ DeprecatedString m_buffer;
// Did we have to look ahead in the textIterator to confirm the current chunk?
bool m_didLookAhead;
diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp
index 2c0518e..f480c07 100644
--- a/WebCore/editing/TypingCommand.cpp
+++ b/WebCore/editing/TypingCommand.cpp
@@ -280,8 +280,6 @@ EditAction TypingCommand::editingAction() const
void TypingCommand::markMisspellingsAfterTyping()
{
- if (!document()->frame()->editor()->isContinuousSpellCheckingEnabled())
- return;
// Take a look at the selection that results after typing and determine whether we need to spellcheck.
// Since the word containing the current selection is never marked, this does a check to
// see if typing made a new word that is not in the current selection. Basically, you
diff --git a/WebCore/editing/VisiblePosition.cpp b/WebCore/editing/VisiblePosition.cpp
index 7571035..3ca28f7 100644
--- a/WebCore/editing/VisiblePosition.cpp
+++ b/WebCore/editing/VisiblePosition.cpp
@@ -26,7 +26,6 @@
#include "config.h"
#include "VisiblePosition.h"
-#include "CString.h"
#include "Document.h"
#include "Element.h"
#include "HTMLNames.h"
@@ -36,7 +35,6 @@
#include "Text.h"
#include "htmlediting.h"
#include "visible_units.h"
-#include <stdio.h>
namespace WebCore {
@@ -248,12 +246,12 @@ IntRect VisiblePosition::caretRect() const
return m_deepPosition.node()->renderer()->caretRect(m_deepPosition.offset(), m_affinity);
}
-void VisiblePosition::debugPosition(const char* msg) const
+void VisiblePosition::debugPosition(const char *msg) const
{
if (isNull())
fprintf(stderr, "Position [%s]: null\n", msg);
else
- fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().utf8().data(), m_deepPosition.node(), m_deepPosition.offset());
+ fprintf(stderr, "Position [%s]: %s [%p] at %d\n", msg, m_deepPosition.node()->nodeName().deprecatedString().latin1(), m_deepPosition.node(), m_deepPosition.offset());
}
#ifndef NDEBUG
diff --git a/WebCore/editing/htmlediting.cpp b/WebCore/editing/htmlediting.cpp
index c2d1fb5..a8d7702 100644
--- a/WebCore/editing/htmlediting.cpp
+++ b/WebCore/editing/htmlediting.cpp
@@ -367,11 +367,11 @@ int maxDeepOffset(const Node *node)
String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfParagraph, bool endIsEndOfParagraph)
{
- static String twoSpaces(" ");
- static String nbsp("\xa0");
- static String pattern(" \xa0");
+ static DeprecatedString twoSpaces(" ");
+ static DeprecatedString nbsp("\xa0");
+ static DeprecatedString pattern(" \xa0");
- String rebalancedString = string;
+ DeprecatedString rebalancedString = string.deprecatedString();
rebalancedString.replace(noBreakSpace, ' ');
rebalancedString.replace('\n', ' ');
@@ -385,7 +385,7 @@ String stringWithRebalancedWhitespace(const String& string, bool startIsStartOfP
if (endIsEndOfParagraph && rebalancedString[end] == ' ')
rebalancedString.replace(end, 1, nbsp);
- return rebalancedString;
+ return String(rebalancedString);
}
bool isTableStructureNode(const Node *node)
diff --git a/WebCore/editing/markup.cpp b/WebCore/editing/markup.cpp
index 4dad8ca..bcff364 100644
--- a/WebCore/editing/markup.cpp
+++ b/WebCore/editing/markup.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -36,6 +36,7 @@
#include "CSSValueKeywords.h"
#include "Comment.h"
#include "DeleteButtonController.h"
+#include "DeprecatedStringList.h"
#include "Document.h"
#include "DocumentFragment.h"
#include "DocumentType.h"
@@ -44,6 +45,7 @@
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "InlineTextBox.h"
+#include "KURL.h"
#include "Logging.h"
#include "ProcessingInstruction.h"
#include "QualifiedName.h"
@@ -84,6 +86,11 @@ private:
String m_value;
};
+static inline void appendString(Vector<UChar>& result, const String& str)
+{
+ result.append(str.characters(), str.length());
+}
+
static void appendAttributeValue(Vector<UChar>& result, const String& attr)
{
const UChar* uchars = attr.characters();
@@ -99,60 +106,51 @@ static void appendAttributeValue(Vector<UChar>& result, const String& attr)
switch (c) {
case '&':
result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ampEntity);
+ appendString(result, ampEntity);
lastCopiedFrom = i + 1;
break;
case '<':
result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, ltEntity);
+ appendString(result, ltEntity);
lastCopiedFrom = i + 1;
break;
case '"':
result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
- append(result, quotEntity);
+ appendString(result, quotEntity);
lastCopiedFrom = i + 1;
}
}
result.append(uchars + lastCopiedFrom, len - lastCopiedFrom);
}
-
-static void append(Vector<UChar>& vector, const char* string)
-{
- const char* p = string;
- while (*p) {
- UChar c = *p++;
- vector.append(c);
- }
-}
-static String escapeContentText(const String& in)
+static DeprecatedString escapeContentText(const String& in)
{
- Vector<UChar> s;
+ DeprecatedString s = "";
unsigned len = in.length();
unsigned lastCopiedFrom = 0;
- s.reserveCapacity(len);
-
- const UChar* characters = in.characters();
+ const UChar* uchars = in.characters();
+ const DeprecatedChar* dchars = reinterpret_cast<const DeprecatedChar*>(uchars);
for (unsigned i = 0; i < len; ++i) {
- UChar c = characters[i];
+ UChar c = uchars[i];
if ((c == '&') | (c == '<')) {
- s.append(characters + lastCopiedFrom, i - lastCopiedFrom);
+ s.append(dchars + lastCopiedFrom, i - lastCopiedFrom);
if (c == '&')
- append(s, "&amp;");
+ s += "&amp;";
else
- append(s, "&lt;");
+ s += "&lt;";
lastCopiedFrom = i + 1;
}
}
- s.append(characters + lastCopiedFrom, len - lastCopiedFrom);
+ s.append(dchars + lastCopiedFrom, len - lastCopiedFrom);
- return String::adopt(s);
+ return s;
}
+
static void appendEscapedContent(Vector<UChar>& result, pair<const UChar*, size_t> range)
{
@@ -168,9 +166,9 @@ static void appendEscapedContent(Vector<UChar>& result, pair<const UChar*, size_
if ((c == '&') | (c == '<')) {
result.append(uchars + lastCopiedFrom, i - lastCopiedFrom);
if (c == '&')
- append(result, ampEntity);
+ appendString(result, ampEntity);
else
- append(result, ltEntity);
+ appendString(result, ltEntity);
lastCopiedFrom = i + 1;
}
}
@@ -178,25 +176,33 @@ static void appendEscapedContent(Vector<UChar>& result, pair<const UChar*, size_
result.append(uchars + lastCopiedFrom, len - lastCopiedFrom);
}
-static void appendQuotedURLAttributeValue(Vector<UChar>& result, const String& urlString)
+static inline void appendDeprecatedString(Vector<UChar>& result, const DeprecatedString& str)
+{
+ result.append(reinterpret_cast<const UChar*>(str.unicode()), str.length());
+}
+
+static void appendQuotedURLAttributeValue(Vector<UChar>& result, String urlString)
{
UChar quoteChar = '\"';
- String strippedURLString = urlString.stripWhiteSpace();
- if (protocolIs(strippedURLString, "javascript")) {
+#ifdef ANDROID_JAVASCRIPT_SECURITY
+ if (protocolIs(urlString.stripWhiteSpace(), "javascript")) {
+#else
+ if (urlString.stripWhiteSpace().startsWith("javascript:", false)) {
+#endif
// minimal escaping for javascript urls
- if (strippedURLString.contains('"')) {
- if (strippedURLString.contains('\''))
- strippedURLString.replace('\"', "&quot;");
+ if (urlString.contains('\"')) {
+ if (urlString.contains('\''))
+ urlString.replace('\"', "&quot;");
else
quoteChar = '\'';
}
result.append(quoteChar);
- append(result, strippedURLString);
+ appendString(result, urlString);
result.append(quoteChar);
return;
}
- // FIXME: This does not fully match other browsers. Firefox escapes spaces and other special characters.
+ // FIXME this does not fully match other browsers. Firefox escapes spaces and other special characters.
result.append(quoteChar);
appendAttributeValue(result, urlString);
result.append(quoteChar);
@@ -290,15 +296,6 @@ static void removeEnclosingMailBlockquoteStyle(CSSMutableStyleDeclaration* style
blockquoteStyle->diff(style);
}
-static void removeDefaultStyles(CSSMutableStyleDeclaration* style, Document* document)
-{
- if (!document || !document->documentElement())
- return;
-
- RefPtr<CSSMutableStyleDeclaration> documentStyle = computedStyle(document->documentElement())->copyInheritableProperties();
- documentStyle->diff(style);
-}
-
static bool shouldAddNamespaceElem(const Element* elem)
{
// Don't add namespace attribute if it is already defined for this elem.
@@ -338,10 +335,10 @@ static void appendNamespace(Vector<UChar>& result, const AtomicString& prefix, c
namespaces.set(pre, ns.impl());
static const String xmlns("xmlns");
result.append(' ');
- append(result, xmlns);
+ appendString(result, xmlns);
if (!prefix.isEmpty()) {
result.append(':');
- append(result, prefix);
+ appendString(result, prefix);
}
result.append('=');
@@ -372,29 +369,36 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
}
bool useRenderedText = !enclosingNodeWithTag(Position(const_cast<Node*>(node), 0), selectTag);
- String markup = escapeContentText(useRenderedText ? renderedText(node, range) : stringValueForRange(node, range));
+ DeprecatedString markup = escapeContentText(useRenderedText ? renderedText(node, range) : stringValueForRange(node, range));
if (annotate)
markup = convertHTMLTextToInterchangeFormat(markup, static_cast<const Text*>(node));
- append(result, markup);
+ appendDeprecatedString(result, markup);
break;
}
case Node::COMMENT_NODE:
- append(result, static_cast<const Comment*>(node)->toString());
+ appendString(result, static_cast<const Comment*>(node)->toString());
+ break;
+ case Node::DOCUMENT_NODE: {
+ // FIXME: I think the comment below (and therefore this code) is wrong now
+ // Documents do not normally contain a docType as a child node, force it to print here instead.
+ const DocumentType* docType = static_cast<const Document*>(node)->doctype();
+ if (docType)
+ appendString(result, docType->toString());
break;
- case Node::DOCUMENT_NODE:
+ }
case Node::DOCUMENT_FRAGMENT_NODE:
break;
case Node::DOCUMENT_TYPE_NODE:
- append(result, static_cast<const DocumentType*>(node)->toString());
+ appendString(result, static_cast<const DocumentType*>(node)->toString());
break;
case Node::PROCESSING_INSTRUCTION_NODE:
- append(result, static_cast<const ProcessingInstruction*>(node)->toString());
+ appendString(result, static_cast<const ProcessingInstruction*>(node)->toString());
break;
case Node::ELEMENT_NODE: {
result.append('<');
const Element* el = static_cast<const Element*>(node);
bool convert = convertBlocksToInlines & isBlock(const_cast<Node*>(node));
- append(result, el->nodeNamePreservingCase());
+ appendString(result, el->nodeNamePreservingCase());
NamedAttrMap *attrs = el->attributes();
unsigned length = attrs->length();
if (!documentIsHTML && namespaces && shouldAddNamespaceElem(el))
@@ -408,9 +412,9 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
result.append(' ');
if (documentIsHTML)
- append(result, attr->name().localName());
+ appendString(result, attr->name().localName());
else
- append(result, attr->name().toString());
+ appendString(result, attr->name().toString());
result.append('=');
@@ -437,7 +441,7 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
style->setProperty(CSS_PROP_DISPLAY, CSS_VAL_INLINE, true);
if (style->length() > 0) {
static const String stylePrefix(" style=\"");
- append(result, stylePrefix);
+ appendString(result, stylePrefix);
appendAttributeValue(result, style->cssText());
result.append('\"');
}
@@ -452,7 +456,7 @@ static void appendStartMarkup(Vector<UChar>& result, const Node *node, const Ran
break;
}
case Node::CDATA_SECTION_NODE:
- append(result, static_cast<const CDATASection*>(node)->toString());
+ appendString(result, static_cast<const CDATASection*>(node)->toString());
break;
case Node::ATTRIBUTE_NODE:
case Node::ENTITY_NODE:
@@ -503,7 +507,7 @@ static void appendEndMarkup(Vector<UChar>& result, const Node* node)
result.append('<');
result.append('/');
- append(result, static_cast<const Element*>(node)->nodeNamePreservingCase());
+ appendString(result, static_cast<const Element*>(node)->nodeNamePreservingCase());
result.append('>');
}
@@ -540,7 +544,7 @@ static void completeURLs(Node* node, const String& baseURL)
{
Vector<AttributeChange> changes;
- KURL parsedBaseURL(baseURL);
+ KURL baseURLAsKURL(baseURL.deprecatedString());
Node* end = node->traverseNextSibling();
for (Node* n = node; n != end; n = n->traverseNextNode()) {
@@ -550,8 +554,10 @@ static void completeURLs(Node* node, const String& baseURL)
unsigned length = attrs->length();
for (unsigned i = 0; i < length; i++) {
Attribute* attr = attrs->attributeItem(i);
- if (e->isURLAttribute(attr))
- changes.append(AttributeChange(e, attr->name(), KURL(parsedBaseURL, attr->value()).string()));
+ if (e->isURLAttribute(attr)) {
+ String completedURL = KURL(baseURLAsKURL, attr->value().deprecatedString()).string();
+ changes.append(AttributeChange(e, attr->name(), completedURL));
+ }
}
}
}
@@ -620,10 +626,10 @@ String joinMarkups(const Vector<String> preMarkups, const Vector<String>& postMa
result.reserveCapacity(length);
for (size_t i = preCount; i > 0; --i)
- append(result, preMarkups[i - 1]);
+ appendString(result, preMarkups[i - 1]);
for (size_t i = 0; i < postCount; ++i)
- append(result, postMarkups[i]);
+ appendString(result, postMarkups[i]);
return String::adopt(result);
}
@@ -772,16 +778,6 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
specialCommonAncestor = commonAncestorBlock;
}
- bool selectedOneOrMoreParagraphs = startOfParagraph(visibleStart) != startOfParagraph(visibleEnd) ||
- isStartOfParagraph(visibleStart) && isEndOfParagraph(visibleEnd);
-
- // Retain the Mail quote level by including all ancestor mail block quotes.
- if (lastClosed && annotate && selectedOneOrMoreParagraphs) {
- for (Node *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode())
- if (isMailBlockquote(ancestor))
- specialCommonAncestor = ancestor;
- }
-
Node* checkAncestor = specialCommonAncestor ? specialCommonAncestor : commonAncestor;
if (checkAncestor->renderer()) {
RefPtr<CSSMutableStyleDeclaration> checkAncestorStyle = computedStyle(checkAncestor)->copyInheritableProperties();
@@ -814,7 +810,7 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
if (style->length()) {
Vector<UChar> openTag;
static const String divStyle("<div style=\"");
- append(openTag, divStyle);
+ appendString(openTag, divStyle);
appendAttributeValue(openTag, style->cssText());
openTag.append('\"');
openTag.append('>');
@@ -837,9 +833,6 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
}
}
- static const String styleSpanOpen = String("<span class=\"" AppleStyleSpanClass "\" style=\"");
- static const String styleSpanClose("</span>");
-
// Add a wrapper span with the styles that all of the nodes in the markup inherit.
Node* parentOfLastClosed = lastClosed ? lastClosed->parentNode() : 0;
if (parentOfLastClosed && parentOfLastClosed->renderer()) {
@@ -850,9 +843,6 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
// get the color of content pasted into blockquotes right.
removeEnclosingMailBlockquoteStyle(style.get(), parentOfLastClosed);
- // Document default styles will be added on another wrapper span.
- removeDefaultStyles(style.get(), document);
-
// Since we are converting blocks to inlines, remove any inherited block properties that are in the style.
// This cuts out meaningless properties and prevents properties from magically affecting blocks later
// if the style is cloned for a new block element during a future editing operation.
@@ -861,37 +851,35 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
if (style->length() > 0) {
Vector<UChar> openTag;
- append(openTag, styleSpanOpen);
+ const String spanClassStyle = String("<span class=\"" AppleStyleSpanClass "\" style=\"");
+ appendString(openTag, spanClassStyle);
appendAttributeValue(openTag, style->cssText());
openTag.append('\"');
openTag.append('>');
preMarkups.append(String::adopt(openTag));
- markups.append(styleSpanClose);
- }
- }
-
- if (lastClosed && lastClosed != document->documentElement()) {
- // Add a style span with the document's default styles. We add these in a separate
- // span so that at paste time we can differentiate between document defaults and user
- // applied styles.
- RefPtr<CSSMutableStyleDeclaration> defaultStyle = computedStyle(document->documentElement())->copyInheritableProperties();
-
- if (defaultStyle->length() > 0) {
- Vector<UChar> openTag;
- append(openTag, styleSpanOpen);
- appendAttributeValue(openTag, defaultStyle->cssText());
- openTag.append('\"');
- openTag.append('>');
- preMarkups.append(String::adopt(openTag));
- markups.append(styleSpanClose);
+ static const String spanCloseTag("</span>");
+ markups.append(spanCloseTag);
}
}
// FIXME: The interchange newline should be placed in the block that it's in, not after all of the content, unconditionally.
if (annotate && needInterchangeNewlineAfter(visibleEnd.previous()))
markups.append(interchangeNewlineString);
-
+
+ bool selectedOneOrMoreParagraphs = startOfParagraph(visibleStart) != startOfParagraph(visibleEnd) ||
+ isStartOfParagraph(visibleStart) && isEndOfParagraph(visibleEnd);
+
+ // Retain the Mail quote level by including all ancestor mail block quotes.
+ if (lastClosed && annotate && selectedOneOrMoreParagraphs) {
+ for (Node *ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (isMailBlockquote(ancestor)) {
+ preMarkups.append(getStartMarkup(ancestor, updatedRange.get(), annotate));
+ markups.append(getEndMarkup(ancestor));
+ }
+ }
+ }
+
if (deleteButton)
deleteButton->enable();
@@ -906,7 +894,7 @@ PassRefPtr<DocumentFragment> createFragmentFromMarkup(Document* document, const
RefPtr<DocumentFragment> fragment = element->createContextualFragment(markup);
- if (fragment && !baseURL.isEmpty() && baseURL != blankURL() && baseURL != document->baseURL())
+ if (fragment && !baseURL.isEmpty() && baseURL != "about:blank" && baseURL != document->baseURL())
completeURLs(fragment.get(), baseURL);
return fragment.release();
@@ -938,7 +926,7 @@ String createMarkup(const Node* node, EChildrenOnly includeChildren, Vector<Node
return String::adopt(result);
}
-static void fillContainerFromString(ContainerNode* paragraph, const String& string)
+static void fillContainerFromString(ContainerNode* paragraph, const DeprecatedString& string)
{
Document* document = paragraph->document();
@@ -951,13 +939,12 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
ASSERT(string.find('\n') == -1);
- Vector<String> tabList;
- string.split('\t', true, tabList);
- String tabText = "";
+ DeprecatedStringList tabList = DeprecatedStringList::split('\t', string, true);
+ DeprecatedString tabText = "";
bool first = true;
- size_t numEntries = tabList.size();
- for (size_t i = 0; i < numEntries; ++i) {
- const String& s = tabList[i];
+ while (!tabList.isEmpty()) {
+ DeprecatedString s = tabList.first();
+ tabList.pop_front();
// append the non-tab textual part
if (!s.isEmpty()) {
@@ -966,15 +953,15 @@ static void fillContainerFromString(ContainerNode* paragraph, const String& stri
ASSERT(ec == 0);
tabText = "";
}
- RefPtr<Node> textNode = document->createTextNode(stringWithRebalancedWhitespace(s, first, i + 1 == numEntries));
+ RefPtr<Node> textNode = document->createTextNode(stringWithRebalancedWhitespace(s, first, tabList.isEmpty()));
paragraph->appendChild(textNode.release(), ec);
ASSERT(ec == 0);
}
// there is a tab after every entry, except the last entry
// (if the last character is a tab, the list gets an extra empty entry)
- if (i + 1 != numEntries)
- tabText.append('\t');
+ if (!tabList.isEmpty())
+ tabText += '\t';
else if (!tabText.isEmpty()) {
paragraph->appendChild(createTabSpanElement(document, tabText), ec);
ASSERT(ec == 0);
@@ -1002,7 +989,7 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
if (text.isEmpty())
return fragment.release();
- String string = text;
+ DeprecatedString string = text.deprecatedString();
string.replace("\r\n", "\n");
string.replace('\r', '\n');
@@ -1032,14 +1019,13 @@ PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String
Node* block = enclosingBlock(context->startNode());
bool useClonesOfEnclosingBlock = !block->hasTagName(bodyTag);
- Vector<String> list;
- string.split('\n', true, list); // true gets us empty strings in the list
- size_t numLines = list.size();
- for (size_t i = 0; i < numLines; ++i) {
- const String& s = list[i];
+ DeprecatedStringList list = DeprecatedStringList::split('\n', string, true); // true gets us empty strings in the list
+ while (!list.isEmpty()) {
+ DeprecatedString s = list.first();
+ list.pop_front();
RefPtr<Element> element;
- if (s.isEmpty() && i + 1 == numLines) {
+ if (s.isEmpty() && list.isEmpty()) {
// For last line, use the "magic BR" rather than a P.
element = document->createElementNS(xhtmlNamespaceURI, "br", ec);
ASSERT(ec == 0);