8000 fix: Fix `menu.popup()` bugs by felixrieseberg · Pull Request #11385 · electron/electron · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: Fix menu.popup() bugs #11385

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 12, 2017
Merged

fix: Fix menu.popup() bugs #11385

merged 11 commits into from
Dec 12, 2017

Conversation

felixrieseberg
Copy link
Member

This PR does three things:

• Calling menu.popup({}) used to be okay, but broke in the last beta. This fixes that.
• We assigned defaults incorrectly, overriding user input 😱
• Tests!

Closes #11376

@felixrieseberg felixrieseberg requested a review from a team December 8, 2017 22:54
Copy link
Member
@ckerr ckerr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I appreciate the fix and the new tests. 👍

However I'm a little confused about the context of this PR and would like a little more information. See inline comments

@@ -45,6 +45,7 @@ Menu.prototype._init = function () {

Menu.prototype.popup = function (window, x, y, positioningItem) {
let [newX, newY, newPosition, newWindow] = [x, y, positioningItem, window]
let opts

// menu.popup(x, y, positioningItem)
if (!window) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look right to me. We used to check window != null, now we check !window

https://github.com/electron/electron/pull/10888/files

Old conditional:

if (window != null && (typeof window !== 'object' || window.constructor !== BrowserWindow)) {

Current conditional:

if (!window) {
 - // Shift.  + // shift over values
 - positioningItem = y  + if (typeof window !== 'object' || window.constructor !== BrowserWindow) {

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As far as I can tell, the old code here and the new code do the same thing. It's not super easy to read, but if you want a change in this PR, I'm happy to make one!

Copy link
Member
@ckerr ckerr Dec 9, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the better link 😄

I'm referring to where the old test (line 150 on lhs) of if (window != null ... is replaced with (line 50 rhs) if (!window) which is nearly the opposite test. This seems unintentional to me because the logic on the following conditionals are unchanged.

If I'm misreading this, that's fine, just correct me :)

If it's broken, a fix + regression test would be great.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You know what, I think you're right. Let me beef up all the tests here to make sure that this PR fixes all the issues with the method right now.

throw new Error(`Cannot open Menu without a BrowserWindow present`)
}
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is more complicated before, and actually seems more complicated than the code was before #10888 as well.

So I'm trying to understand, is this a regression caused by #10888? If so, I think I'd prefer that we back that out + add your tests + then take another run at a refactor.

Alternately, was this broken before #10888 as well?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was broken before 10888, too. We default to showing in the focused window, but a focused window might not be present. I took the liberty here of going with the first window if we can't find one, but we could easily continue to throw and take this portion out.

The important portion here is really that we don't override newX just because x isn't a number (and so on).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not disagreeing with the choice of taking the first window, was just was trying to understand if this was a 10888 regression because the pre-10888 code and the code here didn't do the same things.

@felixrieseberg
Copy link
Member Author

@ckerr Slightly improved behavior: popup will now return what it'll actually pass off into native-land. Also, we're actually testing that it behaves the way it's supposed to.

@ckerr
Copy link
Member
ckerr commented Dec 11, 2017

The linter is being such a linter today. 🙄

standard: Use JavaScript Standard Style (https://standardjs.com)
/home/builduser/project/lib/browser/api/menu.js:51:14: Unexpected mix of '&&' and '||'.
/home/builduser/project/lib/browser/api/menu.js:51:44: Unexpected mix of '&&' and '||'.

Copy link
Member
@ckerr ckerr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 these expanded tests

if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
if (window && typeof window !== 'object' || window.constructor !== BrowserWindow) {
Copy link
Contributor
@alexeykuzmin alexeykuzmin Dec 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this check be replaced with a simpler if (window && !(window instance of BrowserWindow))? It will also fix a linter error.

UPD see a comment below about if (window && ...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I'm wondering what prompted that typeof window !== 'object' clause in the first place

if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
if (window && typeof window !== 'object' || window.constructor !== BrowserWindow) {
Copy link
Contributor
@alexeykuzmin alexeykuzmin Dec 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (window && ...

I guess it's a mistake.
This check was supposed to test that null of undefined were not explicitly provided as a window, right?
But what if it's a call in this form:

menu.popup(/* x */ 0, /* y */ 0, positioningItem)

0 won't pass this check and the shift won't happen.

Let's change the check to if (window != null && ...

@felixrieseberg
Copy link
Member Auth 6D40 or

Excellent feedback, thanks a ton. Implemented!

}

// menu.popup({})
if (window && window.constructor !== BrowserWindow) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numbers will pass this check too:

42 && 42..constructor !== BrowserWindow  // true!

(window != null) && (window.constructor === Object) should work fine.

if (typeof window !== 'object' || window.constructor !== BrowserWindow) {
[newPosition, newY, newX, newWindow] = [y, x, window, null]
}
if (window != null && !(window instanceof BrowserWindow)) {
Copy link
Member
@ckerr ckerr Dec 11, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is clearer than before.

Reading the code as it is now, this test looks very similar to the one in the next block five lines down, if (window && window.constructor !== BrowserWindow). If these are equivalent, they should be folded together for readability because right now it scans as if there is a subtle, uncommented difference between the two tests.

Nothing personal in throwing this back yet again. This code is already an improvement over what's in master.

UPD: Alexey's comment is more to the heart of the problem

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is actually a subtle difference - the first one checks if it's anything other than a BrowserWindow, the second one if it's specifically an object 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does now but didn't when I made that comment 😈

Thanks for working through all these improvements and adding tests. 💚

@ckerr ckerr merged commit e73fe10 into master Dec 12, 2017
@ckerr ckerr deleted the async-menu branch December 12, 2017 00:02
@alexeykuzmin alexeykuzmin restored the async-menu branch December 12, 2017 10:45
@ckerr
Copy link
Member
ckerr commented Dec 12, 2017

Reverted for now until we get a clean CI pass.

#11415 (comment)

@alexeykuzmin alexeykuzmin deleted the async-menu branch December 12, 2017 20:10
@ckerr ckerr restored the async-menu branch December 19, 2017 15:50
@ckerr ckerr deleted the async-menu branch December 19, 2017 15:53
@ckerr ckerr restored the async-menu branch December 19, 2017 16:03
@felixrieseberg felixrieseberg deleted the async-menu branch January 2, 2018 15:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

menu.popup() doesn't accept the "async" option anymore.
3 participants
0