Changeset 171218 in webkit


Ignore:
Timestamp:
Jul 18, 2014 2:50:01 AM (10 years ago)
Author:
krit@webkit.org
Message:

REGRESSION (r169105): Crash in selection
https://bugs.webkit.org/show_bug.cgi?id=134303

Patch by Radu Stavila <stavila@adobe.com> on 2014-07-18
Reviewed by Ryosuke Niwa.

Source/WebCore:
When splitting the selection between different subtrees, all subtrees must have their selection cleared before
starting to apply the new selection. Otherwise, when selecting objects in a named flow thread and going up
its containing block chain, we can end up in the view's selection root, which has not yet been updated and so
we get inconsistent data.

To achieve this goal, the selection update was split into a "clear" and an "apply" method. The updateSelectionForSubtrees
method first iterates through all subtrees and performs the "clear" method and then starts all over again
and performs the "apply" method.

Also, the selectionStart/End members in RenderView have been renamed to fix problems caused by the fact that
RenderView inherits SelectionSubtreeRoot, which also has the same selectionStart/End members.

Test: fast/regions/selection/crash-deselect.html

  • WebCore.xcodeproj/project.pbxproj:
  • rendering/RenderBlock.cpp:

(WebCore::RenderBlock::isSelectionRoot):

  • rendering/RenderSelectionInfo.h:
  • rendering/RenderView.cpp:

(WebCore::RenderView::RenderView):
(WebCore::RenderView::setSelection): Renamed m_selectionStart/End to m_unsplitSelectionStart/End
(WebCore::RenderView::splitSelectionBetweenSubtrees):
(WebCore::RenderView::updateSelectionForSubtrees): Added, clears and re-applies selection for all selection subtrees.
(WebCore::RenderView::clearSubtreeSelection): Added, clears selection and returns previously selected information.
(WebCore::RenderView::applySubtreeSelection): Added, updates the selection status of all objects inside the selection tree, compares old and new data and repaints accordingly.
(WebCore::RenderView::getSelection): Renamed m_selectionStart/End to m_unsplitSelectionStart/End
(WebCore::RenderView::setSubtreeSelection): Deleted.

  • rendering/RenderView.h:
  • rendering/SelectionSubtreeRoot.cpp:

(WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot):

  • rendering/SelectionSubtreeRoot.h:

(WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData):

LayoutTests:
Added test for the crash that occurred in some cases when selecting.

  • fast/regions/selection/crash-deselect-expected.txt: Added.
  • fast/regions/selection/crash-deselect.html: Added.
Location:
trunk
Files:
2 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r171210 r171218  
     12014-07-18  Radu Stavila  <stavila@adobe.com>
     2
     3        REGRESSION (r169105): Crash in selection
     4        https://bugs.webkit.org/show_bug.cgi?id=134303
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        Added test for the crash that occurred in some cases when selecting.
     9
     10        * fast/regions/selection/crash-deselect-expected.txt: Added.
     11        * fast/regions/selection/crash-deselect.html: Added.
     12
    1132014-07-17  Zalan Bujtas  <zalan@apple.com>
    214
  • trunk/Source/WebCore/ChangeLog

    r171215 r171218  
     12014-07-18  Radu Stavila  <stavila@adobe.com>
     2
     3        REGRESSION (r169105): Crash in selection
     4        https://bugs.webkit.org/show_bug.cgi?id=134303
     5
     6        Reviewed by Ryosuke Niwa.
     7
     8        When splitting the selection between different subtrees, all subtrees must have their selection cleared before
     9        starting to apply the new selection. Otherwise, when selecting objects in a named flow thread and going up
     10        its containing block chain, we can end up in the view's selection root, which has not yet been updated and so
     11        we get inconsistent data.
     12
     13        To achieve this goal, the selection update was split into a "clear" and an "apply" method. The updateSelectionForSubtrees
     14        method first iterates through all subtrees and performs the "clear" method and then starts all over again
     15        and performs the "apply" method.
     16
     17        Also, the selectionStart/End members in RenderView have been renamed to fix problems caused by the fact that
     18        RenderView inherits SelectionSubtreeRoot, which also has the same selectionStart/End members.
     19
     20        Test: fast/regions/selection/crash-deselect.html
     21
     22        * WebCore.xcodeproj/project.pbxproj:
     23        * rendering/RenderBlock.cpp:
     24        (WebCore::RenderBlock::isSelectionRoot):
     25        * rendering/RenderSelectionInfo.h:
     26        * rendering/RenderView.cpp:
     27        (WebCore::RenderView::RenderView):
     28        (WebCore::RenderView::setSelection): Renamed m_selectionStart/End to m_unsplitSelectionStart/End
     29        (WebCore::RenderView::splitSelectionBetweenSubtrees):
     30        (WebCore::RenderView::updateSelectionForSubtrees): Added, clears and re-applies selection for all selection subtrees.
     31        (WebCore::RenderView::clearSubtreeSelection): Added, clears selection and returns previously selected information.
     32        (WebCore::RenderView::applySubtreeSelection): Added, updates the selection status of all objects inside the selection tree, compares old and new data and repaints accordingly.
     33        (WebCore::RenderView::getSelection): Renamed m_selectionStart/End to m_unsplitSelectionStart/End
     34        (WebCore::RenderView::setSubtreeSelection): Deleted.
     35        * rendering/RenderView.h:
     36        * rendering/SelectionSubtreeRoot.cpp:
     37        (WebCore::SelectionSubtreeRoot::SelectionSubtreeRoot):
     38        * rendering/SelectionSubtreeRoot.h:
     39        (WebCore::SelectionSubtreeRoot::OldSelectionData::OldSelectionData):
     40
    1412014-07-17  Jer Noble  <jer.noble@apple.com>
    242
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r171188 r171218  
    467467                0F099D0817B968A100FF84B9 /* WebCoreTypedArrayController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0F099D0617B968A100FF84B9 /* WebCoreTypedArrayController.cpp */; };
    468468                0F099D0917B968A100FF84B9 /* WebCoreTypedArrayController.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F099D0717B968A100FF84B9 /* WebCoreTypedArrayController.h */; settings = {ATTRIBUTES = (Private, ); }; };
    469                 0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F11A54E0F39233100C37884 /* RenderSelectionInfo.h */; };
     469                0F11A54F0F39233100C37884 /* RenderSelectionInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F11A54E0F39233100C37884 /* RenderSelectionInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
    470470                0F13163E16ED0CC80035CC04 /* PlatformCAFilters.h in Headers */ = {isa = PBXBuildFile; fileRef = 0F13163D16ED0CC80035CC04 /* PlatformCAFilters.h */; settings = {ATTRIBUTES = (Private, ); }; };
    471471                0F13164016ED0CDE0035CC04 /* PlatformCAFiltersMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 0F13163F16ED0CDE0035CC04 /* PlatformCAFiltersMac.mm */; };
  • trunk/Source/WebCore/rendering/RenderBlock.cpp

    r170871 r171218  
    18291829        return true;
    18301830   
    1831     if (view().selectionStart()) {
    1832         Node* startElement = view().selectionStart()->node();
     1831    if (view().selectionUnsplitStart()) {
     1832        Node* startElement = view().selectionUnsplitStart()->node();
    18331833        if (startElement && startElement->rootEditableElement() == element())
    18341834            return true;
  • trunk/Source/WebCore/rendering/RenderSelectionInfo.h

    r170758 r171218  
    2626#define RenderSelectionInfo_h
    2727
     28#include "GapRects.h"
    2829#include "IntRect.h"
    29 #include "RenderBox.h"
     30#include "RenderBlock.h"
    3031#include "RenderText.h"
    3132
  • trunk/Source/WebCore/rendering/RenderView.cpp

    r170774 r171218  
    9797    : RenderBlockFlow(document, WTF::move(style))
    9898    , m_frameView(*document.view())
    99     , m_selectionStart(0)
    100     , m_selectionEnd(0)
    101     , m_selectionStartPos(-1)
    102     , m_selectionEndPos(-1)
     99    , m_unsplitSelectionStart(0)
     100    , m_unsplitSelectionEnd(0)
     101    , m_unsplitSelectionStartPos(-1)
     102    , m_unsplitSelectionEndPos(-1)
    103103    , m_rendererCount(0)
    104104    , m_maximalOutlineSize(0)
     
    843843    m_selectionWasCaret = frame().selection().isCaret();
    844844    // Just return if the selection hasn't changed.
    845     if (m_selectionStart == start && m_selectionStartPos == startPos &&
    846         m_selectionEnd == end && m_selectionEndPos == endPos && !caretChanged)
    847         return;
     845    if (m_unsplitSelectionStart == start && m_unsplitSelectionStartPos == startPos
     846        && m_unsplitSelectionEnd == end && m_unsplitSelectionEndPos == endPos && !caretChanged) {
     847        return;
     848    }
    848849
    849850    // Set global positions for new selection.
    850     m_selectionStart = start;
    851     m_selectionStartPos = startPos;
    852     m_selectionEnd = end;
    853     m_selectionEndPos = endPos;
     851    m_unsplitSelectionStart = start;
     852    m_unsplitSelectionStartPos = startPos;
     853    m_unsplitSelectionEnd = end;
     854    m_unsplitSelectionEndPos = endPos;
    854855
    855856    // If there is no RenderNamedFlowThreads we follow the regular selection.
    856857    if (!hasRenderNamedFlowThreads()) {
    857         setSubtreeSelection(*this, start, startPos, end, endPos, blockRepaintMode);
     858        RenderSubtreesMap singleSubtreeMap;
     859        singleSubtreeMap.set(this, SelectionSubtreeRoot(start, startPos, end, endPos));
     860        updateSelectionForSubtrees(singleSubtreeMap, blockRepaintMode);
    858861        return;
    859862    }
     
    865868{
    866869    // Compute the visible selection end points for each of the subtrees.
    867     typedef HashMap<SelectionSubtreeRoot*, SelectionSubtreeRoot> RenderSubtreesMap;
    868870    RenderSubtreesMap renderSubtreesMap;
    869871
     
    899901        }
    900902    }
    901 
    902     for (RenderSubtreesMap::iterator i = renderSubtreesMap.begin(); i != renderSubtreesMap.end(); ++i) {
    903         SelectionSubtreeRoot subtreeSelectionData = i->value;
     903   
     904    updateSelectionForSubtrees(renderSubtreesMap, blockRepaintMode);
     905}
     906
     907void RenderView::updateSelectionForSubtrees(RenderSubtreesMap& renderSubtreesMap, SelectionRepaintMode blockRepaintMode)
     908{
     909    SubtreeOldSelectionDataMap oldSelectionDataMap;
     910    for (auto it = renderSubtreesMap.begin(); it != renderSubtreesMap.end(); ++it) {
     911        std::unique_ptr<OldSelectionData> oldSelectionData = std::make_unique<OldSelectionData>();
     912        clearSubtreeSelection(*it->key, blockRepaintMode, *oldSelectionData);
     913        oldSelectionDataMap.set(it->key, std::move(oldSelectionData));
     914
     915        SelectionSubtreeRoot& subtreeSelectionData = it->value;
    904916        subtreeSelectionData.adjustForVisibleSelection(document());
    905         setSubtreeSelection(*i->key, subtreeSelectionData.selectionStart(), subtreeSelectionData.selectionStartPos(),
    906             subtreeSelectionData.selectionEnd(), subtreeSelectionData.selectionEndPos(), blockRepaintMode);
    907     }
    908 }
    909 
    910 void RenderView::setSubtreeSelection(SelectionSubtreeRoot& root, RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode)
     917       
     918        SelectionSubtreeRoot& root = *it->key;
     919        root.setSelectionStart(subtreeSelectionData.selectionStart());
     920        root.setSelectionStartPos(subtreeSelectionData.selectionStartPos());
     921        root.setSelectionEnd(subtreeSelectionData.selectionEnd());
     922        root.setSelectionEndPos(subtreeSelectionData.selectionEndPos());
     923    }
     924
     925    // Update selection status for the objects inside the selection subtrees.
     926    // This needs to be done after the previous loop updated the selectionStart/End
     927    // parameters of all subtrees because we're going to be climbing up the containing
     928    // block chain and we might end up in a different selection subtree.
     929    for (auto it = renderSubtreesMap.begin(); it != renderSubtreesMap.end(); ++it) {
     930        SelectionSubtreeRoot subtreeSelectionData = it->value;
     931        OldSelectionData& oldSelectionData = *oldSelectionDataMap.get(it->key);
     932        applySubtreeSelection(*it->key, subtreeSelectionData.selectionStart(), subtreeSelectionData.selectionEnd(), subtreeSelectionData.selectionEndPos(), blockRepaintMode, oldSelectionData);
     933    }
     934}
     935
     936void RenderView::clearSubtreeSelection(const SelectionSubtreeRoot& root, SelectionRepaintMode blockRepaintMode, OldSelectionData& oldSelectionData)
    911937{
    912938    // Record the old selected objects.  These will be used later
    913939    // when we compare against the new selected objects.
    914     int oldStartPos = root.selectionStartPos();
    915     int oldEndPos = root.selectionEndPos();
    916 
    917     // Objects each have a single selection rect to examine.
    918     typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectedObjectMap;
    919     SelectedObjectMap oldSelectedObjects;
    920     SelectedObjectMap newSelectedObjects;
    921 
     940    oldSelectionData.selectionStartPos = root.selectionStartPos();
     941    oldSelectionData.selectionEndPos = root.selectionEndPos();
     942   
    922943    // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
    923944    // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
    924945    // the union of those rects might remain the same even when changes have occurred.
    925     typedef HashMap<RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>> SelectedBlockMap;
    926     SelectedBlockMap oldSelectedBlocks;
    927     SelectedBlockMap newSelectedBlocks;
    928946
    929947    RenderObject* os = root.selectionStart();
     
    934952            && os->selectionState() != SelectionNone) {
    935953            // Blocks are responsible for painting line gaps and margin gaps.  They must be examined as well.
    936             oldSelectedObjects.set(os, std::make_unique<RenderSelectionInfo>(os, true));
     954            oldSelectionData.selectedObjects.set(os, std::make_unique<RenderSelectionInfo>(os, true));
    937955            if (blockRepaintMode == RepaintNewXOROld) {
    938956                RenderBlock* cb = os->containingBlock();
    939957                while (cb && !cb->isRenderView()) {
    940                     std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).iterator->value;
     958                    std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = oldSelectionData.selectedBlocks.add(cb, nullptr).iterator->value;
    941959                    if (blockInfo)
    942960                        break;
     
    950968    }
    951969
    952     // Now clear the selection.
    953     SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end();
    954     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i)
     970    auto oldObjectsEnd = oldSelectionData.selectedObjects.end();
     971    for (auto i = oldSelectionData.selectedObjects.begin(); i != oldObjectsEnd; ++i)
    955972        i->key->setSelectionStateIfNeeded(SelectionNone);
    956 
    957     // set selection start and end
    958     root.setSelectionStart(start);
    959     root.setSelectionStartPos(startPos);
    960     root.setSelectionEnd(end);
    961     root.setSelectionEndPos(endPos);
    962 
     973}
     974
     975void RenderView::applySubtreeSelection(SelectionSubtreeRoot& root, RenderObject* start, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode, const OldSelectionData& oldSelectionData)
     976{
    963977    // Update the selection status of all objects between selectionStart and selectionEnd
    964978    if (start && start == end)
     
    972986
    973987    RenderObject* o = start;
    974     stop = rendererAfterPosition(end, endPos);
    975     selectionIterator = SelectionIterator(o);
     988    RenderObject* stop = rendererAfterPosition(end, endPos);
     989    SelectionIterator selectionIterator(o);
    976990   
    977991    while (o && o != stop) {
     
    9861000    // Now that the selection state has been updated for the new objects, walk them again and
    9871001    // put them in the new objects list.
     1002    SelectedObjectMap newSelectedObjects;
     1003    SelectedBlockMap newSelectedBlocks;
    9881004    o = start;
    9891005    selectionIterator = SelectionIterator(o);
     
    10201036
    10211037    // Have any of the old selected objects changed compared to the new selection?
    1022     for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) {
    1023         RenderObject* obj = i->key;
     1038    auto oldObjectsEnd = oldSelectionData.selectedObjects.end();
     1039    for (auto it = oldSelectionData.selectedObjects.begin(); it != oldObjectsEnd; ++it) {
     1040        RenderObject* obj = it->key;
    10241041        RenderSelectionInfo* newInfo = newSelectedObjects.get(obj);
    1025         RenderSelectionInfo* oldInfo = i->value.get();
     1042        RenderSelectionInfo* oldInfo = it->value.get();
    10261043        if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()
    1027             || (root.selectionStart() == obj && oldStartPos != root.selectionStartPos())
    1028             || (root.selectionEnd() == obj && oldEndPos != root.selectionEndPos())) {
     1044            || (root.selectionStart() == obj && oldSelectionData.selectionStartPos != root.selectionStartPos())
     1045            || (root.selectionEnd() == obj && oldSelectionData.selectionEndPos != root.selectionEndPos())) {
    10291046            oldInfo->repaint();
    10301047            if (newInfo) {
     
    10361053
    10371054    // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
    1038     SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end();
    1039     for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i)
    1040         i->value->repaint();
     1055    auto newObjectsEnd = newSelectedObjects.end();
     1056    for (auto it = newSelectedObjects.begin(); it != newObjectsEnd; ++it)
     1057        it->value->repaint();
    10411058
    10421059    // Have any of the old blocks changed?
    1043     SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end();
    1044     for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) {
    1045         RenderBlock* block = i->key;
     1060    auto oldBlocksEnd = oldSelectionData.selectedBlocks.end();
     1061    for (auto it = oldSelectionData.selectedBlocks.begin(); it != oldBlocksEnd; ++it) {
     1062        RenderBlock* block = it->key;
    10461063        RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block);
    1047         RenderBlockSelectionInfo* oldInfo = i->value.get();
     1064        RenderBlockSelectionInfo* oldInfo = it->value.get();
    10481065        if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
    10491066            oldInfo->repaint();
     
    10561073
    10571074    // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
    1058     SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end();
    1059     for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i)
    1060         i->value->repaint();
     1075    auto newBlocksEnd = newSelectedBlocks.end();
     1076    for (auto it = newSelectedBlocks.begin(); it != newBlocksEnd; ++it)
     1077        it->value->repaint();
    10611078}
    10621079
    10631080void RenderView::getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const
    10641081{
    1065     startRenderer = m_selectionStart;
    1066     startOffset = m_selectionStartPos;
    1067     endRenderer = m_selectionEnd;
    1068     endOffset = m_selectionEndPos;
     1082    startRenderer = m_unsplitSelectionStart;
     1083    startOffset = m_unsplitSelectionStartPos;
     1084    endRenderer = m_unsplitSelectionEnd;
     1085    endOffset = m_unsplitSelectionEndPos;
    10691086}
    10701087
  • trunk/Source/WebCore/rendering/RenderView.h

    r170774 r171218  
    9090    void getSelection(RenderObject*& startRenderer, int& startOffset, RenderObject*& endRenderer, int& endOffset) const;
    9191    void clearSelection();
    92     RenderObject* selectionStart() const { return m_selectionStart; }
    93     RenderObject* selectionEnd() const { return m_selectionEnd; }
     92    RenderObject* selectionUnsplitStart() const { return m_unsplitSelectionStart; }
     93    RenderObject* selectionUnsplitEnd() const { return m_unsplitSelectionEnd; }
    9494    IntRect selectionBounds(bool clipToVisibleContent = true) const;
    9595    void repaintSelection() const;
     
    305305
    306306    void splitSelectionBetweenSubtrees(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode blockRepaintMode);
    307     void setSubtreeSelection(SelectionSubtreeRoot&, RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode);
     307    void clearSubtreeSelection(const SelectionSubtreeRoot&, SelectionRepaintMode, OldSelectionData&);
     308    void updateSelectionForSubtrees(RenderSubtreesMap&, SelectionRepaintMode);
     309    void applySubtreeSelection(SelectionSubtreeRoot&, RenderObject* start, RenderObject* end, int endPos, SelectionRepaintMode, const OldSelectionData&);
    308310    LayoutRect subtreeSelectionBounds(const SelectionSubtreeRoot&, bool clipToVisibleContent = true) const;
    309311    void repaintSubtreeSelection(const SelectionSubtreeRoot&) const;
     
    312314    FrameView& m_frameView;
    313315
    314     RenderObject* m_selectionStart;
    315     RenderObject* m_selectionEnd;
    316     int m_selectionStartPos;
    317     int m_selectionEndPos;
     316    RenderObject* m_unsplitSelectionStart;
     317    RenderObject* m_unsplitSelectionEnd;
     318    int m_unsplitSelectionStartPos;
     319    int m_unsplitSelectionEndPos;
    318320
    319321    uint64_t m_rendererCount;
  • trunk/Source/WebCore/rendering/SelectionSubtreeRoot.cpp

    r169273 r171218  
    4646}
    4747
     48SelectionSubtreeRoot::SelectionSubtreeRoot(RenderObject* selectionStart, int selectionStartPos, RenderObject* selectionEnd, int selectionEndPos)
     49    : m_selectionStart(selectionStart)
     50    , m_selectionStartPos(selectionStartPos)
     51    , m_selectionEnd(selectionEnd)
     52    , m_selectionEndPos(selectionEndPos)
     53{
     54}
     55
    4856void SelectionSubtreeRoot::adjustForVisibleSelection(Document& document)
    4957{
  • trunk/Source/WebCore/rendering/SelectionSubtreeRoot.h

    r169273 r171218  
    3232
    3333#include "RenderObject.h"
     34#include "RenderSelectionInfo.h"
    3435
    3536namespace WebCore {
     
    3940class SelectionSubtreeRoot {
    4041public:
     42   
     43    typedef HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>> SelectedObjectMap;
     44    typedef HashMap<RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>> SelectedBlockMap;
     45    typedef HashMap<SelectionSubtreeRoot*, SelectionSubtreeRoot> RenderSubtreesMap;
     46
     47    struct OldSelectionData {
     48        OldSelectionData()
     49            : selectionStartPos(-1)
     50            , selectionEndPos(-1)
     51        {
     52        }
     53
     54        int selectionStartPos;
     55        int selectionEndPos;
     56        SelectedObjectMap selectedObjects;
     57        SelectedBlockMap selectedBlocks;
     58    };
     59   
     60    typedef HashMap<SelectionSubtreeRoot*, std::unique_ptr<OldSelectionData>> SubtreeOldSelectionDataMap;
    4161
    4262    SelectionSubtreeRoot();
     63    SelectionSubtreeRoot(RenderObject* selectionStart, int selectionStartPos, RenderObject* selectionEnd, int selectionEndPos);
    4364
    4465    RenderObject* selectionStart() const { return m_selectionStart; }
Note: See TracChangeset for help on using the changeset viewer.