GrapesJS codemirror event issue

Question re how to the 'more accurate' codemirror 'change' event which is triggered key by key. We need it cos if we paste or backspace or delete etc. in codemirror then the regular 'change' event is never issued! But how do we get this event to trigger the proper, usual 'onEvent' below? Currently cheating and doing the onEvent work here with this special handler. Solution later found - see https://github.com/artf/grapesjs/issues/3135

by Andy Bulka

HTML

<script src="https://unpkg.com/grapesjs"></script>
<link rel="stylesheet" href="https://unpkg.com/grapesjs/dist/css/grapes.min.css">
<script src="https://unpkg.com/grapesjs-blocks-basic"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.59.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.59.2/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.59.2/mode/javascript/javascript.min.js"></script>
    <div id="gjs">
      <div id="gjs">
        <p>
          Hello world.
        </p>
        <p>
          Drag me somewhere...
        </p>
        <p>
          Bye bye world, nice simple example.
        </p>
        <button type="button" data-scriptable="true">Run Script</button>
      </div>
    </div>

CSS

body, html {
  margin: 0;
  height: 100%;
}

Babel + JSX

function customScriptPlugin(editor) {

  const codemirrorEnabled = true  // otherwise trait editor is just a plain textarea

  const script = function (props) {
    this.onclick = function () {  // this doesn't work in jsfiddle?
      // eval(props.jscript)
      console.log('would have eval', props.jscript)
    }
  };

  editor.DomComponents.addType("customScript", {
    isComponent: el => el.tagName == 'BUTTON' && el.hasAttribute && el.hasAttribute("data-scriptable"),
    model: {
      defaults: {
        traits: [
          {
            // type: 'text',
            type: 'jcodemirror-editor',  // defined below
            name: 'jscript',
            changeProp: true,
          }
        ],
        script,
        jscript: `let res = 1 + 3; console.log('result is', res);`,
        'script-props': ['jscript'],
      },
    },
  });

  editor.TraitManager.addType('jcodemirror-editor', {
    createInput({ trait }) {
      const el = document.createElement('div');
      el.innerHTML = `
<form>
<textarea id="myjscript" name="myjscript" rows="14">
</textarea>
</form>
</div>
`

      if (codemirrorEnabled) {
        const textareaEl = el.querySelector('textarea');
        var myCodeMirror = CodeMirror.fromTextArea(textareaEl, {
          mode: "javascript",
          lineWrapping: true,
        });

        // This is the 'more accurate' codemirror 'change' event
        // which is triggered key by key. We need it cos if we paste
        // or backspace or delete etc. in codemirror then the
        // regular 'change' event is never issued! But how do we get
        // this event to trigger the proper, usual 'onEvent' below?
        // Currently cheating and doing the onEvent work here with
        // this special handler.
        myCodeMirror.on("change", function (cm, changeObj) { // HACK
          const component = editor.getSelected()
          const code_to_run = myCodeMirror.getValue()
          component.getTrait('jscript').set('value', code_to_run);
      ...