Skip to content
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

input element removed from the DOM consumes ^Z until its undo stack is empty #3682

Closed
DanielDignam opened this issue Dec 3, 2015 · 4 comments

Comments

@DanielDignam
Copy link

Minimal repro: https://gist.github.com/DanielDignam/b49084941a2f731501d5

We are using node 4.1.1, Chrome 45.0.2454.85, and Electron 0.35.2, on Windows 10

Run attached app. Notice ^Z reports correctly to the console. Type something into the input box and hit the button to remove the element from the DOM. Hit ^Z notice it doesn't report. Hit ^Z again and notice it does.

If you rerun and paste something into the text box N times you'll notice the number of ^Z's it takes before it is reported is N+1.

The implication is that the input box is still processing events even though it is no longer in the DOM, and doesn't pass the ^Z on until it has emptied its Undo stack.

This breaks undo in our application where application undo actions will not be restored on ^Z if an input field has been used and then removed from the DOM.

We want to undo other state in our application when there is no form/input.

<!DOCTYPE html>
<html>
<head>
    <title>Hello World!</title>
</head>
<body id='body'>
<h1>Hello World!</h1>
We are using node <script>document.write(process.versions.node)</script>,
Chrome <script>document.write(process.versions.chrome)</script>,
and Electron <script>document.write(process.versions.electron)</script>.
<script>
    function removeInput(event) {
        var i = document.getElementById("foo");
        var b = document.getElementById("body");
        b.removeChild(i);
    }
    const remote = require('electron').remote;
    const Menu = remote.Menu;
    const MenuItem = remote.MenuItem;
    var template = [
        {
            label: 'Edit',
            submenu: [
                {
                    label: 'Undo',
                    accelerator: 'CmdOrCtrl+Z',
                    click: function () {
                        console.log('Undo called');
                    },
                    enabled: true
                }
            ]
        }];
    menu = Menu.buildFromTemplate(template);
    Menu.setApplicationMenu(menu);
</script>
<input id='foo' type='text'/>
<input type='button' onclick='removeInput()'/>
</body>
</html>
@zcbenz
Copy link
Member

zcbenz commented Dec 4, 2015

This is a bug of Chromium when handling DOM inputs, I think the solution is to handle the input with DOM events manually instead of relying on Menu's accelerator.

To fix this we have to dig into Chromium's source code, but that is just too much work. Reporting it to Chromium is unlikely to work too because to reproduce it you have to add a custom menu item to Chrome, which is not possible.

I'm closing this as won't fix since probably no one would look into it, and you can work around it by listening to DOM's key events.

@evgenykochetkov
Copy link

evgenykochetkov commented Nov 14, 2018

For people who stumbled upon this issue like me: here is the issue in the Chromium bug tracker, at the time of writing it is still not fixed.

@erikjalevik
Copy link

I am working around this by creating the menu item without an accelerator and listening for the Ctrl+Z key event in the renderer. This works. However, how can I now get the "Ctrl+Z" shortcut to show up next to "Undo" in the menu?

@Arkellys
Copy link

I am working around this by creating the menu item without an accelerator and listening for the Ctrl+Z key event in the renderer. This works. However, how can I now get the "Ctrl+Z" shortcut to show up next to "Undo" in the menu?

You can detect if an event comes from the accelerator with event.triggeredByAccelerator so you can keep the accelerator (so it shows up in the menu item) and cancel the action if the call comes from it.

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

No branches or pull requests

5 participants