WebCore:

2009-04-21  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by Darin Adler.

        https://bugs.webkit.org/show_bug.cgi?id=19644
        Text copied with Select All pastes with a indent but shouldn't
        <rdar://problem/6102483> 
        Pasting the content of an HTML message in Mail causes addition nested <div> elements to be added
        
        To improve selectall/copy/paste fidelity of certain pages, we began wrapping copied content with
        a div that held properties and attributes from the fully selected body.  To fix the above issues, 
        only do this if if the body has certain properties or attributes.  We'll begin adding to this list as 
        necessary.  For now it's just background colors and images.  Tested copy/paste of nytimes, wired,
        arstechnica, and several others.
        
        Massive nesting can still happen, it will just be much less common.

        * editing/markup.cpp:
        (WebCore::createMarkup): 

LayoutTests:

2009-04-21  Justin Garcia  <justin.garcia@apple.com>

        Reviewed by Darin Adler.

        https://bugs.webkit.org/show_bug.cgi?id=19644
        Text copied with Select All pastes with a indent but shouldn't
        <rdar://problem/6102483> 
        Pasting the content of an HTML message in Mail causes addition nested <div> elements to be added

        * editing/pasteboard/19644-1-expected.txt: Added.
        * editing/pasteboard/19644-1.html: Added.
        * editing/pasteboard/19644-2-expected.txt: Added.
        * editing/pasteboard/19644-2.html: Added.
        * platform/mac/editing/inserting/insert-3907422-fix-expected.txt:
        * platform/mac/editing/pasteboard/paste-text-015-expected.checksum:
        * platform/mac/editing/pasteboard/paste-text-015-expected.png:
        * platform/mac/editing/pasteboard/paste-text-015-expected.txt:
        * platform/mac/editing/style/font-family-with-space-expected.txt:



