| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) | 2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org) |
| 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. | 3 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserv
ed. |
| 4 * | 4 * |
| 5 * This library is free software; you can redistribute it and/or | 5 * This library is free software; you can redistribute it and/or |
| 6 * modify it under the terms of the GNU Library General Public | 6 * modify it under the terms of the GNU Library General Public |
| 7 * License as published by the Free Software Foundation; either | 7 * License as published by the Free Software Foundation; either |
| 8 * version 2 of the License, or (at your option) any later version. | 8 * version 2 of the License, or (at your option) any later version. |
| 9 * | 9 * |
| 10 * This library is distributed in the hope that it will be useful, | 10 * This library is distributed in the hope that it will be useful, |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 56 , m_selectionEnd(nullptr) | 56 , m_selectionEnd(nullptr) |
| 57 , m_selectionStartPos(-1) | 57 , m_selectionStartPos(-1) |
| 58 , m_selectionEndPos(-1) | 58 , m_selectionEndPos(-1) |
| 59 , m_pageLogicalHeight(0) | 59 , m_pageLogicalHeight(0) |
| 60 , m_pageLogicalHeightChanged(false) | 60 , m_pageLogicalHeightChanged(false) |
| 61 , m_layoutState(0) | 61 , m_layoutState(0) |
| 62 , m_renderQuoteHead(nullptr) | 62 , m_renderQuoteHead(nullptr) |
| 63 , m_layoutCounterCount(0) | 63 , m_layoutCounterCount(0) |
| 64 , m_hitTestCount(0) | 64 , m_hitTestCount(0) |
| 65 { | 65 { |
| 66 // init RenderObject attributes | 66 // init LayoutObject attributes |
| 67 setInline(false); | 67 setInline(false); |
| 68 | 68 |
| 69 m_minPreferredLogicalWidth = 0; | 69 m_minPreferredLogicalWidth = 0; |
| 70 m_maxPreferredLogicalWidth = 0; | 70 m_maxPreferredLogicalWidth = 0; |
| 71 | 71 |
| 72 setPreferredLogicalWidthsDirty(MarkOnlyThis); | 72 setPreferredLogicalWidthsDirty(MarkOnlyThis); |
| 73 | 73 |
| 74 setPositionState(AbsolutePosition); // to 0,0 :) | 74 setPositionState(AbsolutePosition); // to 0,0 :) |
| 75 } | 75 } |
| 76 | 76 |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 120 } | 120 } |
| 121 | 121 |
| 122 LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightT
ype) const | 122 LayoutUnit RenderView::availableLogicalHeight(AvailableLogicalHeightType heightT
ype) const |
| 123 { | 123 { |
| 124 // If we have columns, then the available logical height is reduced to the c
olumn height. | 124 // If we have columns, then the available logical height is reduced to the c
olumn height. |
| 125 if (hasColumns()) | 125 if (hasColumns()) |
| 126 return columnInfo()->columnHeight(); | 126 return columnInfo()->columnHeight(); |
| 127 return RenderBlockFlow::availableLogicalHeight(heightType); | 127 return RenderBlockFlow::availableLogicalHeight(heightType); |
| 128 } | 128 } |
| 129 | 129 |
| 130 bool RenderView::isChildAllowed(RenderObject* child, const RenderStyle&) const | 130 bool RenderView::isChildAllowed(LayoutObject* child, const RenderStyle&) const |
| 131 { | 131 { |
| 132 return child->isBox(); | 132 return child->isBox(); |
| 133 } | 133 } |
| 134 | 134 |
| 135 void RenderView::layoutContent() | 135 void RenderView::layoutContent() |
| 136 { | 136 { |
| 137 ASSERT(needsLayout()); | 137 ASSERT(needsLayout()); |
| 138 | 138 |
| 139 RenderBlockFlow::layout(); | 139 RenderBlockFlow::layout(); |
| 140 | 140 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 158 // and discrete paint invalidation rects, so marking full paint invalidation
here is more likely to cost less. | 158 // and discrete paint invalidation rects, so marking full paint invalidation
here is more likely to cost less. |
| 159 // Otherwise, per-descendant paint invalidation is more likely to avoid unne
cessary full paint invalidation. | 159 // Otherwise, per-descendant paint invalidation is more likely to avoid unne
cessary full paint invalidation. |
| 160 | 160 |
| 161 if (shouldUsePrintingLayout()) | 161 if (shouldUsePrintingLayout()) |
| 162 return true; | 162 return true; |
| 163 | 163 |
| 164 if (!style()->isHorizontalWritingMode() || size().width() != viewWidth()) | 164 if (!style()->isHorizontalWritingMode() || size().width() != viewWidth()) |
| 165 return true; | 165 return true; |
| 166 | 166 |
| 167 if (size().height() != viewHeight()) { | 167 if (size().height() != viewHeight()) { |
| 168 if (RenderObject* backgroundRenderer = this->backgroundRenderer()) { | 168 if (LayoutObject* backgroundRenderer = this->backgroundRenderer()) { |
| 169 // When background-attachment is 'fixed', we treat the viewport (ins
tead of the 'root' | 169 // When background-attachment is 'fixed', we treat the viewport (ins
tead of the 'root' |
| 170 // i.e. html or body) as the background positioning area, and we sho
uld full paint invalidation | 170 // i.e. html or body) as the background positioning area, and we sho
uld full paint invalidation |
| 171 // viewport resize if the background image is not composited and nee
ds full paint invalidation on | 171 // viewport resize if the background image is not composited and nee
ds full paint invalidation on |
| 172 // background positioning area resize. | 172 // background positioning area resize. |
| 173 if (!m_compositor || !m_compositor->needsFixedRootBackgroundLayer(la
yer())) { | 173 if (!m_compositor || !m_compositor->needsFixedRootBackgroundLayer(la
yer())) { |
| 174 if (backgroundRenderer->style()->hasFixedBackgroundImage() | 174 if (backgroundRenderer->style()->hasFixedBackgroundImage() |
| 175 && mustInvalidateFillLayersPaintOnHeightChange(backgroundRen
derer->style()->backgroundLayers())) | 175 && mustInvalidateFillLayersPaintOnHeightChange(backgroundRen
derer->style()->backgroundLayers())) |
| 176 return true; | 176 return true; |
| 177 } | 177 } |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 | 180 |
| 181 return false; | 181 return false; |
| 182 } | 182 } |
| 183 | 183 |
| 184 void RenderView::layout() | 184 void RenderView::layout() |
| 185 { | 185 { |
| 186 if (!document().paginated()) | 186 if (!document().paginated()) |
| 187 setPageLogicalHeight(0); | 187 setPageLogicalHeight(0); |
| 188 | 188 |
| 189 if (shouldUsePrintingLayout()) | 189 if (shouldUsePrintingLayout()) |
| 190 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth()
; | 190 m_minPreferredLogicalWidth = m_maxPreferredLogicalWidth = logicalWidth()
; |
| 191 | 191 |
| 192 SubtreeLayoutScope layoutScope(*this); | 192 SubtreeLayoutScope layoutScope(*this); |
| 193 | 193 |
| 194 // Use calcWidth/Height to get the new width/height, since this will take th
e full page zoom factor into account. | 194 // Use calcWidth/Height to get the new width/height, since this will take th
e full page zoom factor into account. |
| 195 bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || size(
).width() != viewWidth() || size().height() != viewHeight()); | 195 bool relayoutChildren = !shouldUsePrintingLayout() && (!m_frameView || size(
).width() != viewWidth() || size().height() != viewHeight()); |
| 196 if (relayoutChildren) { | 196 if (relayoutChildren) { |
| 197 layoutScope.setChildNeedsLayout(this); | 197 layoutScope.setChildNeedsLayout(this); |
| 198 for (RenderObject* child = firstChild(); child; child = child->nextSibli
ng()) { | 198 for (LayoutObject* child = firstChild(); child; child = child->nextSibli
ng()) { |
| 199 if (child->isSVGRoot()) | 199 if (child->isSVGRoot()) |
| 200 continue; | 200 continue; |
| 201 | 201 |
| 202 if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight(
)) | 202 if ((child->isBox() && toRenderBox(child)->hasRelativeLogicalHeight(
)) |
| 203 || child->style()->logicalHeight().isPercent() | 203 || child->style()->logicalHeight().isPercent() |
| 204 || child->style()->logicalMinHeight().isPercent() | 204 || child->style()->logicalMinHeight().isPercent() |
| 205 || child->style()->logicalMaxHeight().isPercent()) | 205 || child->style()->logicalMaxHeight().isPercent()) |
| 206 layoutScope.setChildNeedsLayout(child); | 206 layoutScope.setChildNeedsLayout(child); |
| 207 } | 207 } |
| 208 | 208 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 239 if ((mode & IsFixed) && m_frameView) { | 239 if ((mode & IsFixed) && m_frameView) { |
| 240 transformState.move(m_frameView->scrollOffsetForViewportConstrainedObjec
ts()); | 240 transformState.move(m_frameView->scrollOffsetForViewportConstrainedObjec
ts()); |
| 241 // IsFixed flag is only applicable within this RenderView. | 241 // IsFixed flag is only applicable within this RenderView. |
| 242 mode &= ~IsFixed; | 242 mode &= ~IsFixed; |
| 243 } | 243 } |
| 244 | 244 |
| 245 if (paintInvalidationContainer == this) | 245 if (paintInvalidationContainer == this) |
| 246 return; | 246 return; |
| 247 | 247 |
| 248 if (mode & TraverseDocumentBoundaries) { | 248 if (mode & TraverseDocumentBoundaries) { |
| 249 if (RenderObject* parentDocRenderer = frame()->ownerRenderer()) { | 249 if (LayoutObject* parentDocRenderer = frame()->ownerRenderer()) { |
| 250 transformState.move(-frame()->view()->scrollOffset()); | 250 transformState.move(-frame()->view()->scrollOffset()); |
| 251 if (parentDocRenderer->isBox()) | 251 if (parentDocRenderer->isBox()) |
| 252 transformState.move(toRenderBox(parentDocRenderer)->contentBoxOf
fset()); | 252 transformState.move(toRenderBox(parentDocRenderer)->contentBoxOf
fset()); |
| 253 parentDocRenderer->mapLocalToContainer(paintInvalidationContainer, t
ransformState, mode, wasFixed, paintInvalidationState); | 253 parentDocRenderer->mapLocalToContainer(paintInvalidationContainer, t
ransformState, mode, wasFixed, paintInvalidationState); |
| 254 return; | 254 return; |
| 255 } | 255 } |
| 256 } | 256 } |
| 257 } | 257 } |
| 258 | 258 |
| 259 const RenderObject* RenderView::pushMappingToContainer(const LayoutLayerModelObj
ect* ancestorToStopAt, RenderGeometryMap& geometryMap) const | 259 const LayoutObject* RenderView::pushMappingToContainer(const LayoutLayerModelObj
ect* ancestorToStopAt, RenderGeometryMap& geometryMap) const |
| 260 { | 260 { |
| 261 LayoutSize offsetForFixedPosition; | 261 LayoutSize offsetForFixedPosition; |
| 262 LayoutSize offset; | 262 LayoutSize offset; |
| 263 RenderObject* container = 0; | 263 LayoutObject* container = 0; |
| 264 | 264 |
| 265 if (m_frameView) | 265 if (m_frameView) |
| 266 offsetForFixedPosition = LayoutSize(m_frameView->scrollOffsetForViewport
ConstrainedObjects()); | 266 offsetForFixedPosition = LayoutSize(m_frameView->scrollOffsetForViewport
ConstrainedObjects()); |
| 267 | 267 |
| 268 if (geometryMap.mapCoordinatesFlags() & TraverseDocumentBoundaries) { | 268 if (geometryMap.mapCoordinatesFlags() & TraverseDocumentBoundaries) { |
| 269 if (RenderPart* parentDocRenderer = frame()->ownerRenderer()) { | 269 if (RenderPart* parentDocRenderer = frame()->ownerRenderer()) { |
| 270 offset = -LayoutSize(m_frameView->scrollOffset()); | 270 offset = -LayoutSize(m_frameView->scrollOffset()); |
| 271 offset += parentDocRenderer->contentBoxOffset(); | 271 offset += parentDocRenderer->contentBoxOffset(); |
| 272 container = parentDocRenderer; | 272 container = parentDocRenderer; |
| 273 } | 273 } |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 rects.append(pixelSnappedIntRect(accumulatedOffset, LayoutSize(layer()->size
()))); | 429 rects.append(pixelSnappedIntRect(accumulatedOffset, LayoutSize(layer()->size
()))); |
| 430 } | 430 } |
| 431 | 431 |
| 432 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const | 432 void RenderView::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const |
| 433 { | 433 { |
| 434 if (wasFixed) | 434 if (wasFixed) |
| 435 *wasFixed = false; | 435 *wasFixed = false; |
| 436 quads.append(FloatRect(FloatPoint(), layer()->size())); | 436 quads.append(FloatRect(FloatPoint(), layer()->size())); |
| 437 } | 437 } |
| 438 | 438 |
| 439 static RenderObject* rendererAfterPosition(RenderObject* object, unsigned offset
) | 439 static LayoutObject* rendererAfterPosition(LayoutObject* object, unsigned offset
) |
| 440 { | 440 { |
| 441 if (!object) | 441 if (!object) |
| 442 return 0; | 442 return 0; |
| 443 | 443 |
| 444 RenderObject* child = object->childAt(offset); | 444 LayoutObject* child = object->childAt(offset); |
| 445 return child ? child : object->nextInPreOrderAfterChildren(); | 445 return child ? child : object->nextInPreOrderAfterChildren(); |
| 446 } | 446 } |
| 447 | 447 |
| 448 static LayoutRect selectionRectForRenderer(const RenderObject* object) | 448 static LayoutRect selectionRectForRenderer(const LayoutObject* object) |
| 449 { | 449 { |
| 450 if (!object->isRooted()) | 450 if (!object->isRooted()) |
| 451 return LayoutRect(); | 451 return LayoutRect(); |
| 452 | 452 |
| 453 if (!object->canUpdateSelectionOnRootLineBoxes()) | 453 if (!object->canUpdateSelectionOnRootLineBoxes()) |
| 454 return LayoutRect(); | 454 return LayoutRect(); |
| 455 | 455 |
| 456 return object->selectionRectForPaintInvalidation(object->containerForPaintIn
validation()); | 456 return object->selectionRectForPaintInvalidation(object->containerForPaintIn
validation()); |
| 457 } | 457 } |
| 458 | 458 |
| 459 IntRect RenderView::selectionBounds() | 459 IntRect RenderView::selectionBounds() |
| 460 { | 460 { |
| 461 // Now create a single bounding box rect that encloses the whole selection. | 461 // Now create a single bounding box rect that encloses the whole selection. |
| 462 LayoutRect selRect; | 462 LayoutRect selRect; |
| 463 | 463 |
| 464 typedef HashSet<const RenderBlock*> VisitedContainingBlockSet; | 464 typedef HashSet<const RenderBlock*> VisitedContainingBlockSet; |
| 465 VisitedContainingBlockSet visitedContainingBlocks; | 465 VisitedContainingBlockSet visitedContainingBlocks; |
| 466 | 466 |
| 467 commitPendingSelection(); | 467 commitPendingSelection(); |
| 468 RenderObject* os = m_selectionStart; | 468 LayoutObject* os = m_selectionStart; |
| 469 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos
); | 469 LayoutObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos
); |
| 470 while (os && os != stop) { | 470 while (os && os != stop) { |
| 471 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec
tionEnd) && os->selectionState() != SelectionNone) { | 471 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec
tionEnd) && os->selectionState() != SelectionNone) { |
| 472 // Blocks are responsible for painting line gaps and margin gaps. Th
ey must be examined as well. | 472 // Blocks are responsible for painting line gaps and margin gaps. Th
ey must be examined as well. |
| 473 selRect.unite(selectionRectForRenderer(os)); | 473 selRect.unite(selectionRectForRenderer(os)); |
| 474 const RenderBlock* cb = os->containingBlock(); | 474 const RenderBlock* cb = os->containingBlock(); |
| 475 while (cb && !cb->isRenderView()) { | 475 while (cb && !cb->isRenderView()) { |
| 476 selRect.unite(selectionRectForRenderer(cb)); | 476 selRect.unite(selectionRectForRenderer(cb)); |
| 477 VisitedContainingBlockSet::AddResult addResult = visitedContaini
ngBlocks.add(cb); | 477 VisitedContainingBlockSet::AddResult addResult = visitedContaini
ngBlocks.add(cb); |
| 478 if (!addResult.isNewEntry) | 478 if (!addResult.isNewEntry) |
| 479 break; | 479 break; |
| 480 cb = cb->containingBlock(); | 480 cb = cb->containingBlock(); |
| 481 } | 481 } |
| 482 } | 482 } |
| 483 | 483 |
| 484 os = os->nextInPreOrder(); | 484 os = os->nextInPreOrder(); |
| 485 } | 485 } |
| 486 | 486 |
| 487 return pixelSnappedIntRect(selRect); | 487 return pixelSnappedIntRect(selRect); |
| 488 } | 488 } |
| 489 | 489 |
| 490 void RenderView::invalidatePaintForSelection() | 490 void RenderView::invalidatePaintForSelection() |
| 491 { | 491 { |
| 492 HashSet<RenderBlock*> processedBlocks; | 492 HashSet<RenderBlock*> processedBlocks; |
| 493 | 493 |
| 494 RenderObject* end = rendererAfterPosition(m_selectionEnd, m_selectionEndPos)
; | 494 LayoutObject* end = rendererAfterPosition(m_selectionEnd, m_selectionEndPos)
; |
| 495 for (RenderObject* o = m_selectionStart; o && o != end; o = o->nextInPreOrde
r()) { | 495 for (LayoutObject* o = m_selectionStart; o && o != end; o = o->nextInPreOrde
r()) { |
| 496 if (!o->canBeSelectionLeaf() && o != m_selectionStart && o != m_selectio
nEnd) | 496 if (!o->canBeSelectionLeaf() && o != m_selectionStart && o != m_selectio
nEnd) |
| 497 continue; | 497 continue; |
| 498 if (o->selectionState() == SelectionNone) | 498 if (o->selectionState() == SelectionNone) |
| 499 continue; | 499 continue; |
| 500 | 500 |
| 501 o->setShouldInvalidateSelection(); | 501 o->setShouldInvalidateSelection(); |
| 502 | 502 |
| 503 // Blocks are responsible for painting line gaps and margin gaps. They m
ust be examined as well. | 503 // Blocks are responsible for painting line gaps and margin gaps. They m
ust be examined as well. |
| 504 for (RenderBlock* block = o->containingBlock(); block && !block->isRende
rView(); block = block->containingBlock()) { | 504 for (RenderBlock* block = o->containingBlock(); block && !block->isRende
rView(); block = block->containingBlock()) { |
| 505 if (!processedBlocks.add(block).isNewEntry) | 505 if (!processedBlocks.add(block).isNewEntry) |
| 506 break; | 506 break; |
| 507 block->setShouldInvalidateSelection(); | 507 block->setShouldInvalidateSelection(); |
| 508 } | 508 } |
| 509 } | 509 } |
| 510 } | 510 } |
| 511 | 511 |
| 512 // When exploring the RenderTree looking for the nodes involved in the Selection
, sometimes it's | 512 // When exploring the RenderTree looking for the nodes involved in the Selection
, sometimes it's |
| 513 // required to change the traversing direction because the "start" position is b
elow the "end" one. | 513 // required to change the traversing direction because the "start" position is b
elow the "end" one. |
| 514 static inline RenderObject* getNextOrPrevRenderObjectBasedOnDirection(const Rend
erObject* o, const RenderObject* stop, bool& continueExploring, bool& exploringB
ackwards) | 514 static inline LayoutObject* getNextOrPrevLayoutObjectBasedOnDirection(const Layo
utObject* o, const LayoutObject* stop, bool& continueExploring, bool& exploringB
ackwards) |
| 515 { | 515 { |
| 516 RenderObject* next; | 516 LayoutObject* next; |
| 517 if (exploringBackwards) { | 517 if (exploringBackwards) { |
| 518 next = o->previousInPreOrder(); | 518 next = o->previousInPreOrder(); |
| 519 continueExploring = next && !(next)->isRenderView(); | 519 continueExploring = next && !(next)->isRenderView(); |
| 520 } else { | 520 } else { |
| 521 next = o->nextInPreOrder(); | 521 next = o->nextInPreOrder(); |
| 522 continueExploring = next && next != stop; | 522 continueExploring = next && next != stop; |
| 523 exploringBackwards = !next && (next != stop); | 523 exploringBackwards = !next && (next != stop); |
| 524 if (exploringBackwards) { | 524 if (exploringBackwards) { |
| 525 next = stop->previousInPreOrder(); | 525 next = stop->previousInPreOrder(); |
| 526 continueExploring = next && !next->isRenderView(); | 526 continueExploring = next && !next->isRenderView(); |
| 527 } | 527 } |
| 528 } | 528 } |
| 529 | 529 |
| 530 return next; | 530 return next; |
| 531 } | 531 } |
| 532 | 532 |
| 533 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e
nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) | 533 void RenderView::setSelection(LayoutObject* start, int startPos, LayoutObject* e
nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) |
| 534 { | 534 { |
| 535 // This code makes no assumptions as to if the rendering tree is up to date
or not | 535 // This code makes no assumptions as to if the rendering tree is up to date
or not |
| 536 // and will not try to update it. Currently clearSelection calls this | 536 // and will not try to update it. Currently clearSelection calls this |
| 537 // (intentionally) without updating the rendering tree as it doesn't care. | 537 // (intentionally) without updating the rendering tree as it doesn't care. |
| 538 // Other callers may want to force recalc style before calling this. | 538 // Other callers may want to force recalc style before calling this. |
| 539 | 539 |
| 540 // Make sure both our start and end objects are defined. | 540 // Make sure both our start and end objects are defined. |
| 541 // Check www.msnbc.com and try clicking around to find the case where this h
appened. | 541 // Check www.msnbc.com and try clicking around to find the case where this h
appened. |
| 542 if ((start && !end) || (end && !start)) | 542 if ((start && !end) || (end && !start)) |
| 543 return; | 543 return; |
| 544 | 544 |
| 545 // Just return if the selection hasn't changed. | 545 // Just return if the selection hasn't changed. |
| 546 if (m_selectionStart == start && m_selectionStartPos == startPos && | 546 if (m_selectionStart == start && m_selectionStartPos == startPos && |
| 547 m_selectionEnd == end && m_selectionEndPos == endPos) | 547 m_selectionEnd == end && m_selectionEndPos == endPos) |
| 548 return; | 548 return; |
| 549 | 549 |
| 550 // Record the old selected objects. These will be used later | 550 // Record the old selected objects. These will be used later |
| 551 // when we compare against the new selected objects. | 551 // when we compare against the new selected objects. |
| 552 int oldStartPos = m_selectionStartPos; | 552 int oldStartPos = m_selectionStartPos; |
| 553 int oldEndPos = m_selectionEndPos; | 553 int oldEndPos = m_selectionEndPos; |
| 554 | 554 |
| 555 // Objects each have a single selection rect to examine. | 555 // Objects each have a single selection rect to examine. |
| 556 typedef HashMap<RenderObject*, SelectionState> SelectedObjectMap; | 556 typedef HashMap<LayoutObject*, SelectionState> SelectedObjectMap; |
| 557 SelectedObjectMap oldSelectedObjects; | 557 SelectedObjectMap oldSelectedObjects; |
| 558 // FIXME: |newSelectedObjects| doesn't really need to store the SelectionSta
te, it's just more convenient | 558 // FIXME: |newSelectedObjects| doesn't really need to store the SelectionSta
te, it's just more convenient |
| 559 // to have it use the same data structure as |oldSelectedObjects|. | 559 // to have it use the same data structure as |oldSelectedObjects|. |
| 560 SelectedObjectMap newSelectedObjects; | 560 SelectedObjectMap newSelectedObjects; |
| 561 | 561 |
| 562 // Blocks contain selected objects and fill gaps between them, either on the
left, right, or in between lines and blocks. | 562 // Blocks contain selected objects and fill gaps between them, either on the
left, right, or in between lines and blocks. |
| 563 // In order to get the paint invalidation rect right, we have to examine lef
t, middle, and right rects individually, since otherwise | 563 // In order to get the paint invalidation rect right, we have to examine lef
t, middle, and right rects individually, since otherwise |
| 564 // the union of those rects might remain the same even when changes have occ
urred. | 564 // the union of those rects might remain the same even when changes have occ
urred. |
| 565 typedef HashMap<RenderBlock*, SelectionState> SelectedBlockMap; | 565 typedef HashMap<RenderBlock*, SelectionState> SelectedBlockMap; |
| 566 SelectedBlockMap oldSelectedBlocks; | 566 SelectedBlockMap oldSelectedBlocks; |
| 567 // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionStat
e, it's just more convenient | 567 // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionStat
e, it's just more convenient |
| 568 // to have it use the same data structure as |oldSelectedBlocks|. | 568 // to have it use the same data structure as |oldSelectedBlocks|. |
| 569 SelectedBlockMap newSelectedBlocks; | 569 SelectedBlockMap newSelectedBlocks; |
| 570 | 570 |
| 571 RenderObject* os = m_selectionStart; | 571 LayoutObject* os = m_selectionStart; |
| 572 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos
); | 572 LayoutObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos
); |
| 573 bool exploringBackwards = false; | 573 bool exploringBackwards = false; |
| 574 bool continueExploring = os && (os != stop); | 574 bool continueExploring = os && (os != stop); |
| 575 while (continueExploring) { | 575 while (continueExploring) { |
| 576 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec
tionEnd) && os->selectionState() != SelectionNone) { | 576 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec
tionEnd) && os->selectionState() != SelectionNone) { |
| 577 // Blocks are responsible for painting line gaps and margin gaps. T
hey must be examined as well. | 577 // Blocks are responsible for painting line gaps and margin gaps. T
hey must be examined as well. |
| 578 oldSelectedObjects.set(os, os->selectionState()); | 578 oldSelectedObjects.set(os, os->selectionState()); |
| 579 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { | 579 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { |
| 580 RenderBlock* cb = os->containingBlock(); | 580 RenderBlock* cb = os->containingBlock(); |
| 581 while (cb && !cb->isRenderView()) { | 581 while (cb && !cb->isRenderView()) { |
| 582 SelectedBlockMap::AddResult result = oldSelectedBlocks.add(c
b, cb->selectionState()); | 582 SelectedBlockMap::AddResult result = oldSelectedBlocks.add(c
b, cb->selectionState()); |
| 583 if (!result.isNewEntry) | 583 if (!result.isNewEntry) |
| 584 break; | 584 break; |
| 585 cb = cb->containingBlock(); | 585 cb = cb->containingBlock(); |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 } | 588 } |
| 589 | 589 |
| 590 os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExplori
ng, exploringBackwards); | 590 os = getNextOrPrevLayoutObjectBasedOnDirection(os, stop, continueExplori
ng, exploringBackwards); |
| 591 } | 591 } |
| 592 | 592 |
| 593 // Now clear the selection. | 593 // Now clear the selection. |
| 594 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); | 594 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); |
| 595 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj
ectsEnd; ++i) | 595 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj
ectsEnd; ++i) |
| 596 i->key->setSelectionStateIfNeeded(SelectionNone); | 596 i->key->setSelectionStateIfNeeded(SelectionNone); |
| 597 | 597 |
| 598 // set selection start and end | 598 // set selection start and end |
| 599 m_selectionStart = start; | 599 m_selectionStart = start; |
| 600 m_selectionStartPos = startPos; | 600 m_selectionStartPos = startPos; |
| 601 m_selectionEnd = end; | 601 m_selectionEnd = end; |
| 602 m_selectionEndPos = endPos; | 602 m_selectionEndPos = endPos; |
| 603 | 603 |
| 604 // Update the selection status of all objects between m_selectionStart and m
_selectionEnd | 604 // Update the selection status of all objects between m_selectionStart and m
_selectionEnd |
| 605 if (start && start == end) | 605 if (start && start == end) |
| 606 start->setSelectionStateIfNeeded(SelectionBoth); | 606 start->setSelectionStateIfNeeded(SelectionBoth); |
| 607 else { | 607 else { |
| 608 if (start) | 608 if (start) |
| 609 start->setSelectionStateIfNeeded(SelectionStart); | 609 start->setSelectionStateIfNeeded(SelectionStart); |
| 610 if (end) | 610 if (end) |
| 611 end->setSelectionStateIfNeeded(SelectionEnd); | 611 end->setSelectionStateIfNeeded(SelectionEnd); |
| 612 } | 612 } |
| 613 | 613 |
| 614 RenderObject* o = start; | 614 LayoutObject* o = start; |
| 615 stop = rendererAfterPosition(end, endPos); | 615 stop = rendererAfterPosition(end, endPos); |
| 616 | 616 |
| 617 while (o && o != stop) { | 617 while (o && o != stop) { |
| 618 if (o != start && o != end && o->canBeSelectionLeaf()) | 618 if (o != start && o != end && o->canBeSelectionLeaf()) |
| 619 o->setSelectionStateIfNeeded(SelectionInside); | 619 o->setSelectionStateIfNeeded(SelectionInside); |
| 620 o = o->nextInPreOrder(); | 620 o = o->nextInPreOrder(); |
| 621 } | 621 } |
| 622 | 622 |
| 623 layer()->clearBlockSelectionGapsBounds(); | 623 layer()->clearBlockSelectionGapsBounds(); |
| 624 | 624 |
| 625 // Now that the selection state has been updated for the new objects, walk t
hem again and | 625 // Now that the selection state has been updated for the new objects, walk t
hem again and |
| 626 // put them in the new objects list. | 626 // put them in the new objects list. |
| 627 o = start; | 627 o = start; |
| 628 exploringBackwards = false; | 628 exploringBackwards = false; |
| 629 continueExploring = o && (o != stop); | 629 continueExploring = o && (o != stop); |
| 630 while (continueExploring) { | 630 while (continueExploring) { |
| 631 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS
tate() != SelectionNone) { | 631 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS
tate() != SelectionNone) { |
| 632 newSelectedObjects.set(o, o->selectionState()); | 632 newSelectedObjects.set(o, o->selectionState()); |
| 633 RenderBlock* cb = o->containingBlock(); | 633 RenderBlock* cb = o->containingBlock(); |
| 634 while (cb && !cb->isRenderView()) { | 634 while (cb && !cb->isRenderView()) { |
| 635 SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, c
b->selectionState()); | 635 SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, c
b->selectionState()); |
| 636 if (!result.isNewEntry) | 636 if (!result.isNewEntry) |
| 637 break; | 637 break; |
| 638 cb = cb->containingBlock(); | 638 cb = cb->containingBlock(); |
| 639 } | 639 } |
| 640 } | 640 } |
| 641 | 641 |
| 642 o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring
, exploringBackwards); | 642 o = getNextOrPrevLayoutObjectBasedOnDirection(o, stop, continueExploring
, exploringBackwards); |
| 643 } | 643 } |
| 644 | 644 |
| 645 if (!m_frameView) | 645 if (!m_frameView) |
| 646 return; | 646 return; |
| 647 | 647 |
| 648 // Have any of the old selected objects changed compared to the new selectio
n? | 648 // Have any of the old selected objects changed compared to the new selectio
n? |
| 649 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj
ectsEnd; ++i) { | 649 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj
ectsEnd; ++i) { |
| 650 RenderObject* obj = i->key; | 650 LayoutObject* obj = i->key; |
| 651 SelectionState newSelectionState = obj->selectionState(); | 651 SelectionState newSelectionState = obj->selectionState(); |
| 652 SelectionState oldSelectionState = i->value; | 652 SelectionState oldSelectionState = i->value; |
| 653 if (newSelectionState != oldSelectionState | 653 if (newSelectionState != oldSelectionState |
| 654 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) | 654 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) |
| 655 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { | 655 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { |
| 656 obj->setShouldInvalidateSelection(); | 656 obj->setShouldInvalidateSelection(); |
| 657 newSelectedObjects.remove(obj); | 657 newSelectedObjects.remove(obj); |
| 658 } | 658 } |
| 659 } | 659 } |
| 660 | 660 |
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 779 startPos = candidate; | 779 startPos = candidate; |
| 780 Position endPos = selection.end(); | 780 Position endPos = selection.end(); |
| 781 candidate = endPos.upstream(); | 781 candidate = endPos.upstream(); |
| 782 if (candidate.isCandidate()) | 782 if (candidate.isCandidate()) |
| 783 endPos = candidate; | 783 endPos = candidate; |
| 784 | 784 |
| 785 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted | 785 // We can get into a state where the selection endpoints map to the same Vis
iblePosition when a selection is deleted |
| 786 // because we don't yet notify the FrameSelection of text removal. | 786 // because we don't yet notify the FrameSelection of text removal. |
| 787 if (startPos.isNull() || endPos.isNull() || selection.visibleStart() == sele
ction.visibleEnd()) | 787 if (startPos.isNull() || endPos.isNull() || selection.visibleStart() == sele
ction.visibleEnd()) |
| 788 return; | 788 return; |
| 789 RenderObject* startRenderer = startPos.anchorNode()->renderer(); | 789 LayoutObject* startRenderer = startPos.anchorNode()->renderer(); |
| 790 RenderObject* endRenderer = endPos.anchorNode()->renderer(); | 790 LayoutObject* endRenderer = endPos.anchorNode()->renderer(); |
| 791 if (!startRenderer || !endRenderer) | 791 if (!startRenderer || !endRenderer) |
| 792 return; | 792 return; |
| 793 ASSERT(startRenderer->view() == this && endRenderer->view() == this); | 793 ASSERT(startRenderer->view() == this && endRenderer->view() == this); |
| 794 setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer,
endPos.deprecatedEditingOffset()); | 794 setSelection(startRenderer, startPos.deprecatedEditingOffset(), endRenderer,
endPos.deprecatedEditingOffset()); |
| 795 } | 795 } |
| 796 | 796 |
| 797 RenderObject* RenderView::selectionStart() | 797 LayoutObject* RenderView::selectionStart() |
| 798 { | 798 { |
| 799 commitPendingSelection(); | 799 commitPendingSelection(); |
| 800 return m_selectionStart; | 800 return m_selectionStart; |
| 801 } | 801 } |
| 802 | 802 |
| 803 RenderObject* RenderView::selectionEnd() | 803 LayoutObject* RenderView::selectionEnd() |
| 804 { | 804 { |
| 805 commitPendingSelection(); | 805 commitPendingSelection(); |
| 806 return m_selectionEnd; | 806 return m_selectionEnd; |
| 807 } | 807 } |
| 808 | 808 |
| 809 void RenderView::selectionStartEnd(int& startPos, int& endPos) | 809 void RenderView::selectionStartEnd(int& startPos, int& endPos) |
| 810 { | 810 { |
| 811 commitPendingSelection(); | 811 commitPendingSelection(); |
| 812 startPos = m_selectionStartPos; | 812 startPos = m_selectionStartPos; |
| 813 endPos = m_selectionEndPos; | 813 endPos = m_selectionEndPos; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 831 | 831 |
| 832 IntRect RenderView::unscaledDocumentRect() const | 832 IntRect RenderView::unscaledDocumentRect() const |
| 833 { | 833 { |
| 834 LayoutRect overflowRect(layoutOverflowRect()); | 834 LayoutRect overflowRect(layoutOverflowRect()); |
| 835 flipForWritingMode(overflowRect); | 835 flipForWritingMode(overflowRect); |
| 836 return pixelSnappedIntRect(overflowRect); | 836 return pixelSnappedIntRect(overflowRect); |
| 837 } | 837 } |
| 838 | 838 |
| 839 bool RenderView::rootBackgroundIsEntirelyFixed() const | 839 bool RenderView::rootBackgroundIsEntirelyFixed() const |
| 840 { | 840 { |
| 841 if (RenderObject* backgroundRenderer = this->backgroundRenderer()) | 841 if (LayoutObject* backgroundRenderer = this->backgroundRenderer()) |
| 842 return backgroundRenderer->hasEntirelyFixedBackground(); | 842 return backgroundRenderer->hasEntirelyFixedBackground(); |
| 843 return false; | 843 return false; |
| 844 } | 844 } |
| 845 | 845 |
| 846 RenderObject* RenderView::backgroundRenderer() const | 846 LayoutObject* RenderView::backgroundRenderer() const |
| 847 { | 847 { |
| 848 if (Element* documentElement = document().documentElement()) { | 848 if (Element* documentElement = document().documentElement()) { |
| 849 if (RenderObject* rootObject = documentElement->renderer()) | 849 if (LayoutObject* rootObject = documentElement->renderer()) |
| 850 return rootObject->rendererForRootBackground(); | 850 return rootObject->rendererForRootBackground(); |
| 851 } | 851 } |
| 852 return 0; | 852 return 0; |
| 853 } | 853 } |
| 854 | 854 |
| 855 LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const | 855 LayoutRect RenderView::backgroundRect(RenderBox* backgroundRenderer) const |
| 856 { | 856 { |
| 857 if (!hasColumns()) | 857 if (!hasColumns()) |
| 858 return unscaledDocumentRect(); | 858 return unscaledDocumentRect(); |
| 859 | 859 |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 981 } | 981 } |
| 982 | 982 |
| 983 void RenderView::invalidateDisplayItemClients(DisplayItemList* displayItemList)
const | 983 void RenderView::invalidateDisplayItemClients(DisplayItemList* displayItemList)
const |
| 984 { | 984 { |
| 985 RenderBlockFlow::invalidateDisplayItemClients(displayItemList); | 985 RenderBlockFlow::invalidateDisplayItemClients(displayItemList); |
| 986 if (m_frameView) | 986 if (m_frameView) |
| 987 displayItemList->invalidate(m_frameView->displayItemClient()); | 987 displayItemList->invalidate(m_frameView->displayItemClient()); |
| 988 } | 988 } |
| 989 | 989 |
| 990 } // namespace blink | 990 } // namespace blink |
| OLD | NEW |