Skip to content
Permalink
Browse files
Scroll To Text Fragment Indicator flashes though banners.
https://bugs.webkit.org/show_bug.cgi?id=245116
rdar://99669383

Reviewed by Tim Horton.

The text indicator is flashing through banners that are over the text at the time of
flash. In order to stop this, check the edge of the indicator and do not start it if
either end is occluded. This does not deal with popups that show up part way through
the flash of the indicator.

* Source/WebCore/page/FrameView.cpp:
(WebCore::FrameView::textFragmentIndicatorTimerFired):

Canonical link: https://commits.webkit.org/254494@main
  • Loading branch information
megangardner committed Sep 14, 2022
1 parent 3b0345e commit 13be919f4512dc3771840c699abf5389bbe422e9
Showing 1 changed file with 38 additions and 4 deletions.
@@ -2457,20 +2457,54 @@ void FrameView::textFragmentIndicatorTimerFired()
ASSERT(frame().document());
auto& document = *frame().document();

if (!m_pendingTextFragmentIndicatorRange)
if (!m_pendingTextFragmentIndicatorRange) {
cancelScheduledTextFragmentIndicatorTimer();
return;
}

if (m_pendingTextFragmentIndicatorText != plainText(m_pendingTextFragmentIndicatorRange.value()))
if (m_pendingTextFragmentIndicatorText != plainText(m_pendingTextFragmentIndicatorRange.value())) {
cancelScheduledTextFragmentIndicatorTimer();
return;
}

auto range = m_pendingTextFragmentIndicatorRange.value();
TemporarySelectionChange selectionChange(document, { range }, { TemporarySelectionOption::DelegateMainFrameScroll, TemporarySelectionOption::RevealSelectionBounds, TemporarySelectionOption::UserTriggered, TemporarySelectionOption::ForceCenterScroll });

auto textIndicator = TextIndicator::createWithRange(range, { TextIndicatorOption::DoNotClipToVisibleRect }, WebCore::TextIndicatorPresentationTransition::Bounce);
if (textIndicator)
document.page()->chrome().client().setTextIndicator(textIndicator->data());

auto* page = frame().page();

cancelScheduledTextFragmentIndicatorTimer();

if (!page)
return;

if (textIndicator) {
constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::AllowVisibleChildFrameContentOnly };

auto textRects = RenderFlexibleBox::absoluteTextRects(range);

HitTestResult result;
result = page->mainFrame().eventHandler().hitTestResultAtPoint(LayoutPoint(textRects.first().center()), hitType);
if (!intersects(range, *result.targetNode()))
return;

if (textRects.size() >= 2) {
result = page->mainFrame().eventHandler().hitTestResultAtPoint(LayoutPoint(textRects[1].center()), hitType);
if (!intersects(range, *result.targetNode()))
return;
}

if (textRects.size() >= 4) {
result = page->mainFrame().eventHandler().hitTestResultAtPoint(LayoutPoint(textRects.last().center()), hitType);
if (!intersects(range, *result.targetNode()))
return;
result = page->mainFrame().eventHandler().hitTestResultAtPoint(LayoutPoint(textRects[textRects.size() - 2].center()), hitType);
if (!intersects(range, *result.targetNode()))
return;
}
document.page()->chrome().client().setTextIndicator(textIndicator->data());
}
}

void FrameView::cancelScheduledTextFragmentIndicatorTimer()

0 comments on commit 13be919

Please sign in to comment.