## とあるノートアプリから始まった色々調査
---
### Agenda
- key event
- componsition event
- content editable
----

Note:
之所以會想要做這個主題,是因為我很喜歡看到有新的筆記軟體就會跑去玩。而之前玩到一款網頁版的 note app, 發生了這樣的 bug
只要是CJK的文字就會壞掉。因為想知道為什麼開始調查,所以有了這個分享。
----
Chrome

----
Firefox

---
### key event
Note:
簡單的入門開始。
因為我在開發和前端相關領域的資歷都很淺,今天講的內容可能過分簡單。如果有任何可以補充的歡迎隨時幫我補充。
----
#### 大家都知道的 key event
在 browser 中,當按下鍵盤時會觸發三個事件
- keydown
- keyup
- keypress
----
keydown & keyup
```text
The keydown event is fired when a key is pressed.
The keydown and keyup events provide a code
indicating which key is pressed.
```
Note:
- 首先,「keydown」「keyup」比較好理解,keydown可以連續觸發,而 keyup 只會在放開的那一個瞬間觸發。
- 就像是玩遊戲的時候,可以長按集氣,但只會有一個放開的瞬間釋放
----
Keydown v.s keypress ?
----
MDN:
```text
keypress イベントとは異なり、
keydown イベントはすべてのキーにおいて、
文字が入力されるかどうかにかかわらず発生します。
```
Note:
keypress是一種 press ,雖然看起來很像 keydown,但 keypress 只會被「文字按鍵」觸發。
----
では、問題です。
「はい」を入力するとき、「h」を押すと、
keypressは発火する?しない?
<span>[実験しよう](https://www.w3.org/2002/09/tests/keys.html)<!-- .element: class="fragment" data-fragment-index="1" --></span>
----
A:
発火しない
----
bugについての推論
おそらくこちらのイベント処理がちゃんと処理されてないから、
keydownなどで混乱しちゃって、
バグになった
Note:
ではFirefoxはなんで(ちょっと)うまくいったの?
----
MDN:
```text
Firefox 65 から、
keydown および keyup イベントは IME 入力中でも発生するようになり、
CJKT のユーザーのブラウザー間の互換性が向上しました (バグ 354358)。
```
Note:
この内容はおそらく先ほどのfirefoxがそうなにバグらない理由ではないかと。
---
Wait, What?
IME?
<span><h4>Input Method Editor<!-- .element: class="fragment" data-fragment-index="1" --></h4></span>
----
[Input method editor (インプットメソッドエディター)](https://developer.mozilla.org/ja/docs/Glossary/Input_method_editor)
```text
インプットメソッドエディター (IME) は、
テキスト入力のための特殊なユーザーインターフェイスを提供するプログラムです。
インプットメソッドエディターは多くの場面で使用されています。
```
Note:
也就是說, Firefox 65 から、 keydown および keyup イベントは IME 入力中で発生する。
----
Reactのソースコードを見ましょう
Note:
在寫 React 的時候,我們調用得Event基本上都不是原生的 Event。
React 基本上把 Event 都包起來做了各種處理才交到我們手上。
----
#### [react/packages/react-dom/src/events/plugins/BeforeInputEventPlugin.js](https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/BeforeInputEventPlugin.js)
Composition start
```js
/**
* Does our fallback best-guess model think this event signifies that
* composition has begun?
*/
function isFallbackCompositionStart(
domEventName: DOMEventName,
nativeEvent: any,
): boolean {
return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
}
```
----
```
START_KEYCODE = 229
```
```text
If an Input Method Editor is processing key input
and the event is keydown,
return 229.
```
[keyCode in key events](https://lists.w3.org/Archives/Public/www-dom/2010JulSep/att-0182/keyCode-spec.html)
----
#### [react/packages/react-dom/src/events/plugins/BeforeInputEventPlugin.js](https://github.com/facebook/react/blob/main/packages/react-dom/src/events/plugins/BeforeInputEventPlugin.js)
Composition end
```js
/**
* Does our fallback mode think that this event is the end of composition?
*/
function isFallbackCompositionEnd(
domEventName: DOMEventName,
nativeEvent: any,
): boolean {
switch (domEventName) {
case 'keyup':
// Command keys insert or clear IME input.
return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
// const END_KEYCODES = [9, 13, 27, 32];
// Tab, Return, Esc, Space
case 'keydown':
// Expect IME keyCode on each keydown. If we get any other
// code we must have exited earlier.
return nativeEvent.keyCode !== START_KEYCODE;
case 'keypress':
case 'mousedown':
case 'focusout':
// Events are not possible without cancelling IME.
return true;
default:
return false;
}
}
```
----
Composition Events:
https://codepen.io/keronscribe/pen/PoErpwm
Note:
こちらのテスト用のcodepenを見当たって、
でも、よく見ると一番右がdivでできでいるのインプットエリア。
との初心者の発見がありました。
そこで話戻るですが、
先のめっちゃバグるノードで、もうしかしてこれを使って実装されたのと。
---
あたりです
```html [8]
<div
data-gramm="false"
role="textbox"
dir="ltr"
class="EditorContainer"
data-slate-editor="true"
data-slate-node="value"
contenteditable="true"
style="outline: none; white-space: pre-wrap; overflow-wrap: break-word;"
</div>
```
---
### content editable
```text
HTMLElement インターフェイスの contentEditable プロパティは、
要素が編集可能かどうかを指定します。
この**列挙属性**には、次の値を設定できます。
```
----
```text
この**列挙属性**には、次の値を設定できます。
'true' は、要素の内容が編集可能 (contenteditable) であることを示します。
'false' は、要素が編集できないことを示します。
'inherit' は、要素がその親の編集可能状態を継承することを示します。
```
----
content editable を使っている editor
- GitHub も使っている [CodeMirror](https://github.com/codemirror/CodeMirror/blob/22e9d4f6ce451196803898be1bad859567df6107/src/input/ContentEditableInput.js#L19)
- このスライドを作成する環境の[HackMD](https://hackmd.io/)
- 最近ちょっと話題になってる[lexical](https://github.com/facebook/lexical/blob/4e57eb8d7e0ca00fe998f02b9dd3efaaef858a2e/packages/lexical-react/src/LexicalContentEditable.jsx#L94)
----
[lexical Rich text editor ](https://playground.lexical.dev/)は本当に綺麗と思います。
Note:
Reactも使えるので興味がある方ぜひ
---
{"metaMigratedAt":"2023-06-16T23:29:37.982Z","metaMigratedFrom":"YAML","title":"範例簡報","breaks":true,"slideOptions":"{\"theme\":\"moon\",\"transition\":\"fade\"}","contributors":"[{\"id\":\"55656006-7069-4b3c-b452-8f557a1d2ca8\",\"add\":10347,\"del\":5058}]"}