WebCore:
authorjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 01:33:52 +0000 (01:33 +0000)
committerjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Nov 2007 01:33:52 +0000 (01:33 +0000)
        Reviewed by Darin Adler.

        <rdar://problem/5573879> GMail Beta: Crash in when undoing Remove Formating

        In the new beta, Google has added some custom code on top of our RemoveFormat
        to work around a bug where fully selected lists aren't removed.  This code corrupts
        the undo stack and causes crashes.  This change fixes two problems with RemoveFormat
        so that Google doesn't have to have any custom code. After checking this in I'll
        work on bulletproofing the undo stack

        * WebCore.xcodeproj/project.pbxproj:
        * editing/CompositeEditCommand.cpp:
        (WebCore::CompositeEditCommand::insertLineBreak): Added this convenience method.
        (WebCore::CompositeEditCommand::inputText): Added code to select all inserted text, not
        just the last paragraph.  Added code to support an input string with '\n's.
        * editing/CompositeEditCommand.h:
        * editing/Editor.cpp:
        (WebCore::Editor::removeFormattingAndStyle): Moved code to its own EditCommand.
        * editing/RemoveFormatCommand.cpp: Added. Moved code from removeFormattingAndStyle here.
        (WebCore::RemoveFormatCommand::RemoveFormatCommand):
        (WebCore::RemoveFormatCommand::doApply): Added code to remove fully selected lists.
        * editing/RemoveFormatCommand.h: Added.
        (WebCore::RemoveFormatCommand::editingAction):

LayoutTests:

        Reviewed by Darin Adler.

        <rdar://problem/5573879> GMail Beta: Crash in when undoing Remove Formating

        Added to demonstrate fixes:
        * editing/execCommand/5573879.html: Added.
        * platform/mac/editing/execCommand/5573879-expected.checksum: Added.
        * platform/mac/editing/execCommand/5573879-expected.png: Added.
        * platform/mac/editing/execCommand/5573879-expected.txt: Added.

        Fixes (RemoveFormat now preserves the selection correctly):
        * platform/mac/editing/execCommand/4920742-1-expected.checksum:
        * platform/mac/editing/execCommand/4920742-1-expected.png:
        * platform/mac/editing/execCommand/4920742-1-expected.txt:
        * platform/mac/editing/execCommand/remove-formatting-2-expected.checksum:
        * platform/mac/editing/execCommand/remove-formatting-2-expected.png:
        * platform/mac/editing/execCommand/remove-formatting-2-expected.txt:
        * platform/mac/editing/execCommand/remove-formatting-expected.checksum:
        * platform/mac/editing/execCommand/remove-formatting-expected.png:
        * platform/mac/editing/execCommand/remove-formatting-expected.txt:

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

21 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/execCommand/5573879.html [new file with mode: 0644]
LayoutTests/platform/mac/editing/execCommand/4920742-1-expected.checksum
LayoutTests/platform/mac/editing/execCommand/4920742-1-expected.png
LayoutTests/platform/mac/editing/execCommand/4920742-1-expected.txt
LayoutTests/platform/mac/editing/execCommand/5573879-expected.checksum [new file with mode: 0644]
LayoutTests/platform/mac/editing/execCommand/5573879-expected.png [new file with mode: 0644]
LayoutTests/platform/mac/editing/execCommand/5573879-expected.txt [new file with mode: 0644]
LayoutTests/platform/mac/editing/execCommand/remove-formatting-2-expected.checksum
LayoutTests/platform/mac/editing/execCommand/remove-formatting-2-expected.png
LayoutTests/platform/mac/editing/execCommand/remove-formatting-2-expected.txt
LayoutTests/platform/mac/editing/execCommand/remove-formatting-expected.checksum
LayoutTests/platform/mac/editing/execCommand/remove-formatting-expected.png
LayoutTests/platform/mac/editing/execCommand/remove-formatting-expected.txt
WebCore/ChangeLog
WebCore/WebCore.xcodeproj/project.pbxproj
WebCore/editing/CompositeEditCommand.cpp
WebCore/editing/CompositeEditCommand.h
WebCore/editing/Editor.cpp
WebCore/editing/RemoveFormatCommand.cpp [new file with mode: 0644]
WebCore/editing/RemoveFormatCommand.h [new file with mode: 0644]

