Commit 6e8a9c51 authored by Ehsan Karamad's avatar Ehsan Karamad Committed by Commit Bot

Fix for finding touch regions of Window targets

Currently if a DomWindow in the page has a touch handler, the whole
region for local frame root is added as touch region. This is
incorrect as only the window for corresponding to the document/frame
should be considered -- which is the same treatment that is given to
|document|.

Bug: 830626
Change-Id: Ieebd4116e9753f800fe2534cb0c89da812d22c56
Reviewed-on: https://chromium-review.googlesource.com/1005368Reviewed-by: default avatarRobert Flack <flackr@chromium.org>
Commit-Queue: Ehsan Karamad <ekaramad@chromium.org>
Cr-Commit-Position: refs/heads/master@{#555665}
parent d6e2784f
...@@ -1075,7 +1075,7 @@ Region ScrollingCoordinator::ComputeShouldHandleScrollGestureOnMainThreadRegion( ...@@ -1075,7 +1075,7 @@ Region ScrollingCoordinator::ComputeShouldHandleScrollGestureOnMainThreadRegion(
static void AccumulateDocumentTouchEventTargetRects( static void AccumulateDocumentTouchEventTargetRects(
LayerHitTestRects& rects, LayerHitTestRects& rects,
EventHandlerRegistry::EventHandlerClass event_class, EventHandlerRegistry::EventHandlerClass event_class,
const Document* document, Document* document,
TouchAction supported_fast_actions) { TouchAction supported_fast_actions) {
DCHECK(document); DCHECK(document);
const EventTargetSet* targets = const EventTargetSet* targets =
...@@ -1094,55 +1094,53 @@ static void AccumulateDocumentTouchEventTargetRects( ...@@ -1094,55 +1094,53 @@ static void AccumulateDocumentTouchEventTargetRects(
// implemented by replacing the root cc::layer with the video layer so doing // implemented by replacing the root cc::layer with the video layer so doing
// this optimization causes the compositor to think that there are no // this optimization causes the compositor to think that there are no
// handlers, therefore skip it. // handlers, therefore skip it.
if (!document->GetLayoutView()->Compositor()->InOverlayFullscreenVideo()) { if (!document->GetLayoutView()->Compositor()->InOverlayFullscreenVideo() &&
for (const auto& event_target : *targets) { (!document->View() || !document->View()->ShouldThrottleRendering())) {
EventTarget* target = event_target.key; if (targets->Contains(document) ||
Node* node = target->ToNode(); (document->documentElement() &&
LocalDOMWindow* window = target->ToLocalDOMWindow(); targets->Contains(document->documentElement())) ||
// If the target is inside a throttled frame, skip it. (document->body() && targets->Contains(document->body())) ||
if (window && window->GetFrame()->View() && targets->Contains(document->GetFrame()->DomWindow())) {
window->GetFrame()->View()->ShouldThrottleRendering()) document->GetLayoutView()->ComputeLayerHitTestRects(
continue; rects, supported_fast_actions);
if (node && node->GetDocument().View() && return;
node->GetDocument().View()->ShouldThrottleRendering())
continue;
if (window || node == document || node == document->documentElement() ||
node == document->body()) {
if (auto* layout_view = document->GetLayoutView()) {
layout_view->ComputeLayerHitTestRects(rects, supported_fast_actions);
}
return;
}
} }
} }
for (const auto& event_target : *targets) { for (const auto& event_target : *targets) {
EventTarget* target = event_target.key; EventTarget* target = event_target.key;
Node* node = target->ToNode(); Node* node = target->ToNode();
if (!node || !node->isConnected()) LocalDOMWindow* window = target->ToLocalDOMWindow();
if (!window && (!node || !node->isConnected()))
continue; continue;
Document& document_node =
window ? *window->document() : node->GetDocument();
// If the document belongs to an invisible subframe it does not have a // If the document belongs to an invisible subframe it does not have a
// composited layer and should be skipped. // composited layer and should be skipped.
if (node->GetDocument().IsInInvisibleSubframe()) if (document_node.IsInInvisibleSubframe())
continue; continue;
// If the node belongs to a throttled frame, skip it. // If the node belongs to a throttled frame, skip it.
if (node->GetDocument().View() && if (document_node.View() && document_node.View()->ShouldThrottleRendering())
node->GetDocument().View()->ShouldThrottleRendering())
continue; continue;
// Ignore events which apply to a different LocalFrameRoot, as they have // Ignore events which apply to a different LocalFrameRoot, as they have
// their own lifecycle. Any events that apply to them will get processed // their own lifecycle. Any events that apply to them will get processed
// accordingly. // accordingly.
if (node->GetDocument().GetFrame()->LocalFrameRoot() != if (document_node.GetFrame()->LocalFrameRoot() !=
document->GetFrame()->LocalFrameRoot()) document->GetFrame()->LocalFrameRoot()) {
continue; continue;
}
if (node->IsDocumentNode() && node != document) { if ((window || node->IsDocumentNode()) && &document_node != document) {
AccumulateDocumentTouchEventTargetRects( AccumulateDocumentTouchEventTargetRects(
rects, event_class, ToDocument(node), supported_fast_actions); rects, event_class, &document_node, supported_fast_actions);
} else if (LayoutObject* layout_object = node->GetLayoutObject()) { } else if (node) {
LayoutObject* layout_object = node->GetLayoutObject();
if (!layout_object)
continue;
// If the set also contains one of our ancestor nodes then processing // If the set also contains one of our ancestor nodes then processing
// this node would be redundant. // this node would be redundant.
bool has_touch_event_target_ancestor = false; bool has_touch_event_target_ancestor = false;
......
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "third_party/blink/renderer/core/layout/layout_embedded_content.h" #include "third_party/blink/renderer/core/layout/layout_embedded_content.h"
#include "third_party/blink/renderer/core/layout/layout_view.h" #include "third_party/blink/renderer/core/layout/layout_view.h"
#include "third_party/blink/renderer/core/page/page.h" #include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/page/scrolling/scrolling_coordinator_context.h"
#include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h" #include "third_party/blink/renderer/core/paint/compositing/composited_layer_mapping.h"
#include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h" #include "third_party/blink/renderer/core/paint/compositing/paint_layer_compositor.h"
#include "third_party/blink/renderer/platform/geometry/int_point.h" #include "third_party/blink/renderer/platform/geometry/int_point.h"
...@@ -618,6 +619,53 @@ TEST_P(ScrollingCoordinatorTest, touchActionBlockingHandler) { ...@@ -618,6 +619,53 @@ TEST_P(ScrollingCoordinatorTest, touchActionBlockingHandler) {
EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000)); EXPECT_EQ(region.bounds(), gfx::Rect(0, 0, 1000, 1000));
} }
TEST_P(ScrollingCoordinatorTest, IframeWindowTouchHandler) {
LoadHTML(
R"(<iframe style="width: 275px; height: 250px;"></iframe>)");
WebLocalFrameImpl* child_frame =
ToWebLocalFrameImpl(GetWebView()->MainFrameImpl()->FirstChild());
FrameTestHelpers::LoadHTMLString(child_frame,
R"(<body>
<p style="margin: 1000px"> Hello </p>
<script>
window.addEventListener('touchstart', (e) => {
e.preventDefault();
}, {passive: false});
</script>
</body>)",
URLTestHelpers::ToKURL("about:blank"));
ForceFullCompositingUpdate();
PaintLayer* paint_layer_child_frame =
child_frame->GetFrame()->GetDocument()->GetLayoutView()->Layer();
cc::Region region_child_frame =
paint_layer_child_frame
->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries()
->GraphicsLayerBacking(&paint_layer_child_frame->GetLayoutObject())
->PlatformLayer()
->TouchEventHandlerRegionForTouchActionForTesting(
TouchAction::kTouchActionNone);
PaintLayer* paint_layer_main_frame = GetWebView()
->MainFrameImpl()
->GetFrame()
->GetDocument()
->GetLayoutView()
->Layer();
cc::Region region_main_frame =
paint_layer_main_frame
->EnclosingLayerForPaintInvalidationCrossingFrameBoundaries()
->GraphicsLayerBacking(&paint_layer_main_frame->GetLayoutObject())
->PlatformLayer()
->TouchEventHandlerRegionForTouchActionForTesting(
TouchAction::kTouchActionNone);
EXPECT_TRUE(region_main_frame.bounds().IsEmpty());
EXPECT_FALSE(region_child_frame.bounds().IsEmpty());
// We only check for the content size for verification as the offset is 0x0
// due to child frame having its own composited layer.
EXPECT_EQ(child_frame->GetFrameView()->ContentsSize(),
IntRect(region_child_frame.bounds()).Size());
}
TEST_P(ScrollingCoordinatorTest, overflowScrolling) { TEST_P(ScrollingCoordinatorTest, overflowScrolling) {
RegisterMockedHttpURLLoad("overflow-scrolling.html"); RegisterMockedHttpURLLoad("overflow-scrolling.html");
NavigateTo(base_url_ + "overflow-scrolling.html"); NavigateTo(base_url_ + "overflow-scrolling.html");
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment