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);
...