Skip to content
Permalink
Browse files
InteractionRegion for wrapped text has multiple rects instead of one
https://bugs.webkit.org/show_bug.cgi?id=240748

Reviewed by Wenson Hsieh.

* Source/WebCore/page/InteractionRegion.h:
(WebCore::operator==):
(WebCore::InteractionRegion::encode const):
(WebCore::InteractionRegion::decode):
* Source/WebCore/rendering/EventRegion.cpp:
(WebCore::EventRegion::translate):
(WebCore::EventRegion::dump const):
* Source/WebKit/UIProcess/RemoteLayerTree/RemoteLayerTreeInteractionRegionLayers.mm:
(WebKit::updateLayersForInteractionRegions):
* Source/WebCore/page/DebugPageOverlays.cpp:
(WebCore::pathsForRegion):
(WebCore::InteractionRegionOverlay::activeRegion):
(WebCore::InteractionRegionOverlay::drawRect):
* Source/WebCore/page/InteractionRegion.cpp:
(WebCore::regionForElement):
Maintain InteractionRegion geometry as a Region instead of a vector of rects,
so that we can smush overlapping rectangles together on a per-InteractionRegion basis.

(WebCore::operator<<):
Add dumping code for InteractionRegion (and adopt it in EventRegion).

* LayoutTests/TestExpectations:
* LayoutTests/interaction-region/click-handler-expected.txt: Added.
* LayoutTests/interaction-region/click-handler.html: Added.
* LayoutTests/interaction-region/inline-link-dark-background-expected.txt: Added.
* LayoutTests/interaction-region/inline-link-dark-background.html: Added.
* LayoutTests/interaction-region/inline-link-expected.txt: Added.
* LayoutTests/interaction-region/inline-link.html: Added.
* LayoutTests/interaction-region/split-inline-link-expected.txt: Added.
* LayoutTests/interaction-region/split-inline-link.html: Added.
* LayoutTests/interaction-region/wrapped-inline-link-expected.txt: Added.
* LayoutTests/interaction-region/wrapped-inline-link.html: Added.
Add some basic interaction region tests, currently disabled by default
because they can only be run if you turn on the build-time flag.

"wrapped-inline-link.html" covers the case we are fixing by adopting Region;
the others are more generic tests that we should have had before.

Canonical link: https://commits.webkit.org/250840@main
git-svn-id: https://svn.webkit.org/repository/webkit/trunk@294614 268f45cc-cd09-0410-ab3c-d52691b4dbfc
  • Loading branch information
hortont424 committed May 21, 2022
1 parent 127ac8e commit 9ebbc1144a7969dd171d5af111454f76354b9a2e
Showing 16 changed files with 288 additions and 27 deletions.
@@ -88,6 +88,7 @@ fast/media/ios [ Skip ]
fast/dom/Range/mac [ Skip ]
remote-layer-tree/ios [ Skip ]
inspector/page/setScreenSizeOverride.html [ Skip ]
interaction-region [ Skip ]

# Requires async overflow scrolling
compositing/shared-backing/overflow-scroll [ Skip ]
@@ -0,0 +1,23 @@
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(region
(rect (0,0) width=100 height=100)
)
(hasLightBackground 1)
(borderRadius 10.00)])
)
)
)
)

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html>
<style>
body { margin: 0; }

#button {
display: inline-block;
width: 100px;
height: 100px;
background-color: green;
cursor: pointer;
border-radius: 10px;
}
</style>
<body>
<div id="button" onclick="click()"></div>

<pre id="results"></pre>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.onload = function () {
if (window.internals)
results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
};
</script>
</body>
</html>
@@ -0,0 +1,24 @@
This is a link.
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #000000)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(region
(rect (-3,-3) width=35 height=24)
)
(hasLightBackground 0)
(borderRadius 0.00)])
)
)
)
)

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<style>
body {
margin: 0;
background-color: black;
color: white;
}
</style>
<body>
<a href="#">This</a> is a link.

<pre id="results"></pre>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.onload = function () {
if (window.internals)
results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
};
</script>
</body>
</html>
@@ -0,0 +1,24 @@
This is a link.
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(region
(rect (-3,-3) width=35 height=24)
)
(hasLightBackground 1)
(borderRadius 0.00)])
)
)
)
)

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<style>
body { margin: 0; }
</style>
<body>
<a href="#">This</a> is a link.

