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.

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();

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());
}

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.

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

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:
- Copy the script from the Github Gist with the Bookmarklet source code
- On your Internet browser, create a bookmark and then add the script copied in step 1 as the bookmark URL.
- 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