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

8000 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
41 changes: 30 additions & 11 deletions lib/browser/api/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,30 +45,49 @@ 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) {
// shift over values
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. 💚

[newPosition, newY, newX, newWindow] = [y, x, window, null]
}

// menu.popup({})
if (window != null && window.constructor === Object) {
opts = window
// menu.popup(window, {})
if (x && typeof x === 'object') {
const opts = x
} else if (x && typeof x === 'object') {
opts = x
}

if (opts) {
newX = opts.x
newY = opts.y
newPosition = opts.positioningItem
}

// set defaults
if (typeof x !== 'number') newX = -1
if (typeof y !== 'number') newY = -1
if (typeof positioningItem !== 'number') newPosition = -1
if (!window) newWindow = BrowserWindow.getFocusedWindow()
if (typeof newX !== 'number') newX = -1
if (typeof newY !== 'number') newY = -1
if (typeof newPosition !== 'number') newPosition = -1
if (!newWindow || (newWindow && newWindow.constructor !== BrowserWindow)) {
newWindow = BrowserWindow.getFocusedWindow()

// No window focused?
if (!newWindow) {
const browserWindows = BrowserWindow.getAllWindows()

if (browserWindows && browserWindows.length > 0) {
newWindow = browserWindows[0]
} else {
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.


this.popupAt(newWindow, newX, newY, newPosition)

return { browserWindow: newWindow, x: newX, y: newY, position: newPosition }
}

Menu.prototype.closePopup = function (window) {
Expand Down
47 changes: 46 additions & 1 deletion spec/api-menu-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,52 @@ describe('Menu module', () => {
})

it('returns immediately', () => {
menu.popup(w, {x: 100, y: 100, async: true})
const { browserWindow, x, y } = menu.popup(w, {x: 100, y: 101})

assert.equal(browserWindow, w)
assert.equal(x, 100)
assert.equal(y, 101)

menu.closePopup(w)
})

it('works without a given BrowserWindow and options', () => {
const { browserWindow, x, y } = menu.popup({x: 100, y: 101})

assert.equal(browserWindow.constructor.name, 'BrowserWindow')
assert.equal(x, 100)
assert.equal(y, 101)

menu.closePopup()
})

it('works without a given BrowserWindow', () => {
const { browserWindow, x, y } = menu.popup(100, 101)

assert.equal(browserWindow.constructor.name, 'BrowserWindow')
assert.equal(x, 100)
assert.equal(y, 101)

menu.closePopup()
})

it('works without a given BrowserWindow and 0 options', () => {
const { browserWindow, x, y } = menu.popup(0, 1)

assert.equal(browserWindow.constructor.name, 'BrowserWindow')
assert.equal(x, 0)
assert.equal(y, 1)

menu.closePopup()
})

it('works with a given BrowserWindow and no options', () => {
const { browserWindow, x, y } = menu.popup(w, 100, 101)

assert.equal(browserWindow, w)
assert.equal(x, 100)
assert.equal(y, 101)

menu.closePopup(w)
})
})
Expand Down
0