ソースを参照

Merge branch 'main' into mdx

Remco Haszing 2 年 前
コミット
62e11b4b49

+ 18 - 0
.azure-pipelines/publish-nightly.yml

@@ -23,6 +23,16 @@ resources:
       ref: main
       endpoint: Monaco
 
+parameters:
+  - name: vscodeRef
+    displayName: The VS Code commit id. When left empty, the main branched is used.
+    type: string
+    default: ''
+  - name: prereleaseVersion
+    displayName: The prerelease version. When left empty, dev-${today} is used.
+    type: string
+    default: ''
+
 extends:
   template: azure-pipelines/npm-package/pipeline.yml@templates
   parameters:
@@ -35,6 +45,10 @@ extends:
             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 +64,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

+ 1 - 1
.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)

+ 6 - 0
.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.

+ 28 - 0
CHANGELOG.md

@@ -1,5 +1,33 @@
 # Monaco Editor Changelog
 
+## [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

+ 23 - 19
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
-
-## Shipping a new monaco-editor npm module
+## Publishing a stable build monaco-editor build
 
-- 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`
+- 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.39.0-dev.20230606#XQAAAAKzBQAAAAAAAABBqQkHQ5NjdMjwa-jY7SIQ9S7DNlzs5W-mwj0fe1ZCDRFc9ws9XQE0SJE1jc2VKxhaLFIw9vEWSxW3yscw9ajfg2SGxNmVfIdymzfNMmpU96miXJZvs8c7gcyo98bKVzbks7HoMVAZiOQjzsGSo4vYRPplxTKh4qJ5_s9m1RB0u1a8RPwJXtmqrYtToAekuwuDQ2im8_QvtfSt1HbJIiHVd2zPiTBSeoC03JVOCBfBsHUM0AOblitxr0yoEKp5yCNj9Xx68iP2xX6l7R-oQQP0QegyE5JU_S6OAtnV--nu4J_lwqYHYrlBXuqsqRU-cKhSqrbrcWCxKMEmQyZkUHmM75vxSD8qepWmGk7BA4eU4YQI7tZ6g74Y0LXfIckS_2A-xIQYChatES1wLXoLosL4FhDqugt7bJg6Lelf09SdwM_NgJuVqmU8jOyMkHaKZ4nkZt61mFhR3Wa4KUfFUTCro6cKL3tIHInvgOfg8gpWdNOKy19pICfKSDYlWkn6rPgZxR0b-KCbY8K3_B6h8_TU8JfXlva5OmzfgvNBQcN_UE95r5zuBUua8JDaVLTOUKDRsOj5DYNx9KGGgicA2qjH3IlyyuOfgPTmNssWQv496rVgpqm4Zpt3DGSDY-1vxbGQe7m135DxLbACD70fgH8-C-ou2umXUKDrJbZJI2EFFMvzvZVBZVEp7Fa2j7161WJ_oyFj1HvHtTMvvrE_0P2g-u--1zh_9OHJ_ybwLAA)
+  - 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://vscode-tools.azurewebsites.net/acknowledgement/))
+  - Commit
+  - [Trigger build](https://dev.azure.com/monacotools/Monaco/_build?definitionId=416)
 
-#### 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

+ 1 - 1
README.md

@@ -37,7 +37,7 @@ It is recommended to develop against the `dev` version, and in production to use
   - [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!

ファイルの差分が大きいため隠しています
+ 544 - 164
package-lock.json


+ 4 - 4
package.json

@@ -1,7 +1,7 @@
 {
 	"name": "monaco-editor",
-	"version": "0.37.1",
-	"vscodeRef": "8f74fbfd1f2d8f6268a42df131726b218aafe511",
+	"version": "0.39.0",
+	"vscodeRef": "78390793536f5f43e17ff7c97b260bd2a5d1060c",
 	"private": true,
 	"description": "A browser based code editor",
 	"homepage": "https://github.com/microsoft/monaco-editor",
@@ -52,7 +52,7 @@
 		"jsdom": "^19.0.0",
 		"jsonc-parser": "^3.0.0",
 		"mocha": "^9.2.0",
-		"monaco-editor-core": "^0.37.0-dev.20230403",
+		"monaco-editor-core": "^0.39.0-dev.20230605",
 		"parcel": "^2.7.0",
 		"pin-github-action": "^1.8.0",
 		"playwright": "^1.32.2",
@@ -64,7 +64,7 @@
 		"terser": "^5.14.2",
 		"ts-node": "^10.6.0",
 		"typescript": "^5.0.2",
-		"vite": "^3.1.8",
+		"vite": "^3.2.7",
 		"vscode-css-languageservice": "5.4.1",
 		"vscode-html-languageservice": "4.2.4",
 		"vscode-json-languageservice": "4.2.1",

+ 9 - 9
samples/browser-esm-vite-react/package-lock.json

@@ -13,7 +13,7 @@
 				"react": "^17.0.2",
 				"react-dom": "^17.0.2",
 				"typescript": "^5.0.2",
-				"vite": "^2.9.13"
+				"vite": "^2.9.16"
 			}
 		},
 		"node_modules/@ampproject/remapping": {
@@ -1372,15 +1372,15 @@
 			}
 		},
 		"node_modules/vite": {
-			"version": "2.9.13",
-			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.13.tgz",
-			"integrity": "sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw==",
+			"version": "2.9.16",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz",
+			"integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==",
 			"dev": true,
 			"dependencies": {
 				"esbuild": "^0.14.27",
 				"postcss": "^8.4.13",
 				"resolve": "^1.22.0",
-				"rollup": "^2.59.0"
+				"rollup": ">=2.59.0 <2.78.0"
 			},
 			"bin": {
 				"vite": "bin/vite.js"
@@ -2298,16 +2298,16 @@
 			"dev": true
 		},
 		"vite": {
-			"version": "2.9.13",
-			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.13.tgz",
-			"integrity": "sha512-AsOBAaT0AD7Mhe8DuK+/kE4aWYFMx/i0ZNi98hJclxb4e0OhQcZYUrvLjIaQ8e59Ui7txcvKMiJC1yftqpQoDw==",
+			"version": "2.9.16",
+			"resolved": "https://registry.npmjs.org/vite/-/vite-2.9.16.tgz",
+			"integrity": "sha512-X+6q8KPyeuBvTQV8AVSnKDvXoBMnTx8zxh54sOwmmuOdxkjMmEJXH2UEchA+vTMps1xw9vL64uwJOWryULg7nA==",
 			"dev": true,
 			"requires": {
 				"esbuild": "^0.14.27",
 				"fsevents": "~2.3.2",
 				"postcss": "^8.4.13",
 				"resolve": "^1.22.0",
-				"rollup": "^2.59.0"
+				"rollup": ">=2.59.0 <2.78.0"
 			}
 		}
 	}

+ 1 - 1
samples/browser-esm-vite-react/package.json

@@ -15,6 +15,6 @@
 		"@types/react-dom": "^17.0.11",
 		"@vitejs/plugin-react": "^1.1.4",
 		"typescript": "^5.0.2",
-		"vite": "^2.9.13"
+		"vite": "^2.9.16"
 	}
 }

+ 6 - 0
scripts/ci/env.ts

@@ -0,0 +1,6 @@
+export function getEnv(): {
+	VSCODE_REF: string | undefined;
+	PRERELEASE_VERSION: string | undefined;
+} {
+	return process.env as any;
+}

+ 3 - 2
scripts/ci/monaco-editor-core-prepare.ts

@@ -1,6 +1,7 @@
 import { mkdir, rm } from 'fs/promises';
 import { join, resolve } from 'path';
 import { PackageJson, group, gitShallowClone, run, writeJsonFile, getNightlyVersion } from '../lib';
+import { getEnv } from './env';
 
 const selfPath = __dirname;
 const rootPath = join(selfPath, '..', '..');
@@ -21,8 +22,8 @@ async function prepareMonacoEditorCoreReleaseStableOrNightly() {
 		version = monacoEditorPackageJson.version;
 		ref = monacoEditorPackageJson.vscodeRef;
 	} else if (arg === 'nightly') {
-		version = getNightlyVersion(monacoEditorPackageJson.version);
-		ref = 'main';
+		version = getNightlyVersion(monacoEditorPackageJson.version, getEnv().PRERELEASE_VERSION);
+		ref = getEnv().VSCODE_REF || 'main';
 	} else {
 		throw new Error('Invalid argument');
 	}

+ 2 - 1
scripts/ci/monaco-editor-prepare.ts

@@ -1,6 +1,7 @@
 import { readFile } from 'fs/promises';
 import { join, resolve } from 'path';
 import { PackageJson, getNightlyVersion, group, run, writeJsonFile, gitCommitId } from '../lib';
+import { getEnv } from './env';
 
 const selfPath = __dirname;
 const rootPath = join(selfPath, '..', '..');
@@ -23,7 +24,7 @@ async function prepareMonacoEditorReleaseStableOrNightly() {
 	if (arg === 'stable') {
 		version = monacoEditorPackageJson.version;
 	} else if (arg === 'nightly') {
-		version = getNightlyVersion(monacoEditorPackageJson.version);
+		version = getNightlyVersion(monacoEditorPackageJson.version, getEnv().PRERELEASE_VERSION);
 	} else {
 		throw new Error('Invalid argument');
 	}

+ 4 - 2
scripts/lib/index.ts

@@ -73,14 +73,16 @@ export async function writeJsonFile(filePath: string, jsonData: unknown): Promis
 	await writeFile(filePath, JSON.stringify(jsonData, null, '\t') + '\n');
 }
 
-export function getNightlyVersion(version: string): string {
+export function getNightlyVersion(version: string, prerelease: string | undefined): string {
 	const pieces = version.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}`;
