Steps to Reproduce:
oninput event.Environment: Mithril 1.0.1 on Chrome 56.0.2924.87 (Windows 10).
Previous Related Issue: #358
Sample Code:
module.exports =
{ oninit:
vn => {
const id = Number( vn.attrs.id )
const stream = M.loadItem( id )
vn.state.data = { id, stream, initial: stream() }
}
, view: vn =>
<div>
<label class="label">
Last Name
<input
class="input"
type="text"
placeholder="Last Name"
onchange={ X.setStreamPropToValueAttr( vn.state.data.stream )( 'lastName' ) }
value={ X.getStreamProp( vn.state.data.stream )( 'lastName' ) }
/>
</label>
</div>
}
@kurtmilam Just to be sure, does this happen when you navigate to another page, or on routed components, and you navigate back to a previous route?
Also, @kurtmilam, could you verify it also repros with v1.1.0 (the latest release)?
@pygy This occurs on routed components when I navigate to a previous route using the browser's back or forward buttons. I believe it's due to the fact that the action that triggers the input's onupdate event also causes the input to be removed from the DOM.
@isiahmeadows I have just verified that the described behavior still occurs with mithril v1.1.0 .
@kurtmilam One last thing: could you edit your repro down to something that doesn't require external functions?
@isiahmeadows I've just confirmed that the behavior persists when the component in question is stripped to bare bones:
import m from 'mithril'
module.exports =
{ view: vn =>
<input onchange={ console.log } />
}
It persists when I swap out the JSX syntax for javascript:
import m from 'mithril'
module.exports =
{ view: vn =>
m( 'input', { onchange: console.log } )
}
It persists when I switch to ES5 syntax, getting rid of the arrow function:
import m from 'mithril'
module.exports =
{ view: function () {
return m( 'input', { onchange: console.log } )
}
}
@kurtmilam JSX is okay. I just needed a minimal workable repro.
How are you redrawing the component?
@isiahmeadows I wanted to eliminate all possible variables 馃槣
The component is drawn on a specific route. The 'app' is just an experiment based on an extended version of the simple application (from the mithril docs). The behavior occurs when I change an input on my '/edit/:id' route, then navigate back to the '/list' route while focus is still in the input.
I'm seeing probably the same error with Mithril v1.1.6:
mithril.v1.1.6.js:817 Uncaught DOMException: Failed to execute 'removeChild' on 'Node': The node to be removed is no longer a child of this node. Perhaps it was moved in a 'blur' event handler?
at removeNodeFromDOM (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:817:30)
at continuation (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:806:6)
at removeNode (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:794:3)
at updateNode (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:635:4)
at updateNodes (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:556:6)
at updateElement (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:687:4)
at updateNode (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:629:15)
at updateNodes (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:537:12)
at updateElement (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:687:4)
at updateNode (http://localhost:8334/pointrel20171122/bootstrap/mithril.v1.1.6.js:629:15)
I don't have it isolated to a simple case. In my situation, it seems to happen in a drawing app I am writing when I click onto some SVG objects and the app removes some input fields being displayed associated with a different SVG object. The consequence is it leaves the old input fields displayed alongside new ones.
This might be the root cause and some possible solutions:
https://stackoverflow.com/questions/21926083/failed-to-execute-removechild-on-node#22934552
Edit: I am seeing this in Chromium 63. I have not tested this with Firefox.
Great...so something we need to work around internally (i.e. don't actually call the callback if we're currently removing the node)? 馃槮
Edit: Thanks for the link! It's very informative. (That's a super odd DOM edge case, though.)
So finally, a fix incoming in #2286.
We need a working self-contained repro that reproduces it at least some of the time. Could one of you all experiencing it put together a Flems? It doesn't have to be minimal, just self-contained.
I'd be happy to work up a repro, but I'm not sure it'll work in flems or code sandbox (just tried in both), since I only saw the error when I used the browser's forward or back button to navigate to a different route in my mithril application while my input still had focus.
@kurtmilam If you have to, drop a debugger statement in the view of an offending component and try stepping through it. That might help you in isolating a repro case.
Alternatively, you could do input.focus() + location.hash = ....
@kurtmilam you can post it as a gist then?
Filename: index.html, load Mithril through https://unpkg.com/[email protected], then we can load it with bl.ocks.org which is just a gist viewer.
@kurtmilam Do note that iframes do still work with hash navigation and history navigation.
@kurtmilam Found anything reproducible yet? At this point, we're not even looking for anything minimal, just self-contained (even if it means slapping together a full repo we have to clone).
PSA: I don't care if it's a website at this point - as long as you can point me to where the functionality breaks, I'm willing to reverse engineer minified JS and place strategic breakpoints if I have to to isolate this bug.
I was able to reproduce this on Chrome 53 (probably the version I was using when I initially reported this issue), but have not been able to reproduce it on Chrome 70 or the latest versions of Firefox or Safari.
I reproduced it using this flems experiment.
Steps to reproduce:
/user/{id} route./list route.et voila!
Screen shot (a little messy because I was running a virtual copy of Chrome 53 on turbo.net):

Apologies that it's taken so long to help track this down.
@kurtmilam Yeah, that reads like a browser bug we can't really work around, especially if setting the hash directly doesn't trigger identical behavior. Given it takes a seriously old Chrome version for it to repro, I'm not sure we can fix it. BTW, we only support the last 2 versions of Chrome, so you need to create a repro that works on one of those.
Closing for now. If anyone can reproduce this bug again, please file a new issue.