diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index cb94a686a0e1326a9441de01a8feb4d49adebeda..b3df1e955799d84f1efa2d2666d062367be04248 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,21 @@ +2011-03-24 Enrica Casucci + + Reviewed by Darin Adler. + + Repeated copy and paste-in-place operation results in increasingly verbose HTML. + + https://bugs.webkit.org/show_bug.cgi?id=56874 + + * editing/pasteboard/paste-text-with-style-expected.txt: Added. + * editing/pasteboard/paste-text-with-style.html: Added. + The following are new results for existing tests that now produce + a different markup. + * platform/mac/editing/pasteboard/5065605-expected.txt: + * platform/mac/editing/pasteboard/display-block-on-spans-expected.txt: + * platform/mac/editing/pasteboard/paste-text-011-expected.txt: + * platform/mac/editing/pasteboard/paste-text-at-tabspan-001-expected.txt: + * platform/mac/editing/pasteboard/paste-text-at-tabspan-002-expected.txt: + 2011-03-24 Adam Roben Add some flaky tests to the mac-wk2 and win-wk2 Skipped files diff --git a/LayoutTests/editing/pasteboard/paste-text-with-style-expected.txt b/LayoutTests/editing/pasteboard/paste-text-with-style-expected.txt new file mode 100644 index 0000000000000000000000000000000000000000..f071ded1c8b7208b3767bf73246ee89eb7a78077 --- /dev/null +++ b/LayoutTests/editing/pasteboard/paste-text-with-style-expected.txt @@ -0,0 +1,42 @@ +EDITING DELEGATE: shouldBeginEditingInDOMRange:range from 0 of DIV > BODY > HTML > #document to 5 of DIV > BODY > HTML > #document +EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > I > B > DIV > BODY > HTML > #document to 9 of #text > FONT > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of #text > I > B > DIV > BODY > HTML > #document to 9 of #text > FONT > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 9 of #text > FONT > DIV > DIV > BODY > HTML > #document to 9 of #text > FONT > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification +EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification +EDITING DELEGATE: webViewDidEndEditing:WebViewDidEndEditingNotification + +Markup before: +| " +" +| +| +| "<#selection-caret>hello bold and italic" +|
+| +| "hello italic" +|
+| +| color="#ff0000" +| "hello red" +| " +" + +Markup after: +| +| +| "hello bold and italic" +|
+| +| "hello italic" +|
+| +| color="#ff0000" +| "hello red<#selection-caret>" +| " +" diff --git a/LayoutTests/editing/pasteboard/paste-text-with-style.html b/LayoutTests/editing/pasteboard/paste-text-with-style.html new file mode 100644 index 0000000000000000000000000000000000000000..325a008093244977de757a59ad63831690470e2b --- /dev/null +++ b/LayoutTests/editing/pasteboard/paste-text-with-style.html @@ -0,0 +1,61 @@ + + + + + + + + + + +Editing Test + + +
+
+Tests: +
+Fix for this bug: +<https://bugs.webkit.org/show_bug.cgi?id=56874> Repeated copy and paste-in-place operation results in increasingly verbose HTML. +
+
+Expected Results: +
+The markup before and after should be identical. +
+
+
+hello bold and italic
hello italic
hello red
+
+ + + + + diff --git a/LayoutTests/platform/mac/editing/pasteboard/5065605-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/5065605-expected.txt index 33ac10b49fd37df1f4b7655c3e18d2c58dc25207..41c602c5ff01de7a5c20dbe50b16dcd8f2695355 100644 --- a/LayoutTests/platform/mac/editing/pasteboard/5065605-expected.txt +++ b/LayoutTests/platform/mac/editing/pasteboard/5065605-expected.txt @@ -18,16 +18,11 @@ layer at (0,0) size 800x600 RenderBlock {DIV} at (0,36) size 784x36 RenderBlock (anonymous) at (0,0) size 784x18 RenderInline {FONT} at (0,0) size 148x18 [color=#FF0000] - RenderInline {SPAN} at (0,0) size 148x18 [color=#000000] - RenderInline {FONT} at (0,0) size 148x18 [color=#FF0000] - RenderText {#text} at (0,0) size 148x18 - text run at (0,0) width 148: "This text should be red." - RenderBlock (anonymous) at (0,18) size 784x18 [color=#FF0000] - RenderBlock {DIV} at (0,0) size 784x18 [color=#000000] - RenderInline {FONT} at (0,0) size 148x18 [color=#FF0000] - RenderText {#text} at (0,0) size 148x18 - text run at (0,0) width 148: "This text should be red." + RenderText {#text} at (0,0) size 148x18 + text run at (0,0) width 148: "This text should be red." + RenderBlock {DIV} at (0,18) size 784x18 + RenderInline {FONT} at (0,0) size 148x18 [color=#FF0000] + RenderText {#text} at (0,0) size 148x18 + text run at (0,0) width 148: "This text should be red." RenderBlock (anonymous) at (0,36) size 784x0 - RenderInline {FONT} at (0,0) size 0x0 [color=#FF0000] - RenderInline {FONT} at (0,0) size 0x0 [color=#FF0000] -caret: position 24 of child 0 {#text} of child 0 {FONT} of child 1 {DIV} of child 0 {FONT} of child 2 {DIV} of child 2 {DIV} of body +caret: position 24 of child 0 {#text} of child 0 {FONT} of child 1 {DIV} of child 2 {DIV} of child 2 {DIV} of body diff --git a/LayoutTests/platform/mac/editing/pasteboard/display-block-on-spans-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/display-block-on-spans-expected.txt index 7149c20c7be580402dbcba210810e93f3dd215c7..f660dd651a99d90b2980062d5fb7d7b96f617ddc 100644 --- a/LayoutTests/platform/mac/editing/pasteboard/display-block-on-spans-expected.txt +++ b/LayoutTests/platform/mac/editing/pasteboard/display-block-on-spans-expected.txt @@ -5,7 +5,7 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of #text > B > SPAN > DIV > BODY > HTML > #document to 4 of #text > B > SPAN > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > B > SPAN > B > SPAN > DIV > BODY > HTML > #document to 4 of #text > B > SPAN > B > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 4 of #text > B > SPAN > DIV > BODY > HTML > #document to 4 of #text > B > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification layer at (0,0) size 800x600 @@ -33,11 +33,10 @@ layer at (0,0) size 800x600 RenderText {#text} at (0,0) size 137x18 text run at (0,0) width 137: "This is a paragraph." RenderBlock {SPAN} at (0,18) size 784x18 - RenderInline {B} at (0,0) size 182x18 - RenderInline {SPAN} at (0,0) size 30x18 - RenderInline {B} at (0,0) size 30x18 - RenderText {#text} at (0,0) size 30x18 - text run at (0,0) width 30: "This" + RenderInline {B} at (0,0) size 30x18 + RenderText {#text} at (0,0) size 30x18 + text run at (0,0) width 30: "This" + RenderInline {B} at (0,0) size 152x18 RenderText {#text} at (30,0) size 152x18 text run at (30,0) width 152: " is another paragraph." -caret: position 4 of child 0 {#text} of child 0 {B} of child 0 {SPAN} of child 0 {B} of child 2 {SPAN} of child 5 {DIV} of body +caret: position 4 of child 0 {#text} of child 0 {B} of child 2 {SPAN} of child 5 {DIV} of body diff --git a/LayoutTests/platform/mac/editing/pasteboard/paste-text-011-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/paste-text-011-expected.txt index 01c30d139f53649841b068a2d0fcf2f776d47110..46bf0a424c0168de0139d2a0c77557eb5ba580e0 100644 --- a/LayoutTests/platform/mac/editing/pasteboard/paste-text-011-expected.txt +++ b/LayoutTests/platform/mac/editing/pasteboard/paste-text-011-expected.txt @@ -9,7 +9,7 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of P > BODY > HTML > #document to 0 of P > BODY > HTML > #document givenAction:WebViewInsertActionPasted EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 5 of #text > B > FONT > P > B > FONT > P > BODY > HTML > #document to 5 of #text > B > FONT > P > B > FONT > P > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 5 of #text > B > FONT > P > FONT > P > BODY > HTML > #document to 5 of #text > B > FONT > P > FONT > P > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification layer at (0,0) size 800x600 @@ -30,7 +30,6 @@ layer at (0,0) size 800x600 RenderBlock {P} at (0,74) size 784x58 RenderBlock (anonymous) at (0,0) size 784x0 RenderInline {FONT} at (0,0) size 0x0 - RenderInline {B} at (0,0) size 0x0 RenderBlock (anonymous) at (0,0) size 784x58 RenderBlock {P} at (0,0) size 784x21 RenderInline {FONT} at (0,0) size 55x20 @@ -44,7 +43,5 @@ layer at (0,0) size 800x600 text run at (0,0) width 55: "there" RenderBlock (anonymous) at (0,74) size 784x0 RenderInline {FONT} at (0,0) size 0x0 - RenderInline {B} at (0,0) size 0x0 RenderInline {FONT} at (0,0) size 0x0 - RenderInline {B} at (0,0) size 0x0 -caret: position 5 of child 0 {#text} of child 0 {B} of child 0 {FONT} of child 1 {P} of child 0 {B} of child 0 {FONT} of child 4 {P} of body +caret: position 5 of child 0 {#text} of child 0 {B} of child 0 {FONT} of child 1 {P} of child 0 {FONT} of child 4 {P} of body diff --git a/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-001-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-001-expected.txt index e4ebf4bc28eab900d00d5ca25f1176d937f6002d..0321ae54fd15112073801f1bd384ecc7226a8290 100644 --- a/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-001-expected.txt +++ b/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-001-expected.txt @@ -4,11 +4,11 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted -EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification layer at (0,0) size 800x600 @@ -20,13 +20,12 @@ layer at (0,0) size 800x600 RenderInline {SPAN} at (0,0) size 155x28 RenderText {#text} at (14,14) size 11x28 text run at (14,14) width 11: "a" - RenderInline {SPAN} at (0,0) size 133x28 - RenderInline {SPAN} at (0,0) size 23x28 - RenderText {#text} at (25,14) size 23x28 - text run at (25,14) width 23: "ax" + RenderText {#text} at (25,14) size 23x28 + text run at (25,14) width 23: "ax" + RenderInline {SPAN} at (0,0) size 110x28 RenderText {#text} at (48,14) size 110x28 text run at (48,14) width 110: "\x{9}\x{9}\x{9}" RenderText {#text} at (158,14) size 11x28 text run at (158,14) width 11: "z" RenderText {#text} at (0,0) size 0x0 -caret: position 2 of child 0 {#text} of child 0 {SPAN} of child 1 {SPAN} of child 1 {SPAN} of child 1 {DIV} of body +caret: position 2 of child 1 {#text} of child 1 {SPAN} of child 1 {DIV} of body diff --git a/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-002-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-002-expected.txt index a2411d80e1c15891b3d4c4a427a55c4db4084572..13789ae7b7bfc33a9883dffcdfe2aef2d5e0599a 100644 --- a/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-002-expected.txt +++ b/LayoutTests/platform/mac/editing/pasteboard/paste-text-at-tabspan-002-expected.txt @@ -6,11 +6,11 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 1 of #text > SPAN > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > SPAN > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 1 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification -EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > SPAN > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE +EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 1 of #text > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > DIV > BODY > HTML > #document toDOMRange:range from 2 of #text > SPAN > DIV > BODY > HTML > #document to 2 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification layer at (0,0) size 800x600 @@ -25,13 +25,12 @@ layer at (0,0) size 800x600 RenderInline {SPAN} at (0,0) size 37x28 RenderText {#text} at (25,14) size 37x28 text run at (25,14) width 37: "\x{9}" - RenderInline {SPAN} at (0,0) size 96x28 - RenderInline {SPAN} at (0,0) size 23x28 - RenderText {#text} at (62,14) size 23x28 - text run at (62,14) width 23: "ax" + RenderText {#text} at (62,14) size 23x28 + text run at (62,14) width 23: "ax" + RenderInline {SPAN} at (0,0) size 73x28 RenderText {#text} at (85,14) size 73x28 text run at (85,14) width 73: "\x{9}\x{9}" RenderText {#text} at (158,14) size 11x28 text run at (158,14) width 11: "z" RenderText {#text} at (0,0) size 0x0 -caret: position 2 of child 0 {#text} of child 0 {SPAN} of child 2 {SPAN} of child 1 {SPAN} of child 1 {DIV} of body +caret: position 2 of child 2 {#text} of child 1 {SPAN} of child 1 {DIV} of body diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 1b29f0753bffbe89fe99600f9696a2df3e75b5a7..73f8ccd156b0dc4becd11933c3b2fceaaf058df7 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,25 @@ +2011-03-24 Enrica Casucci + + Reviewed by Darin Adler. + + Repeated copy and paste-in-place operation results in increasingly verbose HTML. + + https://bugs.webkit.org/show_bug.cgi?id=56874 + + When we calculate the style to apply at the insertion point we compare the initial + style at the insertion point against the style calculated at the span we wrap the + copied markup fragment with. We could end up with a series of unnecessary spans + to remove the initial style that simply grow our markup. + The consists in moving the insertion point outside any inline element that could + affect the fragment being inserted when we are not pasting and matching the style. + + Test: editing/pasteboard/paste-text-with-style.html + + * editing/ReplaceSelectionCommand.cpp: + (WebCore::isInlineNodeWithStyle): Added. + (WebCore::ReplaceSelectionCommand::doApply): Added logic to change the insertion + point according to the new rules. + 2011-03-24 Benjamin Poulain Reviewed by Kenneth Rohde Christiansen. diff --git a/Source/WebCore/editing/ReplaceSelectionCommand.cpp b/Source/WebCore/editing/ReplaceSelectionCommand.cpp index 9d8e1329489fa62c9f7d24ac51e5d753ff2b5dc9..591f38b77f2e5da00923554a2bce85cd7e5d9a9c 100644 --- a/Source/WebCore/editing/ReplaceSelectionCommand.cpp +++ b/Source/WebCore/editing/ReplaceSelectionCommand.cpp @@ -43,6 +43,7 @@ #include "HTMLInputElement.h" #include "HTMLInterchange.h" #include "HTMLNames.h" +#include "NodeList.h" #include "SelectionController.h" #include "SmartReplace.h" #include "TextIterator.h" @@ -776,6 +777,34 @@ static Node* enclosingInline(Node* node) return node; } +static bool isInlineNodeWithStyle(const Node* node) +{ + // We don't want to skip over any block elements. + if (!node->renderer() || !node->renderer()->isInline()) + return false; + + if (!node->isHTMLElement()) + return false; + + // We can skip over elements whose class attribute is + // one of our internal classes. + const HTMLElement* element = static_cast(node); + AtomicString classAttributeValue = element->getAttribute(classAttr); + if (classAttributeValue == AppleStyleSpanClass + || classAttributeValue == AppleTabSpanClass + || classAttributeValue == AppleConvertedSpace + || classAttributeValue == ApplePasteAsQuotation) + return true; + + // We can skip inline elements that don't have attributes or whose only + // attribute is the style attribute. + const NamedNodeMap* attributeMap = element->attributeMap(); + if (!attributeMap || attributeMap->isEmpty() || (attributeMap->length() == 1 && element->hasAttribute(styleAttr))) + return true; + + return false; +} + void ReplaceSelectionCommand::doApply() { VisibleSelection selection = endingSelection(); @@ -917,6 +946,29 @@ void ReplaceSelectionCommand::doApply() // outside of preceding tags. insertionPos = positionAvoidingPrecedingNodes(insertionPos); + // If we are not trying to match the destination style we prefer a position + // that is outside inline elements that provide style. + // This way we can produce a less verbose markup. + // We can skip this optimization for fragments not wrapped in one of + // our style spans and for positions inside list items + // since insertAsListItems already does the right thing. + if (!m_matchStyle && !enclosingList(insertionPos.anchorNode()) && isStyleSpan(fragment.firstChild())) { + Node* parentNode = insertionPos.anchorNode()->parentNode(); + while (parentNode && parentNode->renderer() && isInlineNodeWithStyle(parentNode)) { + // If we are in the middle of a text node, we need to split it before we can + // move the insertion position. + if (insertionPos.anchorNode()->isTextNode() && insertionPos.anchorType() == Position::PositionIsOffsetInAnchor && insertionPos.offsetInContainerNode() && !insertionPos.atLastEditingPositionForNode()) + splitTextNodeContainingElement(static_cast(insertionPos.anchorNode()), insertionPos.offsetInContainerNode()); + + // If the style element has more than one child, we need to split it. + if (parentNode->firstChild()->nextSibling()) + splitElement(static_cast(parentNode), insertionPos.computeNodeAfterPosition()); + + insertionPos = positionInParentBeforeNode(parentNode); + parentNode = parentNode->parentNode(); + } + } + // FIXME: When pasting rich content we're often prevented from heading down the fast path by style spans. Try // again here if they've been removed.