Electron: input element removed from the DOM consumes ^Z until its undo stack is empty

Created on 3 Dec 2015  路  3Comments  路  Source: electron/electron

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>

All 3 comments

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.

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.

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?

Was this page helpful?
0 / 5 - 0 ratings