BlockWrapper doesn't work with composition mode

Hi @marijn, thanks for the great work on block wrappers, I’ve recently tried this out and it works amazingly.

However I had to revert the change because I noticed that triggering composition mode inside a block wrapper element can lead to fatal errors:

This typically happens when you use an input method like Chinese Pinyin.

Here’s a minimal repro:

import {basicSetup, EditorView} from "codemirror"
import {BlockWrapper, ViewPlugin} from "@codemirror/view"
import {Range} from "@codemirror/state"
import {syntaxTree} from "@codemirror/language"
import {markdown} from "@codemirror/lang-markdown"
import {languages} from "@codemirror/language-data"

// The Markdown parser will dynamically load parsers
// for code blocks, using @codemirror/language-data to
// look up the appropriate dynamic import.
let view = new EditorView({
  doc: "Hello\n\n```javascript\nlet x = 'y'\n```",
  extensions: [
    basicSetup,
    markdown({codeLanguages: languages}),
    ViewPlugin.fromClass(class {}, {
      provide: () => EditorView.blockWrappers.of(view => {
        const ranges: Range<BlockWrapper>[] = []
        for (const {from, to} of view.visibleRanges) {
          syntaxTree(view.state).iterate({
            from, to,
            enter: node => {
              if (node.name === 'FencedCode') {
                const range = BlockWrapper.create({
                  tagName: 'div',
                  attributes: {'class': 'cm-fenced-code-block'}
                }).range(node.from, node.to)
                ranges.push(range)
              }
            }
          })
        }
        return BlockWrapper.set(ranges)
      })
    })
  ],
  parent: document.body
})

Please let me know if you need a working project setup instead, I can create a git repo since attaching zip isn’t allowed.

Thanks!

Oh wow, that was pretty bad. This patch should help.

1 Like

Thanks for the quick fix and release!