Reviewed by Darin Adler.
authorjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2008 19:28:05 +0000 (19:28 +0000)
committerjustin.garcia@apple.com <justin.garcia@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Feb 2008 19:28:05 +0000 (19:28 +0000)
        <rdar://problem/5694920> Typing (esp. deleting) is slower due to TOT WebCore

        These changes bring deleting performance back to old levels on the phone
        except for deleting the first space to the right of a word, which we are
        still working on.

        * dom/Position.cpp:
        (WebCore::Position::upstream): Avoid the use of enclosingBlock when determining
        if we have left the original enclosing block or entered a new one, and avoid
        rootEditableElement for determining if we have changed editability.  These
        operations are expensive.
        (WebCore::Position::downstream): Ditto.

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

WebCore/ChangeLog
WebCore/dom/Position.cpp

index 94ff7b0c49f17aadb9c199cb698161b9e1d20cef..304f3bd62f07876674a7d6e37ab51dfd5d46b0d4 100644 (file)
@@ -1,3 +1,20 @@
+2008-02-19  Justin Garcia  <justin.garcia@apple.com>
+
+        Reviewed by Darin Adler.
+
+        <rdar://problem/5694920> Typing (esp. deleting) is slower due to TOT WebCore 
+        
+        These changes bring deleting performance back to old levels on the phone
+        except for deleting the first space to the right of a word, which we are
+        still working on.
+
+        * dom/Position.cpp:
+        (WebCore::Position::upstream): Avoid the use of enclosingBlock when determining
+        if we have left the original enclosing block or entered a new one, and avoid
+        rootEditableElement for determining if we have changed editability.  These
+        operations are expensive.
+        (WebCore::Position::downstream): Ditto.
+
 2008-02-19  Darin Adler  <darin@apple.com>
 
         Rubber stamped by Anders.
index 2de7d01492355d427e32c9ceea8514cb8a58e072..f6e90e1cd9a9a25f47799852dda4faba804c2e45 100644 (file)
@@ -303,19 +303,20 @@ Position Position::upstream() const
         return Position();
     
     // iterate backward from there, looking for a qualified position
-    Node* block = enclosingBlock(startNode);
+    Node* originalBlock = enclosingBlock(startNode);
     PositionIterator lastVisible = *this;
     PositionIterator currentPos = lastVisible;
-    Node* originalRoot = node()->rootEditableElement();
+    bool startEditable = startNode->isContentEditable();
     for (; !currentPos.atStart(); currentPos.decrement()) {
         Node* currentNode = currentPos.node();
         
-        if (currentNode->rootEditableElement() != originalRoot)
+        bool currentEditable = currentNode->isContentEditable();
+        if (startEditable && !currentEditable || !startEditable && currentEditable)
             break;
 
         // Don't enter a new enclosing block flow or table element.  There is code below that
-        // terminates early if we're about to leave an enclosing block flow or table element.
-        if (block != enclosingBlock(currentNode))
+        // terminates early if we're about to leave a block.
+        if (isBlock(currentNode) && currentNode != originalBlock)
             return lastVisible;
 
         // skip position in unrendered or invisible node
@@ -328,8 +329,8 @@ Position Position::upstream() const
             lastVisible = currentPos;
         
         // Don't leave a block flow or table element.  We could rely on code above to terminate and 
-        // return lastVisible on the next iteration, but we terminate early.
-        if (currentNode == enclosingBlock(currentNode) && currentPos.atStartOfNode())
+        // return lastVisible on the next iteration, but we terminate early to avoid doing a nodeIndex() call.
+        if (isBlock(currentNode) && currentPos.atStartOfNode())
             return lastVisible;
 
         // Return position after tables and nodes which have content that can be ignored.
@@ -375,14 +376,15 @@ Position Position::downstream() const
         return Position();
 
     // iterate forward from there, looking for a qualified position
-    Node* block = enclosingBlock(startNode);
+    Node* originalBlock = enclosingBlock(startNode);
     PositionIterator lastVisible = *this;
     PositionIterator currentPos = lastVisible;
-    Node* originalRoot = node()->rootEditableElement();
+    bool startEditable = startNode->isContentEditable();
     for (; !currentPos.atEnd(); currentPos.increment()) {   
         Node* currentNode = currentPos.node();
         
-        if (currentNode->rootEditableElement() != originalRoot)
+        bool currentEditable = currentNode->isContentEditable();
+        if (startEditable && !currentEditable || !startEditable && currentEditable)
             break;
 
         // stop before going above the body, up into the head
@@ -390,8 +392,13 @@ Position Position::downstream() const
         if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
             break;
             
-        // Do not enter a new enclosing block flow or table element, and don't leave the original one.
-        if (block != enclosingBlock(currentNode))
+        // Do not enter a new enclosing block.
+        if (isBlock(currentNode) && currentNode != originalBlock)
+            return lastVisible;
+        // Do not leave the original enclosing block.
+        // Note: The first position after the last one in the original block 
+        // will be [originalBlock->parentNode(), originalBlock->nodeIndex() + 1].
+        if (originalBlock && originalBlock->parentNode() == currentNode)
             return lastVisible;
 
         // skip position in unrendered or invisible node