2011-04-19 Ryosuke Niwa <rniwa@webkit.org>
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Apr 2011 18:05:52 +0000 (18:05 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 19 Apr 2011 18:05:52 +0000 (18:05 +0000)
commit6f6feac6ef393f51203922557e8c3d225118f12d
treeaa605156b83f1ab0b736248ce4db557c1831ac9b
parent17c301f5bb9dcf6422e10e478fd0d8de433d5b4b
2011-04-19  Ryosuke Niwa  <rniwa@webkit.org>

        Reviewed by Dimitri Glazkov.

        REGRESSION(r74228-75294): removing nodes is 200+ times slower when selection is inside a shadow DOM
        https://bugs.webkit.org/show_bug.cgi?id=57061

        The bug was caused by Range::compareNode's incorrectly returning NODE_INSIDE when the selection is inside
        a shadow DOM and the node is outside of the shadow DOM. This caused respondToNodeModification to call
        RenderView::clearSelection every time a node is removed when selection is in a shadow DOM and resulted in
        a significant performance regression.

        Fixed Ranged::compareNode by making Range::compareBoundaryPoints throw a WRONG_DOCUMENT_ERR when there are
        no common ancestors between containerA and containerB. This will force compareNode to also throw an exception
        and prevents respondToNodeModification from clearing selection.

        No new tests because this is a performance improvement and the fix in Range cannot be tested since shadow DOM
        isn't exposed to JavaScript.

        * dom/Range.cpp:
        (WebCore::Range::setStart): Calls compareBoundaryPoints; since we ensures that the root container noes of
        start and end nodes are same, we should never get an exception from compareBoundaryPoints.
        (WebCore::Range::setEnd): Ditto.
        (WebCore::Range::isPointInRange): Calls compareBoundaryPoints; returns false when compareBoundaryPoints
        throws an exception.
        (WebCore::Range::comparePoint): Calls compareBoundaryPoints; exit early when an exception is thrown by
        compareBoundaryPoints.
        (WebCore::Range::compareBoundaryPoints): Throws an exception when two containers do not have a common ancestor.
        (WebCore::Range::boundaryPointsValid): Calls compareBoundaryPoints and checks that it didn't throw an exception.
        * dom/Range.h:
        * editing/SelectionController.cpp:
        (WebCore::SelectionController::respondToNodeModification):
        * editing/htmlediting.cpp:
        (WebCore::comparePositions): Calls compareBoundaryPoints.
        * editing/markup.cpp:
        (WebCore::createMarkup): Calls compareBoundaryPoints; since startNode and pastEnd are both in the same document
        and neither are in a shadow DOM, it should never throw an exception.
        * page/DOMSelection.cpp:
        (WebCore::DOMSelection::containsNode): Calls compareBoundaryPoints; node is fully selected only if no exception
        was thrown.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@84265 268f45cc-cd09-0410-ab3c-d52691b4dbfc
Source/WebCore/ChangeLog
Source/WebCore/dom/Range.cpp
Source/WebCore/dom/Range.h
Source/WebCore/editing/SelectionController.cpp
Source/WebCore/editing/htmlediting.cpp
Source/WebCore/editing/markup.cpp
Source/WebCore/page/DOMSelection.cpp