Skip to content

Commit

Permalink
Merge pull request #2 from Steve-Mcl/update-for-v3
Browse files Browse the repository at this point in the history
Update to latest monaco v0.33.0
  • Loading branch information
knolleary authored Apr 19, 2022
2 parents 9c7f5f1 + a6eac0d commit 63c6bb7
Show file tree
Hide file tree
Showing 14 changed files with 5,610 additions and 2,789 deletions.
178 changes: 87 additions & 91 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,114 +2,110 @@
<html>

<head>
<meta charset="utf-8">
<title></title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta charset="utf-8">
<title></title>
<meta name="author" content="">
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>

<body>

<p>Demonstrating monaco editor esm with i18n, cobalt theme and added types (node-red & nodejs) </p>
<p>Monaco lang should be french (right click inside the editor) </p>
<h2>Demonstrating monaco editor esm with i18n</h2>
<h3>Things to check...</h3>
<ul>
<li>Theme should be set to <code>forge</code></li>
<li>Intellisense for node globals, node-red utility functions should be present</li>
<li>Monaco lang should be spanish (right click inside the editor, check palette menu <kbd>F1</kbd> or <kbd>CTRL-SHIFT-P</kbd>) </li>
</ul>

<div id="monaco-editor" style="height: 500px;">MONACO</div>
<div id="monaco-editor" style="height: 500px;">MONACO</div>

<script src="./output/monaco/dist/locale/fr.js"></script>
<script src="./output/monaco/dist/editor.js" ></script>
<script src="./output/monaco/dist/locale/es.js"></script>
<script src="./output/monaco/dist/editor.js"></script>

<script>
var editor;
(function() {
var base = "./output/monaco/dist/";
var types = "./output/types/";
window.MonacoEnvironment = window.MonacoEnvironment || {};
window.MonacoEnvironment.getWorkerUrl = function (moduleId, label) {
if (label === 'json') return base + 'json.worker.js';
if (label === 'css') return base + 'worker.js';
if (label === 'html') return base + 'html.worker.js';
if (label === 'typescript' || label === 'javascript') return base + 'ts.worker.js';
return base + 'editor.worker.js';
}

const defCode = `const fs = require("fs"); //<< should be of type fs & have intellisense
<script>
let editor;
(function () {
const base = "./output/monaco/dist/";
const types = "./output/types/";
const defCode = `const fs = require("fs"); //<< should be of type fs & have intellisense
const os = require("os"); //<< should be of type os & have intellisense
const buf = Buffer.from([1,2,3]); //<< should be of type Buffer & have intellisense
let m = RED.util.cloneMessage({}); //<< hover over cloneMessage - see rich tips
let t = msg.topic; //<< see msg properties after entering msg.
let e = env.get("host"); //<< hover over get - see rich tips
`

const compilerOptions = {
allowJs: true,
checkJs: true,
allowNonTsExtensions: true,
target: monaco.languages.typescript.ScriptTarget.ESNext,
strictNullChecks: false,
strictPropertyInitialization: true,
strictFunctionTypes: true,
strictBindCallApply: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.CommonJS,
typeRoots: ["types"],
lib: ["esnext"] //dont load DOM by default,
}
monaco.languages.typescript.javascriptDefaults.setCompilerOptions(compilerOptions);
const compilerOptions = {
allowJs: true,
checkJs: true,
allowNonTsExtensions: true,
target: monaco.languages.typescript.ScriptTarget.ESNext,
strictNullChecks: false,
strictPropertyInitialization: true,
strictFunctionTypes: true,
strictBindCallApply: true,
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
module: monaco.languages.typescript.ModuleKind.CommonJS,
typeRoots: ["types"],
lib: ["esnext"] //dont load DOM by default,
}
monaco.languages.typescript.javascriptDefaults.setCompilerOptions(compilerOptions);

const diagnosticOptions = {
noSemanticValidation: false,
noSyntaxValidation: false,
diagnosticCodesToIgnore: [
1108, //return not inside function
//2304, //Cannot find name - this one is heavy handed and prevents user seeing stupid errors. Would provide better ACE feature parity (i.e. no need for declaration of vars) but misses lots of errors. Lets be bold & leave it out!
2307, //Cannot find module 'xxx' or its corresponding type declarations
2322, //Type 'unknown' is not assignable to type 'string'
2339, //property does not exist on
2345, //Argument of type xxx is not assignable to parameter of type 'DateTimeFormatOptions'
7043, //i forget what this one is,
80001, //Convert to ES6 module
80004, //JSDoc types may be moved to TypeScript types.
]
};
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions(diagnosticOptions);
const diagnosticOptions = {
noSemanticValidation: false,
noSyntaxValidation: false,
diagnosticCodesToIgnore: [
1108, //return not inside function
//2304, //Cannot find name - this one is heavy handed and prevents user seeing stupid errors. Would provide better ACE feature parity (i.e. no need for declaration of vars) but misses lots of errors. Lets be bold & leave it out!
2307, //Cannot find module 'xxx' or its corresponding type declarations
2322, //Type 'unknown' is not assignable to type 'string'
2339, //property does not exist on
2345, //Argument of type xxx is not assignable to parameter of type 'DateTimeFormatOptions'
7043, //i forget what this one is,
80001, //Convert to ES6 module
80004, //JSDoc types may be moved to TypeScript types.
]
};
monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions(diagnosticOptions);

editor = monaco.editor.create(document.getElementById("monaco-editor"), {
value: defCode,
language: "javascript"
});
var themeName = "monokai"
fetch(base + "theme/" + themeName + ".json").then(response => {
return response.json();
}).then(theme => {
if ((theme.rules && Array.isArray(theme.rules)) || theme.colors) {
monaco.editor.defineTheme(themeName, theme);
monaco.editor.setTheme(themeName);
} else {
console.warn("theme is not valid")
}
}).catch(err => {
console.error(err);
});
const urls = [
types + "node-red/util.d.ts",
types + "node-red/func.d.ts",
types + "node/globals.d.ts",
types + "node/fs.d.ts",
types + "node/os.d.ts",
]
var promises = urls.map(url => fetch(url).then(y => y.text()));
Promise.all(promises).then(results => {
console.log(results);
for (let index = 0; index < results.length; index++) {
const ts = results[index];
const fn = urls[index].replace(types,"");
monaco.languages.typescript.javascriptDefaults.addExtraLib(ts, `file://types/${fn}`);
}
});
})();
editor = monaco.editor.create(document.getElementById("monaco-editor"), {
value: defCode,
language: "javascript"
});
var themeName = "forge"
fetch(base + "theme/" + themeName + ".json").then(response => {
return response.json();
}).then(theme => {
if ((theme.rules && Array.isArray(theme.rules)) || theme.colors) {
monaco.editor.defineTheme(themeName, theme);
monaco.editor.setTheme(themeName);
} else {
console.warn("theme is not valid")
}
}).catch(err => {
console.error(err);
});
const urls = [
types + "node-red/util.d.ts",
types + "node-red/func.d.ts",
types + "node/globals.d.ts",
types + "node/fs.d.ts",
types + "node/os.d.ts",
]
var promises = urls.map(url => fetch(url).then(y => y.text()));
Promise.all(promises).then(results => {
console.log(results);
for (let index = 0; index < results.length; index++) {
const ts = results[index];
const fn = urls[index].replace(types, "");
monaco.languages.typescript.javascriptDefaults.addExtraLib(ts, `file://types/${fn}`);
}
});
})();

</script>
</script>

</body>

Expand Down
112 changes: 56 additions & 56 deletions generate-monaco-esm-i18n.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,7 @@ const replaceInFile = require("replace-in-file");
const ncp = require("ncp").ncp;
const rimraf = require("rimraf");
const readJson = require('read-package-json')
const { semver, mkDirSafe } = require("./common");
const { tempDir } = require("./paths")


function readPackage(packageFile) {
return new Promise(function(resolve, reject) {
readJson(packageFile, console.error, false, (err,data) => {
if (err) {
reject(err);
} else {
resolve(data)
}
});
});
}
const { semver } = require("./common");

const {
monacoDir,
Expand All @@ -34,10 +20,21 @@ const {
} = require("./paths");

const langDirPrefix = "vscode-language-pack-";
const vsCodeRepository = "git://github.com/Microsoft/vscode-loc.git";

const vsCodeRepository = "https://github.com/Microsoft/vscode-loc.git";
const fileExistsCache = new Map();

function readPackage(packageFile) {
return new Promise(function (resolve, reject) {
readJson(packageFile, console.error, false, (err, data) => {
if (err) {
reject(err);
} else {
resolve(data)
}
});
});
}

/**
* The microsoft/vscode-loc contains many more i18n keys that are used by monaco editor.
* Keys are grouped by source files, so we include only those keys whose source files
Expand All @@ -61,14 +58,14 @@ function sourceFileExists(key) {
* then i18n key. So we modify the each call to `localize` so that it includes
* the source file name.
*
* > nls.localize("my.key", args)
* > nls.localize(key, args)
*
* becomes
*
* > nls.localize("source/file.js", "my.key", args)
* > nls.localize("source/file.js", key, args)
* @param callback
*/
function injectSourcePath(callback) {
function injectSourcePath(monacoVersion, callback) {
rimraf(monacoModDir, function (err) {
if (err) {
callback(err);
Expand All @@ -88,26 +85,46 @@ function injectSourcePath(callback) {
if (file.endsWith(".js")) {
const vsPath = path.relative(monacoModEsmDir, path.dirname(file)).replace(/\\/g, "/");
const transPath = vsPath + "/" + path.basename(file, ".js");
//1a. Find localize( : localize( localize2( .localize2( etc (but NOT function localize() )
//1b. Change to localize("path/to/translation/item", xxxx
//2a. Find localize.apply(
//2b. Change to localize.apply("path/to/translation/item", xxxxx
replaceInFile({
files: file,
from: [
/localize\(/g,
/localize\.apply\(\s*([^,]+)\s*,\s*\[/g,
/(?<!function )(localize\d*?\s*?\()/g, //match:- .localize( : localize( localize2( .localize2( etc
/(localize\d*?\.apply)\(\s*([^,]+)\s*,\s*\[/g,
],
to: [
`localize('${transPath}', `,
`localize.apply($1, ['${transPath}', `,
`$1 '${transPath}', `,
`$1($2, ['${transPath}', `,
],
});
if(file.endsWith("services\\htmlLinks.js")) {
//workaround a bug i cant understand - findDocumentLinks is called with null document & an exception occurs
if (file.endsWith("iconLabels.js")) {
//if a translation is missing, prevent error in `stripIcons` (ensures command palette is populated)
replaceInFile({
files: file,
from: [
/stripIcons\(text\)\s?{/g
],
to: [
`stripIcons(text) {\n text = text || "";`
],
});
} else if (file.search(/[\\|\/]editor[\\|\/]editor.api.js$/) > -1) {
//insert version:
//1. Find const api = createMonacoBaseAPI();
//2. Insert Object.defineProperty(api, 'version', {get: function() { return 'x.y.z' }});
// export const version = api.version;
replaceInFile({
files: file,
from: [
/(export.*?function.*?findDocumentLinks.*?{)/g
/(const\s+?)(\w*?)(\s+?=\s+?createMonacoBaseAPI\(\).*$)/gm
],
to: [
`$1\n if(!document) return [];`
`$1$2$3` +
`\nObject.defineProperty($2, 'version', {get: function() { return '${monacoVersion}' }});` +
`\nexport const version = $2.version;`
],
});
}
Expand Down Expand Up @@ -180,44 +197,27 @@ function createScript(lang, locale) {
const sortedLocale = {};
for (const key of sortedKeys) {
sortedLocale[key] = locale[key];
// sortedLocale[safeKey(key)] = locale[key];
}
return "this.MonacoEnvironment = this.MonacoEnvironment || {}; this.MonacoEnvironment.Locale = {language: '" + lang + "', data: " + JSON.stringify(sortedLocale, null, 4) + "};";
return `window.MonacoEnvironment = window.MonacoEnvironment || {};
window.MonacoEnvironment.Locale = window.MonacoLocale = {
language: '${lang}',
data: ${JSON.stringify(sortedLocale, null, 2)}
};`;
}

async function main() {
const pkg = await readPackage("package.json");
const monacoVersion = pkg.devDependencies["monaco-editor"];
const monacoSemver = semver(monacoVersion);
const esm = `import * as monaco from "monaco-editor-esm-i18n";
if(monaco && monaco.monaco) {
monaco = monaco.monaco;
}
if(typeof window!="undefined") {
if(!window.monaco) window.monaco = monaco
}
const monacoDep = pkg.devDependencies["monaco-editor"];
const monacoSemver = semver(monacoDep);
const monacoVersion = monacoSemver.toString();

if(typeof self!="undefined") {
if(!self.monaco) self.monaco = monaco
}
monaco.version = "${monacoSemver.toString()}";
export {
monaco
};
`
//mkDirSafe(tempDir);
mkdirp.sync(tempDir);
var fn = path.join(tempDir, "monaco-editor-esm-i18n.js");
fs.writeFileSync(fn, esm);
mkdirp.sync(gitDir);
injectSourcePath(err => {
injectSourcePath(monacoVersion, err => {
if (err) throw err;
gitPullOrClone(vsCodeRepository, vsCodeLocDir, function (err) {
if (err) throw err;

fs.readdir(vsCodeLocI18nDir, (err, langDirs) => {
if (err) throw err;
langDirs.forEach(langDir => {
Expand Down
Loading

0 comments on commit 63c6bb7

Please sign in to comment.