wysiwygエディタについての学習9


## draft-jsを使ってみる続き

コードにしてみる

### ベース

```js:test.js
import React from 'react'
import { Editor, EditorState, SelectionState, RichUtils, Modifier } from 'draft-js'

export default class MyEditor extends React.Component {
  constructor (props) {
    super(props)
    this.state = {editorState: EditorState.createEmpty()}
    this.onChange = (editorState) => {
      // 保存
      this.setState({editorState})
      console.log('onChange')
    }
    this.onEscape = () => {
      console.log('onEscape')
    }
  }
  /**
   * 太字
   * @private
   */
  _onBoldClick () {
    this.onChange(RichUtils.toggleInlineStyle(this.state.editorState, 'BOLD'))
  }
  /**
   * 描画
   * @returns {XML}
   */
  render () {
    return (
      <div style={{border: '1px solid red', color: 'blue'}}>
        Draft Editor Example.
        <button onClick={this._onBoldClick.bind(this)}>Bold</button>
        <Editor
          editorState={this.state.editorState}
          handleKeyCommand={this.handleKeyCommand}
          onChange={this.onChange}
          onEscape={this.onEscape}
        />
      </div>
    )
  }
}
```

### 選択範囲と書き換え

onChange or beforeInput

```js:test.js
      // 選択範囲の作成1
      // var editerSelectionState = editorState.getSelection()
      // var updatedSelection = editerSelectionState.merge({
      //   // focusKey: 'bar',
      //   anchorOffset: 0,
      //   focusOffset: 3,
      // })
      // console.log(updatedSelection)

      // 選択範囲の作成2
      let currentKey = editorState.getCurrentContent().getFirstBlock().getKey()
      let selectionState = SelectionState.createEmpty(currentKey)
      let updatedSelection = selectionState.merge({
        focusKey: currentKey,
        anchorOffset: 0,
        focusOffset: 3,
        hasFocus: true,
      })
      console.log(updatedSelection)

      // 書き換え
      const contentWithoutDash = Modifier.replaceText(editorState.getCurrentContent(), updatedSelection, '1234')
      // pushを使うべき
      editorState = EditorState.push(
        editorState,
        contentWithoutDash,
        'replace-text' // サンプルをコピーしたが、EditorChangeTypeに従ってないからダメなのかも
      )
```

onChangeで試したが、beforeInputで試すべきだったな

anchorKeyとfocusKeyが同じじゃないと、うまく動かない。
このキーはブロックを示すから。

もうちょっと複雑なブロックを取得してgetKey()を使う例
https://github.com/facebook/draft-js/issues/161

### 入力中状態で文字を変更

beforeInputイベントを使う
'handled'を返して処理を終わる（onChangeは実行されないが、他にも影響ある？）

```js:test.js
  handleBeforeInput (chars, editorState) {
    if (chars === 'a') {
      // 選択範囲の作成2
      let currentKey = editorState.getCurrentContent().getFirstBlock().getKey()
      let selectionState = SelectionState.createEmpty(currentKey)
      let updatedSelection = selectionState.merge({
        focusKey: currentKey,
        anchorOffset: 0,
        focusOffset: 3,
        hasFocus: true,
      })
      console.log(updatedSelection)

      // 書き換え
      const contentWithoutDash = Modifier.replaceText(editorState.getCurrentContent(), updatedSelection, '123456789')

      // 反映:pushを使うべき
      editorState = EditorState.push(
        editorState,
        contentWithoutDash,
        'replace-text' // サンプルをコピーしたが、EditorChangeTypeに従ってないからダメなのかも
      )

      this.setState({editorState})

      return 'handled'
    }
    return 'not-handled'
  }
```

## タスク・メモ

* immutable-jsの知見
	* http://facebook.github.io/immutable-js/docs/#/Record/Record
* Type Flowの知見
	* https://flow.org/en/docs/