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 496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
507 exploringBackwards = !next && (next != stop); | 507 exploringBackwards = !next && (next != stop); |
508 if (exploringBackwards) { | 508 if (exploringBackwards) { |
509 next = stop->previousInPreOrder(); | 509 next = stop->previousInPreOrder(); |
510 continueExploring = next && !next->isRenderView(); | 510 continueExploring = next && !next->isRenderView(); |
511 } | 511 } |
512 } | 512 } |
513 | 513 |
514 return next; | 514 return next; |
515 } | 515 } |
516 | 516 |
517 static void invalidateSelectionForRenderer(RenderObject* object) | |
518 { | |
519 object->setShouldInvalidateSelection(); | |
520 if (object->isBox()) { | |
dsinclair
2014/10/31 14:03:16
if (!object->isBox())
return;
I dislike inden
| |
521 RenderBox* box = toRenderBox(object); | |
522 // FIXME(jchaffraix): ShapeOutside can trigger SVGImage loading, which r eruns the whole state machine | |
523 // in FrameView::updateLayoutAndStyleForPaint. It's allowed to do it in the post-layout hook (why?) | |
524 // but not during the invalidation phase so we just match the current co de 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
| |
525 if (ShapeOutsideInfo* shapeInfo = box->shapeOutsideInfo()) | |
526 shapeInfo->computedShape(); | |
527 } | |
528 } | |
529 | |
517 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) | 530 void RenderView::setSelection(RenderObject* start, int startPos, RenderObject* e nd, int endPos, SelectionPaintInvalidationMode blockPaintInvalidationMode) |
518 { | 531 { |
519 // This code makes no assumptions as to if the rendering tree is up to date or not | 532 // This code makes no assumptions as to if the rendering tree is up to date or not |
520 // and will not try to update it. Currently clearSelection calls this | 533 // and will not try to update it. Currently clearSelection calls this |
521 // (intentionally) without updating the rendering tree as it doesn't care. | 534 // (intentionally) without updating the rendering tree as it doesn't care. |
522 // Other callers may want to force recalc style before calling this. | 535 // Other callers may want to force recalc style before calling this. |
523 | 536 |
524 // Make sure both our start and end objects are defined. | 537 // Make sure both our start and end objects are defined. |
525 // Check www.msnbc.com and try clicking around to find the case where this h appened. | 538 // Check www.msnbc.com and try clicking around to find the case where this h appened. |
526 if ((start && !end) || (end && !start)) | 539 if ((start && !end) || (end && !start)) |
527 return; | 540 return; |
528 | 541 |
529 // Just return if the selection hasn't changed. | 542 // Just return if the selection hasn't changed. |
530 if (m_selectionStart == start && m_selectionStartPos == startPos && | 543 if (m_selectionStart == start && m_selectionStartPos == startPos && |
531 m_selectionEnd == end && m_selectionEndPos == endPos) | 544 m_selectionEnd == end && m_selectionEndPos == endPos) |
532 return; | 545 return; |
533 | 546 |
534 // Record the old selected objects. These will be used later | 547 // Record the old selected objects. These will be used later |
535 // when we compare against the new selected objects. | 548 // when we compare against the new selected objects. |
536 int oldStartPos = m_selectionStartPos; | 549 int oldStartPos = m_selectionStartPos; |
537 int oldEndPos = m_selectionEndPos; | 550 int oldEndPos = m_selectionEndPos; |
538 | 551 |
539 // Objects each have a single selection rect to examine. | 552 // Objects each have a single selection rect to examine. |
540 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, OwnPtrWillBeMemb er<RenderSelectionInfo> > SelectedObjectMap; | 553 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderObject>, SelectionState > SelectedObjectMap; |
dsinclair
2014/10/31 14:03:16
nit: Don't need the space between SelectionState a
| |
541 SelectedObjectMap oldSelectedObjects; | 554 SelectedObjectMap oldSelectedObjects; |
555 // FIXME: |newSelectedObjects| doesn't really need to store the SelectionSta te, it's just more convenient | |
556 // to have it use the same data structure as |oldSelectedObjects|. | |
542 SelectedObjectMap newSelectedObjects; | 557 SelectedObjectMap newSelectedObjects; |
543 | 558 |
544 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks. | 559 // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks. |
545 // In order to get the paint invalidation rect right, we have to examine lef t, middle, and right rects individually, since otherwise | 560 // In order to get the paint invalidation rect right, we have to examine lef t, middle, and right rects individually, since otherwise |
546 // the union of those rects might remain the same even when changes have occ urred. | 561 // the union of those rects might remain the same even when changes have occ urred. |
547 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, OwnPtrWillBeMembe r<RenderBlockSelectionInfo> > SelectedBlockMap; | 562 typedef WillBeHeapHashMap<RawPtrWillBeMember<RenderBlock>, SelectionState > SelectedBlockMap; |
548 SelectedBlockMap oldSelectedBlocks; | 563 SelectedBlockMap oldSelectedBlocks; |
564 // FIXME: |newSelectedBlocks| doesn't really need to store the SelectionStat e, it's just more convenient | |
565 // to have it use the same data structure as |oldSelectedBlocks|. | |
549 SelectedBlockMap newSelectedBlocks; | 566 SelectedBlockMap newSelectedBlocks; |
550 | 567 |
551 RenderObject* os = m_selectionStart; | 568 RenderObject* os = m_selectionStart; |
552 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos ); | 569 RenderObject* stop = rendererAfterPosition(m_selectionEnd, m_selectionEndPos ); |
553 bool exploringBackwards = false; | 570 bool exploringBackwards = false; |
554 bool continueExploring = os && (os != stop); | 571 bool continueExploring = os && (os != stop); |
555 while (continueExploring) { | 572 while (continueExploring) { |
556 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec tionEnd) && os->selectionState() != SelectionNone) { | 573 if ((os->canBeSelectionLeaf() || os == m_selectionStart || os == m_selec tionEnd) && os->selectionState() != SelectionNone) { |
557 // Blocks are responsible for painting line gaps and margin gaps. T hey must be examined as well. | 574 // Blocks are responsible for painting line gaps and margin gaps. T hey must be examined as well. |
558 oldSelectedObjects.set(os, adoptPtrWillBeNoop(new RenderSelectionInf o(os))); | 575 oldSelectedObjects.set(os, os->selectionState()); |
559 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { | 576 if (blockPaintInvalidationMode == PaintInvalidationNewXOROld) { |
560 RenderBlock* cb = os->containingBlock(); | 577 RenderBlock* cb = os->containingBlock(); |
561 while (cb && !cb->isRenderView()) { | 578 while (cb && !cb->isRenderView()) { |
562 OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = ol dSelectedBlocks.add(cb, nullptr).storedValue->value; | 579 SelectedBlockMap::AddResult result = oldSelectedBlocks.add(c b, cb->selectionState()); |
563 if (blockInfo) | 580 if (!result.isNewEntry) |
564 break; | 581 break; |
565 blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo( cb)); | |
566 cb = cb->containingBlock(); | 582 cb = cb->containingBlock(); |
567 } | 583 } |
568 } | 584 } |
569 } | 585 } |
570 | 586 |
571 os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExplori ng, exploringBackwards); | 587 os = getNextOrPrevRenderObjectBasedOnDirection(os, stop, continueExplori ng, exploringBackwards); |
572 } | 588 } |
573 | 589 |
574 // Now clear the selection. | 590 // Now clear the selection. |
575 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); | 591 SelectedObjectMap::iterator oldObjectsEnd = oldSelectedObjects.end(); |
(...skipping 27 matching lines...) Expand all Loading... | |
603 | 619 |
604 layer()->clearBlockSelectionGapsBounds(); | 620 layer()->clearBlockSelectionGapsBounds(); |
605 | 621 |
606 // Now that the selection state has been updated for the new objects, walk t hem again and | 622 // Now that the selection state has been updated for the new objects, walk t hem again and |
607 // put them in the new objects list. | 623 // put them in the new objects list. |
608 o = start; | 624 o = start; |
609 exploringBackwards = false; | 625 exploringBackwards = false; |
610 continueExploring = o && (o != stop); | 626 continueExploring = o && (o != stop); |
611 while (continueExploring) { | 627 while (continueExploring) { |
612 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS tate() != SelectionNone) { | 628 if ((o->canBeSelectionLeaf() || o == start || o == end) && o->selectionS tate() != SelectionNone) { |
613 newSelectedObjects.set(o, adoptPtrWillBeNoop(new RenderSelectionInfo (o))); | 629 newSelectedObjects.set(o, o->selectionState()); |
614 RenderBlock* cb = o->containingBlock(); | 630 RenderBlock* cb = o->containingBlock(); |
615 while (cb && !cb->isRenderView()) { | 631 while (cb && !cb->isRenderView()) { |
616 OwnPtrWillBeMember<RenderBlockSelectionInfo>& blockInfo = newSel ectedBlocks.add(cb, nullptr).storedValue->value; | 632 SelectedBlockMap::AddResult result = newSelectedBlocks.add(cb, c b->selectionState()); |
617 if (blockInfo) | 633 if (!result.isNewEntry) |
618 break; | 634 break; |
619 blockInfo = adoptPtrWillBeNoop(new RenderBlockSelectionInfo(cb)) ; | |
620 cb = cb->containingBlock(); | 635 cb = cb->containingBlock(); |
621 } | 636 } |
622 } | 637 } |
623 | 638 |
624 o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring , exploringBackwards); | 639 o = getNextOrPrevRenderObjectBasedOnDirection(o, stop, continueExploring , exploringBackwards); |
625 } | 640 } |
626 | 641 |
627 if (!m_frameView) | 642 if (!m_frameView) |
628 return; | 643 return; |
629 | 644 |
630 // Have any of the old selected objects changed compared to the new selectio n? | 645 // Have any of the old selected objects changed compared to the new selectio n? |
631 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj ectsEnd; ++i) { | 646 for (SelectedObjectMap::iterator i = oldSelectedObjects.begin(); i != oldObj ectsEnd; ++i) { |
632 RenderObject* obj = i->key; | 647 RenderObject* obj = i->key; |
633 RenderSelectionInfo* newInfo = newSelectedObjects.get(obj); | 648 SelectionState newSelectionState = obj->selectionState(); |
634 RenderSelectionInfo* oldInfo = i->value.get(); | 649 SelectionState oldSelectionState = i->value; |
635 if (!newInfo || newInfo->hasChangedFrom(*oldInfo) | 650 if (newSelectionState != oldSelectionState |
636 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) | 651 || (m_selectionStart == obj && oldStartPos != m_selectionStartPos) |
637 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { | 652 || (m_selectionEnd == obj && oldEndPos != m_selectionEndPos)) { |
638 oldInfo->invalidatePaint(); | 653 invalidateSelectionForRenderer(obj); |
639 if (newInfo) { | 654 newSelectedObjects.remove(obj); |
640 newInfo->object()->setShouldInvalidateSelection(); | |
641 newSelectedObjects.remove(obj); | |
642 } | |
643 } | 655 } |
644 } | 656 } |
645 | 657 |
646 // Any new objects that remain were not found in the old objects dict, and s o they need to be updated. | 658 // Any new objects that remain were not found in the old objects dict, and s o they need to be updated. |
647 SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end(); | 659 SelectedObjectMap::iterator newObjectsEnd = newSelectedObjects.end(); |
648 for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObj ectsEnd; ++i) | 660 for (SelectedObjectMap::iterator i = newSelectedObjects.begin(); i != newObj ectsEnd; ++i) |
649 i->value->object()->setShouldInvalidateSelection(); | 661 invalidateSelectionForRenderer(i->key); |
650 | 662 |
651 // Have any of the old blocks changed? | 663 // Have any of the old blocks changed? |
652 SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end(); | 664 SelectedBlockMap::iterator oldBlocksEnd = oldSelectedBlocks.end(); |
653 for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlock sEnd; ++i) { | 665 for (SelectedBlockMap::iterator i = oldSelectedBlocks.begin(); i != oldBlock sEnd; ++i) |
654 RenderBlock* block = i->key; | 666 invalidateSelectionForRenderer(i->key); |
655 RenderBlockSelectionInfo* newInfo = newSelectedBlocks.get(block); | |
656 RenderBlockSelectionInfo* oldInfo = i->value.get(); | |
657 if (!newInfo || newInfo->hasChangedFrom(*oldInfo)) { | |
658 oldInfo->invalidatePaint(); | |
659 if (newInfo) { | |
660 newInfo->object()->setShouldInvalidateSelection(); | |
661 newSelectedBlocks.remove(block); | |
662 } | |
663 } | |
664 } | |
665 | 667 |
666 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. | 668 // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated. |
667 SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end(); | 669 SelectedBlockMap::iterator newBlocksEnd = newSelectedBlocks.end(); |
668 for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlock sEnd; ++i) | 670 for (SelectedBlockMap::iterator i = newSelectedBlocks.begin(); i != newBlock sEnd; ++i) |
669 i->value->object()->setShouldInvalidateSelection(); | 671 invalidateSelectionForRenderer(i->key); |
670 } | 672 } |
671 | 673 |
672 void RenderView::clearSelection() | 674 void RenderView::clearSelection() |
673 { | 675 { |
674 // For querying RenderLayer::compositingState() | 676 // For querying RenderLayer::compositingState() |
675 // This is correct, since destroying render objects needs to cause eager pai nt invalidations. | 677 // This is correct, since destroying render objects needs to cause eager pai nt invalidations. |
676 DisableCompositingQueryAsserts disabler; | 678 DisableCompositingQueryAsserts disabler; |
677 | 679 |
678 layer()->invalidatePaintForBlockSelectionGaps(); | 680 layer()->invalidatePaintForBlockSelectionGaps(); |
679 setSelection(0, -1, 0, -1, PaintInvalidationNewMinusOld); | 681 setSelection(0, -1, 0, -1, PaintInvalidationNewMinusOld); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 return viewWidth(IncludeScrollbars) / scale; | 874 return viewWidth(IncludeScrollbars) / scale; |
873 } | 875 } |
874 | 876 |
875 double RenderView::layoutViewportHeight() const | 877 double RenderView::layoutViewportHeight() const |
876 { | 878 { |
877 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1; | 879 float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1; |
878 return viewHeight(IncludeScrollbars) / scale; | 880 return viewHeight(IncludeScrollbars) / scale; |
879 } | 881 } |
880 | 882 |
881 } // namespace blink | 883 } // namespace blink |
OLD | NEW |