<pre id="results"></pre>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.onload = function () {
if (window.internals)
results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
};
</script>
</body>
</html>
@@ -0,0 +1,28 @@
A bunch of text before the first line
short second line.
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(region
(rect (197,-3) width=31 height=18)
(rect (-3,15) width=115 height=6)
(rect (197,15) width=31 height=6)
(rect (-3,21) width=115 height=18)
)
(hasLightBackground 1)
(borderRadius 0.00)])
)
)
)
)

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<style>
body { margin: 0; }
</style>
<body>
A bunch of text before the first <a href="#">line<br/>short second line</a>.

<pre id="results"></pre>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.onload = function () {
if (window.internals)
results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
};
</script>
</body>
</html>
@@ -0,0 +1,27 @@
Line
Line
Line
Line
(GraphicsLayer
(anchor 0.00 0.00)
(bounds 800.00 600.00)
(children 1
(GraphicsLayer
(bounds 800.00 600.00)
(contentsOpaque 1)
(drawsContent 1)
(backgroundColor #FFFFFF)
(event region
(rect (0,0) width=800 height=600)

(interaction regions [
(region
(rect (-3,-3) width=36 height=78)
)
(hasLightBackground 1)
(borderRadius 0.00)])
)
)
)
)

@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html>
<style>
body { margin: 0; }
</style>
<body>
<a href="#">Line<br/>Line<br/>Line<br/>Line</a>

<pre id="results"></pre>
<script>
if (window.testRunner)
testRunner.dumpAsText();

window.onload = function () {
if (window.internals)
results.textContent = internals.layerTreeAsText(document, internals.LAYER_TREE_INCLUDES_EVENT_REGION | internals.LAYER_TREE_INCLUDES_ROOT_LAYER_PROPERTIES);
};
</script>
</body>
</html>
@@ -295,9 +295,9 @@ static Vector<Path> pathsForRegion(const InteractionRegion& region)
{
static constexpr float radius = 4;

Vector<FloatRect> rects;
for (auto rect : region.rectsInContentCoordinates)
rects.append(rect);
Vector<FloatRect> rects = region.regionInLayerCoordinates.rects().map([] (auto rect) -> FloatRect {
return rect;
});
return PathUtilities::pathsWithShrinkWrappedRects(rects, std::max(region.borderRadius, radius));
}

@@ -309,7 +309,7 @@ std::optional<InteractionRegion> InteractionRegionOverlay::activeRegion()
for (const auto& region : m_regions) {
float area = 0;
FloatRect boundingRect;
for (const auto& rect : region.rectsInContentCoordinates) {
for (const auto& rect : region.regionInLayerCoordinates.rects()) {
if (boundingRect.isEmpty())
boundingRect = rect;
else
@@ -433,8 +433,8 @@ void InteractionRegionOverlay::drawRect(PageOverlay&, GraphicsContext& context,
context.setStrokeColor(Color::green);

for (const auto& region : m_regions) {
for (const auto& rect : region.rectsInContentCoordinates)
context.strokeRect(rect, 2);
for (const auto& rect : region.regionInLayerCoordinates.rects())
context.strokeRect(rect, 2);
}
}

@@ -111,20 +111,20 @@ static std::optional<InteractionRegion> regionForElement(Element& element)
RoundedRect::Radii borderRadii = downcast<RenderBox>(*renderer).borderRadii();
region.borderRadius = borderRadii.minimumRadius();
}

region.rectsInContentCoordinates = compactMap(rectsInContentCoordinates, [&](auto rect) -> std::optional<FloatRect> {
for (auto rect : rectsInContentCoordinates) {
auto contentsRect = rect;

if (&frameView != &mainFrameView)
contentsRect.intersect(frameClipRect);

if (contentsRect.isEmpty())
return std::nullopt;
continue;

return contentsRect;
});
region.regionInLayerCoordinates.unite(enclosingIntRect(contentsRect));
}

if (region.rectsInContentCoordinates.isEmpty())
if (region.regionInLayerCoordinates.isEmpty())
return std::nullopt;

return region;
@@ -186,4 +186,13 @@ Vector<InteractionRegion> interactionRegions(Page& page, FloatRect rect)
return regions;
}

TextStream& operator<<(TextStream& ts, const InteractionRegion& interactionRegion)
{
ts.dumpProperty("region", interactionRegion.regionInLayerCoordinates);
ts.dumpProperty("hasLightBackground", interactionRegion.hasLightBackground);
ts.dumpProperty("borderRadius", interactionRegion.borderRadius);

return ts;
}

}

0 comments on commit 9ebbc11

Please sign in to comment.