Prosemirror-view upgrade caused Chinese to be affected by Decoration widget during input

After the upgrade, the document changes and the nodesize changes while the Chinese is being input. In this way, the location-dependent decoration needs to be recreated, resulting in the inability to input Chinese.

"name": "prosemirror-view",
"version": "1.12.3",

code:

    apply(tr, old) {
       const pageSettings = _this.editor.options.pageSettings
       return tr.docChanged ? pageDeco(tr.doc, pageSettings) : old
    }

I can’t promise that I’ll be able to look at this soon, but I can promise that I can’t do anything without a lot more information about the browser, platform, and IME system you’re using, preferably accompanied with a full (but minimal) code example to trigger the issue.

hi marijn, thank you for your attention.

os: mac
browser: Google Chrome: 81.0.4000.3(dev)

Part of the code:

function widgetList(doc) {
  let result = []

  function record(from, to) {
    result.push({ from, to })
  }
  // For each node in the document
  doc.descendants((node, pos) => {
    if (node.type.name === 'page_content') {
      record(pos, pos + node.nodeSize)
    }
  })
  return result
}

function pageDeco(doc) {
  let decos = []
  let probArr = []
  widgetList(doc).forEach(prob => {
    probArr.push(prob)
    decos.push(
      Decoration.widget(prob.from, view => {
        return decosNode(view, prob, 'header')
      })
    )
    decos.push(
      Decoration.widget(prob.to, view => {
        return decosNode(view, prob, 'footer')
      })
    )
  })
  return DecorationSet.create(doc, decos)
}

function decosNode(view, prob, name) {
  let node = document.createElement('div')
  node.className = `editor__page_${name}`
  node.innerHTML = `<p>${name}</p>`
  node.ntype = name
  return node
}
let pageWidget = new Plugin({
  key: new PluginKey('page'),
  state: {
    init(_, { doc }) {
      return pageDeco(doc)
    },
    apply(tr, old) {
      return tr.docChanged ? pageDeco(tr.doc) : old
    },
  },
  props: {
    decorations(state) {
      return this.getState(state)
    },
  },
})

Does this block need to pay attention to the value of view.composing?

hi marijn, Is this a problem?

No, updating the view during composition is something the editor does by-design now.

You can make your problem a lot less severe (and make things more efficient to boot) by using the key option to Decoration.widget to avoid redrawing. Still looking into why it is disrupting compositions in the first place, since changes to those decorations shouldn’t really cause the content around them to be redrawn.

This patch should make the code work even when it’s constantly replacing the widgets.

Because I need to add decoration at the end of the content, if I only trigger the update when I type Chinese Pinyin, then the position-based decoration at the end of my content also needs to be changed, which will block the input of the Chinese input method

1 Like

Could you be more specific about where and when the decoration is being created? Or, even better, provide a full, but minimal, demo of the problem?