diff --git a/package-lock.json b/package-lock.json index 081ac824..6702c553 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "monaco-editor", - "version": "0.37.0", + "version": "0.37.1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "monaco-editor", - "version": "0.37.0", + "version": "0.37.1", "hasInstallScript": true, "license": "MIT", "devDependencies": { diff --git a/website/src/runner/index.ts b/website/src/runner/index.ts index 8bc551be..ed1fdd07 100644 --- a/website/src/runner/index.ts +++ b/website/src/runner/index.ts @@ -51,8 +51,10 @@ async function initialize(state: IPreviewState) { document.body.innerHTML += state.html; + const js = massageJs(state.js); + try { - eval(state.js); + eval(js); } catch (err) { const pre = document.createElement("pre"); pre.appendChild( @@ -61,3 +63,35 @@ async function initialize(state: IPreviewState) { document.body.insertBefore(pre, document.body.firstChild); } } + +(globalThis as any).bindModelToCodeStr = function bindModel( + model: any, + codeStringName: string +) { + model.onDidChangeContent(() => { + const value = model.getValue(); + window.parent.postMessage( + { kind: "update-code-string", codeStringName, value }, + "*" + ); + }); +}; + +function massageJs(js: string) { + /* + Alternate experimental syntax: // bind to code string: `editor.getModel()` -> codeString + + const bindToCodeStringRegexp = /\/\/ bind to code string: `(.*?)` -> (.*?)(\n|$)/g; + js = js.replaceAll(bindToCodeStringRegexp, (match, p1, p2) => { + return `globalThis.bindModelToCodeStr(${p1}, ${JSON.stringify(p2)})\n`; + }); + */ + + const setFromRegexp = /\/*\Wset from `(.*?)`:\W*\//g; + for (const m of js.matchAll(setFromRegexp)) { + const p1 = m[1]; + const target = JSON.stringify("set from `" + p1 + "`"); + js += `\n try { globalThis.bindModelToCodeStr(${p1}, ${target}); } catch (e) { console.error(e); }`; + } + return js; +} diff --git a/website/src/website/data/playground-samples/creating-the-diffeditor/hello-diff-world/sample.js b/website/src/website/data/playground-samples/creating-the-diffeditor/hello-diff-world/sample.js index 83089074..84d8ba80 100644 --- a/website/src/website/data/playground-samples/creating-the-diffeditor/hello-diff-world/sample.js +++ b/website/src/website/data/playground-samples/creating-the-diffeditor/hello-diff-world/sample.js @@ -1,8 +1,18 @@ -var originalModel = monaco.editor.createModel("heLLo world!", "text/plain"); -var modifiedModel = monaco.editor.createModel("hello orlando!", "text/plain"); +const originalModel = monaco.editor.createModel( + /* set from `originalModel`: */ `hello world`, + "text/plain" +); +const modifiedModel = monaco.editor.createModel( + /* set from `modifiedModel`: */ `Hello World!`, + "text/plain" +); -var diffEditor = monaco.editor.createDiffEditor( - document.getElementById("container") +const diffEditor = monaco.editor.createDiffEditor( + document.getElementById("container"), + { + originalEditable: true, + automaticLayout: true, + } ); diffEditor.setModel({ original: originalModel, diff --git a/website/src/website/data/playground-samples/creating-the-editor/hello-world/sample.js b/website/src/website/data/playground-samples/creating-the-editor/hello-world/sample.js index c68ae059..7beb8e40 100644 --- a/website/src/website/data/playground-samples/creating-the-editor/hello-world/sample.js +++ b/website/src/website/data/playground-samples/creating-the-editor/hello-world/sample.js @@ -1,10 +1,10 @@ -const text = `function hello() { +const value = /* set from `myEditor.getModel()`: */ `function hello() { alert('Hello world!'); }`; // Hover on each property to see its docs! -monaco.editor.create(document.getElementById("container"), { - value: text, +const myEditor = monaco.editor.create(document.getElementById("container"), { + value, language: "javascript", automaticLayout: true, }); diff --git a/website/src/website/pages/playground/PlaygroundModel.ts b/website/src/website/pages/playground/PlaygroundModel.ts index 7cb6cbf0..85cb1313 100644 --- a/website/src/website/pages/playground/PlaygroundModel.ts +++ b/website/src/website/pages/playground/PlaygroundModel.ts @@ -162,13 +162,19 @@ export class PlaygroundModel { return; } } - this.debouncer.run(() => { + const action = () => { this.isDirty = false; lastState = state; for (const handler of this._previewHandlers) { handler.handlePreview(state); } - }); + }; + + if (state.key !== lastState.key) { + action(); // sync update + } else { + this.debouncer.run(action); + } }, { name: "update preview" } ), @@ -178,6 +184,17 @@ export class PlaygroundModel { let disposable: Disposable | undefined = undefined; waitForLoadedMonaco().then((m) => { + this.dispose.track( + monaco.editor.addEditorAction({ + id: "reload", + label: "Reload", + run: (editor, ...args) => { + this.reload(); + }, + keybindings: [monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter], + }) + ); + const options = monaco.languages.typescript.javascriptDefaults.getCompilerOptions(); monaco.languages.typescript.javascriptDefaults.setDiagnosticsOptions( @@ -222,6 +239,26 @@ export class PlaygroundModel { }); } + setCodeString(codeStringName: string, value: string) { + function escapeRegexpChars(str: string) { + return str.replace(/[-[\]/{}()*+?.\\^$|]/g, "\\$&"); + } + + const regexp = new RegExp( + "(\\b" + + escapeRegexpChars(codeStringName) + + ":[^\\w`]*`)([^`\\\\]|\\n|\\\\\\\\|\\\\`)*`" + ); + debugger; + const js = this.js; + const str = value.replaceAll("\\", "\\\\").replaceAll("`", "\\`"); + const newJs = js.replace(regexp, "$1" + str + "`"); + const autoReload = this.settings.autoReload; + this.settings.autoReload = false; + this.js = newJs; + this.settings.autoReload = autoReload; + } + public showSettingsDialog(): void { this.settingsDialogModel = new SettingsDialogModel( this.settings.settings diff --git a/website/src/website/pages/playground/PlaygroundPageContent.tsx b/website/src/website/pages/playground/PlaygroundPageContent.tsx index 3c1039d5..cdd953cf 100644 --- a/website/src/website/pages/playground/PlaygroundPageContent.tsx +++ b/website/src/website/pages/playground/PlaygroundPageContent.tsx @@ -448,7 +448,16 @@ class Editor extends React.Component<{ () => { const value = this.props.value.get(); if (!this.ignoreChange) { - this.editor!.setValue(value); + this.model.pushEditOperations( + null, + [ + { + range: this.model.getFullModelRange(), + text: value, + }, + ], + () => null + ); } }, { name: "update text" } @@ -458,6 +467,7 @@ class Editor extends React.Component<{ componentWillUnmount() { this.disposables.forEach((d) => d.dispose()); + this.model.dispose(); } } diff --git a/website/src/website/pages/playground/Preview.tsx b/website/src/website/pages/playground/Preview.tsx index e893c472..a6abdca0 100644 --- a/website/src/website/pages/playground/Preview.tsx +++ b/website/src/website/pages/playground/Preview.tsx @@ -48,6 +48,21 @@ export class Preview targetOrigin: "*", }); }); + window.addEventListener("message", (e) => { + if (e.source !== iframe.contentWindow) { + return; + } + const data = e.data as + | { + kind: "update-code-string"; + codeStringName: string; + value: string; + } + | { kind: "" }; + if (data.kind === "update-code-string") { + this.props.model.setCodeString(data.codeStringName, data.value); + } + }); }; componentDidMount() {