MithrilJS / mithril.js

A JavaScript Framework for Building Brilliant Applications

Home Page:https://mithril.js.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Bidirectional textarea loses keyboard events

fidian opened this issue · comments

Mithril.js version: 2.2.2
Browser and OS: Chrome 102.0.5005.115 on Ubuntu 22.04 jammy

Code

flems.io example

Steps to Reproduce

Go to a textarea and alternate very fast between a letter and the space bar. It helps if you use two hands or two fingers on the same hand.

Expected Behavior

Letters and spaces should show up.

Current Behavior

Sometimes letters are dropped. The events are not firing.

Context

I have a website that I'm porting over from Angular. It's a simple cipher site, where the user can type in whatever text and it gets encoded. On some of the pages I have buttons that will alter what you typed in, converting everything to uppercase or removing spaces, or other manipulations. So, I need a bidirectional textarea that allows the user to type in data. My typing speed is fairly fast, so it is easy for me to trigger it by typing in a sentence, but it does not show up if I repeatedly type in "asdfasdfasdf". Spaces appear to the the trigger for this behavior.

If there's another way to implement a bidirectional textarea, I'm totally open to ideas.

The example shows the following that must be able to work in some fashion.

  1. Allowing initial data to populate the textarea. One textarea uses a placeholder because it has no initial data and the other does have initial data.
  2. Allowing the textarea's value to be sent up to the mounted component so it can be used elsewhere. I put the data into a paragraph right below the textarea.
  3. Allowing the value to be changed from outside the InputArea class. This example has a reset that can be triggered.
commented

I've tested this (using the flems) in Chrome, Firefox, and Edge, but can't repro the issue.

Also finding it very difficult to reproduce - including on latest Ubuntu Chrome.
I think the problem is this though: I set up a little test sandbox to capture a variety of input events on a textarea and, for each, captured both what the event described in its own metadata, using an accumulation of this to produce a representation; and the captured element value at the time the event handler resolved.

Then on each redraw, a snapshot is saved with a rasterisation of that data for each such event, and displayed as a table. The results are informative:

  1. keypress resolves before its inferred effect is persisted to the DOM value (accumulation is always ahead of value)
  2. keyup values accumulate out of sync with un-mediated DOM value persistence (the accumulation has spaces and characters out of order with the value)
  3. input is the only robust capture that represents the latest input

What I infer from this is that whichever keyboard event you use, there's a risk that it captures DOM value before the native 'input sequence' has resolved; this value is persisted to the application data model; Mithril queues a redraw as a result of event handler resolution; by the time the redraw resolves, the native DOM input sequence has resolved, and the DOM value is in its 'correct', up-to-date state; Mithril reads the (now stale) value capture from the point of event resolution, compares it to the current DOM value, and (against our assumption) deems the DOM value to be out-of-date, persisting the stored value.

I think by using oninput you ought to be able to guarantee that the captured vnode.dom.value is always the latest. Can you reproduce the error with that modification @fidian?

That works like a charm. Is there a place in the documentation for tips like this one?

Closing because my issue is resolved.