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.

1 Like

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.

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.