index c29d1ed83078af2f439ecb9f69b7ad8a3fc6d4e2..45fe41c02441762aac51e358c8ec01ee6a939a33 100644 (file)
@@ -1,3 +1,26 @@
+2007-11-28  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by Darin Adler.
+        
+        <rdar://problem/5573879> GMail Beta: Crash in when undoing Remove Formating
+
+        Added to demonstrate fixes:
+        * editing/execCommand/5573879.html: Added.
+        * platform/mac/editing/execCommand/5573879-expected.checksum: Added.
+        * platform/mac/editing/execCommand/5573879-expected.png: Added.
+        * platform/mac/editing/execCommand/5573879-expected.txt: Added.
+        
+        Fixes (RemoveFormat now preserves the selection correctly):
+        * platform/mac/editing/execCommand/4920742-1-expected.checksum:
+        * platform/mac/editing/execCommand/4920742-1-expected.png:
+        * platform/mac/editing/execCommand/4920742-1-expected.txt:
+        * platform/mac/editing/execCommand/remove-formatting-2-expected.checksum:
+        * platform/mac/editing/execCommand/remove-formatting-2-expected.png:
+        * platform/mac/editing/execCommand/remove-formatting-2-expected.txt:
+        * platform/mac/editing/execCommand/remove-formatting-expected.checksum:
+        * platform/mac/editing/execCommand/remove-formatting-expected.png:
+        * platform/mac/editing/execCommand/remove-formatting-expected.txt:
+
 2007-11-28  Timothy Hatcher  <timothy@apple.com>
 
         Make this test not depend on the screen size.
diff --git a/LayoutTests/editing/execCommand/5573879.html b/LayoutTests/editing/execCommand/5573879.html
new file mode 100644 (file)
index 0000000..e204d3e
--- /dev/null
@@ -0,0 +1,10 @@
+<p>This tests to make sure that RemoveFormat destroys lists if they are fully selected.  You should see foo\nbar below.</p>
+<div id="div" contenteditable="true"><ul><li>foo</li><li>bar</li></ul></div>
+
+<script>
+div = document.getElementById("div");
+div.focus();
+
+document.execCommand("SelectAll");
+document.execCommand("RemoveFormat");
+</script>
index 3865b9eef12cf363eed4266e366dcb89e302c7f2..02a9760052f6af34963ec787647e94fb926bc6c9 100644 (file)
@@ -1 +1 @@
-d105496c3dc9905b0a9c904e09d4b52b
\ No newline at end of file
+9f0c4c8dd111be7e2c2baaa771fe348a
\ No newline at end of file
index b246c628d10761548d166b9b5f2439fc82477629..8fcf677806040a6c09acd258743c2c6fca5052b1 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/execCommand/4920742-1-expected.png and b/LayoutTests/platform/mac/editing/execCommand/4920742-1-expected.png differ
index 07d590dc778e711209db57d29e689b866b6ff04e..19455d5949fd4002e9ca3d63bc07ba75db2e0a4b 100644 (file)
@@ -13,11 +13,11 @@ layer at (0,0) size 800x600
             text run at (126,18) width 185: "It should be on the last line."
       RenderBlock {DIV} at (0,52) size 784x54
         RenderBlock (anonymous) at (0,0) size 784x0
