ef Editor test

by Yukino Song

HTML

<script src="https://unpkg.com/ef.js@latest"></script>

CSS

.editor {
  line-height: 20px;
  font-size: 20px;
  white-space: pre-wrap;
  word-wrap: break-word;
  border: #000 1px solid;
  min-height: 20px;
  padding: 5px;
}

.splitter {
  min-height: 20px;
  overflow: hidden;
  position: relative;
  line-break: none;
  outline: none;
}

Babel + JSX

const { t, bundle } = ef

const Editor = t`
>div
  >pre.editor
    @keyup = updateInfo
    @click = focus
    @keydown.37 = moveLeft
    @keydown.38 = moveUp
    @keydown.39 = moveRight
    @keydown.40 = moveDown
    @keydown.8 = backspace
    @keydown.46 = delete
    @keydown.13.prevent = newLine
    >span
      .{{contentL = abc}}
    >span.splitter#inputBox
      #spellcheck = false
      #contenteditable
      @blur = applyNew
    >span
      .{{contentR = defghijklmn}}
  >div
    >p
      .anchorOffset: {{anchorOffset}}
    >p
      .baseOffset: {{baseOffset}}
    >p
      .extentOffset: {{extentOffset}}
    >p
      .focusOffset: {{focusOffset}}
    >p
      .isCollapsed: {{isCollapsed}}
    >p
      .rangeCount: {{rangeCount}}
    >p
      .type: {{type}}
`

const editor = new Editor({
  $methods: {
    focus({state}) {
      state.$refs.inputBox.focus()
    },
    updateInfo({state}) {
      const sel = window.getSelection()
      state.$data = {
        anchorOffset: sel.anchorOffset,
        baseOffset: sel.baseOffset,
        extentOffset: sel.extentOffset,
        focusOffset: sel.focusOffset,
        isCollapsed: sel.isCollapsed,
        rangeCount: sel.rangeCount,
        type: sel.type
      }
    },
    applyNew({state}) {
      const sel = window.getSelection()
      const offset = sel.focusOffset
      state.$data.contentL += state.$refs.inputBox.textContent.slice(0, offset)
      state.$data.contentR = `${state.$refs.inputBox.textContent.slice(offset)}${state.$data.contentR}`
      state.$refs.inputBox.textContent = ''
    },
    moveLeft({state}) {
      const sel = window.getSelection()
      if (sel.focusOffset !== 0) return
      const newContent = state.$refs.inputBox.textContent
      state.$refs.inputBox.textContent = ''
      const contentL = state.$data.contentL.split('')
      const char = contentL.pop() || ''
      bundle(() => {
        state.$data.contentL = contentL.join('')
        state.$data.contentR =...