Commit 73857c20 authored by Mike Wasserman's avatar Mike Wasserman Committed by Commit Bot

Window Placement: Check opener's state for window.open

Check the appropriate frame's runtime-enabled feature state.
Pass the |requesting_frame| into SetWindowRectWithAdjustment.
(use window.open's opener, same frame for window.moveTo, etc.)

Fixes cross-screen open for sites with OT tokens & permissions.
(the newly opened window's OT tokens have not yet loaded)
(we generally care about the opener's tokens, not the popup's)

Bug: 1124480
Test: michaelwasserman.github.io/window-placement-demo WAI
Change-Id: I32e88dd252d1b8d04d12363952b643341e47710a
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2391731Reviewed-by: default avatarDaniel Cheng <dcheng@chromium.org>
Commit-Queue: Michael Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/master@{#804018}
parent a034258e
......@@ -1589,7 +1589,8 @@ void LocalDOMWindow::moveBy(int x, int y) const {
window_rect.SaturatedMove(x, y);
// Security check (the spec talks about UniversalBrowserWrite to disable this
// check...)
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame);
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame,
*frame);
}
void LocalDOMWindow::moveTo(int x, int y) const {
......@@ -1605,7 +1606,8 @@ void LocalDOMWindow::moveTo(int x, int y) const {
window_rect.SetLocation(IntPoint(x, y));
// Security check (the spec talks about UniversalBrowserWrite to disable this
// check...)
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame);
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, *frame,
*frame);
}
void LocalDOMWindow::resizeBy(int x, int y) const {
......@@ -1620,7 +1622,7 @@ void LocalDOMWindow::resizeBy(int x, int y) const {
IntRect fr = page->GetChromeClient().RootWindowRect(*frame);
IntSize dest = fr.Size() + IntSize(x, y);
IntRect update(fr.Location(), dest);
page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame);
page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame, *frame);
}
void LocalDOMWindow::resizeTo(int width, int height) const {
......@@ -1635,7 +1637,7 @@ void LocalDOMWindow::resizeTo(int width, int height) const {
IntRect fr = page->GetChromeClient().RootWindowRect(*frame);
IntSize dest = IntSize(width, height);
IntRect update(fr.Location(), dest);
page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame);
page->GetChromeClient().SetWindowRectWithAdjustment(update, *frame, *frame);
}
int LocalDOMWindow::requestAnimationFrame(V8FrameRequestCallback* callback) {
......
......@@ -53,7 +53,8 @@ void ChromeClient::InstallSupplements(LocalFrame& frame) {
}
void ChromeClient::SetWindowRectWithAdjustment(const IntRect& pending_rect,
LocalFrame& frame) {
LocalFrame& frame,
LocalFrame& requesting_frame) {
IntRect screen(GetScreenInfo(frame).available_rect);
IntRect window = pending_rect;
......@@ -67,8 +68,10 @@ void ChromeClient::SetWindowRectWithAdjustment(const IntRect& pending_rect,
// on another screen, and so it should not be limited by the current screen.
// This relies on the embedder clamping bounds to the target screen for now.
// TODO(http://crbug.com/897300): Implement multi-screen clamping in Blink.
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(frame.DomWindow()))
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(
requesting_frame.DomWindow())) {
width = std::min(width, screen.Width());
}
window.SetWidth(width);
size_for_constraining_move.SetWidth(window.Width());
}
......@@ -78,8 +81,10 @@ void ChromeClient::SetWindowRectWithAdjustment(const IntRect& pending_rect,
// on another screen, and so it should not be limited by the current screen.
// This relies on the embedder clamping bounds to the target screen for now.
// TODO(http://crbug.com/897300): Implement multi-screen clamping in Blink.
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(frame.DomWindow()))
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(
requesting_frame.DomWindow())) {
height = std::min(height, screen.Height());
}
window.SetHeight(height);
size_for_constraining_move.SetHeight(window.Height());
}
......@@ -88,7 +93,8 @@ void ChromeClient::SetWindowRectWithAdjustment(const IntRect& pending_rect,
// on another screen, and so it should not be limited by the current screen.
// This relies on the embedder clamping bounds to the target screen for now.
// TODO(http://crbug.com/897300): Implement multi-screen clamping in Blink.
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(frame.DomWindow())) {
if (!RuntimeEnabledFeatures::WindowPlacementEnabled(
requesting_frame.DomWindow())) {
// Constrain the window position within the valid screen area.
window.SetX(
std::max(screen.X(),
......
......@@ -148,9 +148,15 @@ class CORE_EXPORT ChromeClient : public GarbageCollected<ChromeClient> {
virtual void ScheduleAnimation(const LocalFrameView*,
base::TimeDelta = base::TimeDelta()) = 0;
// The specified rectangle is adjusted for the minimum window size and the
// screen, then setWindowRect with the adjusted rectangle is called.
void SetWindowRectWithAdjustment(const IntRect&, LocalFrame&);
// Adjusts |pending_rect| for the minimum window size and |frame|'s screen,
// then calls SetWindowRect on |frame| with the adjusted rectangle.
// Cross-screen window placements are passed on without same-screen clamping
// if the |requesting_frame| (i.e. the opener or |frame| itself) has
// experimental window placement features enabled. The browser will check
// permissions before actually supporting cross-screen placement requests.
void SetWindowRectWithAdjustment(const IntRect& pending_rect,
LocalFrame& frame,
LocalFrame& requesting_frame);
// This gives the rect of the top level window that the given LocalFrame is a
// part of.
......
......@@ -352,7 +352,8 @@ Frame* CreateNewWindow(LocalFrame& opener_frame,
if (features.height_set)
window_rect.SetHeight(features.height);
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, frame);
page->GetChromeClient().SetWindowRectWithAdjustment(window_rect, frame,
opener_frame);
page->GetChromeClient().Show(request.GetNavigationPolicy());
MaybeLogWindowOpen(opener_frame);
......
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