Quill: Japanese Hiragana Windows IME ignores first letter in editor

Created on 10 May 2017  ·  34Comments  ·  Source: quilljs/quill

Typing with the IME enabled in windows 8/IE 11 the very first character seems to be ignored by the IME

  1. Enable Japanese Hiragana IME
  2. Visit quilljs.com/playground
  3. type "tesuto" + enter

Expected behavior:
result: てすと
Actual behavior:
result: t えすと

screen shot 2017-05-09 at 10 08 10 pm

Everything is fine after that

Platforms:
Windows 8.1/ IE 11

Version:

1.2.4

bug ie11

Most helpful comment

I believe I have reproduced the root cause in this pen: https://codepen.io/saw-1473371988/pen/Wjzmay

Basically the IME seems to think the first character is _after_ the insertion point, but the insertion point is corrected after the text node is appended to the block node (I think this happens in selection.js:setNativeRange()). So this is progress! Now to figure out how to fix this,

All 34 comments

Update: removing ql-blank from the editor fixes the problem, so it must be caused by the :before content

Same as #1437

Misread the actual behavior, while not exactly the same, using a Japanese IME on osx produces similar result.

Expected behavior:
result: てすと
Actual behavior:
result: tてすと

I suspect the text node value on the first keypress is added to the line and current index of the line is moved by 1, which is why on Japanese IME pressing te results in the first t is outputted, and when composition ends, the composed value is added next/right to t.

This happens on the dom mutation event callback observed by Parchment.Scroll (and extended by blots/scroll.js), where it creates a text blot & text node on the first keypress on a new line. Adding the subsequent keypresses properly appends, because probably Scroll/Container found a parent node to append to instead of creating a new text node.

But I still cannot find the exact code that consumes the first keypress and move current index forward 😿

@azam removing the :before rule absolutely fixes this issue, but I have no idea why. Trying to re-create this in a code pen without quill I couldn't create the same bug: http://codepen.io/saw-1473371988/pen/EmQMNq

I tried deleting these lines, just to see if the ql-blank class change is making any difference, but it didn't, so I don't see how removing it will resolve the issue:

https://github.com/quilljs/quill/blob/master/core/quill.js#L73
https://github.com/quilljs/quill/blob/master/core/quill.js#L90
https://github.com/quilljs/quill/blob/master/assets/core.styl#L170-L175