-        RenderBlock {DIV} at (0,0) size 784x18
+        RenderBlock {DIV} at (0,0) size 784x54
           RenderText {#text} at (0,0) size 21x18
             text run at (0,0) width 21: "foo"
-        RenderBlock {DIV} at (0,18) size 784x18
-          RenderBR {BR} at (0,0) size 0x18
-        RenderBlock {DIV} at (0,36) size 784x18
-          RenderBR {BR} at (0,0) size 0x18
-caret: position 0 of child 0 {BR} of child 2 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
+          RenderBR {BR} at (21,14) size 0x0
+          RenderBR {BR} at (0,18) size 0x18
+          RenderBR {BR} at (0,36) size 0x18
+selection start: position 0 of child 0 {#text} of child 0 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
+selection end:   position 1 of child 2 {BR} of child 0 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
diff --git a/LayoutTests/platform/mac/editing/execCommand/5573879-expected.checksum b/LayoutTests/platform/mac/editing/execCommand/5573879-expected.checksum
new file mode 100644 (file)
index 0000000..e22b826
--- /dev/null
@@ -0,0 +1 @@
+730cd49434a57952e12a9b5e755eb01a
\ No newline at end of file
diff --git a/LayoutTests/platform/mac/editing/execCommand/5573879-expected.png b/LayoutTests/platform/mac/editing/execCommand/5573879-expected.png
new file mode 100644 (file)
index 0000000..c99d7d5
Binary files /dev/null and b/LayoutTests/platform/mac/editing/execCommand/5573879-expected.png differ
diff --git a/LayoutTests/platform/mac/editing/execCommand/5573879-expected.txt b/LayoutTests/platform/mac/editing/execCommand/5573879-expected.txt
new file mode 100644 (file)
index 0000000..da1c527
--- /dev/null
@@ -0,0 +1,18 @@
+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 784x18
+        RenderText {#text} at (0,0) size 720x18
+          text run at (0,0) width 518: "This tests to make sure that RemoveFormat destroys lists if they are fully selected. "
+          text run at (518,0) width 202: "You should see foo\\nbar below."
+      RenderBlock {DIV} at (0,34) size 784x36
+        RenderBlock {DIV} at (0,0) size 784x36
+          RenderText {#text} at (0,0) size 21x18
+            text run at (0,0) width 21: "foo"
+          RenderBR {BR} at (21,14) size 0x0
+          RenderText {#text} at (0,18) size 20x18
+            text run at (0,18) width 20: "bar"
+selection start: position 0 of child 0 {#text} of child 0 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
+selection end:   position 3 of child 2 {#text} of child 0 {DIV} of child 2 {DIV} of child 0 {BODY} of child 0 {HTML} of document
index 655e84d92e9329e52554cd28a66fcc5516a84cef..8d040d6af2b693d88a7ce807d0cc7dd3e87c5019 100644 (file)
@@ -1 +1 @@
-c7f9b285f46f35ce44440bf13d401c6a
\ No newline at end of file
+49915c98e1df91ab8b8c33517156b618
\ No newline at end of file
index 6fd72ce1a9cf36b9ce779717d5aee96ac07b6822..102ab96a5acee9c864bb54016ad869eab2e46312 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/execCommand/remove-formatting-2-expected.png and b/LayoutTests/platform/mac/editing/execCommand/remove-formatting-2-expected.png differ
index 57eb008b6a643770701d34100c653e902dd76d14..b4478a6c7868acca8390e5c60f13f0ab306a86c4 100644 (file)
@@ -3,10 +3,7 @@ EDITING DELEGATE: webViewDidBeginEditing:WebViewDidBeginEditingNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 4 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 4 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
 layer at (0,0) size 800x600
index 35e60b5278c2a0060e610b2380ac5677cc53353b..4ac48f10c9451b15cd1cb52ad5c6fcb69793ceb0 100644 (file)
@@ -1 +1 @@
-cb32757b197564834ca7a8013b29f3e0
\ No newline at end of file
+68039019574307e193abfb66dd66fdd4
\ No newline at end of file
index 3978188b5905b4ee44b2a1b09af1cbf8ba69f203..3a023bdc9589b3c8e9c1ad3cbed2ea4335869a9d 100644 (file)
Binary files a/LayoutTests/platform/mac/editing/execCommand/remove-formatting-expected.png and b/LayoutTests/platform/mac/editing/execCommand/remove-formatting-expected.png differ
index 20f434ac8a0217211e7f6c937b4e3c2cc12b00f3..0316dafeced91304ca93656ae7645eaf796401bd 100644 (file)
@@ -4,25 +4,9 @@ EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotificatio
 EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document toDOMRange:range from 0 of #text > B > DIV > BODY > HTML > #document to 3 of #text > SPAN > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > BODY > HTML > #document to 0 of DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
+EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV > BODY > HTML > #document to 9 of #text > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
 EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
 EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:range from 11 of #text > DIV > DIV > BODY > HTML > #document to 11 of #text > DIV > DIV > BODY > HTML > #document toDOMRange:range from 0 of DIV > DIV > BODY > HTML > #document to 0 of DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: shouldChangeSelectedDOMRange:(null) toDOMRange:range from 0 of #text > DIV > DIV > BODY > HTML > #document to 9 of #text > DIV > DIV > BODY > HTML > #document affinity:NSSelectionAffinityDownstream stillSelecting:FALSE
-EDITING DELEGATE: webViewDidChangeSelection:WebViewDidChangeSelectionNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
-EDITING DELEGATE: webViewDidChange:WebViewDidChangeNotification
 layer at (0,0) size 800x600
   RenderView at (0,0) size 800x600
 layer at (0,0) size 800x600
@@ -36,15 +20,14 @@ layer at (0,0) size 800x600
             text run at (329,0) width 418: "It demonstrates a bug: everything in the editable region below"
             text run at (0,18) width 576: "should be selected, as everything was selected before Remove Format was performed."
       RenderBlock {DIV} at (0,52) size 784x54
-        RenderBlock (anonymous) at (0,0) size 784x18
-          RenderText {#text} at (0,0) size 63x18
-            text run at (0,0) width 63: "foobarbaz"
-        RenderBlock {DIV} at (0,18) size 784x18
-          RenderText {#text} at (0,0) size 71x18
-            text run at (0,0) width 71: "foo\x{9}bar\x{9}baz"
-        RenderBlock {DIV} at (0,36) size 784x18
-          RenderText {#text} at (0,0) size 63x18
-            text run at (0,0) width 63: "foobarbaz"
+        RenderText {#text} at (0,0) size 63x18
+          text run at (0,0) width 63: "foobarbaz"
+        RenderBR {BR} at (63,14) size 0x0
+        RenderText {#text} at (0,18) size 71x18
+          text run at (0,18) width 71: "foo\x{9}bar\x{9}baz"
+        RenderBR {BR} at (71,32) size 0x0
+        RenderText {#text} at (0,36) size 63x18
+          text run at (0,36) width 63: "foobarbaz"
       RenderBlock {UL} at (0,122) size 784x0
-selection start: position 0 of child 0 {#text} of child 3 {DIV} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
-selection end:   position 9 of child 0 {#text} of child 3 {DIV} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
+selection start: position 0 of child 0 {#text} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
+selection end:   position 9 of child 4 {#text} of child 2 {DIV} of child 1 {BODY} of child 0 {HTML} of document
index cfc4a2524f216ed42cba5e434beb7b4030770e4a..2ad1ce139c7750e9b7d6a876ae1488ea7be13969 100644 (file)
@@ -1,3 +1,29 @@
+2007-11-28  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/5573879> GMail Beta: Crash in when undoing Remove Formating
+        
+        In the new beta, Google has added some custom code on top of our RemoveFormat
+        to work around a bug where fully selected lists aren't removed.  This code corrupts
+        the undo stack and causes crashes.  This change fixes two problems with RemoveFormat
+        so that Google doesn't have to have any custom code. After checking this in I'll 
+        work on bulletproofing the undo stack
+
+        * WebCore.xcodeproj/project.pbxproj: 
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::insertLineBreak): Added this convenience method.
+        (WebCore::CompositeEditCommand::inputText): Added code to select all inserted text, not
+        just the last paragraph.  Added code to support an input string with '\n's.
+        * editing/CompositeEditCommand.h:
+        * editing/Editor.cpp:
+        (WebCore::Editor::removeFormattingAndStyle): Moved code to its own EditCommand.
+        * editing/RemoveFormatCommand.cpp: Added. Moved code from removeFormattingAndStyle here.
+        (WebCore::RemoveFormatCommand::RemoveFormatCommand):
+        (WebCore::RemoveFormatCommand::doApply): Added code to remove fully selected lists.
+        * editing/RemoveFormatCommand.h: Added.
+        (WebCore::RemoveFormatCommand::editingAction):
+
 2007-11-28  Dan Bernstein  <mitz@apple.com>
 
         Reviewed by Dave Hyatt.
index dcc3e494504b3d5e3b5c148ccf786af3f516af1a..27419bfba4c2737cd815513f4a3966b22fa92279 100644 (file)
                C6D74AE409AA290A000B0A52 /* ModifySelectionListLevel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */; };
                D05CED290A40BB2C00C5AF38 /* FormatBlockCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */; };
                D05CED2A0A40BB2C00C5AF38 /* FormatBlockCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */; };
+               D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */; };
+               D06C0D900CFD11460065F43F /* RemoveFormatCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D06C0D8E0CFD11460065F43F /* RemoveFormatCommand.cpp */; };
                D07DEAB90A36554A00CA30F8 /* InsertListCommand.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D07DEAB70A36554A00CA30F8 /* InsertListCommand.cpp */; };
                D07DEABA0A36554A00CA30F8 /* InsertListCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */; };
                D086FE9809D53AAB005BC74D /* UnlinkCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = D086FE9609D53AAB005BC74D /* UnlinkCommand.h */; };
                C6D74AE309AA290A000B0A52 /* ModifySelectionListLevel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ModifySelectionListLevel.cpp; sourceTree = "<group>"; };
                D05CED270A40BB2C00C5AF38 /* FormatBlockCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FormatBlockCommand.cpp; sourceTree = "<group>"; };
                D05CED280A40BB2C00C5AF38 /* FormatBlockCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FormatBlockCommand.h; sourceTree = "<group>"; };
+               D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RemoveFormatCommand.h; sourceTree = "<group>"; };
+               D06C0D8E0CFD11460065F43F /* RemoveFormatCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RemoveFormatCommand.cpp; sourceTree = "<group>"; };
                D07DEAB70A36554A00CA30F8 /* InsertListCommand.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = InsertListCommand.cpp; sourceTree = "<group>"; };
                D07DEAB80A36554A00CA30F8 /* InsertListCommand.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = InsertListCommand.h; sourceTree = "<group>"; };
                D086FE9609D53AAB005BC74D /* UnlinkCommand.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnlinkCommand.h; sourceTree = "<group>"; };
                93309D86099E64910056E581 /* editing */ = {
                        isa = PBXGroup;
                        children = (
+                               D06C0D8D0CFD11460065F43F /* RemoveFormatCommand.h */,
+                               D06C0D8E0CFD11460065F43F /* RemoveFormatCommand.cpp */,
                                ED501DC90B249F3900AE18D9 /* mac */,
                                93309D87099E64910056E581 /* AppendNodeCommand.cpp */,
                                93309D88099E64910056E581 /* AppendNodeCommand.h */,
                                93309DF8099E64920056E581 /* markup.h in Headers */,
                                93309E1E099E64920056E581 /* visible_units.h in Headers */,
                                E1BE512E0CF6C512002EA959 /* XSLTUnicodeSort.h in Headers */,
+                               D06C0D8F0CFD11460065F43F /* RemoveFormatCommand.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
                                93309DF7099E64920056E581 /* markup.cpp in Sources */,
                                93309E1D099E64920056E581 /* visible_units.cpp in Sources */,
                                E1BE512D0CF6C512002EA959 /* XSLTUnicodeSort.cpp in Sources */,
+                               D06C0D900CFD11460065F43F /* RemoveFormatCommand.cpp in Sources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index 8bbe1622250b287f3a3423818264621c7258b07a..a630d38bd766b7bd09dfb64d35b019d138cd059b 100644 (file)
@@ -40,6 +40,7 @@
 #include "HTMLNames.h"
 #include "InlineTextBox.h"
 #include "InsertIntoTextNodeCommand.h"
+#include "InsertLineBreakCommand.h"
 #include "InsertNodeBeforeCommand.h"
 #include "InsertParagraphSeparatorCommand.h"
 #include "InsertTextCommand.h"
@@ -122,6 +123,11 @@ void CompositeEditCommand::insertParagraphSeparator(bool useDefaultParagraphElem
     applyCommandToComposite(new InsertParagraphSeparatorCommand(document(), useDefaultParagraphElement));
 }
 
+void CompositeEditCommand::insertLineBreak()
+{
+    applyCommandToComposite(new InsertLineBreakCommand(document()));
+}
+
 void CompositeEditCommand::insertNodeBefore(Node* insertChild, Node* refChild)
 {
     ASSERT(!refChild->hasTagName(bodyTag));
@@ -262,9 +268,29 @@ void CompositeEditCommand::joinTextNodes(Text *text1, Text *text2)
 
 void CompositeEditCommand::inputText(const String &text, bool selectInsertedText)
 {
-    RefPtr<InsertTextCommand> command = new InsertTextCommand(document());
-    applyCommandToComposite(command);
-    command->input(text, selectInsertedText);
+    int offset = 0;
+    int length = text.length();
+    RefPtr<Range> startRange = new Range(document(), Position(document()->documentElement(), 0), endingSelection().start());
+    int startIndex = TextIterator::rangeLength(startRange.get());
+    int newline;
+    do {
+        newline = text.find('\n', offset);
+        if (newline != offset) {
+            RefPtr<InsertTextCommand> command = new InsertTextCommand(document());
+            applyCommandToComposite(command);
+            int substringLength = newline == -1 ? length - offset : newline - offset;
+            command->input(text.substring(offset, substringLength), false);
+        }
+        if (newline != -1)
+            insertLineBreak();
+            
+        offset = newline + 1;
+    } while (newline != -1 && offset != length);
+    
+    if (selectInsertedText) {
+        RefPtr<Range> selectedRange = TextIterator::rangeFromLocationAndLength(document()->documentElement(), startIndex, length);
+        setEndingSelection(Selection(selectedRange.get()));
+    }
 }
 
 void CompositeEditCommand::insertTextIntoNode(Text *node, int offset, const String &text)
index 23e7f71390126e59ac475d26200db574ae389845..e099fcfdf6c4974a1f09170994c4edfd9853f690 100644 (file)
@@ -58,6 +58,7 @@ protected:
     void insertNodeAt(Node* insertChild, const Position&);
     void insertNodeBefore(Node* insertChild, Node* refChild);
     void insertParagraphSeparator(bool useDefaultParagraphElement = false);
+    void insertLineBreak();
     void insertTextIntoNode(Text* node, int offset, const String& text);
     void joinTextNodes(Text*, Text*);
     void rebalanceWhitespace();
index d2c2035f992dab21be4f71ed0c8e8b52d730d74e..de27ff55b237e6dbe6066817825c5b4011581315 100644 (file)
@@ -61,6 +61,7 @@
 #include "Page.h"
 #include "Pasteboard.h"
 #include "Range.h"
+#include "RemoveFormatCommand.h"
 #include "ReplaceSelectionCommand.h"
 #include "SelectionController.h"
 #include "Sound.h"
@@ -581,27 +582,7 @@ void Editor::decreaseSelectionListLevel()
 
 void Editor::removeFormattingAndStyle()
 {
-    Document* document = m_frame->document();
-    
-    // Make a plain text string from the selection to remove formatting like tables and lists.
-    String string = plainText(m_frame->selectionController()->selection().toRange().get());
-
-    // Get the default style for this editable root, it's the style that we'll give the
-    // content that we're operating on.
-    Node* root = m_frame->selectionController()->rootEditableElement();
-    RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(root);
-    RefPtr<CSSMutableStyleDeclaration> defaultStyle = computedStyle->copyInheritableProperties();
-    
-    // Delete the selected content.
-    // FIXME: We should be able to leave this to insertText, but its delete operation
-    // doesn't preserve the style we're about to set.
-    deleteSelectionWithSmartDelete(false);
-    // Normally, deleting a fully selected anchor and then inserting text will re-create
-    // the removed anchor, but we don't want that behavior here. 
-    setRemovedAnchor(0);
-    // Insert the content with the default style.
-    m_frame->setTypingStyle(defaultStyle.get());
-    TypingCommand::insertText(document, string, true);
+    applyCommand(new RemoveFormatCommand(m_frame->document()));
 }
 
 void Editor::setLastEditCommand(PassRefPtr<EditCommand> lastEditCommand) 
diff --git a/WebCore/editing/RemoveFormatCommand.cpp b/WebCore/editing/RemoveFormatCommand.cpp
new file mode 100644 (file)
index 0000000..57f526a
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2007 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#include "config.h"
+#include "RemoveFormatCommand.h"
+
+#include "CSSComputedStyleDeclaration.h"
+#include "Editor.h"
+#include "Frame.h"
+#include "HTMLNames.h"
+#include "Selection.h"
+#include "SelectionController.h"
+#include "TextIterator.h"
+#include "TypingCommand.h"
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+RemoveFormatCommand::RemoveFormatCommand(Document* document)
+    : CompositeEditCommand(document)
+{
+}
+
+void RemoveFormatCommand::doApply()
+{
+    Frame* frame = document()->frame();
+    
+    // Make a plain text string from the selection to remove formatting like tables and lists.
+    String string = plainText(frame->selectionController()->selection().toRange().get());
+
+    // Get the default style for this editable root, it's the style that we'll give the
+    // content that we're operating on.
+    Node* root = frame->selectionController()->rootEditableElement();
+    RefPtr<CSSComputedStyleDeclaration> computedStyle = new CSSComputedStyleDeclaration(root);
+    RefPtr<CSSMutableStyleDeclaration> defaultStyle = computedStyle->copyInheritableProperties();
+    
+    // Delete the selected content.
+    // FIXME: We should be able to leave this to insertText, but its delete operation
+    // doesn't preserve the style we're about to set.
+    deleteSelection();
+    
+    // Delete doesn't remove fully selected lists.
+    while (breakOutOfEmptyListItem())
+        ;
+    
+    // Normally, deleting a fully selected anchor and then inserting text will re-create
+    // the removed anchor, but we don't want that behavior here. 
+    frame->editor()->setRemovedAnchor(0);
+    // Insert the content with the default style.
+    frame->setTypingStyle(defaultStyle.get());
+    
+    inputText(string, true);
+}
+
+}
diff --git a/WebCore/editing/RemoveFormatCommand.h b/WebCore/editing/RemoveFormatCommand.h
new file mode 100644 (file)
index 0000000..a6df271
--- /dev/null
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2007 Apple Computer, Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef RemoveFormatCommand_h
+#define RemoveFormatCommand_h
+
+#include "CompositeEditCommand.h"
+
+namespace WebCore {
+
+class RemoveFormatCommand : public CompositeEditCommand {
+public:
+    RemoveFormatCommand(Document*);
+    virtual void doApply();
+    virtual EditAction editingAction() const { return EditActionUnspecified; }
+};
+
+} // namespace WebCore
+
+#endif // RemoveFormatCommand_h