Need some help on monaco-editor

Hi ,

Is there a way to access Monaco. Editor object from within Node-Red ?
I am specifically interested in the createDiffEditor and other functions which can help between 2 texts.

(Any other options where i can do diff and then pass it to template node - are also welcome).
Aim is to show diffs via. browser.


If you look at the network requests made by the node-red editor you will see the endpoints used to include Monaco. So in your dashboard or webpage you could link to and create an editor. I did a diff demo with Monaco somewhere on this forum - you could possibly grep the code from that.

Thanks Steve.
Do you refer to this post ?

I dont see anything here the code.

I also checked the network requests.

I see the below. But unable to make out how to use this for my work.

Yeah. I thought I'd posted code. Sorry for the wild goose chase.

Any luck any one ? Since NR already has monaco - i thought it would be easier

Do you know how to import scripts and link CSS in a web page?

If yes, then grab the URLs for Monaco stuff you see in the network tab.

Next head over to the Monaco playground where they have a diff demo

Node-red editor does and it has helper functions. Dashboard does not. Therefore you need to program your web page to link to scripts and CSS served by node-red editor then to instantiate the editor with the required settings to make a diff editor.

I understand this bit - that probably entire thing will need to be done in template HTML node and not in usual Dashboard nodes. I am ok and can work with this.

Done. My knowledge is on Vanilla JS. I managed to link

  1. http://localhost:1880/vendor/monaco/dist/editor.js
  2. http://localhost:1880/vendor/monaco/style.css?v=3.0.0

But as i suspected - based on monaco playground - i tried to do

editor = monaco.editor.create(editorContainer
And as expected i got monaco is not defined error.

I am unable to fathom how to create "monaco" object.

Here you go...


[{"id":"3417f97ab5c6ee77","type":"ui_template","z":"4c5ad8c7caa80822","group":"c3180d6ecfee774b","name":"head and setup","order":2,"width":0,"height":0,"format":"<script src=\"/vendor/monaco/dist/editor.js\"></script>\n<link rel=\"stylesheet\" href=\"/vendor/monaco/style.css\">\n\n<style>\n    @font-face {\n        font-family: \"codicon\";\n        font-display: block;\n        src: url(/vendor/monaco/dist/ade705761eb7e702770d.ttf) format(\"truetype\");\n    }\n</style>\n\n<script>\n    // window.MonacoEnvironment.getWorkerUrl = window.MonacoEnvironment.getWorkerUrl || function (moduleId, label) {\n    window.MonacoEnvironment.getWorkerUrl = function (moduleId, label) {\n        console.log(\"MonacoEnvironment.getWorkerUrl\", moduleId, label)\n        if (label === 'json') { return '/vendor/monaco/dist/json.worker.js'; }\n        if (label === 'css' || label === 'scss') { return '/vendor/monaco/dist/css.worker.js'; }\n        if (label === 'html' || label === 'handlebars') { return '/vendor/monaco/dist/html.worker.js'; }\n        if (label === 'typescript' || label === 'javascript') { return '/vendor/monaco/dist/ts.worker.js'; }\n        return '/vendor/monaco/dist/editor.worker.js';\n    };\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"global","className":"","x":2140,"y":660,"wires":[[]]},{"id":"42418e75db6ccfe2","type":"ui_template","z":"4c5ad8c7caa80822","group":"c3180d6ecfee774b","name":"editor","order":3,"width":"12","height":"8","format":"<div id=\"editor\" style=\"width: 600px; height: 400px;\"></div>\n\n\n<script>\n    (function(scope) {\n        console.log(\"creating diff editor\")\n        scope.originalModel = monaco.editor.createModel('hello world!\\ntoday is a good day to node-red', 'text/plain');\n        scope.modifiedModel = monaco.editor.createModel('hola el mundo!\\ntoday is a good day to eat bread', 'text/plain');\n        scope.diffEditor = monaco.editor.createDiffEditor(document.getElementById('editor'));\n        scope.diffEditor.setModel({\n            original: scope.originalModel,\n            modified: scope.modifiedModel\n        });\n\n        scope.$watch('msg', function(msg) {\n            if (msg && msg.topic == \"set\" && typeof msg.payload === \"object\") {\n                console.log(\"setting left and right panes\", msg.payload)\n                if(msg.payload.left != null) {\n                    scope.originalModel.setValue(msg.payload.left);\n                }\n                if(msg.payload.right != null) {\n                    scope.modifiedModel.setValue(msg.payload.right);\n                }\n            }\n        });\n    })(scope);\n</script>","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","className":"","x":2110,"y":700,"wires":[[]]},{"id":"2c102355b4abaf47","type":"inject","z":"4c5ad8c7caa80822","name":"set text from serverside","props":[{"p":"topic","vt":"str"},{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"set","payload":"{\"left\":\"This\\nis\\nthe\\nleft\\npart\\nset from server side\",\"right\":\"This\\nis\\nthe\\nright\\npart\\nset from server side\"}","payloadType":"json","x":1920,"y":700,"wires":[["42418e75db6ccfe2"]]},{"id":"c3180d6ecfee774b","type":"ui_group","name":"inventory","tab":"a088985c1d3b62a3","order":1,"disp":true,"width":"12","collapse":false,"className":""},{"id":"a088985c1d3b62a3","type":"ui_tab","name":"Supermarket","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

Thank You so very much Steve.
The above worked like a swell. And i dont think i would have reached there. I have not yet tinkered around the head part of site configurations.

I was already able to enhance it to my needs and add some more info which i need.
e.g some Previous and Next buttons to allow user to move him through the changes.