Use Monaco editor in web application

10,494

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/

Share:
10,494

Related videos on Youtube

ritchxu
Author by

ritchxu

Updated on June 04, 2022

Comments

  • ritchxu
    ritchxu almost 2 years

    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?

    • Hackerman
      Hackerman almost 8 years
      Yes you can...actually they do it in their demo page: microsoft.github.io/monaco-editor
    • Hackerman
      Hackerman almost 8 years
      Not at all...you can use it in your own app,you just need to include the relevant js and css files, and that's it
  • ritchxu
    ritchxu almost 8 years
    do you know any reason why when I tried this workaround in a clean MVC application it could work, but when it was used in my real project, an error of Uncaught ReferenceError: require is not defined appeared. Moreover, I noticed if you replaced the source of jquery reference in jsfiddle to link it would generate errors. And that's a difference between my project(jquery 2.2.1) and a clean MVC application(jquery 1.9.1).
  • Hackerman
    Hackerman almost 8 years
    If you check the Monaco Editor demo, they use Jquery 1.9.1, so it is possible that the Editor doesn't works with a higher version....
  • c-sharp-and-swiftui-devni
    c-sharp-and-swiftui-devni almost 4 years
    @Hackerman intellsense is not working in that demo I beleive the person did request it
  • Hackerman
    Hackerman almost 4 years
    @rogue39nin This demo is 4 years old...also the OP accepted the answer 🤓