Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use Monaco editor in web application

We have an MVC web application in which Powershell is used as scripting engine. Currently a textarea element is used for script editing which turns out to be very cumbersome. As Microsoft released Monaco Editor, we were wondering if we could embed the editor in our application as a widget to leverage its capability of syntax check and intellisense. After checking out their documentation, not much related info could be found. Is this possible or Microsoft is not currently supporting the use in a third-party application?

like image 331
ritchxu Avatar asked Jul 20 '16 19:07

ritchxu


People also ask

How does Monaco editor work?

The Monaco Editor is generated straight from VS Code's sources with some shims around services the code needs to make it run in a web browser outside of its home.

How do I use editor in react in Monaco?

The easiest way to use the react-monaco-editor with create-react-app is to use the react-app-rewired project. For setting it up, the following steps are required: Install react-app-rewired : npm install -D react-app-rewired. Replace react-scripts by react-app-rewired in the scripts section of your packages.


1 Answers

This is a workaround to include the Monarc Editoron your website, it still requires files from Microsoft to works, but, it should be work if we download those files locally and modify the baseUrl to point to the right folder:

Basic HTML Code

<section class="try">
    <div class="container">
    <h3>Editor</h3>
        <div class="editor row">
            <div class="span3">                 
                <p>Colorizers are implemented using <a href="monarch.html"
                    target="_blank">Monarch</a>.</p>
            </div>
            <div class="span9">
                <div class="row">
                    <div class="span4">
                        <label class="control-label">Language</label>
                        <select class="language-picker"></select>
                    </div>
                    <div class="span4">
                        <label class="control-label">Theme</label>
                        <select class="theme-picker">
                            <option>Visual Studio</option>
                            <option>Visual Studio Dark</option>
                            <option>High Contrast Dark</option>
                        </select>
                    </div>
                </div>
                <div class="editor-frame">
                    <div class="loading editor" style="display: none;">
                        <div class="progress progress-striped active">
                            <div class="bar"></div>
                        </div>
                    </div>
                    <div id="editor"></div>
                </div>
            </div>
        </div>   
   </div>
</section>

JavaScript Code:

'use strict';
require.config({
    baseUrl: 'https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/min/'
});


var editor = null,
    diffEditor = null;

$(document).ready(function() {
    require(['vs/editor/editor.main'], function() {
        var MODES = (function() {
            var modesIds = monaco.languages.getLanguages().map(function(lang) {
                return lang.id;
            });
            modesIds.sort();

            return modesIds.map(function(modeId) {
                return {
                    modeId: modeId,
                    sampleURL: 'https://microsoft.github.io/monaco-editor/index/samples/sample.' + modeId + '.txt'
                };
            });
        })();

        for (var i = 0; i < MODES.length; i++) {
            var o = document.createElement('option');
            o.textContent = MODES[i].modeId;
            $(".language-picker").append(o);
        }
        $(".language-picker").change(function() {
            loadSample(MODES[this.selectedIndex]);
        });
        $('.language-picker').selectpicker({
            size: 10
        });
        loadSample(MODES[0]);

        $(".theme-picker").change(function() {
            changeTheme(this.selectedIndex);
        });
        $('.theme-picker').selectpicker({
            size: 3
        });

        loadDiffSample();

        $('#inline-diff-checkbox').change(function() {
            diffEditor.updateOptions({
                renderSideBySide: !$(this).is(':checked')
            });
        });
    });

    window.onresize = function() {
        if (editor) {
            editor.layout();
        }
        if (diffEditor) {
            diffEditor.layout();
        }
    };
});

function loadSample(mode) {
    $.ajax({
        type: 'GET',
        url: mode.sampleURL,
        dataType: 'text',
        beforeSend: function() {
            $('.loading.editor').show();
        },
        error: function() {
            if (editor) {
                if (editor.getModel()) {
                    editor.getModel().dispose();
                }
                editor.dispose();
                editor = null;
            }
            $('.loading.editor').fadeOut({
                duration: 200
            });
            $('#editor').empty();
            $('#editor').append('<p class="alert alert-error">Failed to load ' + mode.modeId + ' sample</p>');
        }
    }).done(function(data) {
        if (!editor) {
            $('#editor').empty();
            editor = monaco.editor.create(document.getElementById('editor'), {
                model: null,
            });
        }

        var oldModel = editor.getModel();
        var newModel = monaco.editor.createModel(data, mode.modeId);
        editor.setModel(newModel);
        if (oldModel) {
            oldModel.dispose();
        }
        $('.loading.editor').fadeOut({
            duration: 300
        });
    });
}

function loadDiffSample() {

    var onError = function() {
        $('.loading.diff-editor').fadeOut({
            duration: 200
        });
        $('#diff-editor').append('<p class="alert alert-error">Failed to load diff editor sample</p>');
    };

    $('.loading.diff-editor').show();

    var lhsData = null,
        rhsData = null,
        jsMode = null;

    $.ajax({
        type: 'GET',
        url: 'https://microsoft.github.io/monaco-editor/index/samples/diff.lhs.txt',
        dataType: 'text',
        error: onError
    }).done(function(data) {
        lhsData = data;
        onProgress();
    });

    $.ajax({
        type: 'GET',
        url: 'https://microsoft.github.io/monaco-editor/index/samples/diff.rhs.txt',
        dataType: 'text',
        error: onError
    }).done(function(data) {
        rhsData = data;
        onProgress();
    });

    function onProgress() {
        if (lhsData && rhsData) {
            diffEditor = monaco.editor.createDiffEditor(document.getElementById('diff-editor'), {
                enableSplitViewResizing: false
            });

            var lhsModel = monaco.editor.createModel(lhsData, 'text/javascript');
            var rhsModel = monaco.editor.createModel(rhsData, 'text/javascript');

            diffEditor.setModel({
                original: lhsModel,
                modified: rhsModel
            });

            $('.loading.diff-editor').fadeOut({
                duration: 300
            });
        }
    }
}

function changeTheme(theme) {
    var newTheme = (theme === 1 ? 'vs-dark' : (theme === 0 ? 'vs' : 'hc-black'));
    if (editor) {
        editor.updateOptions({
            'theme': newTheme
        });
    }
    if (diffEditor) {
        diffEditor.updateOptions({
            'theme': newTheme
        });
    }
}

Working fiddle: https://jsfiddle.net/robertrozas/r1b9hbhk/

like image 123
Hackerman Avatar answered Oct 18 '22 22:10

Hackerman