+
+	prerelease = prerelease || `dev.${yyyy}${mm}${dd}`;
+	return `0.${minor + 1}.0-${prerelease}`;
 }
 
 export interface PackageJson {

+ 59 - 0
src/basic-languages/javascript/javascript.test.ts

@@ -39,6 +39,65 @@ testTokenization('javascript', [
 		}
 	],
 
+	// identifiers
+	[
+		{
+			line: 'foo;',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.js' },
+				{ startIndex: 3, type: 'delimiter.js' }
+			]
+		}
+	],
+
+	[
+		{
+			line: 'foo() { return 1; }',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.js' },
+				{ startIndex: 3, type: 'delimiter.parenthesis.js' },
+				{ startIndex: 5, type: '' },
+				{ startIndex: 6, type: 'delimiter.bracket.js' },
+				{ startIndex: 7, type: '' },
+				{ startIndex: 8, type: 'keyword.js' },
+				{ startIndex: 14, type: '' },
+				{ startIndex: 15, type: 'number.js' },
+				{ startIndex: 16, type: 'delimiter.js' },
+				{ startIndex: 17, type: '' },
+				{ startIndex: 18, type: 'delimiter.bracket.js' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '#foo;',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.js' },
+				{ startIndex: 4, type: 'delimiter.js' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '#foo() { return 1; }',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.js' },
+				{ startIndex: 4, type: 'delimiter.parenthesis.js' },
+				{ startIndex: 6, type: '' },
+				{ startIndex: 7, type: 'delimiter.bracket.js' },
+				{ startIndex: 8, type: '' },
+				{ startIndex: 9, type: 'keyword.js' },
+				{ startIndex: 15, type: '' },
+				{ startIndex: 16, type: 'number.js' },
+				{ startIndex: 17, type: 'delimiter.js' },
+				{ startIndex: 18, type: '' },
+				{ startIndex: 19, type: 'delimiter.bracket.js' }
+			]
+		}
+	],
+
 	// Comments - single line
 	[
 		{

+ 1 - 0
src/basic-languages/javascript/javascript.ts

@@ -43,6 +43,7 @@ export const language = <languages.IMonarchLanguage>{
 		'null',
 		'return',
 		'set',
+		'static',
 		'super',
 		'switch',
 		'symbol',

+ 59 - 0
src/basic-languages/typescript/typescript.test.ts

@@ -39,6 +39,65 @@ testTokenization('typescript', [
 		}
 	],
 
+	// identifiers
+	[
+		{
+			line: 'foo;',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.ts' },
+				{ startIndex: 3, type: 'delimiter.ts' }
+			]
+		}
+	],
+
+	[
+		{
+			line: 'foo() { return 1; }',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.ts' },
+				{ startIndex: 3, type: 'delimiter.parenthesis.ts' },
+				{ startIndex: 5, type: '' },
+				{ startIndex: 6, type: 'delimiter.bracket.ts' },
+				{ startIndex: 7, type: '' },
+				{ startIndex: 8, type: 'keyword.ts' },
+				{ startIndex: 14, type: '' },
+				{ startIndex: 15, type: 'number.ts' },
+				{ startIndex: 16, type: 'delimiter.ts' },
+				{ startIndex: 17, type: '' },
+				{ startIndex: 18, type: 'delimiter.bracket.ts' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '#foo;',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.ts' },
+				{ startIndex: 4, type: 'delimiter.ts' }
+			]
+		}
+	],
+
+	[
+		{
+			line: '#foo() { return 1; }',
+			tokens: [
+				{ startIndex: 0, type: 'identifier.ts' },
+				{ startIndex: 4, type: 'delimiter.parenthesis.ts' },
+				{ startIndex: 6, type: '' },
+				{ startIndex: 7, type: 'delimiter.bracket.ts' },
+				{ startIndex: 8, type: '' },
+				{ startIndex: 9, type: 'keyword.ts' },
+				{ startIndex: 15, type: '' },
+				{ startIndex: 16, type: 'number.ts' },
+				{ startIndex: 17, type: 'delimiter.ts' },
+				{ startIndex: 18, type: '' },
+				{ startIndex: 19, type: 'delimiter.bracket.ts' }
+			]
+		}
+	],
+
 	// Comments - single line
 	[
 		{

+ 1 - 1
src/basic-languages/typescript/typescript.ts

@@ -227,7 +227,7 @@ export const language = {
 		common: [
 			// identifiers and keywords
 			[
-				/[a-z_$][\w$]*/,
+				/#?[a-z_$][\w$]*/,
 				{
 					cases: {
 						'@keywords': 'keyword',

+ 1 - 3
src/basic-languages/wgsl/wgsl.ts

@@ -377,7 +377,7 @@ export const language = <languages.IMonarchLanguage>{
 	predeclared_intrinsics,
 	operators,
 
-	symbols: /[!%&*+\-\.\/:;<=>^|_~]+/,
+	symbols: /[!%&*+\-\.\/:;<=>^|_~,]+/,
 
 	tokenizer: {
 		root: [
@@ -402,8 +402,6 @@ export const language = <languages.IMonarchLanguage>{
 			{ include: '@commentOrSpace' },
 			{ include: '@numbers' },
 
-			[/;:\./, 'delimiter'],
-			[/,/, 'delimiter'], // Hack: Should be in previous rule
 			[/[{}()\[\]]/, '@brackets'],
 			['@', 'annotation', '@attribute'],
 			[

+ 1 - 1
src/language/typescript/languageFeatures.ts

@@ -890,7 +890,7 @@ export class OutlineAdapter extends Adapter implements languages.DocumentSymbolP
 				range: this._textSpanToRange(model, item.spans[0]),
 				selectionRange: this._textSpanToRange(model, item.spans[0]),
 				tags: [],
-				children: item.childItems?.map((child) => convert(child, result.name)),
+				children: item.childItems?.map((child) => convert(child, item.text)),
 				containerName: containerLabel
 			};
 			return result;

+ 7 - 3
webpack-plugin/src/loaders/include.ts

@@ -30,8 +30,12 @@ export const pitch: PitchLoaderDefinitionFunction<ILoaderOptions> = 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');
 };

+ 15 - 8
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,7 +14,7 @@ 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") {
@@ -64,16 +64,23 @@ async function initialize(state: IPreviewState) {
 	}
 }
 
-(globalThis as any).bindModelToCodeStr = function bindModel(
+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();
-		window.parent.postMessage(
-			{ kind: "update-code-string", codeStringName, value },
-			"*"
-		);
+		sendMessageToParent({
+			kind: "update-code-string",
+			codeStringName,
+			value,
+		});
 	});
 };
 
@@ -91,7 +98,7 @@ function massageJs(js: string) {
 	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); }`;
+		js += `\n try { globalThis.$bindModelToCodeStr(${p1}, ${target}); } catch (e) { console.error(e); }`;
 	}
 	return js;
 }

+ 11 - 1
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;

+ 1 - 0
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,

+ 2 - 1
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);
 }

+ 1 - 0
website/src/website/pages/home/Home.tsx

@@ -217,6 +217,7 @@ class EditorDemo extends React.Component {
 						value={this.currentSample.value || "loading..."}
 						language={this.currentLanguage?.id}
 						theme={this.currentTheme.id}
+						onDidValueChange={() => {}}
 					/>
 				</div>
 			</div>

+ 27 - 14
website/src/website/pages/playground/PlaygroundModel.ts

@@ -247,11 +247,13 @@ export class PlaygroundModel {
 		const regexp = new RegExp(
 			"(\\b" +
 				escapeRegexpChars(codeStringName) +
-				":[^\\w`]*`)([^`\\\\]|\\n|\\\\\\\\|\\\\`)*`"
+				":[^\\w`]*`)([^`\\\\\\n]|\\n|\\\\\\\\|\\\\\\`|\\\\\\$)*`"
 		);
-		debugger;
 		const js = this.js;
-		const str = value.replaceAll("\\", "\\\\").replaceAll("`", "\\`");
+		const str = value
+			.replaceAll("\\", "\\\\")
+			.replaceAll("$", "\\$$$$")
+			.replaceAll("`", "\\`");
 		const newJs = js.replace(regexp, "$1" + str + "`");
 		const autoReload = this.settings.autoReload;
 		this.settings.autoReload = false;
@@ -320,12 +322,18 @@ function projectEquals(
 	project2: IPlaygroundProject
 ): boolean {
 	return (
-		project1.css === project2.css &&
-		project1.html === project2.html &&
-		project1.js === project2.js
+		normalizeLineEnding(project1.css) ===
+			normalizeLineEnding(project2.css) &&
+		normalizeLineEnding(project1.html) ===
+			normalizeLineEnding(project2.html) &&
+		normalizeLineEnding(project1.js) === normalizeLineEnding(project2.js)
 	);
 }
 
+function normalizeLineEnding(str: string): string {
+	return str.replace(/\r\n/g, "\n");
+}
+
 class StateUrlSerializer implements IHistoryModel {
 	public readonly dispose = Disposable.fn();
 
@@ -441,16 +449,21 @@ class StateUrlSerializer implements IHistoryModel {
 			this._sourceOverride = source;
 		}
 
+		function findExample(hashValue: string): PlaygroundExample | undefined {
+			if (hashValue.startsWith("example-")) {
+				hashValue = hashValue.substring("example-".length);
+			}
+			return getPlaygroundExamples()
+				.flatMap((e) => e.examples)
+				.find((e) => e.id === hashValue);
+		}
+
+		let example: PlaygroundExample | undefined;
+
 		if (!hashValue) {
 			this.model.selectedExample = getPlaygroundExamples()[0].examples[0];
-		} else if (hashValue.startsWith("example-")) {
-			const exampleName = hashValue.substring("example-".length);
-			const example = getPlaygroundExamples()
-				.flatMap((e) => e.examples)
-				.find((e) => e.id === exampleName);
-			if (example) {
-				this.model.selectedExample = example;
-			}
+		} else if ((example = findExample(hashValue))) {
+			this.model.selectedExample = example;
 		} else {
 			let p: IPlaygroundProject | undefined = undefined;
 			if (this.cachedState?.hash === hashValue) {

+ 10 - 10
website/src/website/pages/playground/Preview.tsx

@@ -2,7 +2,11 @@ import * as React from "react";
 import { IPreviewHandler, PlaygroundModel } from "./PlaygroundModel";
 import { observer } from "mobx-react";
 import { observable } from "mobx";
-import { IMessage, IPreviewState } from "../../../shared";
+import {
+	IMessageFromRunner,
+	IMessageToRunner,
+	IPreviewState,
+} from "../../../shared";
 
 @observer
 export class Preview
@@ -40,7 +44,7 @@ export class Preview
 				return;
 			}
 
-			const message: IMessage = {
+			const message: IMessageToRunner = {
 				kind: "initialize",
 				state: this.currentState,
 			};
@@ -52,15 +56,11 @@ export class Preview
 			if (e.source !== iframe.contentWindow) {
 				return;
 			}
-			const data = e.data as
-				| {
-						kind: "update-code-string";
-						codeStringName: string;
-						value: string;
-				  }
-				| { kind: "" };
+			const data = e.data as IMessageFromRunner;
 			if (data.kind === "update-code-string") {
 				this.props.model.setCodeString(data.codeStringName, data.value);
+			} else if (data.kind === "reload") {
+				this.props.model.reload();
 			}
 		});
 	};
@@ -83,7 +83,7 @@ export class Preview
 				{
 					kind: "update-css",
 					css: state.css,
-				} as IMessage,
+				} as IMessageToRunner,
 				{
 					targetOrigin: "*",
 				}

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません