Changeset 268484 in webkit


Ignore:
Timestamp:
Oct 14, 2020 1:42:23 PM (4 years ago)
Author:
Megan Gardner
Message:

Refactor HighlightData
https://bugs.webkit.org/show_bug.cgi?id=217711

Reviewed by Darin Adler.

HighlightData was renamed when it was used for more that selections, but
more than half the file was only supposed to be used to deal with the current
selection, so I've split it back out into a more reasonable set of files.
Also made offsets no longer optional, as there doesn't seem to be a need.
Extended the HighlightData setRenderRange into InlineTextBox, as it's a better
way to calculate that does not use deprecated functions.

No behavior change.

  • Headers.cmake:
  • Sources.txt:
  • WebCore.xcodeproj/project.pbxproj:
  • editing/FrameSelection.cpp:

(WebCore::FrameSelection::setNeedsSelectionUpdate):
(WebCore::DragCaretController::nodeWillBeRemoved):
(WebCore::FrameSelection::respondToNodeModification):
(WebCore::FrameSelection::willBeRemovedFromFrame):
(WebCore::FrameSelection::focusedOrActiveStateChanged):
(WebCore::FrameSelection::updateAppearance):

  • page/FrameView.cpp:

(WebCore::FrameView::paintContentsForSnapshot):

  • platform/DragImage.cpp:

(WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState):
(WebCore::createDragImageForRange):

  • rendering/HighlightData.cpp:

(WebCore::RenderRangeIterator::RenderRangeIterator):
(WebCore::RenderRangeIterator::current const):
(WebCore::RenderRangeIterator::next):
(WebCore::RenderRangeIterator::checkForSpanner):
(WebCore::rendererAfterOffset):
(WebCore::HighlightData::highlightStateForRenderer):
(): Deleted.
(WebCore::isValidRendererForSelection): Deleted.
(WebCore::containingBlockBelowView): Deleted.
(WebCore::collectSelectionData): Deleted.
(WebCore::HighlightData::HighlightData): Deleted.
(WebCore::HighlightData::setSelection): Deleted.
(WebCore::HighlightData::clearSelection): Deleted.
(WebCore::HighlightData::repaintSelection const): Deleted.
(WebCore::HighlightData::collectBounds const): Deleted.
(WebCore::HighlightData::applySelection): Deleted.

  • rendering/HighlightData.h:

(WebCore::RenderRange::RenderRange):
(WebCore::RenderRange::start const):
(WebCore::RenderRange::end const):
(WebCore::RenderRange::startOffset const):
(WebCore::RenderRange::endOffset const):
(WebCore::RenderRange::operator== const):
(WebCore::HighlightData::startOffset const):
(WebCore::HighlightData::endOffset const):
(WebCore::HighlightData::RenderRange::RenderRange): Deleted.
(WebCore::HighlightData::RenderRange::start const): Deleted.
(WebCore::HighlightData::RenderRange::end const): Deleted.
(WebCore::HighlightData::RenderRange::startOffset const): Deleted.
(WebCore::HighlightData::RenderRange::endOffset const): Deleted.
(WebCore::HighlightData::RenderRange::operator== const): Deleted.
(WebCore::HighlightData::bounds const): Deleted.
(WebCore::HighlightData::boundsClippedToVisibleContent const): Deleted.

  • rendering/InlineTextBox.cpp:

(WebCore::InlineTextBox::collectMarkedTextsForHighlights const):

  • rendering/RenderReplaced.cpp:

(WebCore::RenderReplaced::calculateHighlightColor const):

  • rendering/RenderView.h:
  • rendering/SelectionRangeData.cpp: Copied from Source/WebCore/rendering/HighlightData.cpp.

(WebCore::rendererAfterOffset):
(WebCore::isValidRendererForSelection):
(WebCore::containingBlockBelowView):
(WebCore::collectSelectionData):
(WebCore::SelectionRangeData::SelectionData):
(WebCore::SelectionRangeData::set):
(WebCore::SelectionRangeData::clear):
(WebCore::SelectionRangeData::repaint const):
(WebCore::SelectionRangeData::collectBounds const):
(WebCore::SelectionRangeData::apply):

  • rendering/SelectionRangeData.h: Added.

(WebCore::SelectionRangeData::bounds const):
(WebCore::SelectionRangeData::boundsClippedToVisibleContent const):

Location:
trunk/Source/WebCore
Files:
1 added
12 edited
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r268483 r268484  
     12020-10-14  Megan Gardner  <megan_gardner@apple.com>
     2
     3        Refactor HighlightData
     4        https://bugs.webkit.org/show_bug.cgi?id=217711
     5
     6        Reviewed by Darin Adler.
     7
     8        HighlightData was renamed when it was used for more that selections, but
     9        more than half the file was only supposed to be used to deal with the current
     10        selection, so I've split it back out into a more reasonable set of files.
     11        Also made offsets no longer optional, as there doesn't seem to be a need.
     12        Extended the HighlightData setRenderRange into InlineTextBox, as it's a better
     13        way to calculate that does not use deprecated functions.
     14
     15        No behavior change.
     16
     17        * Headers.cmake:
     18        * Sources.txt:
     19        * WebCore.xcodeproj/project.pbxproj:
     20        * editing/FrameSelection.cpp:
     21        (WebCore::FrameSelection::setNeedsSelectionUpdate):
     22        (WebCore::DragCaretController::nodeWillBeRemoved):
     23        (WebCore::FrameSelection::respondToNodeModification):
     24        (WebCore::FrameSelection::willBeRemovedFromFrame):
     25        (WebCore::FrameSelection::focusedOrActiveStateChanged):
     26        (WebCore::FrameSelection::updateAppearance):
     27        * page/FrameView.cpp:
     28        (WebCore::FrameView::paintContentsForSnapshot):
     29        * platform/DragImage.cpp:
     30        (WebCore::ScopedFrameSelectionState::~ScopedFrameSelectionState):
     31        (WebCore::createDragImageForRange):
     32        * rendering/HighlightData.cpp:
     33        (WebCore::RenderRangeIterator::RenderRangeIterator):
     34        (WebCore::RenderRangeIterator::current const):
     35        (WebCore::RenderRangeIterator::next):
     36        (WebCore::RenderRangeIterator::checkForSpanner):
     37        (WebCore::rendererAfterOffset):
     38        (WebCore::HighlightData::highlightStateForRenderer):
     39        (): Deleted.
     40        (WebCore::isValidRendererForSelection): Deleted.
     41        (WebCore::containingBlockBelowView): Deleted.
     42        (WebCore::collectSelectionData): Deleted.
     43        (WebCore::HighlightData::HighlightData): Deleted.
     44        (WebCore::HighlightData::setSelection): Deleted.
     45        (WebCore::HighlightData::clearSelection): Deleted.
     46        (WebCore::HighlightData::repaintSelection const): Deleted.
     47        (WebCore::HighlightData::collectBounds const): Deleted.
     48        (WebCore::HighlightData::applySelection): Deleted.
     49        * rendering/HighlightData.h:
     50        (WebCore::RenderRange::RenderRange):
     51        (WebCore::RenderRange::start const):
     52        (WebCore::RenderRange::end const):
     53        (WebCore::RenderRange::startOffset const):
     54        (WebCore::RenderRange::endOffset const):
     55        (WebCore::RenderRange::operator== const):
     56        (WebCore::HighlightData::startOffset const):
     57        (WebCore::HighlightData::endOffset const):
     58        (WebCore::HighlightData::RenderRange::RenderRange): Deleted.
     59        (WebCore::HighlightData::RenderRange::start const): Deleted.
     60        (WebCore::HighlightData::RenderRange::end const): Deleted.
     61        (WebCore::HighlightData::RenderRange::startOffset const): Deleted.
     62        (WebCore::HighlightData::RenderRange::endOffset const): Deleted.
     63        (WebCore::HighlightData::RenderRange::operator== const): Deleted.
     64        (WebCore::HighlightData::bounds const): Deleted.
     65        (WebCore::HighlightData::boundsClippedToVisibleContent const): Deleted.
     66        * rendering/InlineTextBox.cpp:
     67        (WebCore::InlineTextBox::collectMarkedTextsForHighlights const):
     68        * rendering/RenderReplaced.cpp:
     69        (WebCore::RenderReplaced::calculateHighlightColor const):
     70        * rendering/RenderView.h:
     71        * rendering/SelectionRangeData.cpp: Copied from Source/WebCore/rendering/HighlightData.cpp.
     72        (WebCore::rendererAfterOffset):
     73        (WebCore::isValidRendererForSelection):
     74        (WebCore::containingBlockBelowView):
     75        (WebCore::collectSelectionData):
     76        (WebCore::SelectionRangeData::SelectionData):
     77        (WebCore::SelectionRangeData::set):
     78        (WebCore::SelectionRangeData::clear):
     79        (WebCore::SelectionRangeData::repaint const):
     80        (WebCore::SelectionRangeData::collectBounds const):
     81        (WebCore::SelectionRangeData::apply):
     82        * rendering/SelectionRangeData.h: Added.
     83        (WebCore::SelectionRangeData::bounds const):
     84        (WebCore::SelectionRangeData::boundsClippedToVisibleContent const):
     85
    1862020-10-14  Antoine Quint  <graouts@webkit.org>
    287
  • trunk/Source/WebCore/Headers.cmake

    r268423 r268484  
    14401440    rendering/RootInlineBox.h
    14411441    rendering/ScrollAlignment.h
     1442    rendering/SelectionRangeData.h
    14421443
    14431444    rendering/line/LineWidth.h
  • trunk/Source/WebCore/Sources.txt

    r268355 r268484  
    22222222rendering/RootInlineBox.cpp
    22232223rendering/ScrollAlignment.cpp
     2224rendering/SelectionRangeData.cpp
    22242225rendering/TableLayout.cpp
    22252226rendering/TextDecorationPainter.cpp
  • trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj

    r268453 r268484  
    11981198                445775E520472F73008DCE5D /* LocalDefaultSystemAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = 445775E420472F73008DCE5D /* LocalDefaultSystemAppearance.h */; settings = {ATTRIBUTES = (Private, ); }; };
    11991199                4463CF682212FA68001A8577 /* DataDetectorsCoreSoftLink.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C7941E21C56C29300A4C58E /* DataDetectorsCoreSoftLink.mm */; };
     1200                4465D7BD2536D05E0016666D /* SelectionRangeData.h in Headers */ = {isa = PBXBuildFile; fileRef = 44B38BF42536901A00A4458D /* SelectionRangeData.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12001201                446DC64824A29DAB0061F390 /* PlaybackTargetClientContextIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 446DC64624A29D9B0061F390 /* PlaybackTargetClientContextIdentifier.h */; settings = {ATTRIBUTES = (Private, ); }; };
    12011202                4471710E205AF945000A116E /* MediaQueryParserContext.h in Headers */ = {isa = PBXBuildFile; fileRef = 4471710C205AF945000A116E /* MediaQueryParserContext.h */; settings = {ATTRIBUTES = (Private, ); }; };
     
    79247925                44A28AAB12DFB8AC00AE923B /* MathMLElementFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathMLElementFactory.h; path = DerivedSources/WebCore/MathMLElementFactory.h; sourceTree = BUILT_PRODUCTS_DIR; };
    79257926                44A28AAE12DFB8BF00AE923B /* MathMLNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = MathMLNames.h; path = DerivedSources/WebCore/MathMLNames.h; sourceTree = BUILT_PRODUCTS_DIR; };
     7927                44B38BF42536901A00A4458D /* SelectionRangeData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SelectionRangeData.h; sourceTree = "<group>"; };
     7928                44B38BF925369A8800A4458D /* SelectionRangeData.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SelectionRangeData.cpp; sourceTree = "<group>"; };
    79267929                44C991810F3D1E0D00586670 /* ScrollbarThemeIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollbarThemeIOS.mm; sourceTree = "<group>"; };
    79277930                44C991850F3D1EBE00586670 /* ScrollbarThemeIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ScrollbarThemeIOS.h; sourceTree = "<group>"; };
     
    2925629259                                5D925B650F64D4DD00B847F0 /* ScrollAlignment.cpp */,
    2925729260                                5D925B660F64D4DD00B847F0 /* ScrollAlignment.h */,
     29261                                44B38BF925369A8800A4458D /* SelectionRangeData.cpp */,
     29262                                44B38BF42536901A00A4458D /* SelectionRangeData.h */,
    2925829263                                E31CD750229F749500FBDA19 /* TableLayout.cpp */,
    2925929264                                A8CFF04C0A154F09000A4234 /* TableLayout.h */,
     
    3387833883                                2D5BC42716F882EE007048D0 /* SecurityPolicyViolationEvent.h in Headers */,
    3387933884                                B2C3DA2F0D006C1D00EF6F26 /* SegmentedString.h in Headers */,
     33885                                4465D7BD2536D05E0016666D /* SelectionRangeData.h in Headers */,
    3388033886                                BEA807C90F714A0300524199 /* SelectionRect.h in Headers */,
    3388133887                                51405C89190B014400754F94 /* SelectionRectGatherer.h in Headers */,
  • trunk/Source/WebCore/editing/FrameSelection.cpp

    r267962 r268484  
    452452    m_pendingSelectionUpdate = true;
    453453    if (RenderView* view = m_document->renderView())
    454         view->selection().clearSelection();
     454        view->selection().clear();
    455455}
    456456
     
    508508
    509509    if (RenderView* view = node.document().renderView())
    510         view->selection().clearSelection();
     510        view->selection().clear();
    511511
    512512    clear();
     
    567567    if (clearRenderTreeSelection) {
    568568        if (auto* renderView = node.document().renderView()) {
    569             renderView->selection().clearSelection();
     569            renderView->selection().clear();
    570570
    571571            // Trigger a selection update so the selection will be set again.
     
    15711571
    15721572    if (auto* view = m_document->renderView())
    1573         view->selection().clearSelection();
     1573        view->selection().clear();
    15741574
    15751575    setSelectionWithoutUpdatingAppearance(VisibleSelection(), defaultSetSelectionOptions(), AlignCursorOnScrollIfNeeded, TextGranularity::CharacterGranularity);
     
    20592059    // we have to update places those colors were painted.
    20602060    if (RenderView* view = m_document->renderView())
    2061         view->selection().repaintSelection();
     2061        view->selection().repaint();
    20622062
    20632063    // Caret appears in the active frame.
     
    21542154
    21552155    if (!selection.isRange()) {
    2156         view->selection().clearSelection();
     2156        view->selection().clear();
    21572157        return;
    21582158    }
     
    21792179        int endOffset = endPos.deprecatedEditingOffset();
    21802180        ASSERT(startOffset >= 0 && endOffset >= 0);
    2181         view->selection().setSelection({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) });
     2181        view->selection().set({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) });
    21822182    }
    21832183}
  • trunk/Source/WebCore/page/FrameView.cpp

    r268307 r268484  
    43524352        for (auto* frame = m_frame.ptr(); frame; frame = frame->tree().traverseNext(m_frame.ptr())) {
    43534353            if (auto* renderView = frame->contentRenderer())
    4354                 renderView->selection().clearSelection();
     4354                renderView->selection().clear();
    43554355        }
    43564356    }
  • trunk/Source/WebCore/platform/DragImage.cpp

    r267962 r268484  
    3535#include "RenderElement.h"
    3636#include "RenderView.h"
     37#include "SelectionRangeData.h"
    3738#include "SimpleRange.h"
    3839#include "TextIndicator.h"
     
    144145        if (auto* renderView = frame.contentRenderer()) {
    145146            ASSERT(selection);
    146             renderView->selection().setSelection(selection.value(), HighlightData::RepaintMode::Nothing);
     147            renderView->selection().set(selection.value(), SelectionRangeData::RepaintMode::Nothing);
    147148        }
    148149    }
    149150
    150151    const Frame& frame;
    151     Optional<HighlightData::RenderRange> selection;
     152    Optional<RenderRange> selection;
    152153};
    153154
     
    186187    int endOffset = end.deprecatedEditingOffset();
    187188    ASSERT(startOffset >= 0 && endOffset >= 0);
    188     view->selection().setSelection({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }, HighlightData::RepaintMode::Nothing);
     189    view->selection().set({ startRenderer, endRenderer, static_cast<unsigned>(startOffset), static_cast<unsigned>(endOffset) }, SelectionRangeData::RepaintMode::Nothing);
    189190    // We capture using snapshotFrameRect() because we fake up the selection using
    190191    // FrameView but snapshotSelection() uses the selection from the Frame itself.
  • trunk/Source/WebCore/rendering/HighlightData.cpp

    r268436 r268484  
    4747namespace WebCore {
    4848
    49 namespace { // See bug #177808.
    5049
    51 struct SelectionData {
    52     using RendererMap = HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>>;
    53     using RenderBlockMap = HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>>;
    5450
    55     Optional<unsigned> startOffset;
    56     Optional<unsigned> endOffset;
    57     RendererMap renderers;
    58     RenderBlockMap blocks;
    59 };
     51RenderRangeIterator::RenderRangeIterator(RenderObject* start)
     52    : m_current(start)
     53{
     54    checkForSpanner();
     55}
    6056
    61 class HighlightIterator {
    62 public:
    63     HighlightIterator(RenderObject* start)
    64         : m_current(start)
    65     {
     57RenderObject* RenderRangeIterator::current() const
     58{
     59    return m_current;
     60}
     61
     62RenderObject* RenderRangeIterator::next()
     63{
     64    RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
     65    m_current = m_current->nextInPreOrder(currentSpan);
     66    checkForSpanner();
     67    if (!m_current && currentSpan) {
     68        RenderObject* placeholder = m_spannerStack.last();
     69        m_spannerStack.removeLast();
     70        m_current = placeholder->nextInPreOrder();
    6671        checkForSpanner();
    6772    }
    68    
    69     RenderObject* current() const
    70     {
    71         return m_current;
    72     }
    73    
    74     RenderObject* next()
    75     {
    76         RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
    77         m_current = m_current->nextInPreOrder(currentSpan);
    78         checkForSpanner();
    79         if (!m_current && currentSpan) {
    80             RenderObject* placeholder = m_spannerStack.last();
    81             m_spannerStack.removeLast();
    82             m_current = placeholder->nextInPreOrder();
    83             checkForSpanner();
    84         }
    85         return m_current;
    86     }
     73    return m_current;
     74}
    8775
    88 private:
    89     void checkForSpanner()
    90     {
    91         if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
    92             return;
    93         auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
    94         m_spannerStack.append(&placeholder);
    95         m_current = placeholder.spanner();
    96     }
     76void RenderRangeIterator::checkForSpanner()
     77{
     78    if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
     79        return;
     80    auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
     81    m_spannerStack.append(&placeholder);
     82    m_current = placeholder.spanner();
     83}
    9784
    98     RenderObject* m_current { nullptr };
    99     Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
    100 };
    101 
    102 } // anonymous namespace
    103 
    104 static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset)
     85static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset) // <MMG> used in both, might should not be static
    10586{
    10687    auto* child = renderer.childAt(offset);
    10788    return child ? child : renderer.nextInPreOrderAfterChildren();
    108 }
    109 
    110 static bool isValidRendererForSelection(const RenderObject& renderer, const HighlightData::RenderRange& selection)
    111 {
    112     return (renderer.canBeSelectionLeaf() || &renderer == selection.start() || &renderer == selection.end())
    113         && renderer.selectionState() != RenderObject::HighlightState::None
    114         && renderer.containingBlock();
    115 }
    116 
    117 static RenderBlock* containingBlockBelowView(const RenderObject& renderer)
    118 {
    119     auto* containingBlock = renderer.containingBlock();
    120     return is<RenderView>(containingBlock) ? nullptr : containingBlock;
    121 }
    122 
    123 static SelectionData collectSelectionData(const HighlightData::RenderRange& selection, bool repaintDifference)
    124 {
    125     SelectionData oldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } };
    126     // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
    127     // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
    128     // the union of those rects might remain the same even when changes have occurred.
    129     auto* start = selection.start();
    130     RenderObject* stop = nullptr;
    131     if (selection.end())
    132         stop = rendererAfterOffset(*selection.end(), selection.endOffset().value());
    133     HighlightIterator selectionIterator(start);
    134     while (start && start != stop) {
    135         if (isValidRendererForSelection(*start, selection)) {
    136             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
    137             oldSelectionData.renderers.set(start, makeUnique<RenderSelectionInfo>(*start, true));
    138             if (repaintDifference) {
    139                 for (auto* block = containingBlockBelowView(*start); block; block = containingBlockBelowView(*block)) {
    140                     auto& blockInfo = oldSelectionData.blocks.add(block, nullptr).iterator->value;
    141                     if (blockInfo)
    142                         break;
    143                     blockInfo = makeUnique<RenderBlockSelectionInfo>(*block);
    144                 }
    145             }
    146         }
    147         start = selectionIterator.next();
    148     }
    149     return oldSelectionData;
    150 }
    151 
    152 HighlightData::HighlightData(RenderView& view)
    153     : m_renderView(view)
    154 #if ENABLE(SERVICE_CONTROLS)
    155     , m_selectionRectGatherer(view)
    156 #endif
    157 {
    15889}
    15990
     
    199130        return RenderObject::HighlightState::End;
    200131
    201     auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
     132    auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset());
    202133   
    203     HighlightIterator highlightIterator(m_renderRange.start());
     134    RenderRangeIterator highlightIterator(m_renderRange.start());
    204135    for (auto* currentRenderer = m_renderRange.start(); currentRenderer && currentRenderer != highlightEnd; currentRenderer = highlightIterator.next()) {
    205136        if (currentRenderer == m_renderRange.start())
     
    213144}
    214145
    215 void HighlightData::setSelection(const RenderRange& selection, RepaintMode blockRepaintMode)
    216 {
    217     if ((selection.start() && !selection.end()) || (selection.end() && !selection.start()))
    218         return;
    219     // Just return if the selection hasn't changed.
    220     auto isCaret = m_renderView.frame().selection().isCaret();
    221     if (selection == m_renderRange && m_selectionWasCaret == isCaret)
    222         return;
    223 #if ENABLE(SERVICE_CONTROLS)
    224     // Clear the current rects and create a notifier for the new rects we are about to gather.
    225     // The Notifier updates the Editor when it goes out of scope and is destroyed.
    226     auto rectNotifier = m_selectionRectGatherer.clearAndCreateNotifier();
    227 #endif
    228     m_selectionWasCaret = isCaret;
    229     applySelection(selection, blockRepaintMode);
    230 }
    231 
    232 void HighlightData::clearSelection()
    233 {
    234     m_renderView.layer()->repaintBlockSelectionGaps();
    235     setSelection({ }, HighlightData::RepaintMode::NewMinusOld);
    236 }
    237 
    238 void HighlightData::repaintSelection() const
    239 {
    240     HashSet<RenderBlock*> processedBlocks;
    241     RenderObject* end = nullptr;
    242     if (m_renderRange.end())
    243         end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
    244     HighlightIterator highlightIterator(m_renderRange.start());
    245     for (auto* renderer = highlightIterator.current(); renderer && renderer != end; renderer = highlightIterator.next()) {
    246         if (!renderer->canBeSelectionLeaf() && renderer != m_renderRange.start() && renderer != m_renderRange.end())
    247             continue;
    248         if (renderer->selectionState() == RenderObject::HighlightState::None)
    249             continue;
    250         RenderSelectionInfo(*renderer, true).repaint();
    251         // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
    252         for (auto* block = containingBlockBelowView(*renderer); block; block = containingBlockBelowView(*block)) {
    253             if (!processedBlocks.add(block).isNewEntry)
    254                 break;
    255             RenderSelectionInfo(*block, true).repaint();
    256         }
    257     }
    258 }
    259 
    260 IntRect HighlightData::collectBounds(ClipToVisibleContent clipToVisibleContent) const
    261 {
    262     LOG_WITH_STREAM(Selection, stream << "HighlightData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no"));
    263 
    264     SelectionData::RendererMap renderers;
    265     auto* start = m_renderRange.start();
    266     RenderObject* stop = nullptr;
    267     if (m_renderRange.end())
    268         stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
    269 
    270     HighlightIterator highlightIterator(start);
    271     while (start && start != stop) {
    272         if ((start->canBeSelectionLeaf() || start == m_renderRange.start() || start == m_renderRange.end())
    273             && start->selectionState() != RenderObject::HighlightState::None) {
    274             // Blocks are responsible for painting line gaps and margin gaps. They must be examined as well.
    275             renderers.set(start, makeUnique<RenderSelectionInfo>(*start, clipToVisibleContent == ClipToVisibleContent::Yes));
    276             LOG_WITH_STREAM(Selection, stream << " added start " << *start << " with rect " << renderers.get(start)->rect());
    277 
    278             auto* block = start->containingBlock();
    279             while (block && !is<RenderView>(*block)) {
    280                 LOG_WITH_STREAM(Scrolling, stream << " added block " << *block);
    281                 std::unique_ptr<RenderSelectionInfo>& blockInfo = renderers.add(block, nullptr).iterator->value;
    282                 if (blockInfo)
    283                     break;
    284                 blockInfo = makeUnique<RenderSelectionInfo>(*block, clipToVisibleContent == ClipToVisibleContent::Yes);
    285                 LOG_WITH_STREAM(Selection, stream << " added containing block " << *block << " with rect " << blockInfo->rect());
    286                 block = block->containingBlock();
    287             }
    288         }
    289         start = highlightIterator.next();
    290     }
    291 
    292     // Now create a single bounding box rect that encloses the whole selection.
    293     LayoutRect selectionRect;
    294     for (auto& info : renderers.values()) {
    295         // RenderSelectionInfo::rect() is in the coordinates of the repaintContainer, so map to page coordinates.
    296         LayoutRect currentRect = info->rect();
    297         if (currentRect.isEmpty())
    298             continue;
    299 
    300         if (auto* repaintContainer = info->repaintContainer()) {
    301             FloatRect localRect = currentRect;
    302             FloatQuad absQuad = repaintContainer->localToAbsoluteQuad(localRect);
    303             currentRect = absQuad.enclosingBoundingBox();
    304             LOG_WITH_STREAM(Selection, stream << " rect " << localRect << " mapped to " << currentRect << " in container " << *repaintContainer);
    305         }
    306         selectionRect.unite(currentRect);
    307     }
    308 
    309     LOG_WITH_STREAM(Selection, stream << " final rect " << selectionRect);
    310     return snappedIntRect(selectionRect);
    311 }
    312 
    313 void HighlightData::applySelection(const RenderRange& newSelection, RepaintMode blockRepaintMode)
    314 {
    315     auto oldSelectionData = collectSelectionData(m_renderRange, blockRepaintMode == RepaintMode::NewXOROld);
    316     // Remove current selection.
    317     for (auto* renderer : oldSelectionData.renderers.keys())
    318         renderer->setSelectionStateIfNeeded(RenderObject::HighlightState::None);
    319     m_renderRange = newSelection;
    320     auto* selectionStart = m_renderRange.start();
    321     // Update the selection status of all objects between selectionStart and selectionEnd
    322     if (selectionStart && selectionStart == m_renderRange.end())
    323         selectionStart->setSelectionStateIfNeeded(RenderObject::HighlightState::Both);
    324     else {
    325         if (selectionStart)
    326             selectionStart->setSelectionStateIfNeeded(RenderObject::HighlightState::Start);
    327         if (auto* end = m_renderRange.end())
    328             end->setSelectionStateIfNeeded(RenderObject::HighlightState::End);
    329     }
    330 
    331     RenderObject* selectionEnd = nullptr;
    332     auto* selectionDataEnd = m_renderRange.end();
    333     if (selectionDataEnd)
    334         selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset().value());
    335     HighlightIterator selectionIterator(selectionStart);
    336     for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
    337         if (currentRenderer == selectionStart || currentRenderer == m_renderRange.end())
    338             continue;
    339         if (!currentRenderer->canBeSelectionLeaf())
    340             continue;
    341         currentRenderer->setSelectionStateIfNeeded(RenderObject::HighlightState::Inside);
    342     }
    343 
    344     if (blockRepaintMode != RepaintMode::Nothing)
    345         m_renderView.layer()->clearBlockSelectionGapsBounds();
    346 
    347     // Now that the selection state has been updated for the new objects, walk them again and
    348     // put them in the new objects list.
    349     SelectionData::RendererMap newSelectedRenderers;
    350     SelectionData::RenderBlockMap newSelectedBlocks;
    351     selectionIterator = HighlightIterator(selectionStart);
    352     for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
    353         if (isValidRendererForSelection(*currentRenderer, m_renderRange)) {
    354             std::unique_ptr<RenderSelectionInfo> selectionInfo = makeUnique<RenderSelectionInfo>(*currentRenderer, true);
    355 #if ENABLE(SERVICE_CONTROLS)
    356             for (auto& rect : selectionInfo->collectedSelectionRects())
    357                 m_selectionRectGatherer.addRect(selectionInfo->repaintContainer(), rect);
    358             if (!currentRenderer->isTextOrLineBreak())
    359                 m_selectionRectGatherer.setTextOnly(false);
    360 #endif
    361             newSelectedRenderers.set(currentRenderer, WTFMove(selectionInfo));
    362             auto* containingBlock = currentRenderer->containingBlock();
    363             while (containingBlock && !is<RenderView>(*containingBlock)) {
    364                 std::unique_ptr<RenderBlockSelectionInfo>& blockInfo = newSelectedBlocks.add(containingBlock, nullptr).iterator->value;
    365                 if (blockInfo)
    366                     break;
    367                 blockInfo = makeUnique<RenderBlockSelectionInfo>(*containingBlock);
    368                 containingBlock = containingBlock->containingBlock();
    369 #if ENABLE(SERVICE_CONTROLS)
    370                 m_selectionRectGatherer.addGapRects(blockInfo->repaintContainer(), blockInfo->rects());
    371 #endif
    372             }
    373         }
    374     }
    375 
    376     if (blockRepaintMode == RepaintMode::Nothing)
    377         return;
    378 
    379     // Have any of the old selected objects changed compared to the new selection?
    380     for (auto& selectedRendererInfo : oldSelectionData.renderers) {
    381         auto* renderer = selectedRendererInfo.key;
    382         auto* newInfo = newSelectedRenderers.get(renderer);
    383         auto* oldInfo = selectedRendererInfo.value.get();
    384         if (!newInfo || oldInfo->rect() != newInfo->rect() || oldInfo->state() != newInfo->state()
    385             || (m_renderRange.start() == renderer && oldSelectionData.startOffset != m_renderRange.startOffset())
    386             || (m_renderRange.end() == renderer && oldSelectionData.endOffset != m_renderRange.endOffset())) {
    387             oldInfo->repaint();
    388             if (newInfo) {
    389                 newInfo->repaint();
    390                 newSelectedRenderers.remove(renderer);
    391             }
    392         }
    393     }
    394 
    395     // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
    396     for (auto& selectedRendererInfo : newSelectedRenderers)
    397         selectedRendererInfo.value->repaint();
    398 
    399     // Have any of the old blocks changed?
    400     for (auto& selectedBlockInfo : oldSelectionData.blocks) {
    401         auto* block = selectedBlockInfo.key;
    402         auto* newInfo = newSelectedBlocks.get(block);
    403         auto* oldInfo = selectedBlockInfo.value.get();
    404         if (!newInfo || oldInfo->rects() != newInfo->rects() || oldInfo->state() != newInfo->state()) {
    405             oldInfo->repaint();
    406             if (newInfo) {
    407                 newInfo->repaint();
    408                 newSelectedBlocks.remove(block);
    409             }
    410         }
    411     }
    412 
    413     // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
    414     for (auto& selectedBlockInfo : newSelectedBlocks)
    415         selectedBlockInfo.value->repaint();
    416 }
    417 
    418146} // namespace WebCore
  • trunk/Source/WebCore/rendering/HighlightData.h

    r268436 r268484  
    3131#pragma once
    3232
    33 #include "RenderSelectionInfo.h"
    34 
    35 #if ENABLE(SERVICE_CONTROLS)
    36 #include "SelectionRectGatherer.h"
    37 #endif
     33#include "RenderObject.h"
    3834
    3935namespace WebCore {
    4036
    4137struct HighlightRangeData;
     38class RenderMultiColumnSpannerPlaceholder;
     39
     40class RenderRange {
     41public:
     42    RenderRange() = default;
     43    RenderRange(RenderObject* start, RenderObject* end, unsigned startOffset, unsigned endOffset)
     44        : m_start(makeWeakPtr(start))
     45        , m_end(makeWeakPtr(end))
     46        , m_startOffset(startOffset)
     47        , m_endOffset(endOffset)
     48    {
     49    }
     50
     51    RenderObject* start() const { return m_start.get(); }
     52    RenderObject* end() const { return m_end.get(); }
     53    unsigned startOffset() const { return m_startOffset; }
     54    unsigned endOffset() const { return m_endOffset; }
     55
     56    bool operator==(const RenderRange& other) const
     57    {
     58        return m_start == other.m_start && m_end == other.m_end && m_startOffset == other.m_startOffset && m_endOffset == other.m_endOffset;
     59    }
     60
     61private:
     62    WeakPtr<RenderObject> m_start;
     63    WeakPtr<RenderObject> m_end;
     64    unsigned m_startOffset { 0 };
     65    unsigned m_endOffset { 0 };
     66};
    4267   
     68class RenderRangeIterator {
     69public:
     70    RenderRangeIterator(RenderObject* start);
     71    RenderObject* current() const;
     72    RenderObject* next();
     73   
     74private:
     75    void checkForSpanner();
     76   
     77    RenderObject* m_current { nullptr };
     78    Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
     79};
     80
    4381class HighlightData {
    4482public:
    45     HighlightData(RenderView&);
    46    
    47     class RenderRange {
    48     public:
    49         RenderRange() = default;
    50         RenderRange(RenderObject* start, RenderObject* end, unsigned startOffset, unsigned endOffset)
    51             : m_start(makeWeakPtr(start))
    52             , m_end(makeWeakPtr(end))
    53             , m_startOffset(startOffset)
    54             , m_endOffset(endOffset)
    55         {
    56         }
    57 
    58         RenderObject* start() const { return m_start.get(); }
    59         RenderObject* end() const { return m_end.get(); }
    60         Optional<unsigned> startOffset() const { return m_startOffset; }
    61         Optional<unsigned> endOffset() const { return m_endOffset; }
    62 
    63         bool operator==(const RenderRange& other) const
    64         {
    65             return m_start == other.m_start && m_end == other.m_end && m_startOffset == other.m_startOffset && m_endOffset == other.m_endOffset;
    66         }
    67 
    68     private:
    69         WeakPtr<RenderObject> m_start;
    70         WeakPtr<RenderObject> m_end;
    71         Optional<unsigned> m_startOffset;
    72         Optional<unsigned> m_endOffset;
    73     };
    74    
    7583    void setRenderRange(const RenderRange&);
    7684    bool setRenderRange(const HighlightRangeData&); // Returns true if successful.
    77    
    78     enum class RepaintMode { NewXOROld, NewMinusOld, Nothing };
    79     void setSelection(const RenderRange&, RepaintMode = RepaintMode::NewXOROld);
    8085    const RenderRange& get() const { return m_renderRange; }
    8186
     
    8388    RenderObject* end() const { return m_renderRange.end(); }
    8489
    85     unsigned startOffset() const { ASSERT(m_renderRange.startOffset()); return m_renderRange.startOffset().valueOr(0); }
    86     unsigned endOffset() const { ASSERT(m_renderRange.endOffset()); return m_renderRange.endOffset().valueOr(0); }
     90    unsigned startOffset() const { return m_renderRange.startOffset(); }
     91    unsigned endOffset() const { return m_renderRange.endOffset(); }
    8792
    88     void clearSelection();
    89     IntRect bounds() const { return collectBounds(ClipToVisibleContent::No); }
    90     IntRect boundsClippedToVisibleContent() const { return collectBounds(ClipToVisibleContent::Yes); }
    91     void repaintSelection() const;
    92    
    9393    RenderObject::HighlightState highlightStateForRenderer(const RenderObject&);
    9494
    95 private:
    96     enum class ClipToVisibleContent { Yes, No };
    97     IntRect collectBounds(ClipToVisibleContent) const;
    98     void applySelection(const RenderRange&, RepaintMode);
    99 
    100     const RenderView& m_renderView;
    101 #if ENABLE(SERVICE_CONTROLS)
    102     SelectionRectGatherer m_selectionRectGatherer;
    103 #endif
     95protected:
    10496    RenderRange m_renderRange;
    105     bool m_selectionWasCaret { false };
    10697};
    10798
  • trunk/Source/WebCore/rendering/InlineTextBox.cpp

    r265338 r268484  
    10511051    auto& parentRenderer = parent()->renderer();
    10521052    auto& parentStyle = parentRenderer.style();
     1053    HighlightData highlightData;
    10531054    for (auto& highlight : renderer().document().highlightMap().map()) {
    10541055        auto renderStyle = parentRenderer.getUncachedPseudoStyle({ PseudoId::Highlight, highlight.key }, &parentStyle);
     
    10581059            continue;
    10591060        for (auto& rangeData : highlight.value->rangesData()) {
    1060             if (rangeData->startPosition && rangeData->endPosition) {
    1061                 Position startPosition = rangeData->startPosition.value();
    1062                 Position endPosition = rangeData->endPosition.value();
    1063                 auto* startRenderer = startPosition.deprecatedNode()->renderer();
    1064                 unsigned startOffset = startPosition.deprecatedEditingOffset();
    1065                 auto* endRenderer = endPosition.deprecatedNode()->renderer();
    1066                 unsigned endOffset = endPosition.deprecatedEditingOffset();
    1067                 if (!startRenderer || !endRenderer)
    1068                     continue;
    1069 
    1070                 auto highlightData = HighlightData(renderer().view());
    1071                 highlightData.setRenderRange({ startRenderer, endRenderer, startOffset, endOffset });
    1072                 auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData);
    1073                 if (highlightStart < highlightEnd)
    1074                     markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key });
    1075             }
     1061            if (!highlightData.setRenderRange(rangeData))
     1062                continue;
     1063           
     1064            auto [highlightStart, highlightEnd] = highlightStartEnd(highlightData);
     1065            if (highlightStart < highlightEnd)
     1066                markedTexts.append({ highlightStart, highlightEnd, MarkedText::Highlight, nullptr, highlight.key });
    10761067        }
    10771068    }
  • trunk/Source/WebCore/rendering/RenderReplaced.cpp

    r268436 r268484  
    153153Color RenderReplaced::calculateHighlightColor() const
    154154{
    155     auto highlightData = HighlightData(view());
     155    HighlightData highlightData;
    156156    for (auto& highlight : document().highlightMap().map()) {
    157157        for (auto& rangeData : highlight.value->rangesData()) {
  • trunk/Source/WebCore/rendering/RenderView.h

    r260415 r268484  
    2323
    2424#include "FrameView.h"
    25 #include "HighlightData.h"
    2625#include "Region.h"
    2726#include "RenderBlockFlow.h"
    2827#include "RenderWidget.h"
     28#include "SelectionRangeData.h"
    2929#include <memory>
    3030#include <wtf/HashSet.h>
     
    8585    RenderElement* rendererForRootBackground() const;
    8686
    87     HighlightData& selection() { return m_selection; }
     87    SelectionRangeData& selection() { return m_selection; }
    8888
    8989    bool printing() const;
     
    225225
    226226    mutable std::unique_ptr<Region> m_accumulatedRepaintRegion;
    227     HighlightData m_selection;
     227    SelectionRangeData m_selection;
    228228
    229229    WeakPtr<RenderLayer> m_styleChangeLayerMutationRoot;
  • trunk/Source/WebCore/rendering/SelectionRangeData.cpp

    r268483 r268484  
    11/*
    2  * Copyright (C) 2014 Igalia S.L.
    3  * Copyright (C) 2015-2017 Apple Inc. All rights reserved.
     2 * Copyright (C) 2020 Apple Inc. All rights reserved.
    43 *
    54 * Redistribution and use in source and binary forms, with or without
     
    3029
    3130#include "config.h"
    32 #include "HighlightData.h"
     31#include "SelectionRangeData.h"
    3332
    3433#include "Document.h"
     
    3938#include "Range.h"
    4039#include "RenderLayer.h"
    41 #include "RenderMultiColumnSpannerPlaceholder.h"
    4240#include "RenderObject.h"
    4341#include "RenderView.h"
     
    4745namespace WebCore {
    4846
    49 namespace { // See bug #177808.
    50 
    51 struct SelectionData {
     47namespace {
     48
     49struct SelectionContext {
     50   
    5251    using RendererMap = HashMap<RenderObject*, std::unique_ptr<RenderSelectionInfo>>;
    5352    using RenderBlockMap = HashMap<const RenderBlock*, std::unique_ptr<RenderBlockSelectionInfo>>;
    5453
    55     Optional<unsigned> startOffset;
    56     Optional<unsigned> endOffset;
     54    unsigned startOffset;
     55    unsigned endOffset;
    5756    RendererMap renderers;
    5857    RenderBlockMap blocks;
    5958};
    6059
    61 class HighlightIterator {
    62 public:
    63     HighlightIterator(RenderObject* start)
    64         : m_current(start)
    65     {
    66         checkForSpanner();
    67     }
    68    
    69     RenderObject* current() const
    70     {
    71         return m_current;
    72     }
    73    
    74     RenderObject* next()
    75     {
    76         RenderObject* currentSpan = m_spannerStack.isEmpty() ? nullptr : m_spannerStack.last()->spanner();
    77         m_current = m_current->nextInPreOrder(currentSpan);
    78         checkForSpanner();
    79         if (!m_current && currentSpan) {
    80             RenderObject* placeholder = m_spannerStack.last();
    81             m_spannerStack.removeLast();
    82             m_current = placeholder->nextInPreOrder();
    83             checkForSpanner();
    84         }
    85         return m_current;
    86     }
    87 
    88 private:
    89     void checkForSpanner()
    90     {
    91         if (!is<RenderMultiColumnSpannerPlaceholder>(m_current))
    92             return;
    93         auto& placeholder = downcast<RenderMultiColumnSpannerPlaceholder>(*m_current);
    94         m_spannerStack.append(&placeholder);
    95         m_current = placeholder.spanner();
    96     }
    97 
    98     RenderObject* m_current { nullptr };
    99     Vector<RenderMultiColumnSpannerPlaceholder*> m_spannerStack;
    100 };
    101 
    102 } // anonymous namespace
     60}
    10361
    10462static RenderObject* rendererAfterOffset(const RenderObject& renderer, unsigned offset)
     
    10866}
    10967
    110 static bool isValidRendererForSelection(const RenderObject& renderer, const HighlightData::RenderRange& selection)
     68static bool isValidRendererForSelection(const RenderObject& renderer, const RenderRange& selection)
    11169{
    11270    return (renderer.canBeSelectionLeaf() || &renderer == selection.start() || &renderer == selection.end())
    113         && renderer.selectionState() != RenderObject::HighlightState::None
    114         && renderer.containingBlock();
     71    && renderer.selectionState() != RenderObject::HighlightState::None
     72    && renderer.containingBlock();
    11573}
    11674
     
    12179}
    12280
    123 static SelectionData collectSelectionData(const HighlightData::RenderRange& selection, bool repaintDifference)
    124 {
    125     SelectionData oldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } };
     81static SelectionContext collectSelectionData(const RenderRange& selection, bool repaintDifference)
     82{
     83    SelectionContext oldSelectionData { selection.startOffset(), selection.endOffset(), { }, { } };
    12684    // Blocks contain selected objects and fill gaps between them, either on the left, right, or in between lines and blocks.
    12785    // In order to get the repaint rect right, we have to examine left, middle, and right rects individually, since otherwise
     
    13088    RenderObject* stop = nullptr;
    13189    if (selection.end())
    132         stop = rendererAfterOffset(*selection.end(), selection.endOffset().value());
    133     HighlightIterator selectionIterator(start);
     90        stop = rendererAfterOffset(*selection.end(), selection.endOffset());
     91    RenderRangeIterator selectionIterator(start);
    13492    while (start && start != stop) {
    13593        if (isValidRendererForSelection(*start, selection)) {
     
    150108}
    151109
    152 HighlightData::HighlightData(RenderView& view)
     110SelectionRangeData::SelectionRangeData(RenderView& view)
    153111    : m_renderView(view)
    154112#if ENABLE(SERVICE_CONTROLS)
     
    158116}
    159117
    160 void HighlightData::setRenderRange(const RenderRange& renderRange)
    161 {
    162     ASSERT(renderRange.start() && renderRange.end());
    163     m_renderRange = renderRange;
    164 }
    165 
    166 bool HighlightData::setRenderRange(const HighlightRangeData& rangeData)
    167 {
    168     if (!rangeData.startPosition || !rangeData.endPosition)
    169         return false;
    170    
    171     auto startPosition = rangeData.startPosition.value();
    172     auto endPosition = rangeData.endPosition.value();
    173    
    174     if (!startPosition.containerNode() || !endPosition.containerNode())
    175         return false;
    176    
    177     auto* startRenderer = startPosition.containerNode()->renderer();
    178     auto* endRenderer = endPosition.containerNode()->renderer();
    179    
    180     if (!startRenderer || !endRenderer)
    181         return false;
    182    
    183     unsigned startOffset = startPosition.computeOffsetInContainerNode();
    184     unsigned endOffset = endPosition.computeOffsetInContainerNode();
    185 
    186     setRenderRange({ startRenderer, endRenderer, startOffset, endOffset });
    187     return true;
    188 }
    189 
    190 RenderObject::HighlightState HighlightData::highlightStateForRenderer(const RenderObject& renderer)
    191 {
    192     if (&renderer == m_renderRange.start()) {
    193         if (m_renderRange.start() && m_renderRange.end() && m_renderRange.start() == m_renderRange.end())
    194             return RenderObject::HighlightState::Both;
    195         if (m_renderRange.start())
    196             return RenderObject::HighlightState::Start;
    197     }
    198     if (&renderer == m_renderRange.end())
    199         return RenderObject::HighlightState::End;
    200 
    201     auto* highlightEnd = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
    202    
    203     HighlightIterator highlightIterator(m_renderRange.start());
    204     for (auto* currentRenderer = m_renderRange.start(); currentRenderer && currentRenderer != highlightEnd; currentRenderer = highlightIterator.next()) {
    205         if (currentRenderer == m_renderRange.start())
    206             continue;
    207         if (!currentRenderer->canBeSelectionLeaf())
    208             continue;
    209         if (&renderer == currentRenderer)
    210             return RenderObject::HighlightState::Inside;
    211     }
    212     return RenderObject::HighlightState::None;
    213 }
    214 
    215 void HighlightData::setSelection(const RenderRange& selection, RepaintMode blockRepaintMode)
     118void SelectionRangeData::set(const RenderRange& selection, RepaintMode blockRepaintMode)
    216119{
    217120    if ((selection.start() && !selection.end()) || (selection.end() && !selection.start()))
     
    227130#endif
    228131    m_selectionWasCaret = isCaret;
    229     applySelection(selection, blockRepaintMode);
    230 }
    231 
    232 void HighlightData::clearSelection()
     132    apply(selection, blockRepaintMode);
     133}
     134
     135void SelectionRangeData::clear()
    233136{
    234137    m_renderView.layer()->repaintBlockSelectionGaps();
    235     setSelection({ }, HighlightData::RepaintMode::NewMinusOld);
    236 }
    237 
    238 void HighlightData::repaintSelection() const
     138    set({ }, SelectionRangeData::RepaintMode::NewMinusOld);
     139}
     140
     141void SelectionRangeData::repaint() const
    239142{
    240143    HashSet<RenderBlock*> processedBlocks;
    241144    RenderObject* end = nullptr;
    242145    if (m_renderRange.end())
    243         end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
    244     HighlightIterator highlightIterator(m_renderRange.start());
     146        end = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset());
     147    RenderRangeIterator highlightIterator(m_renderRange.start());
    245148    for (auto* renderer = highlightIterator.current(); renderer && renderer != end; renderer = highlightIterator.next()) {
    246149        if (!renderer->canBeSelectionLeaf() && renderer != m_renderRange.start() && renderer != m_renderRange.end())
     
    258161}
    259162
    260 IntRect HighlightData::collectBounds(ClipToVisibleContent clipToVisibleContent) const
    261 {
    262     LOG_WITH_STREAM(Selection, stream << "HighlightData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no"));
    263 
    264     SelectionData::RendererMap renderers;
     163IntRect SelectionRangeData::collectBounds(ClipToVisibleContent clipToVisibleContent) const
     164{
     165    LOG_WITH_STREAM(Selection, stream << "SelectionData::collectBounds (clip to visible " << (clipToVisibleContent == ClipToVisibleContent::Yes ? "yes" : "no"));
     166   
     167    SelectionContext::RendererMap renderers;
    265168    auto* start = m_renderRange.start();
    266169    RenderObject* stop = nullptr;
    267170    if (m_renderRange.end())
    268         stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset().value());
    269 
    270     HighlightIterator highlightIterator(start);
     171        stop = rendererAfterOffset(*m_renderRange.end(), m_renderRange.endOffset());
     172   
     173    RenderRangeIterator selectionIterator(start);
    271174    while (start && start != stop) {
    272175        if ((start->canBeSelectionLeaf() || start == m_renderRange.start() || start == m_renderRange.end())
     
    275178            renderers.set(start, makeUnique<RenderSelectionInfo>(*start, clipToVisibleContent == ClipToVisibleContent::Yes));
    276179            LOG_WITH_STREAM(Selection, stream << " added start " << *start << " with rect " << renderers.get(start)->rect());
    277 
     180           
    278181            auto* block = start->containingBlock();
    279182            while (block && !is<RenderView>(*block)) {
     
    287190            }
    288191        }
    289         start = highlightIterator.next();
    290     }
    291 
     192        start = selectionIterator.next();
     193    }
     194   
    292195    // Now create a single bounding box rect that encloses the whole selection.
    293196    LayoutRect selectionRect;
     
    297200        if (currentRect.isEmpty())
    298201            continue;
    299 
     202       
    300203        if (auto* repaintContainer = info->repaintContainer()) {
    301204            FloatRect localRect = currentRect;
     
    306209        selectionRect.unite(currentRect);
    307210    }
    308 
     211   
    309212    LOG_WITH_STREAM(Selection, stream << " final rect " << selectionRect);
    310213    return snappedIntRect(selectionRect);
    311214}
    312215
    313 void HighlightData::applySelection(const RenderRange& newSelection, RepaintMode blockRepaintMode)
     216void SelectionRangeData::apply(const RenderRange& newSelection, RepaintMode blockRepaintMode)
    314217{
    315218    auto oldSelectionData = collectSelectionData(m_renderRange, blockRepaintMode == RepaintMode::NewXOROld);
     
    328231            end->setSelectionStateIfNeeded(RenderObject::HighlightState::End);
    329232    }
    330 
     233   
    331234    RenderObject* selectionEnd = nullptr;
    332235    auto* selectionDataEnd = m_renderRange.end();
    333236    if (selectionDataEnd)
    334         selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset().value());
    335     HighlightIterator selectionIterator(selectionStart);
     237        selectionEnd = rendererAfterOffset(*selectionDataEnd, m_renderRange.endOffset());
     238    RenderRangeIterator selectionIterator(selectionStart);
    336239    for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
    337240        if (currentRenderer == selectionStart || currentRenderer == m_renderRange.end())
     
    341244        currentRenderer->setSelectionStateIfNeeded(RenderObject::HighlightState::Inside);
    342245    }
    343 
     246   
    344247    if (blockRepaintMode != RepaintMode::Nothing)
    345248        m_renderView.layer()->clearBlockSelectionGapsBounds();
    346 
     249   
    347250    // Now that the selection state has been updated for the new objects, walk them again and
    348251    // put them in the new objects list.
    349     SelectionData::RendererMap newSelectedRenderers;
    350     SelectionData::RenderBlockMap newSelectedBlocks;
    351     selectionIterator = HighlightIterator(selectionStart);
     252    SelectionContext::RendererMap newSelectedRenderers;
     253    SelectionContext::RenderBlockMap newSelectedBlocks;
     254    selectionIterator = RenderRangeIterator(selectionStart);
    352255    for (auto* currentRenderer = selectionStart; currentRenderer && currentRenderer != selectionEnd; currentRenderer = selectionIterator.next()) {
    353256        if (isValidRendererForSelection(*currentRenderer, m_renderRange)) {
     
    373276        }
    374277    }
    375 
     278   
    376279    if (blockRepaintMode == RepaintMode::Nothing)
    377280        return;
    378 
     281   
    379282    // Have any of the old selected objects changed compared to the new selection?
    380283    for (auto& selectedRendererInfo : oldSelectionData.renderers) {
     
    392295        }
    393296    }
    394 
     297   
    395298    // Any new objects that remain were not found in the old objects dict, and so they need to be updated.
    396299    for (auto& selectedRendererInfo : newSelectedRenderers)
    397300        selectedRendererInfo.value->repaint();
    398 
     301   
    399302    // Have any of the old blocks changed?
    400303    for (auto& selectedBlockInfo : oldSelectionData.blocks) {
     
    410313        }
    411314    }
    412 
     315   
    413316    // Any new blocks that remain were not found in the old blocks dict, and so they need to be updated.
    414317    for (auto& selectedBlockInfo : newSelectedBlocks)
Note: See TracChangeset for help on using the changeset viewer.