Monaco Editor Enhancement

In December of 2017, I wrote an article about a script that could be used to enhance the Dynamics 365 web templates’ ACE editor by increasing its coding area and providing the capability to customize its color theme. Dynamics 365 now has a new liquid editor that comes with portals v9 solutions as explained in this article by Colin Vermander. The new editor is the Microsoft Monaco Editor, which is the editor used in Visual Studio code.

The Monaco editor is quite an improvement over the ACE editor, but it still shows on a fairly small container, as shown below, and you still don’t have the ability to save your changes with CTRL + S.

MonacoPicture1.png

With this in mind, I decided to create another script for the Monaco editor to once again expand the editor to occupy as much of the screen as possible and to provide the ability to save changes by pressing CTRL + S.

 

How are enhancements made?

As was the case with the previous script for the ACE editor, JavaScript is used to modify the elements on the page that displays the editor and to add new elements to the page as well. The main changes are described below.


Expanded editor

The editor was modified so that it now takes the whole width of the screen. In terms of height, all space is used except for the space given to the Dynamics 365 main menu bar and the bar that contains the save icon, the name of the record, and the theme selector.

To expand the editor, the iframe containing the editor container is first modified to occupy the whole width of the screen and most of the height, leaving space for the bar containing the name of the record and theme selector. Then, the iframe content is reloaded, making the editor container automatically expand to the width and height of its parent element, and therefore also occupy the same space as the iframe.

// Get nested iframe element

var iframe2 = innerDoc1.getElementById(editorIframeId);

 

// Set Iframe2 to occupy the whole screen

iframe2.style.position = "fixed";

iframe2.style.width = "100%";

iframe2.style.height = "calc(100% - 26px)";

iframe2.style.top = "28px";

iframe2.style.left = "0";

iframe2.style.zIndex = "2000";

// Reload iframe content so that editor occupies the new space available

iframe2.contentWindow.location.reload();

MonacoPicture2.png

 


Footer bar

This bar, which is normally located at the bottom of the screen and contains the status of the record and the save icon, has now been moved to the top of the screen just below the Dynamics main menu bar. Its content has also been modified to remove the status indicator, to move the save icon to the left, to add the name of the web template on its centre, and to add a theme selector dropdown on its far right.

 

Theme Selector

The theme selector provides the ability to choose from over 40 different themes that can be found in https://github.com/brijeshb42/monaco-themes. Some of the themes were slightly modified so that they would play nicely with the liquid code color scheme. Once a theme has been selected, the selection will be stored in the browser’s local storage so that when the script is executed the next time, it will load the same theme that was previously set.

The themes are applied to the editor by first getting the editor object, then registering each theme to it, and then setting the theme corresponding with the one chosen on the theme selector.

 

// Get editor object

var myMonaco = innerDoc1.getElementById(editorIframeId).contentWindow.monaco;

 

// Define Themes   
myMonaco.editor.defineTheme('active4d',
    {

            "base": "vs",

            "inherit": true,

            "rules": [

                {

                    "background": "e2e9ff",

                    "token": "text.html source.active4d"

                },

                {

                    "foreground": "000000",

                    "token": "text.xml"

                }

                .

                .

                .

            ],

            "colors": {

                "editor.foreground": "#3B3B3B",

                "editor.background": "#FFFFFF",

                "editor.selectionBackground": "#BAD6FD",

                "editor.lineHighlightBackground": "#BAD6FD",

                "editorCursor.foreground": "#404040",

                "editorWhitespace.foreground": "#BFBFBF"

            }

     });

myMonaco.editor.defineTheme('allhallowseve',
    ...);

myMonaco.editor.defineTheme('amy',
    ...);

.
.
.

myMonaco.editor.defineTheme('zenburnesque',
    ...);

 

// Set theme on change of theme selector

$themeSelector.change(function () {

    setMonacoTheme();

});

 

// Sets the theme

function setMonacoTheme() {

    myMonaco.editor.setTheme($themeSelector.val());

    if ($themeSelector.find('option[value="' + $themeSelector.val() + '"]').data('background') == "light") {

        setFooterColor("#f8f8f8", "#666");

    } else {

        setFooterColor("#111", "gray");

    }

    localStorage.setItem("monacoeditorthemename", $themeSelector.val());

}

MonacoPicture3

 

 

Command-based code saving

Changes to code on the editor can be saved by pressing Ctrl + S.

// Adding Ctrl + S for save functionality

$(innerDoc2).on("keydown", function (e) {

    if (e.ctrlKey && e.which === 83) {

        e.preventDefault();

        $innerDoc1.find(".inline-block.save-status-icon.status-icon a img").click();

    }

});

 

Applicable in all places in Dynamics 365 that make use of the Monaco editor

While the script for the ACE editor only worked for web templates, the one for the Monaco editor will also work for the editors used on the Custom JavaScript section of Web Pages, Entity Forms, and Web Form Steps. As shown below, the space available for the editor on these JavaScript sections is very small as you only get to see 7 lines of code at a time.

MonacoPicture4

After applying the script, you get as many lines as your screen will fit.

MonacoPicture5

 

Setup

If you don’t have the Monaco editor in your Dynamics 365 instance, you need to upgrade your Dynamics 365 Portals solution in the Dynamics 365 Administration Center. See Colin Vermander's post: https://colinvermander.com/2018/06/28/dynamics-365-portals-v9-solutions-now-available-and-liquid-editor-change/

Once you have the Monaco editor, follow these steps to apply the script:

  1. Copy the script from the Github Gist with the Bookmarklet source code
  2. On your Internet browser, create a bookmark and then add the script copied in step 1 as the bookmark URL.
  3. Once on a Web Page, Web Form Step, Entity Form, or Web Template, allow a few seconds for the page to fully load and then click on the bookmark created on step 2 to execute the script.

 

Javascript source code

 

https://gist.github.com/Manfroy/645046f74742a9fab9376698204d5a68

Bookmarklet source code

https://gist.github.com/Manfroy/46bfe73585f36a0e85865d5eaa4d9901