diff --git a/.azure-pipelines/publish-nightly.yml b/.azure-pipelines/publish-nightly.yml
index 4a757c36..e5c622eb 100644
--- a/.azure-pipelines/publish-nightly.yml
+++ b/.azure-pipelines/publish-nightly.yml
@@ -23,6 +23,16 @@ resources:
ref: main
endpoint: Monaco
+parameters:
+ - name: vscodeRef
+ displayName: The VS Code commit id.
+ type: string
+ default: 'main'
+ - name: prereleaseVersion
+ displayName: The prerelease version.
+ type: string
+ default: 'dev-${today}'
+
extends:
template: azure-pipelines/npm-package/pipeline.yml@templates
parameters:
@@ -31,10 +41,17 @@ extends:
workingDirectory: $(Build.SourcesDirectory)/dependencies/vscode/out-monaco-editor-core
testPlatforms: []
buildSteps:
+ - script: sudo apt install -y libkrb5-dev
+ displayName: Install libkrb5-dev
+
- script: npm ci
displayName: Install NPM dependencies
- script: yarn ts-node ./scripts/ci/monaco-editor-core-prepare nightly
+ env:
+ VSCODE_REF: ${{ parameters.vscodeRef }}
+ PRERELEASE_VERSION: ${{ parameters.prereleaseVersion }}
+ retryCountOnTaskFailure: 5
displayName: Setup, Build & Test monaco-editor-core
tag: next
@@ -50,6 +67,10 @@ extends:
displayName: Install NPM dependencies
- script: yarn ts-node ./scripts/ci/monaco-editor-prepare nightly
+ env:
+ VSCODE_REF: ${{ parameters.vscodeRef }}
+ PRERELEASE_VERSION: ${{ parameters.prereleaseVersion }}
+ retryCountOnTaskFailure: 5
displayName: Setup, Build & Test monaco-editor
tag: next
diff --git a/.azure-pipelines/publish-stable.yml b/.azure-pipelines/publish-stable.yml
index d8cb4813..f2aac055 100644
--- a/.azure-pipelines/publish-stable.yml
+++ b/.azure-pipelines/publish-stable.yml
@@ -37,6 +37,9 @@ extends:
workingDirectory: $(Build.SourcesDirectory)/dependencies/vscode/out-monaco-editor-core
testPlatforms: []
buildSteps:
+ - script: sudo apt install -y libkrb5-dev
+ displayName: Install libkrb5-dev
+
- script: npm ci
displayName: Install NPM dependencies
@@ -68,9 +71,11 @@ extends:
buildSteps:
- script: npm ci
displayName: Install NPM dependencies
+ workingDirectory: $(Build.SourcesDirectory)/webpack-plugin
- script: npm run compile
displayName: Build plugin
+ workingDirectory: $(Build.SourcesDirectory)/webpack-plugin
tag: latest
ghCreateTag: false
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cfb85827..c315421d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,7 +18,7 @@ jobs:
uses: actions/cache@v2
with:
path: '**/node_modules'
- key: ${{ runner.os }}-cacheNodeModules2-${{ hashFiles('**/package-lock.json') }}
+ key: ${{ runner.os }}-cacheNodeModules2-${{ hashFiles('**/package-lock.json', '**/package.json') }}
restore-keys: ${{ runner.os }}-cacheNodeModules2-
- name: execute `npm ci` (1)
diff --git a/.github/workflows/publish/computeState.js b/.github/workflows/publish/computeState.js
deleted file mode 100644
index 6eb18167..00000000
--- a/.github/workflows/publish/computeState.js
+++ /dev/null
@@ -1,103 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-//@ts-check
-
-const fs = require('fs');
-const cp = require('child_process');
-const packageJson = require('../../../package.json');
-
-if (process.argv.length !== 4) {
- console.error(`usage: node computeState.js <"workflow_dispatch"|"schedule"> <"true"|"false">`);
- process.exit(1);
-}
-
-const EVENT_NAME = /** @type {'workflow_dispatch'|'schedule'} */ (process.argv[2]);
-const STR_NIGHTLY = /** @type {'true'|'false'|''} */ (process.argv[3]);
-
-if (!/^((workflow_dispatch)|(schedule))$/.test(EVENT_NAME)) {
- console.error(`usage: node computeState.js <"workflow_dispatch"|"schedule"> <"true"|"false">`);
- process.exit(2);
-}
-
-if (!/^((true)|(false)|())$/.test(STR_NIGHTLY)) {
- console.error(`usage: node computeState.js <"workflow_dispatch"|"schedule"> <"true"|"false">`);
- process.exit(3);
-}
-
-const NIGHTLY = EVENT_NAME === 'schedule' || STR_NIGHTLY === 'true';
-
-const distTag = NIGHTLY ? 'next' : 'latest';
-
-const latestMonacoEditorVersion = npmGetLatestVersion('monaco-editor');
-const version = (() => {
- if (NIGHTLY) {
- const pieces = latestMonacoEditorVersion.split('.');
- const minor = parseInt(pieces[1], 10);
- const date = new Date();
- const yyyy = date.getUTCFullYear();
- const mm = String(date.getUTCMonth() + 1).padStart(2, '0');
- const dd = String(date.getUTCDate()).padStart(2, '0');
- return `0.${minor + 1}.0-dev.${yyyy}${mm}${dd}`;
- } else {
- return packageJson.version;
- }
-})();
-
-const vscodeBranch = (() => {
- if (NIGHTLY) {
- return 'main';
- } else {
- return packageJson.vscode;
- }
-})();
-
-const skipMonacoEditorCore = (() => {
- return /** @type {'true'|'false'} */ (String(npmExists('monaco-editor-core', version)));
-})();
-
-const skipMonacoEditor = (() => {
- return /** @type {'true'|'false'} */ (String(npmExists('monaco-editor', version)));
-})();
-
-console.log(`
-::set-output name=dist_tag::${distTag}
-::set-output name=version::${version}
-::set-output name=vscode_branch::${vscodeBranch}
-::set-output name=skip_monaco_editor_core::${skipMonacoEditorCore}
-::set-output name=skip_monaco_editor::${skipMonacoEditor}
-`);
-
-/**
- * @param {string} packageName
- * @returns {string}
- */
-function npmGetLatestVersion(packageName) {
- const output = cp.execSync(`npm show ${packageName} version`).toString();
- const version = output.split(/\r\n|\r|\n/g)[0];
- if (!/^0\.(\d+)\.(\d+)$/.test(version)) {
- console.error(`version ${version} does not match 0.x.y`);
- process.exit(1);
- }
- return version;
-}
-
-/**
- * @param {string} packageName
- * @param {string} version
- * @returns {boolean}
- */
-function npmExists(packageName, version) {
- try {
- const output = cp.execSync(`npm show ${packageName}@${version} version`).toString();
- const result = output.split(/\r\n|\r|\n/g)[0];
- if (result.trim().length === 0) {
- return false;
- }
- return true;
- } catch (err) {
- return false;
- }
-}
diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml
index 7508da49..1ff6c69a 100644
--- a/.github/workflows/website.yml
+++ b/.github/workflows/website.yml
@@ -1,23 +1,34 @@
name: Publish Website
on:
- push:
- tags:
- - 'v*'
- # enable users to manually trigger with workflow_dispatch
+ schedule:
+ - cron: 0 23 * * *
workflow_dispatch: {}
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: read
+ pages: write
+ id-token: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: 'pages'
+ cancel-in-progress: false
+
jobs:
- publish-website:
- name: Publish Website
+ deploy:
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@dc323e67f16fb5f7663d20ff7941f27f5809e9b6 # pin@v2
-
+ - name: Checkout
+ uses: actions/checkout@v3
- uses: actions/setup-node@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561 # pin@v2
with:
node-version: 16
-
- name: Cache node modules
id: cacheNodeModules
uses: actions/cache@v2
@@ -25,11 +36,9 @@ jobs:
path: '**/node_modules'
key: ${{ runner.os }}-cacheNodeModules2-${{ hashFiles('**/package-lock.json') }}
restore-keys: ${{ runner.os }}-cacheNodeModules2-
-
- name: execute `npm ci` (1)
if: ${{ steps.cacheNodeModules.outputs.cache-hit != 'true' }}
run: npm ci
-
- name: Build
run: npm run build-monaco-editor
@@ -45,8 +54,13 @@ jobs:
working-directory: website
run: yarn run build
- - name: Upload website to github pages
- uses: peaceiris/actions-gh-pages@bd8c6b06eba6b3d25d72b7a1767993c0aeee42e7 # pin@v3
+ - name: Setup Pages
+ uses: actions/configure-pages@v3
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@v1
with:
- github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./website/dist
+ # Upload entire repository
+ path: './website/dist'
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@v2
diff --git a/.vscode/launch.json b/.vscode/launch.json
index 2d19c833..44c09c98 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -15,6 +15,12 @@
"order": 1
}
},
+ {
+ "name": "Website",
+ "type": "chrome",
+ "request": "launch",
+ "url": "http://localhost:8080/"
+ },
{
// Clone VS Code and make sure the task "Launch Http Server" runs.
// Then the editor is build from sources.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b4a60415..194148df 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,65 @@
# Monaco Editor Changelog
+## [0.42.0]
+
+- Uses new diff editor widget by default. Use `experimental.useVersion2: false` to use the old widget. The old widget will be replaced in the next update.
+- Diff editor uses inline mode by default when width is too small. Use the config option `useInlineViewWhenSpaceIsLimited` to control this behavior.
+- Fixes broken language features when a model is created before the editor.
+
+## [0.41.0]
+
+- `IDiffEditor.diffReviewNext` was renamed to `IDiffEditor.accessibleDiffViewerNext`.
+- `IDiffEditor.diffReviewPrev` was renamed to `IDiffEditor.accessibleDiffViewerPrev`.
+- Introduces `InlineCompletionsProvider.yieldsToGroupIds` to allows inline completion providers to yield to other providers.
+- Bugfixes
+
+Contributions to `monaco-editor`:
+
+- [@claylibrarymarket](https://github.com/claylibrarymarket): Fix Twig's plain text class expression [PR #4063](https://github.com/microsoft/monaco-editor/pull/4063)
+- [@FossPrime (Ray Foss)](https://github.com/FossPrime): Use new GitHub pages workflow [PR #4000](https://github.com/microsoft/monaco-editor/pull/4000)
+- [@leandrocp (Leandro Pereira)](https://github.com/leandrocp): Elixir - Add support for multi-letter uppercase sigils [PR #4041](https://github.com/microsoft/monaco-editor/pull/4041)
+- [@philippleidig (PhilippLe)](https://github.com/philippleidig): Add TwinCAT file support for structured text (st) language [PR #3315](https://github.com/microsoft/monaco-editor/pull/3315)
+- [@remcohaszing (Remco Haszing)](https://github.com/remcohaszing)
+ - Add mdx language [PR #3096](https://github.com/microsoft/monaco-editor/pull/3096)
+ - Export custom TypeScript worker variables [PR #3488](https://github.com/microsoft/monaco-editor/pull/3488)
+ - Document some basic concepts [PR #4087](https://github.com/microsoft/monaco-editor/pull/4087)
+
+## [0.40.0]
+
+- Support for Glyph Margin Widgets
+- Removes `getDiffLineInformationForOriginal` and `getDiffLineInformationForModified` from `IDiffEditor`
+- `createTrustedTypesPolicy` is optional now
+- New option `IModelDecorationOptions.shouldFillLineOnLineBreak`
+- New option `EditorOptions.readOnlyMessage`
+
+## [0.39.0]
+
+- New method `Environment.createTrustedTypesPolicy` to override trusted types handling.
+- Bugfixes
+
+Contributions to `monaco-editor`:
+
+- [@dlitsman (Dmitry Litsman)](https://github.com/dlitsman): Extend the "Rendering Glyphs In The Margin" example to include a transparent color note. [PR #3945](https://github.com/microsoft/monaco-editor/pull/3945)
+- [@dneto0 (David Neto)](https://github.com/dneto0): Avoid a hack in the WGSL lexer [PR #3887](https://github.com/microsoft/monaco-editor/pull/3887)
+- [@spahnke (Sebastian Pahnke)](https://github.com/spahnke)
+ - [JS, TS] Add Monarch support for private identifiers [PR #3919](https://github.com/microsoft/monaco-editor/pull/3919)
+ - [JS] Add static keyword [PR #3922](https://github.com/microsoft/monaco-editor/pull/3922)
+- [@titouanmathis (Titouan Mathis)](https://github.com/titouanmathis): [Webpack Plugin] Fix CJS being injected in ESM files [PR #3933](https://github.com/microsoft/monaco-editor/pull/3933)
+
+## [0.38.0]
+
+- `diffAlgorithm` values changed: `smart` -> `legacy`, `experimental` -> `advanced`
+- New `registerEditorOpener` API
+- New property `IViewZone.showInHiddenAreas` to show view zones in hidden areas
+- New properties `InlineCompletions.suppressSuggestions` and `InlineCompletions.enableForwardStability`
+- Bugfixes
+
+Contributions to `monaco-editor`:
+
+- [@dneto0 (David Neto)](https://github.com/dneto0): Add WebGPU Shading Language tokenizer, with tests [PR #3884](https://github.com/microsoft/monaco-editor/pull/3884)
+- [@kisstkondoros (Tamas Kiss)](https://github.com/kisstkondoros): Fix reference error in convert method of OutlineAdapter [PR #3924](https://github.com/microsoft/monaco-editor/pull/3924)
+- [@tamayika](https://github.com/tamayika): Change moduleResolution to node16 and adopt TS 5.0 [PR #3860](https://github.com/microsoft/monaco-editor/pull/3860)
+
## [0.37.1]
- Fixes Inline Completions feature
diff --git a/MAINTAINING.md b/MAINTAINING.md
index 9b71b787..deb5aee9 100644
--- a/MAINTAINING.md
+++ b/MAINTAINING.md
@@ -2,29 +2,26 @@
(For maintainers only)
-- [P1 Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+-label%3Afeature-request+-label%3Aquestion+-label%3Aupstream+-label%3A%22help+wanted%22+-label%3A%22info-needed%22+-label%3A%22as-designed%22+-label%3Abug+-label%3A*question+)
-- [Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+no%3Aassignee+-label%3Afeature-request+-label%3Aquestion+-label%3Aupstream+-label%3A%22help+wanted%22+-label%3A%22info-needed%22+-label%3A%22as-designed%22+)
+Make sure every unassigned issue is labeled properly:
-## Updating TypeScript
+- [Inbox Queue](https://github.com/microsoft/monaco-editor/issues?q=is%3Aissue+is%3Aopen+no%3Aassignee+-label%3Afeature-request+-label%3Aupstream+-label%3A%22info-needed%22++-label%3Abug+)
-- change typescript's version in `package.json`.
-- execute `npm install .`
-- execute `npm run import-typescript`
-- adopt new APIs
+## Publishing a stable build monaco-editor build
-## Shipping a new monaco-editor npm module
+- Make sure there exists a nightly build from the VS Code commit the stable build should be built from
+- [Compare Last Stable With Nightly](https://microsoft.github.io/monaco-editor/playground.html?source=v0.40.0-dev.20230704#XQAAAAJWBgAAAAAAAABBqQkHQ5NjdMjwa-jY7SIQ9S7DNlzs5W-mwj0fe1ZCDRFc9ws9XQE0SJE1jc2VKxhaLFIw9vEWSxW3yscw_SM66BuzMt6m3zM8Thvb-XSMR_Da8IdBq3FOgly-7-xuaHSi_yUg58ZO9Mr-RKT7GyHzHoU8B9N7P-uTzmCdhT2Vv-4gNRbWSMQCUPrfmzFCkSH_WR2Vc8LGx2m0uRSFiJu82B1mS0RM-eriU9PTOqAgBrlPUMTU44VrHyVOqgs5BFrUuUHwGDzUHxeNuUk-kg2u70awQLQ83wD4o2EbSefqfIWkk2Yi0mnUS903tLA4V17MD_6OHIRArunMPL6E14ZCW0_Aql21F62Fmz--i_pNbqBIpSlBbZl6LzA1HzNsoDH7i2rn1qAw55L1MjwOU4QQMCJfffmJznAbGoZWkXK91OPYlOGNHNGG-MPUFsY5JSjLfvCWOvXypW9ZVkBZMo1qUbtE135CLqbaBiw52f3eOPBTru3IL_wT__ciAFI5NDiVOeN8V9zqkzbwiFNeQyZcjxmrDLjYTPJpao0dG61Um0w4FpVud8p77bjoAdEfG8JNO97W4cawj0HvMfvcZS81P7IsijZqA7KyVsdq79iCJQuMO31aS86cM4GTNT0TvdI7p62uiEmm9X6ZjF8oSLxW87Vt0oYAZ5wBePqdN6FwNO6BWACt2Ep9i5Q6h-mOy7_JWOiPTOH0Zz3v6SaNhjxJwZAqNG3FqvRTgLg-au-pfa8PD0No3U15UyWeqrVXSthGFghLJ16ppEwFCqFfQ6Vr0leZtSZXyk41-t5ZKMG-KQjzq1XE2PnuyOz60nV4GaYvGlMHrXz-XrEqb2kwNf_pBee0)
+ - Update [package.json](./package.json)
+ - set `version` to next stable
+ - set `vscodeRef` to _vscodeCommitId_
+ - update `devDependencies.monaco-editor-core` to _version_
+ - Run `npm install` to update lockfile
+ - Update [CHANGELOG.md](./CHANGELOG.md)
+ - API Changes / Breaking Changes / New and noteworthy
+ - Thank you ([use this tool](https://tools.code.visualstudio.com/acknowledgement))
+ - Commit
+ - [Trigger build](https://dev.azure.com/monacotools/Monaco/_build?definitionId=416)
-- update `package.json` and bump `"version"` as necessary
-- update `package.json` and edit `"vscode"` to point to the vscode repo commit that should be shipped at `monaco-editor-core` (both `monaco-editor-core` and `monaco-editor` will be published under the same version defined in `package.json`).
-- write entry in `CHANGELOG.md`
- - API Changes / Breaking Changes / New and noteworthy
- - Thank you ([use this tool](https://vscode-tools.azurewebsites.net/acknowledgement/))
-- trigger a build using [`Publish to npm`](https://github.com/microsoft/monaco-editor/actions/workflows/publish.yml) and type false when asked "is nightly?"
-- if the publish succeeded, run `git tag 0.x.y` and `git push origin 0.x.y`
-- edit `package.json` and update the `"monaco-editor-core"` dev dependency.
-- run `npm install`
-
-#### 8. Publish new webpack plugin
+#### Publish new webpack plugin
- **TBD**
- https://github.com/microsoft/monaco-editor/tree/main/webpack-plugin
@@ -41,3 +38,10 @@
- use `npm version major`
- publish using `npm publish`
- remember to push tags upstream
+
+## Updating TypeScript
+
+- change typescript's version in `package.json`.
+- execute `npm install .`
+- execute `npm run import-typescript`
+- adopt new APIs
diff --git a/README.md b/README.md
index 297e8cf9..eee79f77 100644
--- a/README.md
+++ b/README.md
@@ -31,13 +31,39 @@ You will get:
It is recommended to develop against the `dev` version, and in production to use the `min` version.
+## Concepts
+
+Monaco editor is best known for being the text editor that powers VS Code. However, it's a bit more nuanced. Some basic understanding about the underlying concepts is needed to use Monaco editor effectively.
+
+### Models
+
+Models are at the heart of Monaco editor. It's what you interact with when managing content. A model represents a file that has been opened. This could represent a file that exists on a file system, but it doesn't have to. For example, the model holds the text content, determines the language of the content, and tracks the edit history of the content.
+
+### URIs
+
+Each model is identified by a URI. This is why it's not possible for two models to have the same URI. Ideally when you represent content in Monaco editor, you should think of a virtual file system that matches the files your users are editing. For example, you could use `file:///` as a base path. If a model is created without a URI, its URI will be `inmemory://model/1`. The number increases as more models are created.
+
+### Editors
+
+An editor is a user facing view of the model. This is what gets attached to the DOM and what your users see visually. Typical editor operations are displaying a model, managing the view state, or executing actions or commands.
+
+### Providers
+
+Providers provide smart editor features. For example, this includes completion and hover information. It is not the same as, but often maps to [language server protocol](https://microsoft.github.io/language-server-protocol) features.
+
+Providers work on models. Some smart features depends on the file URI. For example, for TypeScript to resolve imports, or for JSON IntelliSense to determine which JSON schema to apply to which model. So it's important to choose proper model URIs.
+
+### Disposables
+
+Many Monaco related objects often implement the `.dispose()` method. This method is intended to perform cleanups when a resource is no longer needed. For example, calling `model.dispose()` will unregister it, freeing up the URI for a new model. Editors should be disposed to free up resources and remove their model listeners.
+
## Documentation
- Learn how to integrate the editor with these [complete samples](./samples/).
- [Integrate the AMD version](./docs/integrate-amd.md).
- [Integrate the ESM version](./docs/integrate-esm.md)
- Learn how to use the editor API and try out your own customizations in the [playground](https://microsoft.github.io/monaco-editor/playground.html).
-- Explore the [API docs](https://microsoft.github.io/monaco-editor/docs.html) or read them straight from [`monaco.d.ts`](https://github.com/microsoft/monaco-editor/blob/main/website/typedoc/monaco.d.ts).
+- Explore the [API docs](https://microsoft.github.io/monaco-editor/docs.html) or read them straight from [`monaco.d.ts`](https://microsoft.github.io/monaco-editor/node_modules/monaco-editor/monaco.d.ts).
- Read [this guide](https://github.com/microsoft/monaco-editor/wiki/Accessibility-Guide-for-Integrators) to ensure the editor is accessible to all your users!
- Create a Monarch tokenizer for a new programming language [in the Monarch playground](https://microsoft.github.io/monaco-editor/monarch.html).
- Ask questions on [StackOverflow](https://stackoverflow.com/questions/tagged/monaco-editor)! Search open and closed issues, there are a lot of tips in there!
diff --git a/build/importTypescript.ts b/build/importTypescript.ts
index c2e67267..84b7edc8 100644
--- a/build/importTypescript.ts
+++ b/build/importTypescript.ts
@@ -37,6 +37,16 @@ export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
let tsServices = fs.readFileSync(path.join(TYPESCRIPT_LIB_SOURCE, 'typescript.js')).toString();
+ tsServices = tsServices
+ .replace(
+ 'const path = matchedStar ? subst.replace("*", matchedStar) : subst;',
+ 'const path = matchedStar ? subst.replace("*", matchedStar) : subst; // CodeQL [SM02383] This is a false positive, the code is from the TypeScript compiler'
+ )
+ .replace(
+ 'return key.replace("*", matchedStar);',
+ 'return key.replace("*", matchedStar); // CodeQL [SM02383] This is a false positive, the code is from the TypeScript compiler'
+ );
+
// The output from this build will only be accessible via ESM; rather than removing
// references to require/module, define them as dummy variables that bundlers will ignore.
// The TS code can figure out that it's not running under Node even with these defined.
diff --git a/build/simpleserver.ts b/build/simpleserver.ts
index 76224554..bdfe8e51 100644
--- a/build/simpleserver.ts
+++ b/build/simpleserver.ts
@@ -10,8 +10,6 @@ import yaserver = require('yaserver');
import { REPO_ROOT } from './utils';
import { ensureDir } from './fs';
-const WEBSITE_GENERATED_PATH = path.join(REPO_ROOT, 'website/playground/new-samples');
-
generateTestSamplesTask();
const SERVER_ROOT = path.normalize(path.join(REPO_ROOT, '../'));
@@ -53,106 +51,6 @@ function generateTestSamplesTask() {
const destination = path.join(REPO_ROOT, 'test/manual/generated/all-samples.js');
ensureDir(path.dirname(destination));
fs.writeFileSync(destination, prefix + JSON.stringify(samples, null, '\t') + suffix);
-
- /** @type {{ chapter: string; name: string; id: string; path: string; }[]} */
- const PLAY_SAMPLES = require(path.join(WEBSITE_GENERATED_PATH, 'all.js')).PLAY_SAMPLES;
- /** @type {{ path: string; name: string; }[]} */
- const locations = [];
- for (let i = 0; i < PLAY_SAMPLES.length; i++) {
- const sample = PLAY_SAMPLES[i];
- const sampleId = sample.id;
- const samplePath = path.join(WEBSITE_GENERATED_PATH, sample.path);
-
- const html = fs.readFileSync(path.join(samplePath, 'sample.html'));
- const js = fs.readFileSync(path.join(samplePath, 'sample.js'));
- const css = fs.readFileSync(path.join(samplePath, 'sample.css'));
-
- const result = [
- '',
- '',
- '',
- '
',
- ' ',
- ' ',
- '',
- '',
- '',
- '[<< BACK] ',
- 'THIS IS A GENERATED FILE VIA `npm run simpleserver`',
- '',
- '',
- '',
- '',
- '
';
+ div.innerHTML = // CodeQL [SM03712] This code is not deployed and serves as local test code. No risk of malicious input.
+ '
' + // CodeQL [SM03712] This code is not deployed and serves as local test code. No risk of malicious input.
+ renderLoadingOptions(true) + // CodeQL [SM03712] This code is not deployed and serves as local test code. No risk of malicious input.
+ (isRelease ? '' : `
${renderLoadingOptions(false)}`) + // CodeQL [SM03712] This code is not deployed and serves as local test code. No risk of malicious input.
+ '
'; // CodeQL [SM03712] This code is not deployed and serves as local test code. No risk of malicious input.
document.body.appendChild(div);
@@ -47,7 +47,7 @@
for (let i = 0; i < aElements.length; i++) {
let aElement = aElements[i];
if (aElement.className === 'loading-opts') {
- aElement.href += window.location.search;
+ aElement.href += window.location.search; // CodeQL [SM01507] This code is not deployed and serves as local test code. No risk of malicious input.
}
}
})();
diff --git a/test/manual/index.js b/test/manual/index.js
index f18a3d5e..b1942b89 100644
--- a/test/manual/index.js
+++ b/test/manual/index.js
@@ -1,4 +1,4 @@
-///
+///
define(['require', './samples'], function (require, SAMPLES) {
const domutils = require('vs/base/browser/dom');
@@ -20,16 +20,10 @@ define(['require', './samples'], function (require, SAMPLES) {
renderWhitespace: true
});
- editor.addCommand(
- {
- ctrlCmd: true,
- key: 'F9'
- },
- function (ctx, args) {
- alert('Command Running!!');
- console.log(ctx);
- }
- );
+ editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.F9, function (ctx, args) {
+ alert('Command Running!!');
+ console.log(ctx);
+ });
editor.addAction({
id: 'my-unique-id',
diff --git a/webpack-plugin/package-lock.json b/webpack-plugin/package-lock.json
index a2fca095..32b06e28 100644
--- a/webpack-plugin/package-lock.json
+++ b/webpack-plugin/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "monaco-editor-webpack-plugin",
- "version": "7.0.1",
+ "version": "7.1.0",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "monaco-editor-webpack-plugin",
- "version": "7.0.1",
+ "version": "7.1.0",
"license": "MIT",
"dependencies": {
"loader-utils": "^2.0.2"
diff --git a/webpack-plugin/package.json b/webpack-plugin/package.json
index 114d315c..145dfc8b 100644
--- a/webpack-plugin/package.json
+++ b/webpack-plugin/package.json
@@ -1,6 +1,6 @@
{
"name": "monaco-editor-webpack-plugin",
- "version": "7.0.1",
+ "version": "7.1.0",
"description": "A webpack plugin for the Monaco Editor",
"main": "out/index.js",
"typings": "./out/index.d.ts",
diff --git a/webpack-plugin/src/loaders/include.ts b/webpack-plugin/src/loaders/include.ts
index f8705471..4bebcce9 100644
--- a/webpack-plugin/src/loaders/include.ts
+++ b/webpack-plugin/src/loaders/include.ts
@@ -30,8 +30,12 @@ export const pitch: PitchLoaderDefinitionFunction = function pit
...(globals
? Object.keys(globals).map((key) => `self[${JSON.stringify(key)}] = ${globals[key]};`)
: []),
- ...pre.map((include: any) => `require(${stringifyRequest(include)});`),
- `module.exports = require(${stringifyRequest(`!!${remainingRequest}`)});`,
- ...post.map((include: any) => `require(${stringifyRequest(include)});`)
+ ...pre.map((include: any) => `import ${stringifyRequest(include)};`),
+ `
+import * as monaco from ${stringifyRequest(`!!${remainingRequest}`)};
+export * from ${stringifyRequest(`!!${remainingRequest}`)};
+export default monaco;
+ `,
+ ...post.map((include: any) => `import ${stringifyRequest(include)};`)
].join('\n');
};
diff --git a/website/index/samples/sample.mdx.txt b/website/index/samples/sample.mdx.txt
new file mode 100644
index 00000000..295a0c28
--- /dev/null
+++ b/website/index/samples/sample.mdx.txt
@@ -0,0 +1,92 @@
+---
+frontmatter: data
+yaml: true
+---
+
+[link](https://example.com)
+
+~~~
+aasd
+asd
+asd
+~~~
+
+# Hello MDX {1+2}
+
+import { MyComponent } from './MyComponent'
+
+This is **bold {'foo' + 1} text**
+
+This is _emphasis {'foo' + 1} text_
+
+This is *emphasis {'foo' + 1} text too*
+
+ This is an indented *code* block
+
+export function foo() {
+ console.log('asd', 1)
+ if(true) {
+ return 'yep'
+ }
+ return 'nope'
+}
+
+
+This is regular content
+
+- this is a list
+
+* this is also a list
+
++ me too!
+
+1. pizza
+2. fries
+3. ice cream
+
+----
+
+_________
+
+***\
+~~~css
+body {
+ color: red;
+}
+~~~
+
+> - this is a list
+>
+> * this is also a list
+>
+> + me too!
+>
+> 1. pizza
+> 2. fries
+> 3. ice cream
+>
+> ---
+>
+> _________
+>
+> ***
+>
+> ```css
+> body {
+> color: red;
+> }
+> ```
+
+> This is a blockquote
+>
+>> This is a nested {'blockquote'}
+
+{'foo' + 1 + 2 + {} + 12}
+
+{/* this is a comment */}
+
+
+
+ This is **also** markdown.
+
+
diff --git a/website/package.json b/website/package.json
index f86bd77e..657513c6 100644
--- a/website/package.json
+++ b/website/package.json
@@ -24,7 +24,7 @@
"mini-css-extract-plugin": "^2.6.1",
"mobx": "^5.15.4",
"mobx-react": "^6.2.2",
- "monaco-editor": "^0.35.0",
+ "monaco-editor": "^0.42.0-dev-20230906",
"react": "^17.0.2",
"react-bootstrap": "^2.4.0",
"react-dom": "^17.0.2",
diff --git a/website/src/monaco-loader.ts b/website/src/monaco-loader.ts
index 2c771a0c..898b08d7 100644
--- a/website/src/monaco-loader.ts
+++ b/website/src/monaco-loader.ts
@@ -84,7 +84,7 @@ function loadScript(path: string): Promise {
script.onload = () => res();
script.async = true;
script.type = "text/javascript";
- script.src = path;
+ script.src = path; // CodeQL [SM01507] This is safe because the runner (that allows for dynamic paths) runs in an isolated iframe. The hosting website uses a static path configuration. // CodeQL [SM03712] This is safe because the runner (that allows for dynamic paths) runs in an isolated iframe. The hosting website uses a static path configuration.
document.head.appendChild(script);
});
}
diff --git a/website/src/runner/index.ts b/website/src/runner/index.ts
index 8bc551be..aaedd7e5 100644
--- a/website/src/runner/index.ts
+++ b/website/src/runner/index.ts
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { loadMonaco } from "../monaco-loader";
-import { IMessage, IPreviewState } from "../shared";
+import { IMessageFromRunner, IMessageToRunner, IPreviewState } from "../shared";
import "./style.scss";
window.addEventListener("message", (event) => {
@@ -14,14 +14,14 @@ window.addEventListener("message", (event) => {
console.error("not in sandbox");
return;
}
- const e = event.data as IMessage | { kind: undefined };
+ const e = event.data as IMessageToRunner | { kind: undefined };
if (e.kind === "initialize") {
initialize(e.state);
} else if (e.kind === "update-css") {
const style = document.getElementById(
"custom-style"
) as HTMLStyleElement;
- style.innerHTML = e.css;
+ style.innerHTML = e.css; // CodeQL [SM03712] This is safe because the runner runs in an isolated iframe.
}
});
@@ -46,13 +46,15 @@ async function initialize(state: IPreviewState) {
const style = document.createElement("style");
style.id = "custom-style";
- style.innerHTML = state.css;
+ style.innerHTML = state.css; // CodeQL [SM03712] This is safe because the runner runs in an isolated iframe. This feature is essential to the functionality of the playground. // CodeQL [SM02688] This is safe because the runner runs in an isolated iframe. This feature is essential to the functionality of the playground.
document.body.appendChild(style);
document.body.innerHTML += state.html;
+ const js = massageJs(state.js);
+
try {
- eval(state.js);
+ eval(js); // CodeQL [SM01632] This is safe because the runner runs in an isolated iframe. This feature is essential to the functionality of the playground. // CodeQL [SM02688] This is safe because the runner runs in an isolated iframe. This feature is essential to the functionality of the playground.
} catch (err) {
const pre = document.createElement("pre");
pre.appendChild(
@@ -61,3 +63,42 @@ async function initialize(state: IPreviewState) {
document.body.insertBefore(pre, document.body.firstChild);
}
}
+
+function sendMessageToParent(message: IMessageFromRunner) {
+ window.parent.postMessage(message, "*");
+}
+
+(globalThis as any).$sendMessageToParent = sendMessageToParent;
+
+(globalThis as any).$bindModelToCodeStr = function bindModel(
+ model: any,
+ codeStringName: string
+) {
+ model.onDidChangeContent(() => {
+ const value = model.getValue();
+ sendMessageToParent({
+ 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/shared.ts b/website/src/shared.ts
index 71036e39..0165733f 100644
--- a/website/src/shared.ts
+++ b/website/src/shared.ts
@@ -5,7 +5,7 @@
import { IMonacoSetup } from "./monaco-loader";
-export type IMessage =
+export type IMessageToRunner =
| {
kind: "initialize";
state: IPreviewState;
@@ -15,6 +15,16 @@ export type IMessage =
css: string;
};
+export type IMessageFromRunner =
+ | {
+ kind: "update-code-string";
+ codeStringName: string;
+ value: string;
+ }
+ | {
+ kind: "reload";
+ };
+
export interface IPlaygroundProject {
js: string;
css: string;
@@ -22,6 +32,6 @@ export interface IPlaygroundProject {
}
export interface IPreviewState extends IPlaygroundProject {
- key: number;
+ reloadKey: number;
monacoSetup: IMonacoSetup;
}
diff --git a/website/src/website/components/Loader.tsx b/website/src/website/components/Loader.tsx
new file mode 100644
index 00000000..236aa75c
--- /dev/null
+++ b/website/src/website/components/Loader.tsx
@@ -0,0 +1,40 @@
+import * as React from "react";
+export class Loader extends React.Component<
+ { children: (value: T) => React.ReactChild; loader: () => Promise },
+ { value: T | undefined; hasValue: boolean }
+> {
+ constructor(props: any) {
+ super(props);
+ this.state = { value: undefined, hasValue: false };
+ if (!this.state.value) {
+ this.props.loader().then((value) => {
+ this.setState({
+ hasValue: true,
+ value,
+ });
+ });
+ }
+ }
+
+ render() {
+ if (!this.state.hasValue) {
+ return null;
+ }
+ return this.props.children(this.state.value!);
+ }
+}
+
+/**
+ * Decorates a component so that it only gets mounted when monaco is loaded.
+ */
+export function withLoader(
+ loader: () => Promise
+): (
+ Component: React.FunctionComponent | React.ComponentClass
+) => any {
+ return (Component) => {
+ return (props: any) => (
+ {() => }
+ );
+ };
+}
diff --git a/website/src/website/components/monaco/MonacoEditor.tsx b/website/src/website/components/monaco/MonacoEditor.tsx
index bd8d47af..57e47761 100644
--- a/website/src/website/components/monaco/MonacoEditor.tsx
+++ b/website/src/website/components/monaco/MonacoEditor.tsx
@@ -249,6 +249,7 @@ export class MonacoDiffEditor extends React.Component<
minimap: { enabled: false },
automaticLayout: false,
theme: this.props.theme,
+ originalEditable: true,
});
this.editor.setModel({
original: this.props.originalModel,
diff --git a/website/src/website/components/monaco/MonacoLoader.tsx b/website/src/website/components/monaco/MonacoLoader.tsx
index 44665417..61ea1c46 100644
--- a/website/src/website/components/monaco/MonacoLoader.tsx
+++ b/website/src/website/components/monaco/MonacoLoader.tsx
@@ -26,6 +26,7 @@ export class MonacoLoader extends React.Component<
return this.props.children(this.state.monaco);
}
}
+
/**
* Decorates a component so that it only gets mounted when monaco is loaded.
*/
diff --git a/website/src/website/data/home-samples/sample.mdx.txt b/website/src/website/data/home-samples/sample.mdx.txt
new file mode 100644
index 00000000..0e2479f9
--- /dev/null
+++ b/website/src/website/data/home-samples/sample.mdx.txt
@@ -0,0 +1,91 @@
+---
+title: Hello!
+---
+
+import {Chart} from './chart.js'
+import population from './population.js'
+import {External} from './some/place.js'
+
+export const year = 2018
+export const pi = 3.14
+
+export function SomeComponent(props) {
+ const name = (props || {}).name || 'world'
+
+ return
+
Hi, {name}!
+
+
and some more things
+
+}
+
+export function Local(props) {
+ return
+}
+
+# Last yearβs snowfall
+
+In {year}, the snowfall was above average.
+It was followed by a warm spring which caused
+flood conditions in many of the nearby rivers.
+
+
+
+
+ > Some notable things in a block quote!
+
+
+# Heading (rank 1)
+## Heading 2
+### 3
+#### 4
+##### 5
+###### 6
+
+> Block quote
+
+* Unordered
+* List
+
+1. Ordered
+2. List
+
+A paragraph, introducing a thematic break:
+
+---
+
+```js
+// Get an element.
+const element = document.querySelectorAll('#hi')
+
+// Add a class.
+element.classList.add('asd')
+```
+
+a [link](https://example.com), an , some *emphasis*,
+something **strong**, and finally a little `code()`.
+
+}
+/>
+
+Two π° is: {Math.PI * 2}
+
+{(function () {
+ const guess = Math.random()
+
+ if (guess > 0.66) {
+ return Look at us.
+ }
+
+ if (guess > 0.33) {
+ return Who would have guessed?!
+ }
+
+ return Not me.
+})()}
+
+{/* A comment! */}
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/data/playground-samples/interacting-with-the-editor/rendering-glyphs-in-the-margin/sample.css b/website/src/website/data/playground-samples/interacting-with-the-editor/rendering-glyphs-in-the-margin/sample.css
index 6aa88f43..92c07cbc 100644
--- a/website/src/website/data/playground-samples/interacting-with-the-editor/rendering-glyphs-in-the-margin/sample.css
+++ b/website/src/website/data/playground-samples/interacting-with-the-editor/rendering-glyphs-in-the-margin/sample.css
@@ -2,5 +2,6 @@
background: red;
}
.myContentClass {
- background: lightblue;
+ /* Make sure to use transparent colors for the selection to work */
+ background: rgba(173, 216, 230, 0.5);
}
diff --git a/website/src/website/pages/home/Home.tsx b/website/src/website/pages/home/Home.tsx
index 9e77ebf3..759a06b2 100644
--- a/website/src/website/pages/home/Home.tsx
+++ b/website/src/website/pages/home/Home.tsx
@@ -172,10 +172,9 @@ class EditorDemo extends React.Component {
IntelliSense, Validation
- Paragraph of text beneath the heading to explain
- the heading. We'll add onto it with another
- sentence and probably just keep going until we
- run out of words.
+ Get completions and errors directly in the
+ browser for supported languages. Or write your
+ own completion providers in JavaScript.
@@ -184,10 +183,9 @@ class EditorDemo extends React.Component {
Basic Syntax Colorization
- Paragraph of text beneath the heading to explain
- the heading. We'll add onto it with another
- sentence and probably just keep going until we
- run out of words.
+ Colorize code using our pre-built syntax
+ highlighting, or configure your own custom
+ colorization.