Reviewed by Darin
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Oct 2004 21:19:35 +0000 (21:19 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 21 Oct 2004 21:19:35 +0000 (21:19 +0000)
        Significant improvement to the way that whitespace is handled during editing.

        * khtml/editing/htmlediting.cpp:
        (khtml::CompositeEditCommand::deleteInsignificantText): New functions (there are actually
        two being added with this name) that delete "insignificant" unrendered text.
        (khtml::CompositeEditCommand::deleteInsignificantTextDownstream): Takes a position,
        calculates the downstream position to use as the endpoint for the deletion, and
        then calls deleteInsignificantText with this start and end.
        (khtml::DeleteSelectionCommand::doApply): Call new deleteInsignificantTextDownstream function.
        (khtml::InputNewlineCommand::doApply): Ditto.
        (khtml::InputTextCommand::input): Ditto.
        * khtml/editing/htmlediting.h: Add new declarations.

        Modified layout test results:
        * layout-tests/editing/deleting/delete-block-merge-contents-016-expected.txt:
        * layout-tests/editing/deleting/delete-block-merge-contents-017-expected.txt:
        * layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt:
        * layout-tests/editing/deleting/delete-selection-001-expected.txt:
        * layout-tests/editing/deleting/delete-tab-001-expected.txt:
        * layout-tests/editing/deleting/delete-tab-004-expected.txt:
        * layout-tests/editing/deleting/delete-trailing-ws-001-expected.txt:
        * layout-tests/editing/inserting/insert-3659587-fix-expected.txt:
        * layout-tests/editing/inserting/insert-3775316-fix-expected.txt:
        * layout-tests/editing/inserting/insert-3778059-fix-expected.txt:
        * layout-tests/editing/inserting/insert-br-001-expected.txt:
        * layout-tests/editing/inserting/insert-br-004-expected.txt:
        * layout-tests/editing/inserting/insert-br-005-expected.txt:
        * layout-tests/editing/inserting/insert-br-006-expected.txt:
        * layout-tests/editing/inserting/insert-tab-001-expected.txt:
        * layout-tests/editing/inserting/insert-tab-002-expected.txt:
        * layout-tests/editing/inserting/insert-tab-004-expected.txt:
        * layout-tests/editing/inserting/insert-text-with-newlines-expected.txt:
        * layout-tests/editing/inserting/typing-001-expected.txt:
        * layout-tests/editing/inserting/typing-around-br-001-expected.txt:
        * layout-tests/editing/inserting/typing-around-image-001-expected.txt:
        * layout-tests/editing/style/typing-style-003-expected.txt:
        * layout-tests/editing/undo/redo-typing-001-expected.txt:
        * layout-tests/editing/undo/undo-typing-001-expected.txt:

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

27 files changed:
LayoutTests/editing/deleting/delete-block-merge-contents-016-expected.txt
LayoutTests/editing/deleting/delete-block-merge-contents-017-expected.txt
LayoutTests/editing/deleting/delete-contiguous-ws-001-expected.txt
LayoutTests/editing/deleting/delete-selection-001-expected.txt
LayoutTests/editing/deleting/delete-tab-001-expected.txt
LayoutTests/editing/deleting/delete-tab-004-expected.txt
LayoutTests/editing/deleting/delete-trailing-ws-001-expected.txt
LayoutTests/editing/inserting/insert-3659587-fix-expected.txt
LayoutTests/editing/inserting/insert-3775316-fix-expected.txt
LayoutTests/editing/inserting/insert-3778059-fix-expected.txt
LayoutTests/editing/inserting/insert-br-001-expected.txt
LayoutTests/editing/inserting/insert-br-004-expected.txt
LayoutTests/editing/inserting/insert-br-005-expected.txt
LayoutTests/editing/inserting/insert-br-006-expected.txt
LayoutTests/editing/inserting/insert-tab-001-expected.txt
LayoutTests/editing/inserting/insert-tab-002-expected.txt
LayoutTests/editing/inserting/insert-tab-004-expected.txt
LayoutTests/editing/inserting/insert-text-with-newlines-expected.txt
LayoutTests/editing/inserting/typing-001-expected.txt
LayoutTests/editing/inserting/typing-around-br-001-expected.txt
LayoutTests/editing/inserting/typing-around-image-001-expected.txt
LayoutTests/editing/style/typing-style-003-expected.txt
LayoutTests/editing/undo/redo-typing-001-expected.txt
LayoutTests/editing/undo/undo-typing-001-expected.txt
WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp
WebCore/khtml/editing/htmlediting.h

index 6cbd531e7d29aa6aac52a557ab0c46d1364acfbc..c2fa680355c0c7b20b389de29c36a646bf408872 100644 (file)
@@ -9,9 +9,7 @@ layer at (0,0) size 800x600
             RenderText {TEXT} at (0,0) size 65x28
               text run at (0,0) width 65: "This is"
             RenderText {TEXT} at (65,0) size 106x28
-              text run at (65,0) width 6: " "
-              text run at (71,0) width 100: "some text."
-            RenderBR {BR} at (0,0) size 0x0
+              text run at (65,0) width 106: " some text."
 selection is CARET:
 start:      position 7 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
 upstream:   position 7 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
index 989911dfcb6841e479bcdcad15535cef3d42d27e..ae3afe6195e6ecf65f17d1debe6631fa0ddbf89d 100644 (file)
@@ -13,4 +13,4 @@ layer at (0,0) size 800x600
 selection is CARET:
 start:      position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
 upstream:   position 8 of child 1 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
-downstream: position 7 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
+downstream: position 0 of child 2 {TEXT} of child 1 {DIV} of child 2 {DIV} of root {DIV}
index eb3055516e21bf9a0c672c8460b3b9fae7e747f9..305c95b91461d9dacf344b84dc4586c1a76576d3 100644 (file)
@@ -6,10 +6,9 @@ layer at (0,0) size 800x600
       RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
         RenderInline {SPAN} at (0,0) size 78x28
           RenderText {TEXT} at (14,14) size 78x28
-            text run at (14,14) width 38: "foo "
-            text run at (52,14) width 40: " baz"
+            text run at (14,14) width 78: "foo  baz"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
 upstream:   position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
-downstream: position 8 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
index 717d6d585fb462d151bd6ce6698f331dd5746688..55ace4b54ec0645285e257fab8e39a1c47cf2111 100644 (file)
@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
             text run at (57,14) width 34: "baz"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
 upstream:   position 0 of  of root {DIV}
-downstream: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
index 01c6cce20ca35263906c4fb61ba2956883f0ceee..e6160cbb73a7e0d328ed2e3fe195d83cc8b3fe14 100644 (file)
@@ -9,6 +9,6 @@ layer at (0,0) size 800x600
             text run at (14,14) width 56: "    foo"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
index fd45c3b0e9d0456cde76f53e60984374d7dbb7df..9080dafc118659ee1a8d0c87402b5fe60988d627 100644 (file)
@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
             text run at (14,42) width 56: "    foo"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
index 717d6d585fb462d151bd6ce6698f331dd5746688..55ace4b54ec0645285e257fab8e39a1c47cf2111 100644 (file)
@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
             text run at (57,14) width 34: "baz"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
 upstream:   position 0 of  of root {DIV}
-downstream: position 2 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+downstream: position 0 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
index 062df42a1adb0de558dbcd8bee44fa8712d68632..6ac228a8291a6eedd4f9ded14f352b614f9f91fc 100644 (file)
@@ -12,7 +12,8 @@ layer at (0,0) size 800x600
             RenderText {TEXT} at (14,42) size 36x28
               text run at (14,42) width 36: "xxx"
             RenderBR {BR} at (0,0) size 0x0
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 3 of child 3 {TEXT} of child 1 {B} of child 1 {SPAN} of root {DIV}
-upstream:   position 3 of child 3 {TEXT} of child 1 {B} of child 1 {SPAN} of root {DIV}
-downstream: position 0 of child 4 {BR} of child 1 {B} of child 1 {SPAN} of root {DIV}
+start:      position 3 of child 3 {TEXT} of child 1 {B} of child 2 {SPAN} of root {DIV}
+upstream:   position 3 of child 3 {TEXT} of child 1 {B} of child 2 {SPAN} of root {DIV}
+downstream: position 0 of child 4 {BR} of child 1 {B} of child 2 {SPAN} of root {DIV}
index 6631dda68c846574817c96ad937dc2e3417f1c97..0ebe4539a2532fd7ae7be59fdc19853b0d3077ae 100644 (file)
@@ -11,6 +11,7 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (14,42) size 12x28
             text run at (14,42) width 12: "x"
           RenderBR {BR} at (0,0) size 0x0
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 1 of child 3 {TEXT} of child 1 {SPAN} of root {DIV}
 upstream:   position 1 of child 3 {TEXT} of child 1 {SPAN} of root {DIV}
index 13c63488320cd053d903ba3850c56a3cf9c534b5..a57cb5bdf3c3c07ad8be65e155a34a843b759dcc 100644 (file)
@@ -16,6 +16,6 @@ layer at (0,0) size 800x600
             RenderText {TEXT} at (0,0) size 42x28
               text run at (0,0) width 42: "Test"
 selection is CARET:
-start:      position 1 of child 2 {TEXT} of child 2 {DIV} of root {DIV}
-upstream:   position 1 of child 2 {TEXT} of child 2 {DIV} of root {DIV}
-downstream: position 0 of child 3 {BR} of child 2 {DIV} of root {DIV}
+start:      position 1 of child 3 {TEXT} of child 2 {DIV} of root {DIV}
+upstream:   position 1 of child 3 {TEXT} of child 2 {DIV} of root {DIV}
+downstream: position 0 of child 4 {BR} of child 2 {DIV} of root {DIV}
index 5ae04d2032e1e51df730f1ce20285adb71ffc777..20ddba13a1ebab3420303c9c7c9ed60beb1f5acc 100644 (file)
@@ -11,6 +11,7 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (14,42) size 12x28
             text run at (14,42) width 12: "x"
           RenderBR {BR} at (0,0) size 0x0
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
 upstream:   position 1 of child 3 {TEXT} of child 2 {SPAN} of root {DIV}
index e1ce1681ee42dc546a531220dee98a6d5041e688..7042ad9a958befa03d761b3f82b23252bb377523 100644 (file)
@@ -10,6 +10,7 @@ layer at (0,0) size 800x600
           RenderBR {BR} at (0,0) size 0x0
           RenderBR {BR} at (14,42) size 0x28
           RenderBR {BR} at (14,70) size 0x28
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 0 of child 4 {BR} of child 2 {SPAN} of root {DIV}
 upstream:   position 1 of child 3 {BR} of child 2 {SPAN} of root {DIV}
index 9c45694e28e0cdf97c8450d6974f6e89cfb7da39..ac887a6ad63e2d19364472aec3d4294a4c996f8b 100644 (file)
@@ -12,6 +12,7 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (14,70) size 12x28
             text run at (14,70) width 12: "x"
           RenderBR {BR} at (0,0) size 0x0
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 1 of child 4 {TEXT} of child 2 {SPAN} of root {DIV}
 upstream:   position 1 of child 4 {TEXT} of child 2 {SPAN} of root {DIV}
index bbedced08d9e9f5e67cbba3713f3cefa6eed5bc6..e02770af6b092703ee8edcb31dc22b49b931a670 100644 (file)
@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
             text run at (14,42) width 44: "xfoo"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 1 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 1 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 1 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 1 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 1 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
index 01c6cce20ca35263906c4fb61ba2956883f0ceee..e6160cbb73a7e0d328ed2e3fe195d83cc8b3fe14 100644 (file)
@@ -9,6 +9,6 @@ layer at (0,0) size 800x600
             text run at (14,14) width 56: "    foo"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 4 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
index c35ba45969574daf37a599ebe1c112c8afb5b5e8..7851bb6f794c09ead9129477e2067877e4b69848 100644 (file)
@@ -7,7 +7,8 @@ layer at (0,0) size 800x600
         RenderInline {SPAN} at (0,0) size 56x28
           RenderText {TEXT} at (14,14) size 56x28
             text run at (14,14) width 56: "foo    "
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 7 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
 upstream:   position 7 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
-downstream: position 7 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 3 {TEXT} of root {DIV}
index fd45c3b0e9d0456cde76f53e60984374d7dbb7df..9080dafc118659ee1a8d0c87402b5fe60988d627 100644 (file)
@@ -10,6 +10,6 @@ layer at (0,0) size 800x600
             text run at (14,42) width 56: "    foo"
         RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 4 of child 2 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 4 of child 2 {TEXT} of child 2 {SPAN} of root {DIV}
index d4d72cada98ceef4a8cd72bb5dc5ecdc5b7b9cb5..643e56bdf50617c825f272f24bb3555e407809ad 100644 (file)
@@ -15,9 +15,10 @@ layer at (0,0) size 800x600
             text run at (47,42) width 42: " xxx"
           RenderBR {BR} at (0,0) size 0x0
           RenderBR {BR} at (14,70) size 0x28
-          RenderText {TEXT} at (14,98) size 76x28
-            text run at (14,98) width 76: " bazxxx"
+          RenderText {TEXT} at (14,98) size 70x28
+            text run at (14,98) width 70: "bazxxx"
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 7 of child 7 {TEXT} of child 2 {SPAN} of root {DIV}
-upstream:   position 7 of child 7 {TEXT} of child 2 {SPAN} of root {DIV}
-downstream: position 7 of child 7 {TEXT} of child 2 {SPAN} of root {DIV}
+start:      position 6 of child 7 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 6 of child 7 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 3 {TEXT} of root {DIV}
index bd95d4a7f07a0fd82d95535a81d1a5d98f399a14..bf713c0c7f73d07d6baa421b077ffbed8c98bbbb 100644 (file)
@@ -7,7 +7,8 @@ layer at (0,0) size 800x600
         RenderInline {SPAN} at (0,0) size 176x28
           RenderText {TEXT} at (14,14) size 176x28
             text run at (14,14) width 176: "xxxXXxxxXXxxx"
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
-start:      position 13 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 13 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 13 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 13 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 13 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 3 {TEXT} of root {DIV}
index 10a2a688cb5a7c863be09744d9937ddc5ad6fa59..08301047f87603b44da1480e20a1dd332d332d15 100644 (file)
@@ -28,7 +28,8 @@ layer at (0,0) size 800x600
           RenderBR {BR} at (0,0) size 0x0
           RenderText {TEXT} at (14,210) size 70x28
             text run at (14,210) width 70: "XXxxx"
+        RenderText {TEXT} at (0,0) size 0x0
 selection is CARET:
 start:      position 5 of child 15 {TEXT} of child 2 {SPAN} of root {DIV}
 upstream:   position 5 of child 15 {TEXT} of child 2 {SPAN} of root {DIV}
-downstream: position 5 of child 15 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 3 {TEXT} of root {DIV}
index 306b602704233b327e9b578e57e0687d2a287c8f..19a7b457d122577a04b278f910bb04259bff66fd 100644 (file)
@@ -19,6 +19,6 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (368,95) size 36x28
             text run at (368,95) width 36: "xxx"
 selection is CARET:
-start:      position 3 of child 8 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 3 of child 8 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 3 of child 8 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 3 of child 8 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 3 of child 8 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 3 of child 8 {TEXT} of child 2 {SPAN} of root {DIV}
index 3c787019ef60d620dea2459d1ea97c242f75eb5a..bdab017119951837dd496098527f2cf2449130ba 100644 (file)
@@ -5,6 +5,7 @@ layer at (0,0) size 800x600
     RenderBody {BODY} at (8,8) size 784x584
       RenderBlock {DIV} at (0,0) size 784x56 [border: (2px solid #FF0000)]
         RenderInline {SPAN} at (0,0) size 0x0
+        RenderText {TEXT} at (0,0) size 0x0
         RenderText {TEXT} at (14,14) size 36x28
           text run at (14,14) width 36: "xxx"
         RenderInline {B} at (0,0) size 141x28
@@ -20,6 +21,6 @@ layer at (0,0) size 800x600
                 RenderText {TEXT} at (155,14) size 36x28
                   text run at (155,14) width 36: "xxx"
 selection is CARET:
-start:      position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 3 {B} of root {DIV}
-upstream:   position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 3 {B} of root {DIV}
-downstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 3 {B} of root {DIV}
+start:      position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of root {DIV}
+upstream:   position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of root {DIV}
+downstream: position 3 of child 1 {TEXT} of child 2 {SPAN} of child 2 {SPAN} of child 2 {I} of child 5 {B} of root {DIV}
index da8a0a9c45887c9a0c001dd38fd369ed7bac6665..fadffa918c7aec786e30c13271b4550bdbc99f19 100644 (file)
@@ -8,6 +8,6 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (14,14) size 46x28
             text run at (14,14) width 46: "xXX"
 selection is CARET:
-start:      position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
index da8a0a9c45887c9a0c001dd38fd369ed7bac6665..fadffa918c7aec786e30c13271b4550bdbc99f19 100644 (file)
@@ -8,6 +8,6 @@ layer at (0,0) size 800x600
           RenderText {TEXT} at (14,14) size 46x28
             text run at (14,14) width 46: "xXX"
 selection is CARET:
-start:      position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-upstream:   position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
-downstream: position 1 of child 1 {TEXT} of child 1 {SPAN} of root {DIV}
+start:      position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+upstream:   position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
+downstream: position 1 of child 1 {TEXT} of child 2 {SPAN} of root {DIV}
index 941dff0df0a70cc50032d0124e36c0a663f0f839..a8ce58e13d52717713228138f77c420da5f9b070 100644 (file)
@@ -1,3 +1,46 @@
+2004-10-21  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by Darin
+        
+        Significant improvement to the way that whitespace is handled during editing.
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::CompositeEditCommand::deleteInsignificantText): New functions (there are actually
+        two being added with this name) that delete "insignificant" unrendered text.
+        (khtml::CompositeEditCommand::deleteInsignificantTextDownstream): Takes a position,
+        calculates the downstream position to use as the endpoint for the deletion, and
+        then calls deleteInsignificantText with this start and end.
+        (khtml::DeleteSelectionCommand::doApply): Call new deleteInsignificantTextDownstream function.
+        (khtml::InputNewlineCommand::doApply): Ditto.
+        (khtml::InputTextCommand::input): Ditto.
+        * khtml/editing/htmlediting.h: Add new declarations.
+        
+        Modified layout test results:
+        * layout-tests/editing/deleting/delete-block-merge-contents-016-expected.txt:
+        * layout-tests/editing/deleting/delete-block-merge-contents-017-expected.txt:
+        * layout-tests/editing/deleting/delete-contiguous-ws-001-expected.txt:
+        * layout-tests/editing/deleting/delete-selection-001-expected.txt:
+        * layout-tests/editing/deleting/delete-tab-001-expected.txt:
+        * layout-tests/editing/deleting/delete-tab-004-expected.txt:
+        * layout-tests/editing/deleting/delete-trailing-ws-001-expected.txt:
+        * layout-tests/editing/inserting/insert-3659587-fix-expected.txt:
+        * layout-tests/editing/inserting/insert-3775316-fix-expected.txt:
+        * layout-tests/editing/inserting/insert-3778059-fix-expected.txt:
+        * layout-tests/editing/inserting/insert-br-001-expected.txt:
+        * layout-tests/editing/inserting/insert-br-004-expected.txt:
+        * layout-tests/editing/inserting/insert-br-005-expected.txt:
+        * layout-tests/editing/inserting/insert-br-006-expected.txt:
+        * layout-tests/editing/inserting/insert-tab-001-expected.txt:
+        * layout-tests/editing/inserting/insert-tab-002-expected.txt:
+        * layout-tests/editing/inserting/insert-tab-004-expected.txt:
+        * layout-tests/editing/inserting/insert-text-with-newlines-expected.txt:
+        * layout-tests/editing/inserting/typing-001-expected.txt:
+        * layout-tests/editing/inserting/typing-around-br-001-expected.txt:
+        * layout-tests/editing/inserting/typing-around-image-001-expected.txt:
+        * layout-tests/editing/style/typing-style-003-expected.txt:
+        * layout-tests/editing/undo/redo-typing-001-expected.txt:
+        * layout-tests/editing/undo/undo-typing-001-expected.txt:
+
 2004-10-21  David Hyatt  <hyatt@apple.com>
 
        Fix for 3847054, assertion failure in RenderText::layout() on news.com page.  Fix getInlineRun so that
index 442acbba3ba58247b8182b655f0081b15fc75146..9b330d5d9e67d9d33316d1c47d1083f43d49affb 100644 (file)
@@ -759,49 +759,93 @@ NodeImpl *CompositeEditCommand::applyTypingStyle(NodeImpl *child) const
     return childToAppend;
 }
 
-void CompositeEditCommand::deleteUnrenderedText(NodeImpl *node)
+void CompositeEditCommand::deleteInsignificantText(TextImpl *textNode, int start, int end)
 {
-    if (!node)
+    if (!textNode || !textNode->renderer() || start >= end)
         return;
 
-    if (node->isTextNode()) {
-        if (!node->renderer() || !static_cast<RenderText *>(node->renderer())->firstTextBox())
-            removeNode(node);
-        else {
-            TextImpl *text = static_cast<TextImpl *>(node);
-            if (text->caretMinOffset() > 0)
-                deleteText(text, 0, text->caretMinOffset());
-            if ((int)text->length() > text->caretMaxOffset())
-                deleteText(text, text->caretMaxOffset(), text->length() - text->caretMaxOffset());
+    RenderText *textRenderer = static_cast<RenderText *>(textNode->renderer());
+    InlineTextBox *box = textRenderer->firstTextBox();
+    if (!box) {
+        // whole text node is empty
+        removeNode(textNode);
+        return;    
+    }
+    
+    long length = textNode->length();
+    if (start >= length || end > length)
+        return;
+
+    int removed = 0;
+    InlineTextBox *prevBox = 0;
+    DOMStringImpl *str = 0;
+
+    // This loop structure works to process all gaps preceding a box,
+    // and also will look at the gap after the last box.
+    while (prevBox || box) {
+        int gapStart = prevBox ? prevBox->m_start + prevBox->m_len : 0;
+        if (end < gapStart)
+            // No more chance for any intersections
+            break;
+
+        int gapEnd = box ? box->m_start : length;
+        bool indicesIntersect = start <= gapEnd && end >= gapStart;
+        int gapLen = gapEnd - gapStart;
+        if (indicesIntersect && gapLen > 0) {
+            gapStart = kMax(gapStart, start);
+            gapEnd = kMin(gapEnd, end);
+            if (!str) {
+                str = textNode->string()->substring(start, end - start);
+                str->ref();
+            }    
+            // remove text in the gap
+            str->remove(gapStart - start - removed, gapLen);
+            removed += gapLen;
         }
+        
+        prevBox = box;
+        if (box)
+            box = box->nextTextBox();
+    }
+
+    if (str) {
+        // Replace the text between start and end with our pruned version.
+        replaceText(textNode, start, end - start, str);
+        str->deref();
     }
 }
 
-void CompositeEditCommand::deleteUnrenderedText(const Position &pos)
+void CompositeEditCommand::deleteInsignificantText(const Position &start, const Position &end)
 {
-    if (pos.isNull())
+    if (start.isNull() || end.isNull())
         return;
 
-    Position upstream = pos.upstream(StayInBlock);
-    Position downstream = pos.downstream(StayInBlock);
-    Position block = Position(pos.node()->enclosingBlockFlowElement(), 0);
-    
-    NodeImpl *node = upstream.node();
-    while (node && node != downstream.node()) {
+    if (RangeImpl::compareBoundaryPoints(start.node(), start.offset(), end.node(), end.offset()) >= 0)
+        return;
+
+    NodeImpl *node = start.node();
+    while (node) {
         NodeImpl *next = node->traverseNextNode();
-        deleteUnrenderedText(node);
+    
+        if (node->isTextNode()) {
+            TextImpl *textNode = static_cast<TextImpl *>(node);
+            bool isStartNode = node == start.node();
+            bool isEndNode = node == end.node();
+            int startOffset = isStartNode ? start.offset() : 0;
+            int endOffset = isEndNode ? end.offset() : textNode->length();
+            deleteInsignificantText(textNode, startOffset, endOffset);
+        }
+            
+        if (node == end.node())
+            break;
         node = next;
     }
-    deleteUnrenderedText(downstream.node());
-    
-    if (pos.node()->inDocument())
-        setEndingSelection(pos);
-    else if (upstream.node()->inDocument())
-        setEndingSelection(upstream);
-    else if (downstream.node()->inDocument())
-        setEndingSelection(downstream);
-    else
-        setEndingSelection(block);
+}
+
+void CompositeEditCommand::deleteInsignificantTextDownstream(const DOM::Position &pos)
+{
+    Position end = VisiblePosition(pos).next().deepEquivalent().downstream(StayInBlock);
+    deleteInsignificantText(pos, end);
 }
 
 void CompositeEditCommand::insertBlockPlaceholderIfNeeded(NodeImpl *node)
@@ -1284,6 +1328,9 @@ void DeleteSelectionCommand::doApply()
     Position leading = upstreamStart.leadingWhitespacePosition();
     Position trailing = downstreamEnd.trailingWhitespacePosition();
     bool trailingValid = true;
+
+    // Delete any text that may hinder our ability to fixup whitespace after the detele
+    deleteInsignificantTextDownstream(trailing);    
     
     debugPosition("upstreamStart    ", upstreamStart);
     debugPosition("downstreamStart  ", downstreamStart);
@@ -1310,25 +1357,16 @@ void DeleteSelectionCommand::doApply()
     CSSStyleDeclarationImpl *style = computedStyle->copyInheritableProperties();
     style->ref();
     computedStyle->deref();
-    
-    if (startBlock != endBlock) {
-        // Delete some unrendered whitespace. This prepares the startBlock to
-        // receive content that will be merged from endBlock. Do this before 
-        // deleting, since deleting content can alter the notion of what 
-        // should collapse away.
-        // stay in this block and delete unrenderered text from the upstreamStart location
-        deleteUnrenderedText(upstreamStart);
-        Position upstreamInPreviousBlock(upstreamStart.upstream()); // Note no StayInBlock on upstream call.
-        if (upstreamInPreviousBlock != upstreamStart)
-            // cross blocks and delete unrenderered text from the upstream
-            // position in startBlock. 
-            deleteUnrenderedText(upstreamInPreviousBlock);
-    }
 
     NodeImpl *startNode = upstreamStart.node();
     int startOffset = upstreamStart.offset();
     if (startOffset >= startNode->caretMaxOffset()) {
-        // None of the first node is to be deleted, so move to next.
+        if (startNode->isTextNode()) {
+            // Delete any insignificant text from this node.
+            TextImpl *text = static_cast<TextImpl *>(startNode);
+            if (text->length() > (unsigned)startNode->caretMaxOffset())
+                deleteText(text, startNode->caretMaxOffset(), text->length() - startNode->caretMaxOffset());
+        }
         startNode = startNode->traverseNextNode();
         startOffset = 0;
     }
@@ -1430,18 +1468,13 @@ void DeleteSelectionCommand::doApply()
     // Perform whitespace fixup
     FixupWhitespace:
 
-    if (leading.isNotNull() || trailing.isNotNull())
-        document()->updateLayout();
-
-    debugPosition("endingPosition   ", endingPosition);
-    
-    if (leading.isNotNull() && !leading.isRenderedCharacter()) {
+    document()->updateLayout();
+    if (leading.isNotNull() && (trailing.isNotNull() || !leading.isRenderedCharacter())) {
         LOG(Editing, "replace leading");
         TextImpl *textNode = static_cast<TextImpl *>(leading.node());
         replaceText(textNode, leading.offset(), 1, nonBreakingSpaceString());
     }
-
-    if (trailing.isNotNull()) {
+    else if (trailing.isNotNull()) {
         if (trailingValid) {
             if (!trailing.isRenderedCharacter()) {
                 LOG(Editing, "replace trailing [valid]");
@@ -1461,6 +1494,8 @@ void DeleteSelectionCommand::doApply()
         }
     }
 
+    debugPosition("endingPosition   ", endingPosition);
+
     // If the delete emptied a block, add in a placeholder so the block does not
     // seem to disappear.
     insertBlockPlaceholderIfNeeded(endingPosition.node());
@@ -1573,8 +1608,6 @@ void InputNewlineCommand::insertNodeBeforePosition(NodeImpl *node, const Positio
 void InputNewlineCommand::doApply()
 {
     deleteSelection();
-    deleteUnrenderedText(endingSelection().start());
-    
     Selection selection = endingSelection();
 
     int exceptionCode = 0;
@@ -1641,10 +1674,6 @@ void InputNewlineCommand::doApply()
         LOG(Editing, "input newline case 4");
         ASSERT(pos.node()->isTextNode());
         
-        // See if there is trailing whitespace we need to consider
-        // Note: leading whitespace just works. Blame the web.
-        Position trailing = pos.downstream(StayInBlock).trailingWhitespacePosition();
-
         // Do the split
         TextImpl *textNode = static_cast<TextImpl *>(pos.node());
         TextImpl *textBeforeNode = document()->createTextNode(textNode->substringData(0, selection.start().offset(), exceptionCode));
@@ -1655,9 +1684,9 @@ void InputNewlineCommand::doApply()
         
         // Handle whitespace that occurs after the split
         document()->updateLayout();
-        if (trailing.isNotNull() && !endingPosition.isRenderedCharacter()) {
+        if (!endingPosition.isRenderedCharacter()) {
             // Clear out all whitespace and insert one non-breaking space
-            deleteUnrenderedText(endingPosition);
+            deleteInsignificantTextDownstream(endingPosition);
             insertText(textNode, 0, nonBreakingSpaceString());
         }
         
@@ -1776,7 +1805,9 @@ void InputTextCommand::input(const DOMString &text, bool selectInsertedText)
     if (selection.isRange())
         deleteSelection();
     
-    deleteUnrenderedText(endingSelection().start());
+    // Delete any insignificant text that could get in the way of whitespace turning
+    // out correctly after the insertion.
+    deleteInsignificantTextDownstream(endingSelection().end().trailingWhitespacePosition());
     
     // Make sure the document is set up to receive text
     Position pos = prepareForTextInsertion(adjustDownstream);
index d1cd0d7f797ec67eb706c60925edb22a9e15f42e..6be1a47ac94b0bcae1412fc93b48a3b33c2cf1c9 100644 (file)
@@ -195,8 +195,10 @@ protected:
     void splitTextNode(DOM::TextImpl *text, long offset);
 
     DOM::NodeImpl *applyTypingStyle(DOM::NodeImpl *) const;
-    void deleteUnrenderedText(DOM::NodeImpl *);
-    void deleteUnrenderedText(const DOM::Position &pos);
+
+    void deleteInsignificantText(DOM::TextImpl *, int start, int end);
+    void deleteInsignificantText(const DOM::Position &start, const DOM::Position &end);
+    void deleteInsignificantTextDownstream(const DOM::Position &);
 
     void insertBlockPlaceholderIfNeeded(DOM::NodeImpl *);
     void removeBlockPlaceholderIfNeeded(DOM::NodeImpl *);