feat: enable innerWidth and innerHeight for window open (#47038)
feat: enable innerWidth and innerHeight for window open (#46749) * feat: enable innerWidth and innerHeight for window open * update comment for added special innerWidth and innerHeight * update 100 min spec requirement handling * update testing to include getContentSize * update macOS min requirement handling * adjust refactored consts * update const values from nativewindowviews Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Michaela Laurencin <35157522+mlaurencin@users.noreply.github.com>
This commit is contained in:
parent
8b2b155c5d
commit
6a0e31633a
6 changed files with 87 additions and 8 deletions
|
@ -26,7 +26,12 @@ const keysOfTypeNumberCompileTimeCheck: { [K in IntegerBrowserWindowOptionKeys]
|
|||
};
|
||||
// Note `top` / `left` are special cases from the browser which we later convert
|
||||
// to y / x.
|
||||
const keysOfTypeNumber = new Set(['top', 'left', ...Object.keys(keysOfTypeNumberCompileTimeCheck)]);
|
||||
// NOTE(@mlaurencin) `innerWidth` / `innerHeight` are also special cases. The spec
|
||||
// states that `width` and `height` represent the window content size and are equivalent
|
||||
// to `innerWidth` / `innerHeight`. However, our implementation currently incorrectly maps
|
||||
// `width` and `height` to `outerWidth` and `outerHeight`, or the size of the window
|
||||
// with all border and related window chrome.
|
||||
const keysOfTypeNumber = new Set(['top', 'left', 'innerWidth', 'innerHeight', ...Object.keys(keysOfTypeNumberCompileTimeCheck)]);
|
||||
|
||||
/**
|
||||
* Note that we only allow "0" and "1" boolean conversion when the type is known
|
||||
|
|
|
@ -120,8 +120,8 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
|||
ui::NativeTheme::GetInstanceForNativeUi()->AddObserver(this);
|
||||
display::Screen::GetScreen()->AddObserver(this);
|
||||
|
||||
const int width = options.ValueOrDefault(options::kWidth, 800);
|
||||
const int height = options.ValueOrDefault(options::kHeight, 600);
|
||||
int width = options.ValueOrDefault(options::kWidth, 800);
|
||||
int height = options.ValueOrDefault(options::kHeight, 600);
|
||||
|
||||
NSRect main_screen_rect = [[[NSScreen screens] firstObject] frame];
|
||||
gfx::Rect bounds(round((NSWidth(main_screen_rect) - width) / 2),
|
||||
|
@ -283,8 +283,23 @@ NativeWindowMac::NativeWindowMac(const gin_helper::Dictionary& options,
|
|||
}
|
||||
|
||||
// Resize to content bounds.
|
||||
const bool use_content_size =
|
||||
// NOTE(@mlaurencin) Spec requirements can be found here:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/open#width
|
||||
constexpr int kMinSizeReqdBySpec = 100;
|
||||
int inner_width = 0;
|
||||
int inner_height = 0;
|
||||
bool use_content_size =
|
||||
options.ValueOrDefault(options::kUseContentSize, false);
|
||||
options.Get(options::kinnerWidth, &inner_width);
|
||||
options.Get(options::kinnerHeight, &inner_height);
|
||||
if (inner_width || inner_height) {
|
||||
use_content_size = true;
|
||||
if (inner_width)
|
||||
width = std::max(kMinSizeReqdBySpec, inner_width);
|
||||
if (inner_height)
|
||||
height = std::max(kMinSizeReqdBySpec, inner_height);
|
||||
}
|
||||
|
||||
if (!has_frame() || use_content_size)
|
||||
SetContentSize(gfx::Size(width, height));
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
|||
|
||||
const int width = options.ValueOrDefault(options::kWidth, 800);
|
||||
const int height = options.ValueOrDefault(options::kHeight, 600);
|
||||
const gfx::Rect bounds{0, 0, width, height};
|
||||
gfx::Rect bounds{0, 0, width, height};
|
||||
widget_size_ = bounds.size();
|
||||
|
||||
widget()->AddObserver(this);
|
||||
|
@ -406,10 +406,25 @@ NativeWindowViews::NativeWindowViews(const gin_helper::Dictionary& options,
|
|||
// Default content view.
|
||||
SetContentView(new views::View());
|
||||
|
||||
options.Get(options::kUseContentSize, &use_content_size_);
|
||||
|
||||
// NOTE(@mlaurencin) Spec requirements can be found here:
|
||||
// https://developer.mozilla.org/en-US/docs/Web/API/Window/open#width
|
||||
int kMinSizeReqdBySpec = 100;
|
||||
int inner_width = 0;
|
||||
int inner_height = 0;
|
||||
options.Get(options::kinnerWidth, &inner_width);
|
||||
options.Get(options::kinnerHeight, &inner_height);
|
||||
if (inner_width || inner_height) {
|
||||
use_content_size_ = true;
|
||||
if (inner_width)
|
||||
bounds.set_width(std::max(kMinSizeReqdBySpec, inner_width));
|
||||
if (inner_height)
|
||||
bounds.set_height(std::max(kMinSizeReqdBySpec, inner_height));
|
||||
}
|
||||
|
||||
gfx::Size size = bounds.size();
|
||||
if (has_frame() &&
|
||||
options.Get(options::kUseContentSize, &use_content_size_) &&
|
||||
use_content_size_)
|
||||
if (has_frame() && use_content_size_)
|
||||
size = ContentBoundsToWindowBounds(gfx::Rect(size)).size();
|
||||
|
||||
widget()->CenterWindow(size);
|
||||
|
|
|
@ -26,6 +26,8 @@ inline constexpr std::string_view kMinWidth = "minWidth";
|
|||
inline constexpr std::string_view kMinHeight = "minHeight";
|
||||
inline constexpr std::string_view kMaxWidth = "maxWidth";
|
||||
inline constexpr std::string_view kMaxHeight = "maxHeight";
|
||||
inline constexpr std::string_view kinnerWidth = "innerWidth";
|
||||
inline constexpr std::string_view kinnerHeight = "innerHeight";
|
||||
inline constexpr std::string_view kResizable = "resizable";
|
||||
inline constexpr std::string_view kMovable = "movable";
|
||||
inline constexpr std::string_view kMinimizable = "minimizable";
|
||||
|
|
|
@ -1459,6 +1459,41 @@ describe('chromium features', () => {
|
|||
expect(eventData).to.equal('size: 350 450');
|
||||
});
|
||||
|
||||
it('window opened with innerWidth option has the same innerWidth', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
|
||||
const windowUrl = `file://${fixturesPath}/pages/window-open-size-inner.html`;
|
||||
const windowCreatedPromise = once(app, 'browser-window-created') as Promise<[any, BrowserWindow]>;
|
||||
const eventDataPromise = w.webContents.executeJavaScript(`(async () => {
|
||||
const message = new Promise(resolve => window.addEventListener('message', resolve, { once: true }));
|
||||
b = window.open(${JSON.stringify(windowUrl)}, '', 'show=no,innerWidth=400,height=450');
|
||||
const e = await message;
|
||||
b.close();
|
||||
return e.data;
|
||||
})()`);
|
||||
const [[, newWindow], eventData] = await Promise.all([windowCreatedPromise, eventDataPromise]);
|
||||
|
||||
expect(newWindow.getContentSize().toString()).to.equal('400,450');
|
||||
expect(eventData).to.equal('size: 400 450');
|
||||
});
|
||||
it('window opened with innerHeight option has the same innerHeight', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.loadFile(path.resolve(__dirname, 'fixtures', 'blank.html'));
|
||||
const windowUrl = `file://${fixturesPath}/pages/window-open-size-inner.html`;
|
||||
const windowCreatedPromise = once(app, 'browser-window-created') as Promise<[any, BrowserWindow]>;
|
||||
const eventDataPromise = w.webContents.executeJavaScript(`(async () => {
|
||||
const message = new Promise(resolve => window.addEventListener('message', resolve, {once: true}));
|
||||
const b = window.open(${JSON.stringify(windowUrl)}, '', 'show=no,width=350,innerHeight=400')
|
||||
const e = await message;
|
||||
b.close();
|
||||
return e.data;
|
||||
})()`);
|
||||
const [[, newWindow], eventData] = await Promise.all([windowCreatedPromise, eventDataPromise]);
|
||||
|
||||
expect(newWindow.getContentSize().toString()).to.equal('350,400');
|
||||
expect(eventData).to.equal('size: 350 400');
|
||||
});
|
||||
|
||||
it('loads preload script after setting opener to null', async () => {
|
||||
const w = new BrowserWindow({ show: false });
|
||||
w.webContents.setWindowOpenHandler(() => ({
|
||||
|
|
7
spec/fixtures/pages/window-open-size-inner.html
vendored
Normal file
7
spec/fixtures/pages/window-open-size-inner.html
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
<html>
|
||||
<body>
|
||||
<script type="text/javascript" charset="utf-8">
|
||||
window.opener.postMessage('size: ' + innerWidth + ' ' + innerHeight, '*')
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Add a link
Reference in a new issue