Reviewed by John
authorkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Nov 2004 15:26:01 +0000 (15:26 +0000)
committerkocienda <kocienda@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 11 Nov 2004 15:26:01 +0000 (15:26 +0000)
        * khtml/editing/htmlediting.cpp:
        (khtml::debugNode): New debugging helper.
        (khtml::DeleteSelectionCommand::initializePositionData): No longer call obsoleted
        startPositionForDelete() and endPositionForDelete() functions. Just use the
        m_selectionToDelete object to determine start and end positions for the delete.
        (khtml::DeleteSelectionCommand::canPerformSpecialCaseAllContentDelete): New
        function that creates a special case for deleting all the content in a root
        editable element.
        (khtml::DeleteSelectionCommand::doApply): Call canPerformSpecialCaseAllContentDelete()
        function before BR special case and the general case delete functions.
        * khtml/editing/htmlediting.h: Updated for changed functions.

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

WebCore/ChangeLog-2005-08-23
WebCore/khtml/editing/htmlediting.cpp
WebCore/khtml/editing/htmlediting.h

index 198b5a6..493eb9d 100644 (file)
@@ -1,8 +1,24 @@
+2004-11-10  Ken Kocienda  <kocienda@apple.com>
+
+        Reviewed by John
+
+        * khtml/editing/htmlediting.cpp:
+        (khtml::debugNode): New debugging helper.
+        (khtml::DeleteSelectionCommand::initializePositionData): No longer call obsoleted
+        startPositionForDelete() and endPositionForDelete() functions. Just use the 
+        m_selectionToDelete object to determine start and end positions for the delete.
+        (khtml::DeleteSelectionCommand::canPerformSpecialCaseAllContentDelete): New
+        function that creates a special case for deleting all the content in a root
+        editable element.
+        (khtml::DeleteSelectionCommand::doApply): Call canPerformSpecialCaseAllContentDelete()
+        function before BR special case and the general case delete functions.
+        * khtml/editing/htmlediting.h: Updated for changed functions.
+
 2004-11-10  Kevin Decker  <kdecker@apple.com>
 
         Reviewed by mjs.
        
-       Fixed <rdar://problem/3875011> DOMNodeList::tryGet() performs unnecessary (and expensive) dom tree traversals. Improved a loop from 2-n-squared to just n-squared.  
+        Fixed <rdar://problem/3875011> DOMNodeList::tryGet() performs unnecessary (and expensive) dom tree traversals. Improved a loop from 2-n-squared to just n-squared.  
 
         * khtml/ecma/kjs_dom.cpp:
         (DOMNodeList::tryGet): Got rid of an unnecessary node traversal. 
index 24830fd..83e69b7 100644 (file)
@@ -96,6 +96,7 @@ using DOM::TreeWalkerImpl;
 #define ASSERT(assertion) assert(assertion)
 #if LOG_DISABLED
 #define debugPosition(a,b) ((void)0)
+#define debugNode(a,b) ((void)0)
 #endif
 #endif
 
@@ -184,6 +185,16 @@ static void debugPosition(const char *prefix, const Position &pos)
         LOG(Editing, "%s%s %p : %d", prefix, getTagName(pos.node()->id()).string().latin1(), pos.node(), pos.offset());
 }
 
+static void debugNode(const char *prefix, const NodeImpl *node)
+{
+    if (!prefix)
+        prefix = "";
+    if (!node)
+        LOG(Editing, "%s <null>", prefix);
+    else
+        LOG(Editing, "%s%s %p", prefix, getTagName(node->id()).string().latin1(), node);
+}
+
 //------------------------------------------------------------------------------------------
 // EditCommandPtr
 
