keyboards icon indicating copy to clipboard operation
keyboards copied to clipboard

bug(chinese): Race condition when using CJK keyboards and typing quickly

Open mcdurdin opened this issue 6 years ago • 2 comments

This is for the chinese keyboard in KeymanWeb.

A race condition -- if you type a number before the suggestions have finished loading, the wrong suggestion is applied. For example, type xue1 quickly. (after caching this behaviour may not be visible, so do this on a clean uncached load).

Originally posted by @mcdurdin in https://github.com/keymanapp/keyman/issues/1754#issuecomment-488880576

mcdurdin avatar Sep 20 '19 21:09 mcdurdin

Oh... oh wow. Found the code that keyboard_chinese uses to process picker input.

When a numerical key (corresponding to a picker suggestion) is pressed, the following (minified) function is called.

  this.aA = function (J, ao, aG) {
    var e = document.createElement('script');
    if (window.event) e.text = 'Keyboard_chinese_obj.executeEvent(' + this.aD + ');';
     else e.innerHTML = 'Keyboard_chinese_obj.executeEvent(' + this.aD + ');';
    this.au[this.aD] = function () {
      Keyboard_chinese_obj.ah(Keyboard_chinese_obj.aC[J], ao, aG);
      document.getElementsByTagName('head') [0].removeChild(e);
    };
    this.aD++;
    e.type = 'text/javascript';
    document.getElementsByTagName('head') [0].appendChild(e);
  }

The picker's suggestion is applied by this.au[this.ad]'s function through the final line with appendChild - through a <script> element inserted into the document by the keyboard. It looks like this is done to ensure an instant call once the current JS event is done processing. That was a bit "fun" to analyze.

So, if this event beats out the event that replaces the picker suggestions, yeah, race event - but it's the keyboard code's fault, not KMW's. There's an ID (this.aD) tracked to ensure the correct event in the sequence is called, but it doesn't look like any effort is made to ensure the suggestion list isn't being updated first.

jahorton avatar Sep 23 '19 03:09 jahorton

It's worth remembering that the CJK keyboards were written before CORS existed. Which meant all kinds of funky code. Even script.onload wasn't consistently supported. IE6 era. Kinda amazing it ever worked at all ;-)

mcdurdin avatar Sep 23 '19 03:09 mcdurdin