Chromium Code Reviews| Index: Source/core/rendering/RenderView.cpp |
| diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp |
| index 294735b508bd2683e1e7260aeb3c54a732808b3a..311da43cf9193d467861e15bed9d73be7c47611f 100644 |
| --- a/Source/core/rendering/RenderView.cpp |
| +++ b/Source/core/rendering/RenderView.cpp |
| @@ -514,6 +514,19 @@ static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const Rend |
| return next; |
| } |
| +static void invalidateSelectionForRenderer(RenderObject* object) |
| +{ |
| + object->setShouldInvalidateSelection(); |
| + if (object->isBox()) { |
|
dsinclair
2014/10/31 14:03:16
if (!object->isBox())
return;
I dislike inden
|
| + RenderBox* box = toRenderBox(object); |
| + // FIXME(jchaffraix): ShapeOutside can trigger SVGImage loading, which reruns the whole state machine |
| + // in FrameView::updateLayoutAndStyleForPaint. It's allowed to do it in the post-layout hook (why?) |
| + // but not during the invalidation phase so we just match the current code by forcing the loading to happen here. |
|
dsinclair
2014/10/31 14:03:16
Can we add a crbug for this so we don't lose track
Julien - ping for review
2014/10/31 22:31:03
https://code.google.com/p/chromium/issues/detail?i
|
| + if (ShapeOutsideInfo* shapeInfo = box->shapeOutsideInfo()) |
| + shapeInfo->computedShape(); |
| + } |
| +} |
| + |
| void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) |
| { |
| // This code makes no assumptions as to if the rendering tree is up to date or not |
| @@ -537,15 +550,19 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e |
| int oldEndPos = m_selectionEndPos; |
| // Objects each have a single selection rect to examine. |
| - typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, OwnPtrWillBeMember<RenderSelectionInfo> > SelectedObjectMap; |
| + typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, SelectionState > SelectedObjectMap; |
|
dsinclair
2014/10/31 14:03:16
nit: Don't need the space between SelectionState a
|
| SelectedObjectMap oldSelectedObjects; |
| + // FIXME: |newSelectedObjects| doesn't really need to store the SelectionState, it's just more convenient |
| + // to have it use the same data structure as |oldSelectedObjects|. |
| SelectedObjectMap newSelectedObjects; |
| // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks. |
| // In order to get the paint invalidation rect right, we have to examine left, middle, and right rects individually, since otherwise |
| // the union of those rects might remain the same even when changes have occurred. |
| - typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, OwnPtrWillBeMember<RenderBlockSelectionInfo> > SelectedBlockMap; |
| + typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, SelectionState > SelectedBlockMap; |
| SelectedBlockMap oldSelectedBlocks; |
| + // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionState, it's just more convenient |
| + // to have it use the same data structure as |oldSelectedBlocks|. |
| SelectedBlockMap newSelectedBlocks; |
| RenderObject* os = m_selectionStart; |
| @@ -555,14 +572,13 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e |
| while (continueExploring) { |
| if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selectionEnd) && os->selectionState() != SelectionNone) { |
| // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well. |
| - oldSelectedObjects.set(os, adoptPtrWillBeNoop(new RenderSelectionInfo(os))); |
| + oldSelectedObjects.set(os, os->selectionState()); |
| if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { |
| RenderBlock* cb = os->containingBlock(); |
| while (cb && !cb->isRenderView()) { |
| - OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = oldSelectedBlocks.add(cb, nullptr).storedValue->value; |
| - if (blockInfo) |
| + SelectedBlockMap::AddResult result = oldSelectedBlocks.add(cb, cb->selectionState()); |
| + if (!result.isNewEntry) |
| break; |
| - blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb)); |
| cb = cb->containingBlock(); |
| } |
| } |
| @@ -610,13 +626,12 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e |
| continueExploring = o && (o != stop); |
| while (continueExploring) { |
| if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionState() != SelectionNone) { |
| - newSelectedObjects.set(o, adoptPtrWillBeNoop(new RenderSelectionInfo(o))); |
| + newSelectedObjects.set(o, o->selectionState()); |
| RenderBlock* cb = o->containingBlock(); |
| while (cb && !cb->isRenderView()) { |
| - OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(cb, nullptr).storedValue->value; |
| - if (blockInfo) |
| + SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, cb->selectionState()); |
| + if (!result.isNewEntry) |
| break; |
| - blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb)); |
| cb = cb->containingBlock(); |
| } |
| } |
| @@ -630,43 +645,30 @@ void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e |
| // Have any of the old selected objects changed compared to the new selection? |
| for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObjectsEnd; ++i) { |
| RenderObject* obj = i->key; |
| - RenderSelectionInfo* newInfo = newSelectedObjects.get(obj); |
| - RenderSelectionInfo* oldInfo = i->value.get(); |
| - if (!newInfo || newInfo->hasChangedFrom(*oldInfo) |
| + SelectionState newSelectionState = obj->selectionState(); |
| + SelectionState oldSelectionState = i->value; |
| + if (newSelectionState != oldSelectionState |
| || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) |
| || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { |
| - oldInfo->invalidatePaint(); |
| - if (newInfo) { |
| - newInfo->object()->setShouldInvalidateSelection(); |
| - newSelectedObjects.remove(obj); |
| - } |
| + invalidateSelectionForRenderer(obj); |
| + newSelectedObjects.remove(obj); |
| } |
| } |
| // Any new objects that remain were not found in the old objects dict, and so they need to be updated. |
| SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end(); |
| for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObjectsEnd; ++i) |
| - i->value->object()->setShouldInvalidateSelection(); |
| + invalidateSelectionForRenderer(i->key); |
| // Have any of the old blocks changed? |
| SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end(); |
| - for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) { |
| - RenderBlock* block = i->key; |
| - RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block); |
| - RenderBlockSelectionInfo* oldInfo = i->value.get(); |
| - if (!newInfo || newInfo->hasChangedFrom(*oldInfo)) { |
| - oldInfo->invalidatePaint(); |
| - if (newInfo) { |
| - newInfo->object()->setShouldInvalidateSelection(); |
| - newSelectedBlocks.remove(block); |
| - } |
| - } |
| - } |
| + for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlocksEnd; ++i) |
| + invalidateSelectionForRenderer(i->key); |
| // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. |
| SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end(); |
| for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlocksEnd; ++i) |
| - i->value->object()->setShouldInvalidateSelection(); |
| + invalidateSelectionForRenderer(i->key); |
| } |
| void RenderView::clearSelection() |