REGRESSION(51522): typing at the end of a line in designMode documents is *very*...
authorenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 May 2010 18:21:02 +0000 (18:21 +0000)
committerenrica@apple.com <enrica@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 May 2010 18:21:02 +0000 (18:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=36037
<rdar://problem/8022887>

Reviewed by Darin Adler.

The performance regression was traced to r51522 but this is not entirely true. That revision introduced, among other things,
additional checks in the method isCandidate of both Position and PositionIterator classes to support scenarios of mixed editability
that were not allowed before. This change uncovered an underlying issue with the decrement method of PositionIterator, that in some
cases would iterate through every position as offset in a block before moving to the last child in the block.
This was exactly the case of the attached test case, where, trying to check if the caret was placed at the end of a block, we were examining
every position in the block before considering the last true position in the block.
The performance was linear with the number of child nodes in the block, instead of constant.

* dom/PositionIterator.cpp:
(WebCore::PositionIterator::decrement):

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

WebCore/ChangeLog
WebCore/dom/PositionIterator.cpp

index 23526ff89a2969a6c1219736ed11b352559152e7..f72f30cbb01d4c0ceb1302b22516a1e36b136f26 100644 (file)
@@ -1,3 +1,22 @@
+2010-05-25  Enrica Casucci  <enrica@apple.com>
+
+        Reviewed by Darin Adler.
+
+        REGRESSION(51522): typing at the end of a line in designMode documents is *very* slow.
+        https://bugs.webkit.org/show_bug.cgi?id=36037
+        <rdar://problem/8022887>
+
+        The performance regression was traced to r51522 but this is not entirely true. That revision introduced, among other things,
+        additional checks in the method isCandidate of both Position and PositionIterator classes to support scenarios of mixed editability
+        that were not allowed before. This change uncovered an underlying issue with the decrement method of PositionIterator, that in some
+        cases would iterate through every position as offset in a block before moving to the last child in the block.
+        This was exactly the case of the attached test case, where, trying to check if the caret was placed at the end of a block, we were examining
+        every position in the block before considering the last true position in the block.
+        The performance was linear with the number of child nodes in the block, instead of constant.
+        
+        * dom/PositionIterator.cpp:
+        (WebCore::PositionIterator::decrement):
+
 2010-05-25  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Darin Adler.
 2010-05-25  Alexey Proskuryakov  <ap@apple.com>
 
         Reviewed by Darin Adler.
index f5b65f5849beb8e821a12491265b9f4503bb589a..619e37651a05bc04e2647b929430d6f074c137dc 100644 (file)
@@ -84,15 +84,14 @@ void PositionIterator::decrement()
         }
         return;
     }
         }
         return;
     }
-
-    if (m_offsetInAnchor) {
-        m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
+    
+    if (m_anchorNode->hasChildNodes()) {
+        m_anchorNode = m_anchorNode->lastChild();
+        m_offsetInAnchor = m_anchorNode->hasChildNodes()? 0: lastOffsetForEditing(m_anchorNode);
     } else {
     } else {
-        if (m_anchorNode->hasChildNodes()) {
-            m_anchorNode = m_anchorNode->lastChild();
-            if (!m_anchorNode->hasChildNodes())
-                m_offsetInAnchor = lastOffsetForEditing(m_anchorNode);
-        } else {
+        if (m_offsetInAnchor)
+            m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
+        else {
             m_nodeAfterPositionInAnchor = m_anchorNode;
             m_anchorNode = m_anchorNode->parentNode();
         }
             m_nodeAfterPositionInAnchor = m_anchorNode;
             m_anchorNode = m_anchorNode->parentNode();
         }