Reviewed by John
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Dec 2004 19:45:47 +0000 (19:45 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 21 Dec 2004 19:45:47 +0000 (19:45 +0000)
        Fix for this bug:

        <rdar://problem/3928305> selecting an entire line and typing over causes new inserted text at top of document

        * khtml/editing/htmlediting.cpp:
        (khtml::DeleteSelectionCommand::insertPlaceholderForAncestorBlockContent): New function to detect case
        formerly undetected and unhandled. This is the crux of the bug fix.
        (khtml::DeleteSelectionCommand::doApply): Call insertPlaceholderForAncestorBlockContent() during
        execution of command.
        * khtml/editing/htmlediting.h: Declare new function.
        * layout-tests/editing/deleting/delete-3928305-fix-expected.txt: Added.
        * layout-tests/editing/deleting/delete-3928305-fix.html: Added.

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

LayoutTests/editing/deleting/delete-3928305-fix-expected.txt [new file with mode: 0644]
LayoutTests/editing/deleting/delete-3928305-fix.html [new file with mode: 0644]
WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp
WebCore/khtml/editing/htmlediting.h

diff --git a/LayoutTests/editing/deleting/delete-3928305-fix-expected.txt b/LayoutTests/editing/deleting/delete-3928305-fix-expected.txt
new file mode 100644 (file)
index 0000000..307c92d
--- /dev/null
@@ -0,0 +1,23 @@
+layer at (0,0) size 800x600
+  RenderCanvas 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 (anonymous) at (0,0) size 784x18
+        RenderText {TEXT} at (0,0) size 309x18
+          text run at (0,0) width 309: "Should see a blank line between \"foo\" and \"baz\""
+      RenderBlock {DIV} at (0,18) size 784x24
+      RenderBlock {DIV} at (0,42) size 784x112 [border: (2px solid #FF0000)]
+        RenderBlock {DIV} at (14,14) size 756x28
+          RenderText {TEXT} at (0,0) size 32x28
+            text run at (0,0) width 32: "foo"
+        RenderBlock {P} at (14,42) size 756x28
+          RenderBR {BR} at (0,0) size 0x28
+        RenderBlock (anonymous) at (14,70) size 756x0
+        RenderBlock {DIV} at (14,70) size 756x28
+          RenderText {TEXT} at (0,0) size 34x28
+            text run at (0,0) width 34: "baz"
+selection is CARET:
+start:      position 0 of child 1 {BR} of child 2 {P} of root {DIV}
+upstream:   position 0 of child 2 {P} of root {DIV}
+downstream: position 0 of child 1 {BR} of child 2 {P} of root {DIV}
diff --git a/LayoutTests/editing/deleting/delete-3928305-fix.html b/LayoutTests/editing/deleting/delete-3928305-fix.html
new file mode 100644 (file)
index 0000000..2d6fdad
--- /dev/null
@@ -0,0 +1,49 @@
+<html> 
+<head>
+
+<script src=../editing.js language="JavaScript" type="text/JavaScript" ></script>
+
+<style>
+.editing { 
+    border: 2px solid red; 
+    padding: 12px; 
+    font-size: 24px; 
+}
+</style>
+
+<script>
+
+function editingTest() {
+    for (i = 0; i < 4; i++)
+       moveSelectionForwardByCharacterCommand(); 
+    for (i = 0; i < 3; i++)
+       extendSelectionForwardByCharacterCommand(); 
+    deleteCommand(); 
+}
+
+</script>
+
+<title>Editing Test</title> 
+</head> 
+<body contenteditable="true">
+
+Should see a blank line between "foo" and "baz"
+<div style="height: 24px"></div>
+
+<div id="root" class="editing">
+<div id="test">foo</div>bar<div>baz</div>
+
+<!-- 
+
+Fix for this bug:
+
+<rdar://problem/3928305> selecting an entire line and typing over causes new inserted text at top of document
+
+-->
+
+<script>
+runEditingTest();
+</script>
+
+</body>
+</html>
index bcc910bbcc6ccf84395a6ae0cb391fd098d60fab..658de647806219517a8f540c738def5e587dbcce 100644 (file)
@@ -1,3 +1,20 @@
+2004-12-21  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by John
+
+        Fix for this bug:
+        
+        <rdar://problem/3928305> selecting an entire line and typing over causes new inserted text at top of document
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::DeleteSelectionCommand::insertPlaceholderForAncestorBlockContent): New function to detect case
+        formerly undetected and unhandled. This is the crux of the bug fix.
+        (khtml::DeleteSelectionCommand::doApply): Call insertPlaceholderForAncestorBlockContent() during
+        execution of command.
+        * khtml/editing/htmlediting.h: Declare new function.
+        * layout-tests/editing/deleting/delete-3928305-fix-expected.txt: Added.
+        * layout-tests/editing/deleting/delete-3928305-fix.html: Added.
+
 2004-12-21  Ken Kocienda  <kocienda@apple.com>
 
         Reviewed by me
index 60140067f0d2926962d59f94f8b4e49502b74703..131c741c4b7b7bd2df090900bfbe18184f872922 100644 (file)
@@ -1550,6 +1550,34 @@ void DeleteSelectionCommand::initializePositionData()
     debugNode(    "m_startNode          ", m_startNode);    
 }
 
+void DeleteSelectionCommand::insertPlaceholderForAncestorBlockContent()
+{
+    // This code makes sure a line does not disappear when deleting in this case:
+    // <p>foo</p>bar<p>baz</p>
+    // Select "bar" and hit delete. If nothing is done, the line containing bar will disappear.
+    // It needs to be held open by inserting a placeholder.
+    // Also see:
+    // <rdar://problem/3928305> selecting an entire line and typing over causes new inserted text at top of document
+    //
+    // The checks below detect the case where the selection contains content in an ancestor block 
+    // surrounded by child blocks.
+    //
+    NodeImpl *upstreamBlock = m_upstreamStart.node()->enclosingBlockFlowElement();
+    NodeImpl *beforeUpstreamBlock = m_upstreamStart.upstream().node()->enclosingBlockFlowElement();
+    
+    if (upstreamBlock != beforeUpstreamBlock && beforeUpstreamBlock->isAncestor(upstreamBlock)) {
+        NodeImpl *downstreamBlock = m_downstreamEnd.node()->enclosingBlockFlowElement();
+        NodeImpl *afterDownstreamBlock = m_downstreamEnd.downstream().node()->enclosingBlockFlowElement();
+        
+        if (afterDownstreamBlock != downstreamBlock && afterDownstreamBlock != upstreamBlock) {
+            NodeImpl *block = createDefaultParagraphElement(document());
+            insertNodeBefore(block, m_upstreamStart.node());
+            insertBlockPlaceholderIfNeeded(block);
+            m_endingPosition = Position(block, 0);
+        }
+    }
+}
+
 void DeleteSelectionCommand::saveTypingStyleState()
 {
     // Figure out the typing style in effect before the delete is done.
@@ -1927,6 +1955,7 @@ void DeleteSelectionCommand::doApply()
     deleteInsignificantTextDownstream(m_trailingWhitespace);    
 
     saveTypingStyleState();
+    insertPlaceholderForAncestorBlockContent();
     
     if (!handleSpecialCaseAllContentDelete())
         if (!handleSpecialCaseBRDelete())
index a6aecb6b921bcd4766c9b3f748b96b81c619cfb4..f462384015f8c2d4a90b1c7ab52e3a3f3bd042d9 100644 (file)
@@ -322,6 +322,7 @@ private:
 
     void initializePositionData();
     void saveTypingStyleState();
+    void insertPlaceholderForAncestorBlockContent();
     bool handleSpecialCaseAllContentDelete();
     bool handleSpecialCaseBRDelete();
     void handleGeneralDelete();