Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swap CodeMirror in CssEditor for monaco-editor #4133

Merged

Conversation

david-poindexter
Copy link
Contributor

Summary

Resolves #4132

Thanks to @valadas for his great help on this PR - it was a lot of fun working on this one!

Light Theme

Screenshot1

Dark Theme

Screenshot2

Find & Replace

Screenshot3

Color Picker

Screenshot4

Command Palette

Screenshot5

@david-poindexter david-poindexter added this to the 9.8.0 milestone Sep 27, 2020
@david-poindexter david-poindexter self-assigned this Sep 27, 2020
Copy link
Contributor

@mitchelsellers mitchelsellers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two questions before I approve, this looks awesome by the way!

  1. It looks like an XCOPY inclusion was done here, which most likely makes sense due to our project structure, but wanted to be sure.

  2. If my previous comment is correct, should we strip language support for things that will not be possible, such as PHP, etc.?

@david-poindexter
Copy link
Contributor Author

  1. As mentioned in Swap CodeMirror in CssEditor for monaco-editor #4132 this is a stepping stone, using the current pattern. Since the CssEditor module is not a proper *.Web project with package management, the monaco-editor is placed in the shared components.

  2. Currently, we are controlling the editor language support in the config for the implementation.

@valadas
Copy link
Contributor

valadas commented Sep 27, 2020

In my opinion this (which is awesome by the way) is a first implementation but ideally we would rework this and others together to make it use it as a node_module like the rest of the projects. But this feels like a nice stepping stone. We can use this too in sql console and config editor. When we do move it to a node_module then webpack will just grab the languages that are consumed (css, xml, sql)... As saving does not allow actually saving a php file, I see no concern here.

@valadas
Copy link
Contributor

valadas commented Sep 27, 2020

I will review this in more details by the way a bit later today...

@mitchelsellers
Copy link
Contributor

As saving does not allow actually saving a php file, I see no concern here.

My only concern is files with PHP in them can show up in security scans, even if they do nothing. We already have some issues like that with the CKEditor.

All good here for now.

Copy link
Contributor

@valadas valadas left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks awesome to me!

@SkyeHoefling
Copy link
Contributor

👋 Hey everyone, I have quite a bit of experience using monaco in DNN. Last year I built my own IDE built into DNN as a proof of concept. Would love to take a look at this before merging. Hoping I can take a look today or tomorrow.

Copy link
Contributor

@SkyeHoefling SkyeHoefling left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@david-poindexter this will be a great addition to DNN, adding the core VSCode editor the Monaco Editor will be amazing!

I have a few concerns which I highlighted in my comments and will summarize here

  • The Monaco Editor is pulled into the DNN source code. We really should use a npm package reference as it will be easier to update in the future. VSCode iterates at an incredibly fast pace and if we need to update the version as this PR exists, it will be a time consuming process. Unless there is a build script or some form of automation
  • This implementation uses the getting started guide's recommendations of RequireJS. Since the DNN Persona Bar core modules all use ReactJS I think it would make sense to use the Monaco Editor's ReactJS component. This will make it easy to drop onto the page and integrate in other core modules.

Is there plans to allow people to switch from dark to light theme or vice-versa? It may be as simple as placing a tooltip explaining how to use the command palette to adjust theme.

Useful NPM Links

  • Monaco Editor
  • ReactJS Monaco Component - This is where things get tricky, there are several different versions out there that all have their pros/cons

I have used both of the react components that wrap the Monaco Editor in the past. If I recall correctly I landed on the react-monaco-editor. Even though it required more webpack configuration it gave me more control.

var initCssEditor = function() {
var monacoEditorLoaderScript = document.createElement('script');
monacoEditorLoaderScript.type = 'text/javascript';
monacoEditorLoaderScript.src = '/Resources/Shared/components/MonacoEditor/loader.js';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is maintaining the MonocoEditor minified source code under our shared components. This will make it difficult to maintain the version of the editor DNN is using. Did you try using any of the npm packages that exist for MonacoEditor?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CSS Editor extension for the Persona Bar does not use React and doesn't have a Webpack config at this point, so this approach was used as a first implementation. The plan is to switch it to use a version from npm.

@david-poindexter @valadas @mitchelsellers Do we want to avoid adding these scripts to the Shared Resources folder if we're planning to remove them soon? We don't want to give developers the impression that they're intended for broader use, right?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bdukes Maybe for this version it would make sense to include under the /Dnn.CssEditor extension until we include this for usage in other locations and properly pull it in? @david-poindexter thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the clarification on the CSS Editor, I thought something was odd when I didn't see any React code.

Is there an item already on the backlog for updating this to use an NPM package instead of adding the minified source code? Was there a barrier to getting it working?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahoefling please refer to #4132 - this is a "stepping stone" solution. This is obviously not the "right way" to do this, but the current CssEditor module in the PersonaBar is not a proper solution with package management. Therefore, that is a task for a future PR.

monacoEditorLoaderScript.src = '/Resources/Shared/components/MonacoEditor/loader.js';
document.body.appendChild(monacoEditorLoaderScript);

require.config({ paths: { 'vs': '/Resources/Shared/components/MonacoEditor' }});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using requireJS is a supported code path for MonacoEditor and it is a great way to get started. The DNN PersonaBar core modules use ReactJS and the MonacoEditor has a ReactJS component that is easy to use in that context. If we are adding this control to a ReactJS page I would consider using that component.

I am not 100% sure how this particular module uses the ReactJS components that is the DNN persona bar modules. In the context of ReactJS I find it much easier to configure the editor and manage it than calling the JS apis. That is my preference and I defer to the maintainers opinions on this one.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Persona Bar extension (CSS Editor) does not use React. I'm not sure if the other extensions which might use Monaco use React or not (SQL and Config Manager).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahoefling this module currently is not using ReactJS. It is plain HTML, JS, CSS. Therefore, this is a stepping stone solution as stated in #4132.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Furthermore, I would love that we don't make it React only :) But agree we should pull it as an npm package, which is a future step after this stepping stone.

Comment on lines +161 to +174
var monacoEditor = cssEditor.create(document.getElementById("monaco-editor"), {
model: cssContent,
language: "css",
wordWrap: 'wordWrapColumn',
wordWrapColumn: 80,
wordWrapMinified: true,
wrappingIndent: "indent",
lineNumbers: "on",
roundedSelection: false,
scrollBeyondLastLine: false,
readOnly: false,
theme: theme,
automaticLayout: true
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See comment about about ReactJS component.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #4132. This is a stepping stone solution. Moving this to a proper module with package management will a future task.

Comment on lines +153 to +159
var theme = "vs-light";
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
theme = "vs-dark";
}
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
theme = e.matches ? "vs-dark" : "vs-light";
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ahoefling regarding your question about switching themes, it looks like the current support is making use of the OS dark/light theme preference.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it follows the Operating System theme that is probably good enough for now

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct @bdukes - it detects the user's preference and themes monaco-editor accordingly.

@SkyeHoefling
Copy link
Contributor

@bdukes shared some insight about the lack of ReactJS in the CSS Editor module. We can disregard all my comments on the ReactJS npm module from my review.

@david-poindexter
Copy link
Contributor Author

@bdukes shared some insight about the lack of ReactJS in the CSS Editor module. We can disregard all my comments on the ReactJS npm module from my review.

Yes, this will be a future task, and we will have the same issue with the ConfigConsole and SqlConsole modules.

@mitchelsellers mitchelsellers merged commit f25f7fe into dnnsoftware:develop Oct 6, 2020
@david-poindexter david-poindexter deleted the monaco-css-editor branch October 6, 2020 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Swap CodeMirror in CssEditor for monaco-editor
5 participants