git-svn-id: svn://svn.chromium.org/blink/trunk@42722 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 13f02f88
2009-04-21 Justin Garcia <justin.garcia@apple.com>
Reviewed by Darin Adler.
https://bugs.webkit.org/show_bug.cgi?id=19644
Text copied with Select All pastes with a indent but shouldn't
<rdar://problem/6102483>
Pasting the content of an HTML message in Mail causes addition nested <div> elements to be added
* editing/pasteboard/19644-1-expected.txt: Added.
* editing/pasteboard/19644-1.html: Added.
* editing/pasteboard/19644-2-expected.txt: Added.
* editing/pasteboard/19644-2.html: Added.
* platform/mac/editing/inserting/insert-3907422-fix-expected.txt:
* platform/mac/editing/pasteboard/paste-text-015-expected.checksum:
* platform/mac/editing/pasteboard/paste-text-015-expected.png:
* platform/mac/editing/pasteboard/paste-text-015-expected.txt:
* platform/mac/editing/style/font-family-with-space-expected.txt:
2009-04-21 Dave Moore <davemoore@google.com> and Eric Seidel <eric@webkit.org>
Reviewed by Darin Adler.
......
This tests for a bug where we would wrap copied markup in a div to hold a fully selected body's attributes and style even if there was nothing special about the body that warranted doing so. After you cut/paste, the text should only have 5 pixels of padding.
<head>
<script>
function runTest() {
document.body.focus();
document.execCommand("SelectAll");
if (!layoutTestController)
return;
layoutTestController.dumpAsText();
document.execCommand("Cut");
document.execCommand("Paste");
document.body.innerText = document.body.innerHTML;
}
</script>
</head>
<body onLoad="runTest();" contentEditable="true" style="padding: 5px; margin: 5px;">This tests for a bug where we would wrap copied markup in a div to hold a fully selected body's attributes and style even if there was nothing special about the body that warranted doing so. After you cut/paste, the text should only have 5 pixels of padding.</body>
<div style="background-color: rgb(187, 187, 187); ">This tests to make sure that we wrap copied markup in a div to hold a fully selected body's attributes and style when the that body has a background-color. If you copy and paste this text into Mail, it should have a grey background.</div>
<head>
<script>
function runTest() {
document.body.focus();
document.execCommand("SelectAll");
if (!layoutTestController)
return;
layoutTestController.dumpAsText();
document.execCommand("Cut");
document.body.style.backgroundColor = "white";
document.execCommand("Paste");
document.body.innerText = document.body.innerHTML;
}
</script>
</head>
<body onLoad="runTest();" contentEditable="true" style="background-color: #bbb;">This tests to make sure that we wrap copied markup in a div to hold a fully selected body's attributes and style when the that body has a background-color. If you copy and paste this text into Mail, it should have a grey background.</body>
......@@ -10,11 +10,11 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > DIV > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > DIV > BODY > HTML > #document to 3 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 3 of #text > DIV > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > DIV > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > DIV > DIV > DIV > DIV > BODY > HTML > #document to 3 of #text > DIV > DIV > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 3 of #text > DIV > BODY > HTML > #document to 3 of #text > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > DIV > BODY > HTML > #document to 3 of #text > DIV > BODY > HTML > #document toDOMRange:range from 3 of #text > BODY > HTML > #document to 3 of #text > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -22,28 +22,28 @@ layer at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x154
RenderBlock {DIV} at (0,0) size 784x154
RenderBlock {DIV} at (0,0) size 784x86
RenderBlock (anonymous) at (0,0) size 784x18
RenderText {#text} at (0,0) size 21x18
text run at (0,0) width 21: "foo"
RenderBlock {BLOCKQUOTE} at (40,34) size 704x18
RenderText {#text} at (0,0) size 20x18
text run at (0,0) width 20: "bar"
RenderBlock (anonymous) at (0,68) size 784x18
RenderText {#text} at (0,0) size 22x18
text run at (0,0) width 22: "baz"
RenderText {#text} at (22,0) size 21x18
text run at (22,0) width 21: "foo"
RenderBlock {DIV} at (0,102) size 784x52
RenderBlock {DIV} at (0,0) size 784x52
RenderBlock (anonymous) at (0,0) size 784x0
RenderBlock {BLOCKQUOTE} at (40,0) size 704x18
RenderText {#text} at (0,0) size 20x18
text run at (0,0) width 20: "bar"
RenderBlock (anonymous) at (0,34) size 784x18
RenderText {#text} at (0,0) size 22x18
text run at (0,0) width 22: "baz"
RenderBlock (anonymous) at (0,154) size 784x0
caret: position 3 of child 1 {#text} of child 0 {DIV} of child 1 {DIV} of child 0 {DIV} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderBlock {DIV} at (0,0) size 784x86
RenderBlock (anonymous) at (0,0) size 784x18
RenderText {#text} at (0,0) size 21x18
text run at (0,0) width 21: "foo"
RenderBlock {BLOCKQUOTE} at (40,34) size 704x18
RenderText {#text} at (0,0) size 20x18
text run at (0,0) width 20: "bar"
RenderBlock (anonymous) at (0,68) size 784x18
RenderText {#text} at (0,0) size 22x18
text run at (0,0) width 22: "baz"
RenderText {#text} at (22,0) size 21x18
text run at (22,0) width 21: "foo"
RenderBlock (anonymous) at (0,86) size 784x0
RenderBlock {BLOCKQUOTE} at (40,102) size 704x18
RenderText {#text} at (0,0) size 20x18
text run at (0,0) width 20: "bar"
RenderBlock (anonymous) at (0,136) size 784x18
RenderText {#text} at (0,0) size 22x18
text run at (0,0) width 22: "baz"
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
caret: position 3 of child 3 {#text} of child 1 {BODY} of child 0 {HTML} of document
ae788bf879d057684b361416ac3c7ccc
\ No newline at end of file
85e39bc35f46a7419de4a51a028fba24
\ No newline at end of file
......@@ -16,15 +16,15 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of P > DIV > DIV > BODY > HTML > #document to 0 of P > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > P > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document to 0 of P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 3 of #text > P > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > P > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of P > P > DIV > DIV > BODY > HTML > #document to 0 of P > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document to 0 of P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: shouldInsertNode:#document-fragment replacingDOMRange:range from 0 of P > P > DIV > DIV > BODY > HTML > #document to 0 of P > P > DIV > DIV > BODY > HTML > #document givenAction:WebViewInsertActionPasted
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > DIV > DIV > SPAN > P > DIV > DIV > SPAN > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > P > P > P > DIV > DIV > BODY > HTML > #document to 3 of #text > P > P > P > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
layer at (0,0) size 800x600
......@@ -32,34 +32,22 @@ layer at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderBlock {DIV} at (0,0) size 784x196
RenderBlock {DIV} at (0,0) size 784x196 [border: (2px solid #FF0000)]
RenderBlock {P} at (14,14) size 756x168
RenderBlock (anonymous) at (0,0) size 756x0
RenderInline {SPAN} at (0,0) size 0x0
RenderBlock (anonymous) at (0,0) size 756x168
RenderBlock {DIV} at (0,0) size 756x168
RenderBlock {DIV} at (0,0) size 756x168 [border: (2px solid #FF0000)]
RenderBlock {P} at (14,14) size 728x28
RenderText {#text} at (0,0) size 32x28
text run at (0,0) width 32: "foo"
RenderBlock {P} at (14,42) size 728x28
RenderText {#text} at (0,0) size 31x28
text run at (0,0) width 31: "bar"
RenderBlock {P} at (14,70) size 728x84
RenderBlock (anonymous) at (0,0) size 728x0
RenderInline {SPAN} at (0,0) size 0x0
RenderBlock (anonymous) at (0,0) size 728x84
RenderBlock {DIV} at (0,0) size 728x84
RenderBlock {DIV} at (0,0) size 728x84 [border: (2px solid #FF0000)]
RenderBlock {P} at (14,14) size 700x28
RenderText {#text} at (0,0) size 32x28
text run at (0,0) width 32: "foo"
RenderBlock {P} at (14,42) size 700x28
RenderText {#text} at (0,0) size 31x28
text run at (0,0) width 31: "bar"
RenderBlock (anonymous) at (0,84) size 728x0
RenderInline {SPAN} at (0,0) size 0x0
RenderBlock (anonymous) at (0,168) size 756x0
RenderInline {SPAN} at (0,0) size 0x0
caret: position 3 of child 0 {#text} of child 1 {P} of child 0 {DIV} of child 0 {DIV} of child 0 {SPAN} of child 2 {P} of child 0 {DIV} of child 0 {DIV} of child 0 {SPAN} of child 0 {P} of child 1 {DIV} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
RenderBlock {DIV} at (0,0) size 784x140
RenderBlock {DIV} at (0,0) size 784x140 [border: (2px solid #FF0000)]
RenderBlock {P} at (14,14) size 756x112
RenderBlock {P} at (0,0) size 756x28
RenderText {#text} at (0,0) size 32x28
text run at (0,0) width 32: "foo"
RenderBlock {P} at (0,28) size 756x28
RenderText {#text} at (0,0) size 31x28
text run at (0,0) width 31: "bar"
RenderBlock (anonymous) at (0,56) size 756x0
RenderBlock {P} at (0,56) size 756x56
RenderBlock {P} at (0,0) size 756x28
RenderText {#text} at (0,0) size 32x28
text run at (0,0) width 32: "foo"
RenderBlock {P} at (0,28) size 756x28
RenderText {#text} at (0,0) size 31x28
text run at (0,0) width 31: "bar"
RenderBlock (anonymous) at (0,56) size 756x0
caret: position 3 of child 0 {#text} of child 1 {P} of child 2 {P} of child 0 {P} of child 1 {DIV} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
......@@ -3,13 +3,13 @@ layer at (0,0) size 800x600
layer at (0,0) size 800x600
RenderBlock {HTML} at (0,0) size 800x600
RenderBody {BODY} at (8,8) size 784x584
RenderInline {SPAN} at (0,0) size 245x15
RenderInline {SPAN} at (0,0) size 490x15
RenderText {#text} at (0,0) size 245x15
text run at (0,0) width 245: "This text should be Times New Roman bold."
RenderInline {SPAN} at (0,0) size 245x15
RenderInline {SPAN} at (0,0) size 245x15
RenderText {#text} at (245,0) size 245x15
text run at (245,0) width 245: "This text should be Times New Roman bold."
RenderInline {SPAN} at (0,0) size 245x15
RenderText {#text} at (245,0) size 245x15
text run at (245,0) width 245: "This text should be Times New Roman bold."
RenderText {#text} at (0,0) size 0x0
RenderText {#text} at (0,0) size 0x0
caret: position 41 of child 0 {#text} of child 1 {SPAN} of child 0 {SPAN} of child 0 {BODY} of child 0 {HTML} of document
caret: position 41 of child 0 {#text} of child 0 {SPAN} of child 1 {SPAN} of child 0 {SPAN} of child 0 {BODY} of child 0 {HTML} of document
2009-04-16 Peter Kasting <pkasting@google.com>
2009-04-21 Justin Garcia <justin.garcia@apple.com>
Reviewed by Darin Adler.
https://bugs.webkit.org/show_bug.cgi?id=19644
Text copied with Select All pastes with a indent but shouldn't
<rdar://problem/6102483>
Pasting the content of an HTML message in Mail causes addition nested <div> elements to be added
To improve selectall/copy/paste fidelity of certain pages, we began wrapping copied content with
a div that held properties and attributes from the fully selected body. To fix the above issues,
only do this if if the body has certain properties or attributes. We'll begin adding to this list as
necessary. For now it's just background colors and images. Tested copy/paste of nytimes, wired,
arstechnica, and several others.
Massive nesting can still happen, it will just be much less common.
* editing/markup.cpp:
(WebCore::createMarkup):
2009-04-21 Peter Kasting <pkasting@google.com>
Reviewed by David Hyatt.
......@@ -742,6 +742,15 @@ static bool isSpecialAncestorBlock(Node* node)
node->hasTagName(h5Tag);
}
static bool shouldIncludeWrapperForFullySelectedRoot(Node* fullySelectedRoot, CSSMutableStyleDeclaration* style)
{
if (fullySelectedRoot->isElementNode() && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
return true;
return style->getPropertyCSSValue(CSSPropertyBackgroundImage) ||
style->getPropertyCSSValue(CSSPropertyBackgroundColor);
}
// FIXME: Shouldn't we omit style info when annotate == DoNotAnnotateForInterchange?
// FIXME: At least, annotation and style info should probably not be included in range.markupString()
String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterchange annotate, bool convertBlocksToInlines)
......@@ -927,29 +936,29 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
specialCommonAncestor = enclosingAnchor;
Node* body = enclosingNodeWithTag(Position(commonAncestor, 0), bodyTag);
// FIXME: Only include markup for a fully selected root (and ancestors of lastClosed up to that root) if
// there are styles/attributes on those nodes that need to be included to preserve the appearance of the copied markup.
// FIXME: Do this for all fully selected blocks, not just the body.
Node* fullySelectedRoot = body && *VisibleSelection::selectionFromContentsOfNode(body).toNormalizedRange() == *updatedRange ? body : 0;
if (annotate && fullySelectedRoot)
specialCommonAncestor = fullySelectedRoot;
RefPtr<CSSMutableStyleDeclaration> fullySelectedRootStyle = fullySelectedRoot ? styleFromMatchedRulesAndInlineDecl(fullySelectedRoot) : 0;
if (annotate && fullySelectedRoot) {
if (shouldIncludeWrapperForFullySelectedRoot(fullySelectedRoot, fullySelectedRootStyle.get()))
specialCommonAncestor = fullySelectedRoot;
}
if (specialCommonAncestor && lastClosed) {
// Also include all of the ancestors of lastClosed up to this special ancestor.
for (Node* ancestor = lastClosed->parentNode(); ancestor; ancestor = ancestor->parentNode()) {
if (ancestor == fullySelectedRoot && !convertBlocksToInlines) {
RefPtr<CSSMutableStyleDeclaration> style = styleFromMatchedRulesAndInlineDecl(fullySelectedRoot);
// Bring the background attribute over, but not as an attribute because a background attribute on a div
// appears to have no effect.
if (!style->getPropertyCSSValue(CSSPropertyBackgroundImage) && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
style->setProperty(CSSPropertyBackgroundImage, "url('" + static_cast<Element*>(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
if (!fullySelectedRootStyle->getPropertyCSSValue(CSSPropertyBackgroundImage) && static_cast<Element*>(fullySelectedRoot)->hasAttribute(backgroundAttr))
fullySelectedRootStyle->setProperty(CSSPropertyBackgroundImage, "url('" + static_cast<Element*>(fullySelectedRoot)->getAttribute(backgroundAttr) + "')");
if (style->length()) {
if (fullySelectedRootStyle->length()) {
Vector<UChar> openTag;
DEFINE_STATIC_LOCAL(const String, divStyle, ("<div style=\""));
append(openTag, divStyle);
appendAttributeValue(openTag, style->cssText(), documentIsHTML);
appendAttributeValue(openTag, fullySelectedRootStyle->cssText(), documentIsHTML);
openTag.append('\"');
openTag.append('>');
preMarkups.append(String::adopt(openTag));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment