WebCore:
authorjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2008 20:42:27 +0000 (20:42 +0000)
committerjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 28 Feb 2008 20:42:27 +0000 (20:42 +0000)
        Reviewed by Darin Adler.

        <rdar://problem/4930986> REGRESSION: Paste As Quotation pastes black text instead of blue

        Add a second style span at copy time to hold document default styles.  This helps us
        differentiate between those and user applied styles at paste time, where we'll want
        to let Mail's Paste As Quotation blockquote override document default styles, but
        not others.

        * css/CSSComputedStyleDeclaration.cpp:
        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Changed the unit type used
        for -webkit-text-stroke-width from CSS_NUMBER to CSS_PX, to match other properties that
        are thick | medium | thin | <length>.  Before, there was a mismatch between the unit
        type of -webkit-text-stroke-width property values in a CSSComputedStyleDeclaration for
        an element and that element's inlineStyleDecl(), causing identical values to always appear
        different to diff().
        * editing/ReplaceSelectionCommand.cpp:
        (WebCore::ReplaceSelectionCommand::handlePasteAsQuotationNode): Fixed.  Don't just change
        the class to an empty string, completely remove it, it's no longer needed.
        (WebCore::handleStyleSpansBeforeInsertion): Moved the optimization from doApply here.
        (WebCore::ReplaceSelectionCommand::handleStyleSpans):
        Added, replaces removeRedundantStyles.
        We aren't (yet) removing all redundant styles, just those on style spans, so I removed the
        unused code and renamed the function.
        There won't be more than two style spans that we need to consider, the one with the
        source document's default styles and styles on the commonAncestor of the copied Range,
        so don't look for more than two.
        Let elements that wrap the incoming fragment override the source document's styles.
        (WebCore::ReplaceSelectionCommand::doApply): Moved code to handleStyleSpansBeforeInsertion
        and call the renamed handleStyleSpans.
        * editing/ReplaceSelectionCommand.h:
        * editing/markup.cpp:
        (WebCore::removeDefaultStyles): Added.  Don't add document defaults to the style span
        that holds user applied styles, since they'll be added to their own style span.
        (WebCore::createMarkup):
        Add a second style span that holds just the document defaults. This lets us differentiate
        between those and user applied styles at paste time.
        Mail blockquotes are just another type of special element, moved their handling there. This
        also lets paste code make assumptions about the position of the two style spans (they are
        *always* parent-child).

LayoutTests:

        Reviewed by Darin Adler.

        <rdar://problem/4930986> REGRESSION: Paste As Quotation pastes black text instead of blue

        Demonstrates the bug:
        * editing/pasteboard/4930986-1-expected.txt: Added.
        * editing/pasteboard/4930986-1.html: Added.
        * editing/pasteboard/4930986-2-expected.txt: Added.
        * editing/pasteboard/4930986-2.html: Added.

        Demonstrates a problem with the first version of the patch:
        * editing/pasteboard/4930986-3-expected.txt: Added.
        * editing/pasteboard/4930986-3.html: Added.

        Visual problem fixed.  An anonymous renderer changed position, DOM remains unchanged:
        * editing/execCommand/5144139-1.html:
        * platform/mac/editing/execCommand/5144139-1-expected.checksum:
        * platform/mac/editing/execCommand/5144139-1-expected.png:
        * platform/mac/editing/execCommand/5144139-1-expected.txt:

        Removed unnecessary style spans, visual result unchanged:
        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.checksum:
        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.png:
        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.txt:
        * platform/mac/editing/style/font-family-with-space-expected.checksum:
        * platform/mac/editing/style/font-family-with-space-expected.png:
        * platform/mac/editing/style/font-family-with-space-expected.txt:

        A style span isn't removed because at paste time because we don't anticipate
        encountering styles on style spans that are non-inheritable, because we don't
        create style spans like that at copy time. Turned this into a text only
        test. Test remains visually unchanged:
        * editing/pasteboard/5245519-expected.txt: Added.
        * editing/pasteboard/5245519.html:
        * platform/mac/editing/pasteboard/5245519-expected.checksum: Removed.
        * platform/mac/editing/pasteboard/5245519-expected.png: Removed.
        * platform/mac/editing/pasteboard/5245519-expected.txt: Removed.

        Added an extra empty anonymous renderer, DOM and visual result remain unchanged:
        * platform/mac/editing/execCommand/create-list-with-hr-expected.checksum:
        * platform/mac/editing/execCommand/create-list-with-hr-expected.png:
        * platform/mac/editing/execCommand/create-list-with-hr-expected.txt:
        * platform/mac/editing/pasteboard/paste-list-001-expected.checksum:
        * platform/mac/editing/pasteboard/paste-list-001-expected.png:
        * platform/mac/editing/pasteboard/paste-list-001-expected.txt:
        * platform/mac/editing/pasteboard/paste-table-001-expected.checksum:
        * platform/mac/editing/pasteboard/paste-table-001-expected.png:
        * platform/mac/editing/pasteboard/paste-table-001-expected.txt:
        * platform/mac/editing/pasteboard/paste-text-003-expected.checksum:
        * platform/mac/editing/pasteboard/paste-text-003-expected.png:
        * platform/mac/editing/pasteboard/paste-text-003-expected.txt:

        Reflects changes to CSSComputedStyleDeclaration::getPropertyCSSValue:
        * fast/css/computed-style-expected.txt:
        * fast/css/computed-style-without-renderer-expected.txt:

        We don't remove styles from style spans that are overridden by all of their
        children, even though they are unnecessary. We've never done this, but now
        that there can be two style spans at paste time we are more likely to have
        a style span left over because of this problem.  Mentioned this in the test
        case and turned this into a text only test:
        * editing/pasteboard/4840662.html:
        * editing/pasteboard/4840662-expected.txt: Added.
        * platform/mac/editing/pasteboard/4840662-expected.checksum: Removed.
        * platform/mac/editing/pasteboard/4840662-expected.png: Removed.
        * platform/mac/editing/pasteboard/4840662-expected.txt: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@30649 268f45cc-cd09-0410-ab3c-d52691b4dbfc

46 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/execCommand/5144139-1.html
LayoutTests/editing/pasteboard/4840662-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/4840662.html
LayoutTests/editing/pasteboard/4930986-1-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/4930986-1.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/4930986-2-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/4930986-2.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/4930986-3-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/4930986-3.html [new file with mode: 0644]
LayoutTests/editing/pasteboard/5245519-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/5245519.html
LayoutTests/fast/css/computed-style-expected.txt
LayoutTests/fast/css/computed-style-without-renderer-expected.txt
LayoutTests/platform/mac/editing/execCommand/5144139-1-expected.checksum
LayoutTests/platform/mac/editing/execCommand/5144139-1-expected.png
LayoutTests/platform/mac/editing/execCommand/5144139-1-expected.txt
LayoutTests/platform/mac/editing/execCommand/create-list-with-hr-expected.checksum
LayoutTests/platform/mac/editing/execCommand/create-list-with-hr-expected.png
LayoutTests/platform/mac/editing/execCommand/create-list-with-hr-expected.txt
LayoutTests/platform/mac/editing/pasteboard/4840662-expected.checksum [deleted file]
LayoutTests/platform/mac/editing/pasteboard/4840662-expected.png [deleted file]
LayoutTests/platform/mac/editing/pasteboard/4840662-expected.txt [deleted file]
LayoutTests/platform/mac/editing/pasteboard/5245519-expected.checksum [deleted file]
LayoutTests/platform/mac/editing/pasteboard/5245519-expected.png [deleted file]
LayoutTests/platform/mac/editing/pasteboard/5245519-expected.txt [deleted file]
LayoutTests/platform/mac/editing/pasteboard/merge-end-blockquote-expected.checksum
LayoutTests/platform/mac/editing/pasteboard/merge-end-blockquote-expected.png
LayoutTests/platform/mac/editing/pasteboard/merge-end-blockquote-expected.txt
LayoutTests/platform/mac/editing/pasteboard/paste-list-001-expected.checksum
LayoutTests/platform/mac/editing/pasteboard/paste-list-001-expected.png
LayoutTests/platform/mac/editing/pasteboard/paste-list-001-expected.txt
LayoutTests/platform/mac/editing/pasteboard/paste-table-001-expected.checksum
LayoutTests/platform/mac/editing/pasteboard/paste-table-001-expected.png
LayoutTests/platform/mac/editing/pasteboard/paste-table-001-expected.txt
LayoutTests/platform/mac/editing/pasteboard/paste-text-003-expected.checksum
LayoutTests/platform/mac/editing/pasteboard/paste-text-003-expected.png
LayoutTests/platform/mac/editing/pasteboard/paste-text-003-expected.txt
LayoutTests/platform/mac/editing/style/font-family-with-space-expected.checksum
LayoutTests/platform/mac/editing/style/font-family-with-space-expected.png
LayoutTests/platform/mac/editing/style/font-family-with-space-expected.txt
WebCore/ChangeLog
WebCore/css/CSSComputedStyleDeclaration.cpp
WebCore/editing/ReplaceSelectionCommand.cpp
WebCore/editing/ReplaceSelectionCommand.h
WebCore/editing/markup.cpp

index a948116c0210f3eaa16111ae39aca431226734a5..c215eaa8b777fa3e211b064d614bd76426cdcf33 100644 (file)
@@ -1,3 +1,72 @@
+2008-02-28  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by Darin Adler.
+        
+        <rdar://problem/4930986> REGRESSION: Paste As Quotation pastes black text instead of blue
+
+        Demonstrates the bug:
+        * editing/pasteboard/4930986-1-expected.txt: Added.
+        * editing/pasteboard/4930986-1.html: Added.
+        * editing/pasteboard/4930986-2-expected.txt: Added.
+        * editing/pasteboard/4930986-2.html: Added.
+        
+        Demonstrates a problem with the first version of the patch:
+        * editing/pasteboard/4930986-3-expected.txt: Added.
+        * editing/pasteboard/4930986-3.html: Added.
+        
+        Visual problem fixed.  An anonymous renderer changed position, DOM remains unchanged:
+        * editing/execCommand/5144139-1.html:
+        * platform/mac/editing/execCommand/5144139-1-expected.checksum:
+        * platform/mac/editing/execCommand/5144139-1-expected.png:
+        * platform/mac/editing/execCommand/5144139-1-expected.txt:
+
+        Removed unnecessary style spans, visual result unchanged:
+        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.checksum:
+        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.png:
+        * platform/mac/editing/pasteboard/merge-end-blockquote-expected.txt:
+        * platform/mac/editing/style/font-family-with-space-expected.checksum:
+        * platform/mac/editing/style/font-family-with-space-expected.png:
+        * platform/mac/editing/style/font-family-with-space-expected.txt:
+        
+        A style span isn't removed because at paste time because we don't anticipate 
+        encountering styles on style spans that are non-inheritable, because we don't 
+        create style spans like that at copy time. Turned this into a text only 
+        test. Test remains visually unchanged:
+        * editing/pasteboard/5245519-expected.txt: Added.
+        * editing/pasteboard/5245519.html:
+        * platform/mac/editing/pasteboard/5245519-expected.checksum: Removed.
+        * platform/mac/editing/pasteboard/5245519-expected.png: Removed.
+        * platform/mac/editing/pasteboard/5245519-expected.txt: Removed.
+
+        Added an extra empty anonymous renderer, DOM and visual result remain unchanged:
+        * platform/mac/editing/execCommand/create-list-with-hr-expected.checksum:
+        * platform/mac/editing/execCommand/create-list-with-hr-expected.png:
+        * platform/mac/editing/execCommand/create-list-with-hr-expected.txt:
+        * platform/mac/editing/pasteboard/paste-list-001-expected.checksum:
+        * platform/mac/editing/pasteboard/paste-list-001-expected.png:
+        * platform/mac/editing/pasteboard/paste-list-001-expected.txt:
+        * platform/mac/editing/pasteboard/paste-table-001-expected.checksum:
+        * platform/mac/editing/pasteboard/paste-table-001-expected.png:
+        * platform/mac/editing/pasteboard/paste-table-001-expected.txt:
+        * platform/mac/editing/pasteboard/paste-text-003-expected.checksum:
+        * platform/mac/editing/pasteboard/paste-text-003-expected.png:
+        * platform/mac/editing/pasteboard/paste-text-003-expected.txt:
+        
+        Reflects changes to CSSComputedStyleDeclaration::getPropertyCSSValue:
+        * fast/css/computed-style-expected.txt:
+        * fast/css/computed-style-without-renderer-expected.txt:
+        
+        We don't remove styles from style spans that are overridden by all of their 
+        children, even though they are unnecessary. We've never done this, but now
+        that there can be two style spans at paste time we are more likely to have 
+        a style span left over because of this problem.  Mentioned this in the test 
+        case and turned this into a text only test:
+        * editing/pasteboard/4840662.html:
+        * editing/pasteboard/4840662-expected.txt: Added.
+        * platform/mac/editing/pasteboard/4840662-expected.checksum: Removed.
+        * platform/mac/editing/pasteboard/4840662-expected.png: Removed.
+        * platform/mac/editing/pasteboard/4840662-expected.txt: Removed.
+        
 2008-02-27  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by John Sullivan.
index 4ee61adad4126427049256e09d4e3762a3fef0a8..9eee1a2c6e66391235152f7a4d4ced9260b0bb64 100644 (file)
@@ -1,4 +1,4 @@
-<p>This tests for a bug when creating a list from a table.  The table should be inside a a list item. <b>This demonstrates a bug: the table should be below the list marker, not above it.</b></p>
+<p>This tests for a bug when creating a list from a table.  The table should be inside a a list item.</p>
 <div contenteditable="true" id="div"><table border="1"><tr><td>foo</td></tr></table></div>
 
 <script>
diff --git a/LayoutTests/editing/pasteboard/4840662-expected.txt b/LayoutTests/editing/pasteboard/4840662-expected.txt
new file mode 100644 (file)
index 0000000..1234bfc
--- /dev/null
@@ -0,0 +1,2 @@
+This tests for a crash when pasting into a link that is display:block. 'bar' is pasted between 'foo' and 'baz', and must be part of the link in order to acheive the expected paragraph structure. It should be part of the link but of the default font style. 'bar' shouldn't be underlined and the second style span is unnecessary, since its only property is overridden by its only child.
+<a id="anchor" href="http://www.google.com/" style="display:block;">foo<span class="Apple-style-span" style="color: rgb(0, 0, 0); -webkit-text-decorations-in-effect: none; ">bar<span class="Apple-style-span" style="-webkit-text-decorations-in-effect: none; "><a id="anchor" href="http://www.google.com/" style="display: inline !important; ">baz</a></span></span></a>
index 9099f560f1e15ce5079503e88b2f633c54efd1e6..18358e68841d75467a8a2d32eca56e30bedea727 100644 (file)
@@ -1,5 +1,5 @@
-<p>This tests for a crash when pasting into a link that is display:block.  'bar' is pasted between 'foo' and 'baz', and must be part of the link in order to acheive the expected paragraph structure.  It should be part of the link but of the default font style.</p>
-<div id="div" contenteditable="true"><a id="anchor" href="http://www.google.com/" style="display:block;">foobaz</a></div>
+<div id="description">This tests for a crash when pasting into a link that is display:block.  'bar' is pasted between 'foo' and 'baz', and must be part of the link in order to acheive the expected paragraph structure.  It should be part of the link but of the default font style. <b>'bar' shouldn't be underlined and the second style span is unnecessary, since its only property is overridden by its only child.</b></div>
+<div id="edit" contenteditable="true"><a id="anchor" href="http://www.google.com/" style="display:block;">foobaz</a></div>
 
 <script>
 var sel = window.getSelection();
@@ -8,4 +8,8 @@ var text = anchor.firstChild;
 sel.setPosition(text, 3);
 
 document.execCommand("InsertHTML", false, "bar");
+if (window.layoutTestController) {
+    layoutTestController.dumpAsText();
+    document.body.innerText = document.getElementById("description").innerText + "\n" + document.getElementById("edit").innerHTML;
+}
 </script>
diff --git a/LayoutTests/editing/pasteboard/4930986-1-expected.txt b/LayoutTests/editing/pasteboard/4930986-1-expected.txt
new file mode 100644 (file)
index 0000000..ac6439b
--- /dev/null
@@ -0,0 +1,2 @@
+This tests to make sure that content that has the document default color is pasted as blue (or whatever the color for quoted content is) during a Paste as Quotation.
+<blockquote>This text should be blue (it should not be wrapped in a style span).</blockquote>
diff --git a/LayoutTests/editing/pasteboard/4930986-1.html b/LayoutTests/editing/pasteboard/4930986-1.html
new file mode 100644 (file)
index 0000000..3b20fbf
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<head>
+<style>
+blockquote {
+    color: blue;
+    border-left: 2px solid blue;
+    margin-left: 0px;
+    padding-left: 10px;
+}
+</style>
+</head>
+<body>
+<div id="description">This tests to make sure that content that has the document default color is pasted as blue (or whatever the color for quoted content is) during a Paste as Quotation.</div>
+<div id="edit" contenteditable="true"></div>
+
+<script>
+edit = document.getElementById("edit");
+description = document.getElementById("description");
+edit.focus();
+document.execCommand("InsertHTML", false, "<blockquote class='Apple-paste-as-quotation'><span class='Apple-style-span' style='color: black;'>This text should be blue (it should not be wrapped in a style span).</span></blockquote>");
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    document.body.innerText = description.innerText + "\n" + edit.innerHTML;
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/4930986-2-expected.txt b/LayoutTests/editing/pasteboard/4930986-2-expected.txt
new file mode 100644 (file)
index 0000000..c0bd830
--- /dev/null
@@ -0,0 +1,2 @@
+This tests to make sure that content that is colored by the user is pasted with that color during a Paste as Quotation.
+<blockquote><span class="Apple-style-span" style="color: red; ">This text should be red (it should be wrapped in a style span).</span></blockquote>
diff --git a/LayoutTests/editing/pasteboard/4930986-2.html b/LayoutTests/editing/pasteboard/4930986-2.html
new file mode 100644 (file)
index 0000000..0d59439
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<head>
+<style>
+blockquote {
+    color: blue;
+    border-left: 2px solid blue;
+    margin-left: 0px;
+    padding-left: 10px;
+}
+</style>
+<script>
+function runTest() {
+    div = document.getElementById("edit");
+    div.focus();
+    document.execCommand("InsertHTML", false, "<blockquote class='Apple-paste-as-quotation'><span class='Apple-style-span' style='color: black;'><span class='Apple-style-span' style='color: red;'>This text should be red (it should be wrapped in a style span).</span></span></blockquote>");
+    if (window.layoutTestController) {
+        window.layoutTestController.dumpAsText();
+        document.body.innerText = document.getElementById("description").innerText + "\n" + div.innerHTML;
+    }
+}
+</script>
+</head>
+<body onload="runTest();">
+<div id="description">This tests to make sure that content that is colored by the user is pasted with that color during a Paste as Quotation.</div>
+<div id="edit" contenteditable="true"></div>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/4930986-3-expected.txt b/LayoutTests/editing/pasteboard/4930986-3-expected.txt
new file mode 100644 (file)
index 0000000..ac8f535
--- /dev/null
@@ -0,0 +1,2 @@
+This tests to make sure that an Apple-paste-as-quotation blockquote can override document default styles even if they are different than the insertion position.
+<blockquote>This text should have the blockquote color (blue). There should be no style spans around it.</blockquote>
diff --git a/LayoutTests/editing/pasteboard/4930986-3.html b/LayoutTests/editing/pasteboard/4930986-3.html
new file mode 100644 (file)
index 0000000..24c11ac
--- /dev/null
@@ -0,0 +1,27 @@
+<html>
+<head>
+<style>
+blockquote {
+    color: blue;
+    padding-left: 10px;
+    margin-left: 0px;
+    border-left: 2px solid blue;
+}
+</style>
+</head>
+<body>
+<div id="description">This tests to make sure that an Apple-paste-as-quotation blockquote can override document default styles even if they are different than the insertion position.</div>
+<div id="edit" contenteditable="true" style="color: red;"></div>
+
+<script>
+edit = document.getElementById("edit");
+description = document.getElementById("description");
+edit.focus();
+document.execCommand("InsertHTML", false, "<blockquote class='Apple-paste-as-quotation'><span class='Apple-style-span' style='color:black;'>This text should have the blockquote color (blue). There should be no style spans around it.</span></blockquote>");
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    document.body.innerText = description.innerText + "\n" + edit.innerHTML;
+}
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/pasteboard/5245519-expected.txt b/LayoutTests/editing/pasteboard/5245519-expected.txt
new file mode 100644 (file)
index 0000000..645909c
--- /dev/null
@@ -0,0 +1,2 @@
+This tests for a crash when pasting content that contains Apple-style-spans that don't have renderers.' You should see 'Hello World!' We don't currently remove the empty invisible style span at paste time because it doesn't anticipate encountering non-inheritable styles on style spans, because we never create those at copy time.
+Hello <span style="display: none; " class="Apple-style-span"></span>World!
index b576743aa78812b1a39b7e8206f63e129d75780d..e69254a9f773636780e6b8ed92e9d3f9acf61176 100644 (file)
@@ -1,8 +1,13 @@
-<p>This tests for a crash when pasting content that contains Apple-style-spans that don't have renderers.' You should see 'Hello World!'</p>
-<div id="div" contenteditable="true"><br></div>
+<div id="description">This tests for a crash when pasting content that contains Apple-style-spans that don't have renderers.' You should see 'Hello World!' We don't currently remove the empty invisible style span at paste time because it doesn't anticipate encountering non-inheritable styles on style spans, because we never create those at copy time.</div>
+<div id="edit" contenteditable="true"><br></div>
 
 <script>
-var div = document.getElementById("div");
-div.focus();
-document.execCommand("InsertHTML", false, "Hello <span style='display:none;' class='Apple-style-span'></span>World!")
+edit = document.getElementById("edit");
+description = document.getElementById("description");
+edit.focus();
+document.execCommand("InsertHTML", false, "Hello <span style='display:none;' class='Apple-style-span'></span>World!");
+if (window.layoutTestController) {
+    window.layoutTestController.dumpAsText();
+    document.body.innerText = description.innerText + "\n" + edit.innerHTML;
+}
 </script>
index 5830a336d77429890af652c753ce4eeb1e132f51..68686a1f849cd277dd10983d4fb7a354f6313cc4 100644 (file)
@@ -122,7 +122,7 @@ z-index: auto;
 -webkit-text-fill-color: rgb(0, 0, 0);
 -webkit-text-security: none;
 -webkit-text-stroke-color: rgb(0, 0, 0);
--webkit-text-stroke-width: 0;
+-webkit-text-stroke-width: 0px;
 -webkit-user-drag: auto;
 -webkit-user-modify: read-only;
 -webkit-user-select: text;
index 76c3ce00d257a3d9364e5f7f5f3fd1a92b4f86cd..855bd7f2bb2a24244291428d56cf7ea0f91a28c4 100644 (file)
@@ -121,7 +121,7 @@ Computed style of an element whose parent's 'display' value is 'none':
     -webkit-text-fill-color: rgb(0, 0, 0)
     -webkit-text-security: none
     -webkit-text-stroke-color: rgb(0, 0, 0)
-    -webkit-text-stroke-width: 0
+    -webkit-text-stroke-width: 0px
     -webkit-user-drag: auto
     -webkit-user-modify: read-only
     -webkit-user-select: text
index 99db9b1160a5244797f9e40c1c6baf1a238ed119..f051c62e19495585607dccc73cc936f4258cf538 100644 (file)
@@ -1 +1 @@
-7a27d6fc595f0e6999bb2ad18397bff3
\ No newline at end of file
+ea40b5cb64b647b0194c8dc8db064b6d
\ No newline at end of file
index 3a48218cf7d0b74f49fb9e34681db44c1a7c10bf..b04b914a2517508f8f846f027eb6b126a793903f 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/execCommand/5144139-1-expected.png and b/LayoutTests/platform/mac/editing/execCommand/5144139-1-expected.png differ
index 96ff9c7de053d20f6465d1b8eebdc9ff12bdcb8a..9f04aa1244db0d113e490e727fc8463ee5144341 100644 (file)
@@ -3,25 +3,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 784x576
-      RenderBlock {P} at (0,0) size 784x36
-        RenderText {#text} at (0,0) size 581x18
+      RenderBlock {P} at (0,0) size 784x18
+        RenderText {#text} at (0,0) size 577x18
           text run at (0,0) width 333: "This tests for a bug when creating a list from a table. "
-          text run at (333,0) width 248: "The table should be inside a a list item. "
-        RenderInline {B} at (0,0) size 777x36
-          RenderText {#text} at (581,0) size 777x36
-            text run at (581,0) width 196: "This demonstrates a bug: the"
-            text run at (0,18) width 340: "table should be below the list marker, not above it."
-      RenderBlock {DIV} at (0,52) size 784x46
+          text run at (333,0) width 244: "The table should be inside a a list item."
+      RenderBlock {DIV} at (0,34) size 784x46
         RenderBlock {UL} at (0,0) size 784x46
           RenderListItem {LI} at (40,0) size 744x46
-            RenderTable {TABLE} at (0,0) size 31x28 [border: (1px outset #808080)]
+            RenderBlock (anonymous) at (0,0) size 744x18
+              RenderListMarker at (-17,0) size 7x18: bullet
+            RenderTable {TABLE} at (0,18) size 31x28 [border: (1px outset #808080)]
               RenderTableSection {TBODY} at (1,1) size 29x26
                 RenderTableRow {TR} at (0,2) size 29x22
                   RenderTableCell {TD} at (2,2) size 25x22 [border: (1px inset #808080)] [r=0 c=0 rs=1 cs=1]
                     RenderText {#text} at (2,2) size 21x18
                       text run at (2,2) width 21: "foo"
-            RenderBlock (anonymous) at (0,28) size 744x18
-              RenderListMarker at (-17,0) size 7x18: bullet
+            RenderBlock (anonymous) at (0,46) size 744x0
         RenderBlock (anonymous) at (0,62) size 784x0
 selection start: position 0 of child 0 {TABLE} of child 0 {LI} of child 0 {UL} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
 selection end:   position 1 of child 0 {TABLE} of child 0 {LI} of child 0 {UL} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
index 07e55826ebbe7263c10c6793a1b9f8eb89e0e2c5..e784b2ecfd47d879b2f585f4c1469aa864665573 100644 (file)
@@ -1 +1 @@
-7d8ed4a08a6169f34146cce72d34f4c2
\ No newline at end of file
+7803bac727a902ee0e75044ecace1578
\ No newline at end of file
index 86e553a07246aab795812c76452d3b7c92053e5f..83610c44f816b4c679da9cbab44d607747ecad87 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/execCommand/create-list-with-hr-expected.png and b/LayoutTests/platform/mac/editing/execCommand/create-list-with-hr-expected.png differ
index e4262ca7758e6e57384b34c42a835815e8daf867..4b7907792d63646dc1b118a3c01ce5d5dcf5f966 100644 (file)
@@ -22,6 +22,7 @@ layer at (0,0) size 800x600
       RenderBlock {DIV} at (0,52) size 784x28
         RenderBlock {UL} at (0,0) size 784x28
           RenderListItem {LI} at (40,0) size 744x28
+            RenderBlock (anonymous) at (0,0) size 744x0
             RenderBlock {HR} at (0,0) size 744x2 [border: (1px inset #000000)]
             RenderBlock (anonymous) at (0,10) size 744x18
               RenderListMarker at (-17,0) size 7x18: bullet
diff --git a/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.checksum b/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.checksum
deleted file mode 100644 (file)
index fed3b01..0000000
+++ /dev/null
@@ -1 +0,0 @@
-0f761deb6f4379cc7e8321b7caff46d8
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.png b/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.png
deleted file mode 100644 (file)
index 72df266..0000000
Binary files a/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.png and /dev/null differ
diff --git a/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/4840662-expected.txt
deleted file mode 100644 (file)
index 0f9d7bc..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-layer at (0,0) size 800x600
-  RenderView 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 {P} at (0,0) size 784x36
-        RenderText {#text} at (0,0) size 781x36
-          text run at (0,0) width 421: "This tests for a crash when pasting into a link that is display:block. "
-          text run at (421,0) width 360: "'bar' is pasted between 'foo' and 'baz', and must be part of"
-          text run at (0,18) width 384: "the link in order to acheive the expected paragraph structure. "
-          text run at (384,18) width 347: "It should be part of the link but of the default font style."
-      RenderBlock {DIV} at (0,52) size 784x18
-        RenderBlock {A} at (0,0) size 784x18 [color=#0000EE]
-          RenderText {#text} at (0,0) size 21x18
-            text run at (0,0) width 21: "foo"
-          RenderInline {SPAN} at (0,0) size 42x18 [color=#000000]
-            RenderText {#text} at (21,0) size 20x18
-              text run at (21,0) width 20: "bar"
-            RenderInline {A} at (0,0) size 22x18 [color=#0000EE]
-              RenderText {#text} at (41,0) size 22x18
-                text run at (41,0) width 22: "baz"
-        RenderBlock (anonymous) at (0,18) size 784x0
-caret: position 3 of child 0 {#text} of child 1 {SPAN} of child 0 {A} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.checksum b/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.checksum
deleted file mode 100644 (file)
index b9c07d8..0000000
+++ /dev/null
@@ -1 +0,0 @@
-37cc348638ebafbdca4889bdfb9746e4
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.png b/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.png
deleted file mode 100644 (file)
index bb591b0..0000000
Binary files a/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.png and /dev/null differ
diff --git a/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.txt b/LayoutTests/platform/mac/editing/pasteboard/5245519-expected.txt
deleted file mode 100644 (file)
index 032a37c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-layer at (0,0) size 800x600
-  RenderView 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 {P} at (0,0) size 784x36
-        RenderText {#text} at (0,0) size 776x36
-          text run at (0,0) width 776: "This tests for a crash when pasting content that contains Apple-style-spans that don't have renderers.' You should see 'Hello"
-          text run at (0,18) width 48: "World!'"
-      RenderBlock {DIV} at (0,52) size 784x18
-        RenderText {#text} at (0,0) size 39x18
-          text run at (0,0) width 39: "Hello "
-        RenderText {#text} at (39,0) size 45x18
-          text run at (39,0) width 45: "World!"
-caret: position 6 of child 1 {#text} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
index 344d1796687cae87c3cc29f5ee2786cebdc824eb..a9e66c3b62d4196dae2b4b0eefc891e8c8aeb85b 100644 (file)
@@ -1 +1 @@
-1b9b9519702657687d74ee0998ba0616
\ No newline at end of file
+3e9438db2edbee3025b3d9bdd073772e
\ No newline at end of file
index ebe768c547288b385a0da1171de8e89c070ea6fc..b271c8fd1f49c3bb20f36ad47ef5464473f8749f 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/pasteboard/merge-end-blockquote-expected.png and b/LayoutTests/platform/mac/editing/pasteboard/merge-end-blockquote-expected.png differ
index fedc7c555e70d2fd90ef94eab63419fbc5406e09..e42f49ebb8612610ee6618cf26618606379d7aed 100644 (file)
@@ -11,7 +11,7 @@ EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > SPAN > DIV > BLOCKQUOTE > DIV > BODY > HTML > #document to 3 of #text > SPAN > DIV > BLOCKQUOTE > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 3 of #text > DIV > BLOCKQUOTE > DIV > BODY > HTML > #document to 3 of #text > DIV > BLOCKQUOTE > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
 layer at (0,0) size 800x600
@@ -38,13 +38,11 @@ layer at (0,0) size 800x600
           RenderBlock {DIV} at (0,0) size 704x18
             RenderText {#text} at (0,0) size 81x18
               text run at (0,0) width 81: "Blockquoted"
-            RenderInline {SPAN} at (0,0) size 21x18
-              RenderText {#text} at (81,0) size 21x18
-                text run at (81,0) width 21: "foo"
+            RenderText {#text} at (81,0) size 21x18
+              text run at (81,0) width 21: "foo"
           RenderBlock {DIV} at (0,18) size 704x18
-            RenderInline {SPAN} at (0,0) size 20x18
-              RenderText {#text} at (0,0) size 20x18
-                text run at (0,0) width 20: "bar"
+            RenderText {#text} at (0,0) size 20x18
+              text run at (0,0) width 20: "bar"
             RenderText {#text} at (20,0) size 33x18
               text run at (20,0) width 33: " Text"
-caret: position 3 of child 0 {#text} of child 0 {SPAN} of child 1 {DIV} of child 0 {BLOCKQUOTE} of child 10 {DIV} of child 1 {BODY} of child 0 {HTML} of document
+caret: position 3 of child 0 {#text} of child 1 {DIV} of child 0 {BLOCKQUOTE} of child 10 {DIV} of child 1 {BODY} of child 0 {HTML} of document
index 0b434bdfeaf4ed178d799c0fe9c710714b96bdf2..dfcf6031a6b7a270f25648b0cabb81669a099d50 100644 (file)
@@ -1 +1 @@
-be0dd0567e71d7ca65d1f3971bc1e8ab
\ No newline at end of file
+16cc7c7f609fb21bb3ead24836c06afd
\ No newline at end of file
index 030c1c6b0e2121d7a194e64d9dd3648b3dc353fc..0db3b7d9a2c7de543235bc01c701acee1a1dfc2a 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/pasteboard/paste-list-001-expected.png and b/LayoutTests/platform/mac/editing/pasteboard/paste-list-001-expected.png differ
index 30feca65302f4f131966b065f66d0037ccf1e623..dcca155a165587d1d3197a5ef7b4b57991bffc9e 100644 (file)
@@ -45,4 +45,5 @@ layer at (0,0) size 800x600
                 RenderListMarker at (-31,0) size 24x28: "3"
                 RenderText {#text} at (0,0) size 211x28
                   text run at (0,0) width 211: "I should be number 3."
+            RenderBlock (anonymous) at (0,112) size 716x0
 caret: position 21 of child 0 {#text} of child 2 {LI} of child 1 {OL} of child 5 {LI} of child 4 {OL} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
index c1d916b8f1bf798d39f35a6495b03f23269b6d39..80618fdabf6b582d3d1b166e3c36703236d26bb5 100644 (file)
@@ -1 +1 @@
-15977586b524fa1983f2edca33ac179d
\ No newline at end of file
+8a3262c6ed008c4f6685ea78a6007181
\ No newline at end of file
index 7bbb0c34a49cccf5350024ec2ffed8985eead8ae..42f12725c7dac6ff3b04f58f3d839f20b0ef51a2 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/pasteboard/paste-table-001-expected.png and b/LayoutTests/platform/mac/editing/pasteboard/paste-table-001-expected.png differ
index 4cea7eaf7c3eb968cf82f08f125bd32f1d305b32..d7f6ec744d8a4f1ec42ab8412374bf9b46d66100 100644 (file)
@@ -82,4 +82,6 @@ layer at (0,0) size 800x600
                 RenderTableCell {TD} at (85,26) size 201x22 [border: (1px inset #808080)] [r=1 c=1 rs=1 cs=1]
                   RenderText {#text} at (2,2) size 197x18
                     text run at (2,2) width 197: "I should be in the right column."
+          RenderBlock (anonymous) at (0,108) size 756x0
+            RenderText {#text} at (0,0) size 0x0
 caret: position 32 of child 0 {#text} of child 1 {TD} of child 1 {TR} of child 0 {TBODY} of child 2 {TABLE} of child 3 {P} of child 1 {DIV} of child 1 {BODY} of child 0 {HTML} of document
index b0887bf86e58d0e7e8bba2e3749c29532956330f..0cd37a1e4d483d5e5240e6a09af01ce026692b1b 100644 (file)
@@ -1 +1 @@
-75d9836b9195747b9f3ddac2ae3e59a5
\ No newline at end of file
+dcb89e929b2f320f3c8febe7aaafeb07
\ No newline at end of file
index 2745a83c5caa69384d2525676e1e83fc30c5ee23..9a8b244dd408a7038ca1c9283e2c21a93747c443 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/pasteboard/paste-text-003-expected.png and b/LayoutTests/platform/mac/editing/pasteboard/paste-text-003-expected.png differ
index 40b921c7c7b262d8d44f825df20d4c02380e7943..70cc0ce982a32395da1506f68693dba233547055 100644 (file)
@@ -115,6 +115,7 @@ layer at (0,0) size 800x600
         RenderBlock {DIV} at (14,42) size 756x56 [border: (2px solid #FF0000)]
           RenderText {#text} at (14,14) size 434x28
             text run at (14,14) width 434: "Which taken at the flood leads on to fortune."
+        RenderBlock (anonymous) at (14,98) size 756x0
         RenderBlock {DIV} at (14,98) size 756x252 [border: (2px solid #FF0000)]
           RenderBlock (anonymous) at (14,14) size 728x0
           RenderBlock {DIV} at (14,14) size 728x56 [border: (2px solid #FF0000)]
@@ -126,6 +127,7 @@ layer at (0,0) size 800x600
           RenderBlock {DIV} at (14,70) size 728x56 [border: (2px solid #FF0000)]
             RenderText {#text} at (14,14) size 434x28
               text run at (14,14) width 434: "Which taken at the flood leads on to fortune."
+          RenderBlock (anonymous) at (14,126) size 728x0
           RenderBlock {DIV} at (14,126) size 728x112 [border: (2px solid #FF0000)]
             RenderBlock (anonymous) at (14,14) size 700x28
               RenderText {#text} at (0,0) size 80x28
index 1d7d06f3e5740c8ab82ef0bdd876a51d43041c34..b01f248191e37c7371faeebc3a92b597c4099fbb 100644 (file)
@@ -1 +1 @@
-ad2fb64e1da980ee74eec20e181c44d5
\ No newline at end of file
+84f6f77ad7ddecc3796b10bad7285ec7
\ No newline at end of file
index 440316e79d37d5acb2f3e282e41651e942c270f8..3b829b40bff93fa210dcb3ea27386bcbee23d58c 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/style/font-family-with-space-expected.png and b/LayoutTests/platform/mac/editing/style/font-family-with-space-expected.png differ
index f8cab3dea9486314b36661a68f4a7c4e343d269e..845f369711bbbab9a42236f25a7657afde01879d 100644 (file)
@@ -8,9 +8,8 @@ layer at (0,0) size 800x600
           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
-          RenderInline {DIV} 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 (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 0 {DIV} 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 1 {SPAN} of child 0 {SPAN} of child 0 {BODY} of child 0 {HTML} of document
index 262baf22d68dce65aaba0181707605b33235150c..8ae430ddd7143c1e9471873cf9c77b8e49b4a38f 100644 (file)
@@ -1,3 +1,46 @@
+2008-02-28  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/4930986> REGRESSION: Paste As Quotation pastes black text instead of blue
+        
+        Add a second style span at copy time to hold document default styles.  This helps us
+        differentiate between those and user applied styles at paste time, where we'll want
+        to let Mail's Paste As Quotation blockquote override document default styles, but
+        not others.
+
+        * css/CSSComputedStyleDeclaration.cpp:
+        (WebCore::CSSComputedStyleDeclaration::getPropertyCSSValue): Changed the unit type used 
+        for -webkit-text-stroke-width from CSS_NUMBER to CSS_PX, to match other properties that 
+        are thick | medium | thin | <length>.  Before, there was a mismatch between the unit 
+        type of -webkit-text-stroke-width property values in a CSSComputedStyleDeclaration for 
+        an element and that element's inlineStyleDecl(), causing identical values to always appear 
+        different to diff().
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::handlePasteAsQuotationNode): Fixed.  Don't just change
+        the class to an empty string, completely remove it, it's no longer needed.
+        (WebCore::handleStyleSpansBeforeInsertion): Moved the optimization from doApply here.
+        (WebCore::ReplaceSelectionCommand::handleStyleSpans): 
+        Added, replaces removeRedundantStyles.
+        We aren't (yet) removing all redundant styles, just those on style spans, so I removed the
+        unused code and renamed the function.
+        There won't be more than two style spans that we need to consider, the one with the 
+        source document's default styles and styles on the commonAncestor of the copied Range, 
+        so don't look for more than two.
+        Let elements that wrap the incoming fragment override the source document's styles.
+        (WebCore::ReplaceSelectionCommand::doApply): Moved code to handleStyleSpansBeforeInsertion
+        and call the renamed handleStyleSpans.
+        * editing/ReplaceSelectionCommand.h:
+        * editing/markup.cpp:
+        (WebCore::removeDefaultStyles): Added.  Don't add document defaults to the style span
+        that holds user applied styles, since they'll be added to their own style span.
+        (WebCore::createMarkup):
+        Add a second style span that holds just the document defaults. This lets us differentiate
+        between those and user applied styles at paste time.
+        Mail blockquotes are just another type of special element, moved their handling there. This
+        also lets paste code make assumptions about the position of the two style spans (they are 
+        *always* parent-child).
+
 2008-02-28  Brent Fulgham <bfulgham@gmail.com>
 
         http://bugs.webkit.org/show_bug.cgi?id=17576
index 4be202c5eacb2827823fe636188feda59e4a4de7..d848c1b82ecf1de36207c5c9b0c484d8d0279baf 100644 (file)
@@ -727,7 +727,7 @@ PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(int proper
         case CSS_PROP__WEBKIT_TEXT_STROKE_COLOR:
             return currentColorOrValidColor(style, style->textStrokeColor());
         case CSS_PROP__WEBKIT_TEXT_STROKE_WIDTH:
-            return new CSSPrimitiveValue(style->textStrokeWidth(), CSSPrimitiveValue::CSS_NUMBER);
+            return new CSSPrimitiveValue(style->textStrokeWidth(), CSSPrimitiveValue::CSS_PX);
         case CSS_PROP_TEXT_TRANSFORM:
             return new CSSPrimitiveValue(style->textTransform());
         case CSS_PROP_TOP:
index a1104806bec51fb498ac7bfbd9a00de8a1d1dbc9..1f66de4bae67eb3d63a1c60b0461d08c4f9aad7a 100644 (file)
@@ -29,6 +29,7 @@
 #include "ApplyStyleCommand.h"
 #include "BeforeTextInsertedEvent.h"
 #include "CSSComputedStyleDeclaration.h"
+#include "CSSProperty.h"
 #include "CSSPropertyNames.h"
 #include "CSSValueKeywords.h"
 #include "Document.h"
@@ -413,84 +414,11 @@ 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))
-        static_cast<Element*>(node)->setAttribute(classAttr, "");
+        removeNodeAttribute(static_cast<Element*>(node), classAttr);
 }
 
 VisiblePosition ReplaceSelectionCommand::positionAtEndOfInsertedContent()
@@ -508,6 +436,146 @@ 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();
@@ -529,7 +597,6 @@ void ReplaceSelectionCommand::doApply()
     
     bool selectionEndWasEndOfParagraph = isEndOfParagraph(visibleEnd);
     bool selectionStartWasStartOfParagraph = isStartOfParagraph(visibleStart);
-    Node* mailBlockquoteEnclosingSelectionStart = nearestMailBlockquote(visibleStart.deepEquivalent().node());
     
     Node* startBlock = enclosingBlock(visibleStart.deepEquivalent().node());
     
@@ -613,16 +680,9 @@ void ReplaceSelectionCommand::doApply()
     // FIXME: Improve typing style.
     // See this bug: <rdar://problem/3769899> Implementation of typing style needs improvement
     frame->clearTypingStyle();
-    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);
-    }
+    setTypingStyle(0);
+    
+    bool handledStyleSpans = handleStyleSpansBeforeInsertion(fragment, insertionPos);
     
     // We're finished if there is nothing to add.
     if (fragment.isEmpty() || !fragment.firstChild())
@@ -658,7 +718,8 @@ void ReplaceSelectionCommand::doApply()
     
     negateStyleRulesThatAffectAppearance();
     
-    removeRedundantStyles(mailBlockquoteEnclosingSelectionStart);
+    if (!handledStyleSpans)
+        handleStyleSpans();
     
     if (!m_firstNodeInserted)
         return;
index 679a90e140c57c69baeaacfd86f40a926940fe1d..d900c71951aec33a2ea5bc217e62137bfb26153d 100644 (file)
@@ -92,8 +92,7 @@ private:
     void removeUnrenderedTextNodesAtEnds();
     
     void negateStyleRulesThatAffectAppearance();
-    void removeRedundantStyles(Node*);
-    
+    void handleStyleSpans();
     void handlePasteAsQuotationNode();
     
     virtual void removeNodePreservingChildren(Node*);
index b15355191e92e16b795e9824c279f6fb6d7af851..4dad8ca86f0aaa09658f2685f07132b320e0989b 100644 (file)
@@ -290,6 +290,15 @@ 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.
@@ -763,6 +772,16 @@ 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();
@@ -818,6 +837,9 @@ 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()) {
@@ -828,6 +850,9 @@ 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.
@@ -836,35 +861,37 @@ String createMarkup(const Range* range, Vector<Node*>* nodes, EAnnotateForInterc
 
         if (style->length() > 0) {
             Vector<UChar> openTag;
-            const String spanClassStyle = String("<span class=\"" AppleStyleSpanClass "\" style=\"");
-            append(openTag, spanClassStyle);
+            append(openTag, styleSpanOpen);
             appendAttributeValue(openTag, style->cssText());
             openTag.append('\"');
             openTag.append('>');
             preMarkups.append(String::adopt(openTag));
             
-            static const String spanCloseTag("</span>");
-            markups.append(spanCloseTag);
+            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);
         }
     }
 
     // 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();