I am testing it out using the local server (http://localhost:9000/standalone/snow/) on macOS Sierra, Chrome 58, Japanese IME (both default Apple & Google Japanese IME) if it helps.

Reason of me suspecting the mutation observer callback is because when I comment out the following line, the first key stopped finalizing as a text node, so I am guessing that the problem lies after this line, or any events emitted after this.

https://github.com/quilljs/parchment/blob/master/src/blot/scroll.ts#L134

Continuing to debug the issue ...

(After some time trying to make the local dev server available to my IE VM) I tried dropping ql-blank, and as you said, it solves the problem, but only on IE. The problem persists on Chrome 58 even on Windows.

@azam ok I can repro on mac now, and it's intermittent. Tab A: no bug, Tab B (incognito): bug

I've tracked this down to insertBefore() in container.ts. I'm not entirely sure _why_ it happens, but the first character entered in a descendant of container.ts results in that insertBefore method being called.

The problem is caused by inserting the textNode of the first text blot before the block:

parentBlot.domNode.insertBefore(this.domNode, (typeof refDomNode !== 'undefined') ? refDomNode : null);

How to fix it is a mystery at this point, especially considering it doesn't always happen.

I believe this may in fact be the same bug as reported in #1437 . That was closed when users disabled the evernote plugin, however discovered that the bug always happens for me in an incognito window in chrome. Also the bug happens if I disable 1password. Enable it: fixes the bug.

Update: 1password extension fixes the bug in safari & chrome. Nothing makes any sense anymore. Up is down.

I believe I have reproduced the root cause in this pen: https://codepen.io/saw-1473371988/pen/Wjzmay

Basically the IME seems to think the first character is _after_ the insertion point, but the insertion point is corrected after the text node is appended to the block node (I think this happens in selection.js:setNativeRange()). So this is progress! Now to figure out how to fix this,

Here is what I think is happening:

When you type the first character in the editor quill creates a <p> to contain it then appends the text node you created to that node this puts the cursor before the character you just typed. Then quill uses the Selection and Range apis to move the cursor after the character. This creates a race condition because the js code is synchronous. The OS starts launching the IME thing (for Japanese typing) as soon as the first character is entered. If the cursor has been moved by the time the IME is getting characters you’re fine. If it hasn’t you aren’t, the IME thinks you are typing in front of where you think you're typing.

Problem cannot be reproduced on develop. Suspecting 01e567e10ce0eac8f1a63fa6f5bc666ad24dcf8a fixed the problem.

@azam I can reproduce in develop, try it in an incognito window.

When I installed this add-on, IME works correctly.
After deleting the add-on, this problem is reproduced again.

https://chrome.google.com/webstore/detail/evernote-web-clipper/pioclpoplcdbaefihamjohnefbikjilc/related?hl=ja

environment:
macOS Sierra 10.12.3 Beta(16D25a)
Google Chrome 58.0.3029.110 (64-bit)
Google Japanese Input (2.20.2700.1)
quill version 1.2.4

I'm exploring solutions to this. The basic issue is we can't append the textNode to it's parent while the IME is open. I've "fixed" the problem by stopping update() in scroll.js while the IME is open and then applying them after, but I'm having issue right now with the model becoming out of sync with the contents of the editor when I do that. Another solution is to attach a text_node to each new block rather than a <br> but his is a huge architectural change

here is one possibly crazy option, change the default child of block from break to text, then modify text so it has a non-empty string (maybe zero-width space, U+200B) as it's default child, then in optimize remove the stray character in the beginning of the text blot. This does work, but it's a huge change because the empty state of the enter would no longer be <p><br></p>

The above change fixes the bug, but is a significant change and probable wrong. @jhchen do you have a suggestion for solving this that wouldn't be as sweeping and destructive?

Here is an override that fixes the issue completely, but you will need to scrub the '\u200B' from your output

I changed ZWS to NUL on as shown on this branch: azam/quill@c7cc4ca199e6bdf9281c93a4907f581063576851 .

I agree that it is a quick workaround. If you want to go this way, there is a lot more to do. I think you might also want to override other inherited methods (length, value, etc) to absorb the change rather than let the user scrub the text themselves.

For example, one of the effects of not overriding these methods is, try writing something and then deleting all text, Editor#isBlank do not evaluate to true, so the place holder will not be shown afterwards.

Creating some sort of a new type of blank blot probably makes more sense.

For our internal use I think I have some overrides that work (I'll add you to the pull request @azam ) but I'm not sure the ideal solution for the library

I can confirm Windows + IE11/Edge is confirmed to not be working. Chrome/Safari should be working as of https://github.com/quilljs/quill/commit/0e7a10c6ad865fa9075636787b1dac09d767bf06

Do someone track this bug?@jhchen ,I have try your method on Chrome/Safari,but it doesn't work.

Interesting find: change the ql-blank to use :after rather than :before, so toggling the class does not trigger the contents to reflow, thus making the IME happy.

But there's a catch, you need to manually position the :after pseudo element with top equal to the inner padding of the editor, about 12px for snow theme. I think this is acceptable 🤔

Update: The Chinese IME still doesn't work after this change, it seems the IMEs are extremely fragile and any updates to the containers can be devastating during compositions.

Update's Update: It turns out that the Chinese IME's bug is not relevant to this issue, the proposed fix should work.

The original steps for reproduction is now working on the latest version of Quill 1.2.6 on the latest IE 11.483.15063.0 and MS Edge 40.15063.0.0. @saw can you try with the latest and see if you are still having issues?

I will as soon as I get back from vacation later this month
On Mon, Jul 17, 2017 at 07:04 Jason Chen notifications@github.com wrote:

The original steps for reproduction is now working on the latest version
of Quill 1.2.6 on the latest IE 11.483.15063.0 and MS Edge 40.15063.0.0.
@saw https://github.com/saw can you try with the latest and see if you
are still having issues?


You are receiving this because you were mentioned.

Reply to this email directly, view it on GitHub
https://github.com/quilljs/quill/issues/1453#issuecomment-315668817, or mute
the thread
https://github.com/notifications/unsubscribe-auth/AABT5xULuhldYpmC0ji2pSzLNajh9cOdks5sOutigaJpZM4NWLyE
.

@jhchen it does _not_ seem to be happening anymore. Do you happen to know what changed to fix this? I'm really curious how you did it.

I can't recall exactly. Try git bisect?

worked before, but recently reappeared.

I also again appeared a bug in window chrome

I found a solution to this issue with IE11. The following CSS will fix this issue.

.ql-editor::before {
    visibility: hidden;
    color: rgba(0, 0, 0, .6);
    content: attr(data-placeholder);
    font-style: italic;
    left: 15px;
    pointer-events: none;
    position: absolute;
    right: 15px;
  }

  .ql-editor.ql-blank::before {
    visibility: visible;
  }

Try this with IE11 and IME : https://jsbin.com/kujavudoki/1/edit?html,css,js,output

I think this issue is caused by changing the DOM tree with psudo-element "::before". If psudo-element is always in the DOM tree, IME will be correct.

It also reappeared in version 2.0.0-dev.2

Any news? problem is reproduced in 1.3.7
Typing 'sui' it should be すい
Firefox 83 - correct first and next attempts
изображение
IE11 - remain s and not correct first symbol, next attempts correct
изображение
Chrome 86 - remain s, next attempts correct
изображение

Was this page helpful?
0 / 5 - 0 ratings