@@ -1402,8 +1413,8 @@ DeleteSelectionCommand::DeleteSelectionCommand(DocumentImpl *document, const Sel
 
 void DeleteSelectionCommand::initializePositionData()
 {
-    Position start = startPositionForDelete();
-    Position end = endPositionForDelete();
+    Position start = m_selectionToDelete.start();
+    Position end = m_selectionToDelete.end();
 
     m_upstreamStart = start.upstream(StayInBlock);
     m_downstreamStart = start.downstream(StayInBlock);
@@ -1435,46 +1446,24 @@ void DeleteSelectionCommand::initializePositionData()
         
     m_trailingWhitespaceValid = true;
     
+    m_startBlock = m_downstreamStart.node()->enclosingBlockFlowElement();
+    m_startBlock->ref();
+    m_endBlock = m_upstreamEnd.node()->enclosingBlockFlowElement();
+    m_endBlock->ref();
+
     debugPosition("m_upstreamStart      ", m_upstreamStart);
     debugPosition("m_downstreamStart    ", m_downstreamStart);
     debugPosition("m_upstreamEnd        ", m_upstreamEnd);
     debugPosition("m_downstreamEnd      ", m_downstreamEnd);
     debugPosition("m_leadingWhitespace  ", m_leadingWhitespace);
     debugPosition("m_trailingWhitespace ", m_trailingWhitespace);
-    
-    m_startBlock = m_downstreamStart.node()->enclosingBlockFlowElement();
-    m_startBlock->ref();
-    m_endBlock = m_upstreamEnd.node()->enclosingBlockFlowElement();
-    m_endBlock->ref();
+    debugNode(    "m_startBlock         ", m_startBlock);
+    debugNode(    "m_endBlock           ", m_endBlock);    
 
     m_startNode = m_upstreamStart.node();
     m_startNode->ref();
 }
 
-Position DeleteSelectionCommand::startPositionForDelete() const
-{
-    Position pos = m_selectionToDelete.start();
-    ASSERT(pos.node()->inDocument());
-
-    ElementImpl *rootElement = pos.node()->rootEditableElement();
-    Position rootStart = Position(rootElement, 0);
-    if (pos == VisiblePosition(rootStart).deepEquivalent())
-        pos = rootStart;
-    return pos;
-}
-
-Position DeleteSelectionCommand::endPositionForDelete() const
-{
-    Position pos = m_selectionToDelete.end();
-    ASSERT(pos.node()->inDocument());
-
-    ElementImpl *rootElement = pos.node()->rootEditableElement();
-    Position rootEnd = Position(rootElement, rootElement ? rootElement->childNodeCount() : 0).equivalentDeepPosition();
-    if (pos == VisiblePosition(rootEnd).deepEquivalent())
-        pos = rootEnd;
-    return pos;
-}
-
 void DeleteSelectionCommand::saveTypingStyleState()
 {
     // Figure out the typing style in effect before the delete is done.
@@ -1487,6 +1476,27 @@ void DeleteSelectionCommand::saveTypingStyleState()
     computedStyle->deref();
 }
 
+bool DeleteSelectionCommand::canPerformSpecialCaseAllContentDelete()
+{
+    Position start = m_downstreamStart;
+    Position end = m_upstreamEnd;
+
+    ElementImpl *rootElement = start.node()->rootEditableElement();
+    Position rootStart = Position(rootElement, 0);
+    Position rootEnd = Position(rootElement, rootElement ? rootElement->childNodeCount() : 0).equivalentDeepPosition();
+    if (start == VisiblePosition(rootStart).downstreamDeepEquivalent() && end == VisiblePosition(rootEnd).deepEquivalent()) {
+        // Delete every child of the root editable element
+        NodeImpl *node = rootElement->firstChild();
+        while (node) {
+            NodeImpl *next = node->traverseNextSibling();
+            removeNode(node);
+            node = next;
+        }
+        return true;
+    }
+    return false;
+}
+
 bool DeleteSelectionCommand::canPerformSpecialCaseBRDelete()
 {
     // Check for special-case where the selection contains only a BR on a line by itself after another BR.
@@ -1814,8 +1824,9 @@ void DeleteSelectionCommand::doApply()
 
     saveTypingStyleState();
     
-    if (!canPerformSpecialCaseBRDelete())
-        performGeneralDelete();
+    if (!canPerformSpecialCaseAllContentDelete())
+        if (!canPerformSpecialCaseBRDelete())
+            performGeneralDelete();
     
     // Do block merge if start and end of selection are in different blocks.
     moveNodesAfterNode();
index 91f7038..215eb07 100644 (file)
@@ -311,9 +311,8 @@ private:
     virtual bool preservesTypingStyle() const;
 
     void initializePositionData();
-    DOM::Position startPositionForDelete() const;
-    DOM::Position endPositionForDelete() const;
     void saveTypingStyleState();
+    bool canPerformSpecialCaseAllContentDelete();
     bool canPerformSpecialCaseBRDelete();
     void performGeneralDelete();
     void fixupWhitespace();