Commit c710b59f authored by David Bokan's avatar David Bokan Committed by Commit Bot

Make visualViewport always use frame's layout viewport

VisualViewport:pageLeft and pageTop returns the visual viewport's
offset from the document origin. This means it's a combination of the
layout viewport's offset and the visualViewport's offset within the
layout viewport.

Currently, this uses the effective root scroller as the layout viewport.
However, this can be used to leak information through a cross origin
iframe and will break down for OOPIFs. The sensible thing to do here is
to redefine these values to always use the original layout viewport.

Bug: 505516
Change-Id: I616d497cc6f1ebe003ff48701da3d6691dc38326
Reviewed-on: https://chromium-review.googlesource.com/806479Reviewed-by: default avatarDave Tapuska <dtapuska@chromium.org>
Commit-Queue: David Bokan <bokan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#524072}
parent 55c663b1
...@@ -82,12 +82,18 @@ float DOMVisualViewport::pageLeft() const { ...@@ -82,12 +82,18 @@ float DOMVisualViewport::pageLeft() const {
if (!frame) if (!frame)
return 0; return 0;
Page* page = frame->GetPage();
if (!page)
return 0;
LocalFrameView* view = frame->View(); LocalFrameView* view = frame->View();
if (!view) if (!view || !view->LayoutViewportScrollableArea())
return 0; return 0;
frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
float viewport_x = view->GetScrollableArea()->GetScrollOffset().Width(); float viewport_x =
page->GetVisualViewport().GetScrollOffset().Width() +
view->LayoutViewportScrollableArea()->GetScrollOffset().Width();
return AdjustForAbsoluteZoom::AdjustScroll(viewport_x, return AdjustForAbsoluteZoom::AdjustScroll(viewport_x,
frame->PageZoomFactor()); frame->PageZoomFactor());
} }
...@@ -97,12 +103,18 @@ float DOMVisualViewport::pageTop() const { ...@@ -97,12 +103,18 @@ float DOMVisualViewport::pageTop() const {
if (!frame) if (!frame)
return 0; return 0;
Page* page = frame->GetPage();
if (!page)
return 0;
LocalFrameView* view = frame->View(); LocalFrameView* view = frame->View();
if (!view) if (!view || !view->LayoutViewportScrollableArea())
return 0; return 0;
frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets(); frame->GetDocument()->UpdateStyleAndLayoutIgnorePendingStylesheets();
float viewport_y = view->GetScrollableArea()->GetScrollOffset().Height(); float viewport_y =
page->GetVisualViewport().GetScrollOffset().Height() +
view->LayoutViewportScrollableArea()->GetScrollOffset().Height();
return AdjustForAbsoluteZoom::AdjustScroll(viewport_y, return AdjustForAbsoluteZoom::AdjustScroll(viewport_y,
frame->PageZoomFactor()); frame->PageZoomFactor());
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "bindings/core/v8/node_or_string.h" #include "bindings/core/v8/node_or_string.h"
#include "core/exported/WebRemoteFrameImpl.h" #include "core/exported/WebRemoteFrameImpl.h"
#include "core/frame/BrowserControls.h" #include "core/frame/BrowserControls.h"
#include "core/frame/DOMVisualViewport.h"
#include "core/frame/FrameTestHelpers.h" #include "core/frame/FrameTestHelpers.h"
#include "core/frame/LocalFrameView.h" #include "core/frame/LocalFrameView.h"
#include "core/frame/RootFrameViewport.h" #include "core/frame/RootFrameViewport.h"
...@@ -21,6 +22,9 @@ ...@@ -21,6 +22,9 @@
#include "core/paint/PaintLayerScrollableArea.h" #include "core/paint/PaintLayerScrollableArea.h"
#include "core/paint/compositing/CompositedLayerMapping.h" #include "core/paint/compositing/CompositedLayerMapping.h"
#include "core/paint/compositing/PaintLayerCompositor.h" #include "core/paint/compositing/PaintLayerCompositor.h"
#include "core/testing/sim/SimDisplayItemList.h"
#include "core/testing/sim/SimRequest.h"
#include "core/testing/sim/SimTest.h"
#include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h" #include "platform/testing/RuntimeEnabledFeaturesTestHelpers.h"
#include "platform/testing/URLTestHelpers.h" #include "platform/testing/URLTestHelpers.h"
#include "platform/testing/UnitTestHelpers.h" #include "platform/testing/UnitTestHelpers.h"
...@@ -1171,6 +1175,74 @@ TEST_P(RootScrollerTest, ImmediateUpdateOfLayoutViewport) { ...@@ -1171,6 +1175,74 @@ TEST_P(RootScrollerTest, ImmediateUpdateOfLayoutViewport) {
&MainFrameView()->GetRootFrameViewport()->LayoutViewport()); &MainFrameView()->GetRootFrameViewport()->LayoutViewport());
} }
class RootScrollerSimTest : public ::testing::WithParamInterface<bool>,
private ScopedRootLayerScrollingForTest,
public SimTest {
public:
RootScrollerSimTest() : ScopedRootLayerScrollingForTest(GetParam()) {}
};
INSTANTIATE_TEST_CASE_P(All, RootScrollerSimTest, ::testing::Bool());
// Tests that the root scroller doesn't affect visualViewport pageLeft and
// pageTop.
TEST_P(RootScrollerSimTest, RootScrollerDoesntAffectVisualViewport) {
WebView().Resize(WebSize(800, 600));
SimRequest request("https://example.com/test.html", "text/html");
LoadURL("https://example.com/test.html");
request.Start();
request.Write(R"HTML(
<!DOCTYPE html>
<style>
body, html {
width: 100%;
height: 100%;
margin: 0px;
}
#spacer {
width: 1000px;
height: 1000px;
}
#container {
width: 100%;
height: 100%;
overflow: auto;
}
</style>
<div id="container">
<div id="spacer"></div>
</div>
)HTML");
GetDocument().GetPage()->GetVisualViewport().SetScale(2);
GetDocument().GetPage()->GetVisualViewport().SetLocation(
FloatPoint(100, 120));
LocalFrame* frame = ToLocalFrame(GetDocument().GetPage()->MainFrame());
EXPECT_EQ(100, frame->DomWindow()->visualViewport()->pageLeft());
EXPECT_EQ(120, frame->DomWindow()->visualViewport()->pageTop());
request.Finish();
Compositor().BeginFrame();
Element* container = GetDocument().getElementById("container");
GetDocument().setRootScroller(container);
Compositor().BeginFrame();
ASSERT_EQ(container,
GetDocument().GetRootScrollerController().EffectiveRootScroller());
container->setScrollTop(50);
container->setScrollLeft(60);
ASSERT_EQ(50, container->scrollTop());
ASSERT_EQ(60, container->scrollLeft());
ASSERT_EQ(100, frame->DomWindow()->visualViewport()->pageLeft());
EXPECT_EQ(120, frame->DomWindow()->visualViewport()->pageTop());
}
class RootScrollerHitTest : public RootScrollerTest { class RootScrollerHitTest : public RootScrollerTest {
public: public:
void CheckHitTestAtBottomOfScreen() { void CheckHitTestAtBottomOfScreen() {
......
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