Browse Source

Merge branch 'main' into main

Henning Dieterichs 3 years ago
parent
commit
75927c6de7
100 changed files with 19456 additions and 7284 deletions
  1. 1 0
      .gitattributes
  2. 7 2
      .github/ISSUE_TEMPLATE/1_bug_report.yaml
  3. 7 0
      .github/publish-failure-issue-template.md
  4. 5 2
      .github/workflows/ci.yml
  5. 27 0
      .github/workflows/locker.yml
  6. 30 0
      .github/workflows/needs-more-info-closer.yml
  7. 25 0
      .github/workflows/pr-chat.yml
  8. 23 9
      .github/workflows/publish.yml
  9. 1 1
      .github/workflows/website.yml
  10. 1 1
      .prettierignore
  11. 65 1
      CHANGELOG.md
  12. 1 1
      CONTRIBUTING.md
  13. 3 4
      MAINTAINING.md
  14. 70 60
      build/build.ts
  15. 0 8
      build/fillers/monaco-editor-core-amd.ts
  16. 8 26
      build/fs.ts
  17. 10 7
      build/importTypescript.ts
  18. 10 14
      build/npm/installAll.ts
  19. 4 6
      build/npm/removeAll.ts
  20. 2 2
      build/postinstall.ts
  21. 53 106
      build/release.ts
  22. 31 37
      build/releaseMetadata.ts
  23. 7 15
      build/simpleserver.ts
  24. 7 0
      build/tsconfig.json
  25. 53 84
      build/utils.ts
  26. 16 23
      build/website.ts
  27. 24 18
      docs/integrate-esm.md
  28. 0 82
      metadata.js
  29. 3249 2
      package-lock.json
  30. 29 25
      package.json
  31. 74 74
      samples/browser-amd-diff-editor/modified.txt
  32. 61 61
      samples/browser-amd-diff-editor/original.txt
  33. 46 2
      samples/browser-esm-esbuild/build.js
  34. 2964 4599
      samples/browser-esm-parcel/package-lock.json
  35. 2 2
      samples/browser-esm-parcel/package.json
  36. 1592 174
      samples/browser-esm-vite-react/package-lock.json
  37. 5 5
      samples/browser-esm-vite-react/package.json
  38. 3660 59
      samples/browser-esm-webpack-typescript-react/package-lock.json
  39. 6 6
      samples/browser-esm-webpack-typescript-react/package.json
  40. 2 2
      samples/browser-esm-webpack/.gitignore
  41. 2 2
      samples/electron-esm-webpack/.gitignore
  42. 5288 4
      samples/package-lock.json
  43. 7 7
      samples/package.json
  44. 1 1
      src/basic-languages/css/css.ts
  45. 1 1
      src/basic-languages/javascript/javascript.contribution.ts
  46. 1 1
      src/basic-languages/less/less.ts
  47. 1 1
      src/basic-languages/scss/scss.ts
  48. 34 0
      src/basic-languages/shell/shell.test.ts
  49. 9 3
      src/basic-languages/shell/shell.ts
  50. 4 7
      src/basic-languages/swift/swift.ts
  51. 1 0
      src/basic-languages/typescript/typescript.ts
  52. 10 2
      src/basic-languages/yaml/yaml.ts
  53. 4 0
      src/fillers/editor.api.d.ts
  54. 3 4
      src/fillers/monaco-editor-core-amd.ts
  55. 4 3
      src/language/common/lspLanguageFeatures.ts
  56. 0 0
      src/language/css/css.worker.ts
  57. 17 1
      src/language/css/cssMode.ts
  58. 55 42
      src/language/css/cssWorker.ts
  59. 43 3
      src/language/css/monaco.contribution.ts
  60. 1 1
      src/language/css/workerManager.ts
  61. 0 0
      src/language/html/html.worker.ts
  62. 1 1
      src/language/html/htmlMode.ts
  63. 1 1
      src/language/html/htmlWorker.ts
  64. 3 3
      src/language/html/monaco.contribution.ts
  65. 1 1
      src/language/html/workerManager.ts
  66. 0 0
      src/language/json/json.worker.ts
  67. 1 1
      src/language/json/jsonMode.ts
  68. 1 1
      src/language/json/jsonWorker.ts
  69. 1 1
      src/language/json/monaco.contribution.ts
  70. 1 1
      src/language/json/tokenization.ts
  71. 1 1
      src/language/json/workerManager.ts
  72. 8 6
      src/language/typescript/languageFeatures.ts
  73. 0 0
      src/language/typescript/lib/editor.worker.d.ts
  74. 1 0
      src/language/typescript/lib/lib.index.ts
  75. 12 0
      src/language/typescript/lib/lib.ts
  76. 349 303
      src/language/typescript/lib/typescriptServices-amd.js
  77. 237 234
      src/language/typescript/lib/typescriptServices.d.ts
  78. 349 303
      src/language/typescript/lib/typescriptServices.js
  79. 1 1
      src/language/typescript/lib/typescriptServicesMetadata.ts
  80. 1 1
      src/language/typescript/monaco.contribution.ts
  81. 1 1
      src/language/typescript/ts.worker.ts
  82. 1 1
      src/language/typescript/tsMode.ts
  83. 9 1
      src/language/typescript/tsWorker.ts
  84. 1 1
      src/language/typescript/workerManager.ts
  85. 0 12
      src/typescript/lib/lib.ts
  86. 0 1
      test/manual/cross-origin.html
  87. 168 194
      test/manual/dev-setup.js
  88. 0 1
      test/manual/diff.html
  89. 29 0
      test/manual/iframe-inner.html
  90. 23 0
      test/manual/iframe.html
  91. 2 1
      test/manual/index.html
  92. 2 2
      test/manual/index.js
  93. 0 1
      test/manual/mouse-fixed.html
  94. 0 1
      test/manual/mouse-scrollable-body.html
  95. 0 1
      test/manual/mouse-scrollable-element.html
  96. 33 33
      test/manual/samples/run-editor-intellisense-js.txt
  97. 0 20
      test/manual/samples/run-editor-jquery-min-js.txt
  98. 9 9
      test/manual/samples/run-editor-korean.txt
  99. 493 493
      test/manual/samples/run-editor-sample-bom-cs.txt
  100. 49 49
      test/manual/samples/run-editor-sample-dynamic.txt

+ 1 - 0
.gitattributes

@@ -0,0 +1 @@
+* text=auto

+ 7 - 2
.github/ISSUE_TEMPLATE/1_bug_report.yaml

@@ -27,11 +27,16 @@ body:
       label: Monaco Editor Playground Code
       description: Please provide the code to reproduce in the [monaco editor playground](https://microsoft.github.io/monaco-editor/playground.html)
       render: typescript
+  - type: textarea
+    id: steps
+    attributes:
+      label: Reproduction Steps
+      description: Please describe the steps (in the playground) that lead to the problematic behavior
   - type: textarea
     id: actual-behavior
     attributes:
-      label: Actual Behavior
-      description: Please describe the actual behavior, as observed in the playground.
+      label: Actual (Problematic) Behavior
+      description: Please describe the actual (problematic) behavior, as observed in the playground.
 
   - type: textarea
     id: expected-behavior

+ 7 - 0
.github/publish-failure-issue-template.md

@@ -0,0 +1,7 @@
+---
+title: NPM Publishing Failed
+assignees: []
+labels: bug
+---
+
+NPM publishing failed. Check the last GitHub Action log.

+ 5 - 2
.github/workflows/ci.yml

@@ -11,7 +11,7 @@ jobs:
 
       - uses: actions/setup-node@v2
         with:
-          node-version: 14
+          node-version: 16
 
       - name: Cache node modules
         id: cacheNodeModules
@@ -48,7 +48,10 @@ jobs:
         run: npm run compile --prefix webpack-plugin
 
       - name: Package using webpack plugin
-        run: npm run smoketest --prefix webpack-plugin
+        run: npm run package-for-smoketest --prefix webpack-plugin
+
+      - name: Package using esbuild
+        run: npm run package-for-smoketest-esbuild
 
       - name: Run smoke test
         run: npm run smoketest

+ 27 - 0
.github/workflows/locker.yml

@@ -0,0 +1,27 @@
+name: Locker
+on:
+  schedule:
+    - cron: 21 23 * * * # 5:20pm Redmond
+  repository_dispatch:
+    types: [trigger-locker]
+  workflow_dispatch:
+
+jobs:
+  main:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout Actions
+        uses: actions/checkout@v2
+        with:
+          repository: 'microsoft/vscode-github-triage-actions'
+          path: ./actions
+          ref: stable
+      - name: Install Actions
+        run: npm install --production --prefix ./actions
+      - name: Run Locker
+        uses: ./actions/locker
+        with:
+          daysSinceClose: 45
+          appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
+          daysSinceUpdate: 3
+          ignoredLabel: '*out-of-scope'

+ 30 - 0
.github/workflows/needs-more-info-closer.yml

@@ -0,0 +1,30 @@
+name: Needs More Info Closer
+on:
+  schedule:
+    - cron: 20 12 * * * # 5:20am Redmond
+  repository_dispatch:
+    types: [trigger-needs-more-info]
+  workflow_dispatch:
+
+jobs:
+  main:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout Actions
+        uses: actions/checkout@v2
+        with:
+          repository: 'microsoft/vscode-github-triage-actions'
+          path: ./actions
+          ref: stable
+      - name: Install Actions
+        run: npm install --production --prefix ./actions
+      - name: Run Needs More Info Closer
+        uses: ./actions/needs-more-info-closer
+        with:
+          appInsightsKey: ${{secrets.TRIAGE_ACTIONS_APP_INSIGHTS}}
+          label: needs more info
+          closeDays: 7
+          additionalTeam: 'spahnke|rcjsuen'
+          closeComment: "This issue has been closed automatically because it needs more information and has not had recent activity. See also our [issue reporting](https://aka.ms/vscodeissuereporting) guidelines.\n\nHappy Coding!"
+          pingDays: 120
+          pingComment: "Hey @${assignee}, this issue might need further attention.\n\n@${author}, you can help us out by closing this issue if the problem no longer exists, or adding more information."

+ 25 - 0
.github/workflows/pr-chat.yml

@@ -0,0 +1,25 @@
+name: PR Chat
+on:
+  pull_request_target:
+    types: [opened, ready_for_review, closed]
+
+jobs:
+  main:
+    runs-on: ubuntu-latest
+    if: ${{ !github.event.pull_request.draft }}
+    steps:
+      - name: Checkout Actions
+        uses: actions/checkout@v2
+        with:
+          repository: 'microsoft/vscode-github-triage-actions'
+          ref: stable
+          path: ./actions
+      - name: Install Actions
+        run: npm install --production --prefix ./actions
+      - name: Run Code Review Chat
+        uses: ./actions/code-review-chat
+        with:
+          token: ${{secrets.GITHUB_TOKEN}}
+          slack_token: ${{ secrets.SLACK_TOKEN }}
+          slack_bot_name: 'VSCodeBot'
+          notification_channel: codereview

+ 23 - 9
.github/workflows/publish.yml

@@ -12,12 +12,13 @@ on:
         default: 'true'
 jobs:
   publish:
+    if: ${{ github.repository == 'microsoft/monaco-editor' }}
     name: Publish to npm
     runs-on: ubuntu-latest
     steps:
       - uses: actions/setup-node@v2
         with:
-          node-version: 14
+          node-version: 16
 
       - name: (monaco-editor) checkout
         uses: actions/checkout@v2
@@ -52,6 +53,11 @@ jobs:
         working-directory: './vscode'
         run: yarn --frozen-lockfile --network-timeout 180000
 
+      - name: (vscode) Download Playwright
+        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
+        working-directory: ./vscode
+        run: yarn playwright-install
+
       - name: (vscode) Run Hygiene Checks
         if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
         working-directory: './vscode'
@@ -96,6 +102,11 @@ jobs:
         working-directory: './vscode'
         run: yarn gulp editor-distro
 
+      - name: Editor ESM sources check
+        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
+        working-directory: './vscode/test/monaco'
+        run: yarn run esm-check
+
       - name: (vscode) Typings validation prep
         if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
         working-directory: './vscode'
@@ -110,21 +121,16 @@ jobs:
           echo "import '../out-monaco-editor-core';" > a.ts
           ../node_modules/.bin/tsc --noEmit
 
-      - name: (vscode) Webpack Editor
+      - name: (vscode) Package Editor with Webpack
         if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
         working-directory: ./vscode/test/monaco
-        run: yarn run bundle
+        run: yarn run bundle-webpack
 
       - name: (vscode) Compile Editor Tests
         if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
         working-directory: ./vscode/test/monaco
         run: yarn run compile
 
-      - name: (vscode) Download Playwright
-        if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
-        working-directory: ./vscode
-        run: yarn playwright-install
-
       - name: (vscode) Run Editor Tests
         if: ${{ steps.state.outputs.skip_monaco_editor_core == 'false' }}
         timeout-minutes: 5
@@ -197,7 +203,7 @@ jobs:
       - name: (monaco-editor) Package using webpack plugin
         if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
         working-directory: './monaco-editor'
-        run: npm run smoketest --prefix webpack-plugin
+        run: npm run package-for-smoketest --prefix webpack-plugin
 
       - name: (monaco-editor) Run smoke test
         if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
@@ -219,3 +225,11 @@ jobs:
         if: ${{ steps.state.outputs.skip_monaco_editor == 'false' }}
         working-directory: './monaco-editor/release'
         run: npm publish --tag ${{ steps.state.outputs.dist_tag }}
+
+      - name: Create Issue On Failure
+        if: failure()
+        uses: JasonEtco/create-an-issue@9e6213aec58987fa7d2f4deb8b256b99e63107a2
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+        with:
+          filename: ./monaco-editor/.github/publish-failure-issue-template.md

+ 1 - 1
.github/workflows/website.yml

@@ -16,7 +16,7 @@ jobs:
 
       - uses: actions/setup-node@v2
         with:
-          node-version: 14
+          node-version: 16
 
       - name: Cache node modules
         id: cacheNodeModules

+ 1 - 1
.prettierignore

@@ -9,7 +9,7 @@
 /samples/browser-esm-webpack-small/dist/*.js
 /samples/browser-esm-webpack-typescript/dist/*.js
 /samples/browser-esm-webpack-typescript-react/dist/*.js
-/src/typescript/lib/
+/src/language/typescript/lib/
 /test/manual/generated/
 /website/lib/
 /website/typedoc/monaco.d.ts

+ 65 - 1
CHANGELOG.md

@@ -1,6 +1,52 @@
 # Monaco Editor Changelog
 
-## [0.32.0] (TBD)
+## [0.34.0] (Unreleased)
+
+- Introduction of `IEditor.createDecorationsCollection` API
+- New function `removeAllMarkers` to remove all markers
+- Support for light high contrast theme
+- Introduction of `BracketPairColorizationOptions.independentColorPoolPerBracketType`
+- Introduction of `PositionAffinity.LeftOfInjectedText` and `PositionAffinity.RightOfInjectedText`
+- Introduction of `IEditorOptions.showFoldingControls: 'never'`
+- Introduction of `IDiffEditorBaseOptions.renderMarginRevertIcon: boolean`
+- Inline Quick Suggestions
+- Introduction of `IContentWidgetPosition.positionAffinity`
+- Provider can now be registered for a `LanguageSelector`
+
+### Breaking Changes
+
+- `IEditorInlayHintsOptions` tweaks
+- Iteration on `InlineCompletion` API
+- `WorkspaceFileEdit` -> `IWorkspaceFileEdit`
+  - `oldUri` -> `oldResource`
+  - `newUri` -> `newResource`
+- `WorkspaceTextEdit` -> `IWorkspaceTextEdit`
+  - `edit` -> `textEdit` (now supports `insertAsSnippet`)
+  - `modelVersionId?: number` -> `versionId: number | undefined`
+- `InlayHint` API tweaks
+- Soft deprecation of `ICodeEditor.deltaDecorations`, no adoption required. `IEditor.createDecorationsCollection` API should be used instead.
+
+## [0.33.0]
+
+- The first parameter of all `monaco.languages.register*Provider` functions has changed to take a `DocumentSelector` instead of a single `languageId`
+- The `Environment.getWorker` function can now return a `Promise`
+
+### Breaking Changes
+
+- `InlayHintKind.Other` is removed.
+
+### Thank you
+
+Contributions to `monaco-editor`:
+
+- [@Dan1ve (Daniel Veihelmann)](https://github.com/Dan1ve): Make Vite sample code Firefox compatible [PR #2991](https://github.com/microsoft/monaco-editor/pull/2991)
+- [@philipturner (Philip Turner)](https://github.com/philipturner): Add `@noDerivative` modifier to Swift [PR #2957](https://github.com/microsoft/monaco-editor/pull/2957)
+
+## [0.32.1] (04.02.2022)
+
+- fixes [an issue with service initialization](https://github.com/microsoft/monaco-editor/issues/2941).
+
+## [0.32.0] (03.02.2022)
 
 ### Breaking Changes
 
@@ -8,6 +54,24 @@
 - `IDiffEditor.getDomNode()` has been renamed to `IDiffEditor.getContainerDomNode()`.
 - `InlayHint.text` has been replaced by `InlayHint.label` and `InlayHintsProvider.provideInlayHints` now returns an `InlayHintList`.
 
+### Thank you
+
+Contributions to `monaco-editor`:
+
+- [@blutorange (Andre Wachsmuth)](https://github.com/blutorange): Implements #2383 Add syntax modes for FreeMarker template language [PR #2847](https://github.com/microsoft/monaco-editor/pull/2847)
+- [@forensicmike (forensicmike1)](https://github.com/forensicmike): Add "cd monaco-editor" to the step by step commandline instructions for cloning and running the samples [PR #2894](https://github.com/microsoft/monaco-editor/pull/2894)
+- [@juan-carlos-diaz](https://github.com/juan-carlos-diaz): Fix #2851 Highlight correctly the attributes and identifiers (with dashes) for Shell language [PR #2871](https://github.com/microsoft/monaco-editor/pull/2871)
+- [@MasterOdin (Matthew Peveler)](https://github.com/MasterOdin): Only run publish workflow on main monaco-editor repo [PR #2926](https://github.com/microsoft/monaco-editor/pull/2926)
+- [@philipturner (Philip Turner)](https://github.com/philipturner)
+  - Update Swift language specification to version 5.5 [PR #2855](https://github.com/microsoft/monaco-editor/pull/2855)
+  - Add @preconcurrency to Swift declaration attributes [PR #2924](https://github.com/microsoft/monaco-editor/pull/2924)
+- [@rcjsuen (Remy Suen)](https://github.com/rcjsuen): Support hyphenated HTML tags in Markdown syntax [PR #2864](https://github.com/microsoft/monaco-editor/pull/2864)
+- [@resistdesign (Ryan Graff)](https://github.com/resistdesign): doc: (samples) Simplify Browser ESM Parcel build [PR #2832](https://github.com/microsoft/monaco-editor/pull/2832)
+- [@ValeraS (Valeriy)](https://github.com/ValeraS)
+  - fix(monaco-editor-webpack-plugin): load monaco-editor with webpack 4 [PR #2818](https://github.com/microsoft/monaco-editor/pull/2818)
+  - tune(monaco-editor-webpack-plugin): expose plugin options type [PR #2853](https://github.com/microsoft/monaco-editor/pull/2853)
+- [@ZusorCode (Tobias Messner)](https://github.com/ZusorCode): Add .cjs extension for javascript files [PR #2929](https://github.com/microsoft/monaco-editor/pull/2929)
+
 ## [0.31.1] (14.12.2021)
 
 - Fixes [a problem with missing colors](https://github.com/microsoft/monaco-editor/issues/2822)

+ 1 - 1
CONTRIBUTING.md

@@ -73,7 +73,7 @@ Open [http://localhost:8080/monaco-editor/test/manual/?editor=src](http://localh
 /src/monaco-editor> npm run compile --prefix webpack-plugin
 
 # package using the webpack plugin
-/src/monaco-editor> npm run smoketest --prefix webpack-plugin
+/src/monaco-editor> npm run package-for-smoketest --prefix webpack-plugin
 
 # run the smoketest
 /src/monaco-editor> npm run smoketest-debug

+ 3 - 4
MAINTAINING.md

@@ -13,14 +13,13 @@
 
 - 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`
-- run `npm run release`
-- write entry in `CHANGELOG.md`
-  - API Changes / Breaking Changes / New and noteworthy
-  - Thank you ([use this tool](https://vscode-tools.azurewebsites.net/acknowledgement/))
 
 #### 8. Publish new webpack plugin
 

+ 70 - 60
build/build.js → build/build.ts

@@ -3,11 +3,9 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const glob = require('glob');
-const { tsc, dts, buildESM, buildAMD } = require('../build/utils');
-const { copyFile, removeDir } = require('../build/fs');
+import glob from 'glob';
+import { tsc, dts, buildESM, buildAMD } from './utils';
+import { copyFile, removeDir } from './fs';
 
 removeDir(`out`);
 
@@ -15,20 +13,24 @@ tsc(`src/tsconfig.json`);
 
 //#region Type Defintion
 
-dts(`out/amd/css/monaco.contribution.d.ts`, `out/release/css/monaco.d.ts`, 'monaco.languages.css');
 dts(
-	`out/amd/html/monaco.contribution.d.ts`,
-	`out/release/html/monaco.d.ts`,
+	`out/amd/language/css/monaco.contribution.d.ts`,
+	`out/release/css.d.ts`,
+	'monaco.languages.css'
+);
+dts(
+	`out/amd/language/html/monaco.contribution.d.ts`,
+	`out/release/html.d.ts`,
 	'monaco.languages.html'
 );
 dts(
-	`out/amd/json/monaco.contribution.d.ts`,
-	`out/release/json/monaco.d.ts`,
+	`out/amd/language/json/monaco.contribution.d.ts`,
+	`out/release/json.d.ts`,
 	'monaco.languages.json'
 );
 dts(
-	`out/amd/typescript/monaco.contribution.d.ts`,
-	`out/release/typescript/monaco.d.ts`,
+	`out/amd/language/typescript/monaco.contribution.d.ts`,
+	`out/release/typescript.d.ts`,
 	'monaco.languages.typescript'
 );
 
@@ -37,24 +39,29 @@ dts(
 //#region css
 
 buildESM({
-	base: 'css',
-	entryPoints: ['src/css/monaco.contribution.ts', 'src/css/cssMode.ts', 'src/css/css.worker.ts'],
-	external: ['monaco-editor-core', '*/cssMode']
+	base: 'language/css',
+	entryPoints: [
+		'src/language/css/monaco.contribution.ts',
+		'src/language/css/cssMode.ts',
+		'src/language/css/css.worker.ts'
+	],
+	external: ['monaco-editor-core', '*/cssMode', '*/monaco.contribution']
 });
 buildAMD({
-	base: 'css',
-	entryPoint: 'src/css/monaco.contribution.ts',
+	base: 'language/css',
+	entryPoint: 'src/language/css/monaco.contribution.ts',
 	amdModuleId: 'vs/language/css/monaco.contribution',
 	amdDependencies: ['vs/editor/editor.api']
 });
 buildAMD({
-	base: 'css',
-	entryPoint: 'src/css/cssMode.ts',
-	amdModuleId: 'vs/language/css/cssMode'
+	base: 'language/css',
+	entryPoint: 'src/language/css/cssMode.ts',
+	amdModuleId: 'vs/language/css/cssMode',
+	external: ['*/monaco.contribution']
 });
 buildAMD({
-	base: 'css',
-	entryPoint: 'src/css/cssWorker.ts',
+	base: 'language/css',
+	entryPoint: 'src/language/css/cssWorker.ts',
 	amdModuleId: 'vs/language/css/cssWorker'
 });
 
@@ -63,28 +70,29 @@ buildAMD({
 //#region html
 
 buildESM({
-	base: 'html',
+	base: 'language/html',
 	entryPoints: [
-		'src/html/monaco.contribution.ts',
-		'src/html/htmlMode.ts',
-		'src/html/html.worker.ts'
+		'src/language/html/monaco.contribution.ts',
+		'src/language/html/htmlMode.ts',
+		'src/language/html/html.worker.ts'
 	],
-	external: ['monaco-editor-core', '*/htmlMode']
+	external: ['monaco-editor-core', '*/htmlMode', '*/monaco.contribution']
 });
 buildAMD({
-	base: 'html',
-	entryPoint: 'src/html/monaco.contribution.ts',
+	base: 'language/html',
+	entryPoint: 'src/language/html/monaco.contribution.ts',
 	amdModuleId: 'vs/language/html/monaco.contribution',
 	amdDependencies: ['vs/editor/editor.api']
 });
 buildAMD({
-	base: 'html',
-	entryPoint: 'src/html/htmlMode.ts',
-	amdModuleId: 'vs/language/html/htmlMode'
+	base: 'language/html',
+	entryPoint: 'src/language/html/htmlMode.ts',
+	amdModuleId: 'vs/language/html/htmlMode',
+	external: ['*/monaco.contribution']
 });
 buildAMD({
-	base: 'html',
-	entryPoint: 'src/html/htmlWorker.ts',
+	base: 'language/html',
+	entryPoint: 'src/language/html/htmlWorker.ts',
 	amdModuleId: 'vs/language/html/htmlWorker'
 });
 
@@ -93,28 +101,29 @@ buildAMD({
 //#region json
 
 buildESM({
-	base: 'json',
+	base: 'language/json',
 	entryPoints: [
-		'src/json/monaco.contribution.ts',
-		'src/json/jsonMode.ts',
-		'src/json/json.worker.ts'
+		'src/language/json/monaco.contribution.ts',
+		'src/language/json/jsonMode.ts',
+		'src/language/json/json.worker.ts'
 	],
-	external: ['monaco-editor-core', '*/jsonMode']
+	external: ['monaco-editor-core', '*/jsonMode', '*/monaco.contribution']
 });
 buildAMD({
-	base: 'json',
-	entryPoint: 'src/json/monaco.contribution.ts',
+	base: 'language/json',
+	entryPoint: 'src/language/json/monaco.contribution.ts',
 	amdModuleId: 'vs/language/json/monaco.contribution',
 	amdDependencies: ['vs/editor/editor.api']
 });
 buildAMD({
-	base: 'json',
-	entryPoint: 'src/json/jsonMode.ts',
-	amdModuleId: 'vs/language/json/jsonMode'
+	base: 'language/json',
+	entryPoint: 'src/language/json/jsonMode.ts',
+	amdModuleId: 'vs/language/json/jsonMode',
+	external: ['*/monaco.contribution']
 });
 buildAMD({
-	base: 'json',
-	entryPoint: 'src/json/jsonWorker.ts',
+	base: 'language/json',
+	entryPoint: 'src/language/json/jsonWorker.ts',
 	amdModuleId: 'vs/language/json/jsonWorker'
 });
 
@@ -123,33 +132,34 @@ buildAMD({
 //#region typescript
 
 copyFile(
-	`src/typescript/lib/typescriptServices-amd.js`,
-	`out/amd/typescript/lib/typescriptServices.js`
+	`src/language/typescript/lib/typescriptServices-amd.js`,
+	`out/amd/language/typescript/lib/typescriptServices.js`
 );
 
 buildESM({
-	base: 'typescript',
+	base: 'language/typescript',
 	entryPoints: [
-		'src/typescript/monaco.contribution.ts',
-		'src/typescript/tsMode.ts',
-		'src/typescript/ts.worker.ts'
+		'src/language/typescript/monaco.contribution.ts',
+		'src/language/typescript/tsMode.ts',
+		'src/language/typescript/ts.worker.ts'
 	],
-	external: ['monaco-editor-core', '*/tsMode']
+	external: ['monaco-editor-core', '*/tsMode', '*/monaco.contribution']
 });
 buildAMD({
-	base: 'typescript',
-	entryPoint: 'src/typescript/monaco.contribution.ts',
+	base: 'language/typescript',
+	entryPoint: 'src/language/typescript/monaco.contribution.ts',
 	amdModuleId: 'vs/language/typescript/monaco.contribution',
 	amdDependencies: ['vs/editor/editor.api']
 });
 buildAMD({
-	base: 'typescript',
-	entryPoint: 'src/typescript/tsMode.ts',
-	amdModuleId: 'vs/language/typescript/tsMode'
+	base: 'language/typescript',
+	entryPoint: 'src/language/typescript/tsMode.ts',
+	amdModuleId: 'vs/language/typescript/tsMode',
+	external: ['*/monaco.contribution']
 });
 buildAMD({
-	base: 'typescript',
-	entryPoint: 'src/typescript/tsWorker.ts',
+	base: 'language/typescript',
+	entryPoint: 'src/language/typescript/tsWorker.ts',
 	amdModuleId: 'vs/language/typescript/tsWorker'
 });
 

+ 0 - 8
build/fillers/monaco-editor-core-amd.ts

@@ -1,8 +0,0 @@
-/*---------------------------------------------------------------------------------------------
- *  Copyright (c) Microsoft Corporation. All rights reserved.
- *  Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
-
-// Resolves with the global monaco API
-
-export = (<any>self).monaco;

+ 8 - 26
build/fs.js → build/fs.ts

@@ -3,18 +3,14 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const fs = require('fs');
-const path = require('path');
+import * as fs from 'fs';
+import * as path from 'path';
 
 const REPO_ROOT = path.join(__dirname, '../');
 
 const existingDirCache = new Set();
-/**
- * @param {string} dirname
- */
-function ensureDir(dirname) {
+
+export function ensureDir(dirname: string) {
 	/** @type {string[]} */
 	const dirs = [];
 
@@ -32,15 +28,11 @@ function ensureDir(dirname) {
 		}
 	});
 }
-exports.ensureDir = ensureDir;
 
 /**
  * Copy a file.
- *
- * @param {string} _source
- * @param {string} _destination
  */
-function copyFile(_source, _destination) {
+export function copyFile(_source: string, _destination: string) {
 	const source = path.join(REPO_ROOT, _source);
 	const destination = path.join(REPO_ROOT, _destination);
 
@@ -49,15 +41,11 @@ function copyFile(_source, _destination) {
 
 	console.log(`Copied ${_source} to ${_destination}`);
 }
-exports.copyFile = copyFile;
 
 /**
  * Remove a directory and all its contents.
- *
- * @param {string} _dirPath
- * @param {((filename:string)=>boolean)} [keep]
  */
-function removeDir(_dirPath, keep) {
+export function removeDir(_dirPath: string, keep?: (filename: string) => boolean) {
 	if (typeof keep === 'undefined') {
 		keep = () => false;
 	}
@@ -68,18 +56,13 @@ function removeDir(_dirPath, keep) {
 	rmDir(dirPath, _dirPath);
 	console.log(`Deleted ${_dirPath}`);
 
-	/**
-	 * @param {string} dirPath
-	 * @param {string} relativeDirPath
-	 * @returns {boolean}
-	 */
-	function rmDir(dirPath, relativeDirPath) {
+	function rmDir(dirPath: string, relativeDirPath: string): boolean {
 		let keepsFiles = false;
 		const entries = fs.readdirSync(dirPath);
 		for (const entry of entries) {
 			const filePath = path.join(dirPath, entry);
 			const relativeFilePath = path.join(relativeDirPath, entry);
-			if (keep(relativeFilePath)) {
+			if (keep!(relativeFilePath)) {
 				keepsFiles = true;
 				continue;
 			}
@@ -95,4 +78,3 @@ function removeDir(_dirPath, keep) {
 		return keepsFiles;
 	}
 }
-exports.removeDir = removeDir;

+ 10 - 7
build/importTypescript.js → build/importTypescript.ts

@@ -3,12 +3,10 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const path = require('path');
-const fs = require('fs');
-const child_process = require('child_process');
-const { REPO_ROOT } = require('./utils');
+import path = require('path');
+import fs = require('fs');
+import child_process = require('child_process');
+import { REPO_ROOT } from './utils';
 
 const generatedNote = `//
 // **NOTE**: Do not edit directly! This file is generated using \`npm run import-typescript\`
@@ -16,7 +14,7 @@ const generatedNote = `//
 `;
 
 const TYPESCRIPT_LIB_SOURCE = path.join(REPO_ROOT, 'node_modules/typescript/lib');
-const TYPESCRIPT_LIB_DESTINATION = path.join(REPO_ROOT, 'src/typescript/lib');
+const TYPESCRIPT_LIB_DESTINATION = path.join(REPO_ROOT, 'src/language/typescript/lib');
 
 (function () {
 	try {
@@ -74,6 +72,11 @@ export const typescriptVersion = "${typeScriptDependencyVersion}";\n`
 		'/* MONACOCHANGE */false/* END MONACOCHANGE */'
 	);
 
+	tsServices = tsServices.replace(
+		/module.exports = ts;/m,
+		'/* MONACOCHANGE */ /*module.exports = ts;*/ /* END MONACOCHANGE */'
+	);
+
 	// Flag any new require calls (outside comments) so they can be corrected preemptively.
 	// To avoid missing cases (or using an even more complex regex), temporarily remove comments
 	// about require() and then check for lines actually calling require().

+ 10 - 14
build/npm/installAll.js → build/npm/installAll.ts

@@ -3,14 +3,12 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const glob = require('glob');
-const path = require('path');
-const fs = require('fs');
-const cp = require('child_process');
+import glob = require('glob');
+import path = require('path');
+import fs = require('fs');
+import cp = require('child_process');
 const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm';
-const { REPO_ROOT } = require('../utils');
+import { REPO_ROOT } from '../utils';
 
 const files = glob.sync('**/package.json', {
 	cwd: REPO_ROOT,
@@ -29,18 +27,16 @@ for (const file of files) {
 }
 
 function npmInstall(location) {
-	/** @type {'inherit'} */
 	const stdio = 'inherit';
-	const opts = {
-		env: process.env,
-		cwd: location,
-		stdio
-	};
 	const args = ['install'];
 
 	console.log(`Installing dependencies in ${location}...`);
 	console.log(`$ npm ${args.join(' ')}`);
-	const result = cp.spawnSync(npm, args, opts);
+	const result = cp.spawnSync(npm, args, {
+		env: process.env,
+		cwd: location,
+		stdio
+	});
 
 	if (result.error || result.status !== 0) {
 		process.exit(1);

+ 4 - 6
build/npm/removeAll.js → build/npm/removeAll.ts

@@ -3,12 +3,10 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const glob = require('glob');
-const path = require('path');
-const fs = require('fs');
-const { REPO_ROOT } = require('../utils');
+import glob from 'glob';
+import path from 'path';
+import fs from 'fs';
+import { REPO_ROOT } from '../utils';
 
 const files = glob.sync('**/package-lock.json', {
 	cwd: REPO_ROOT,

+ 2 - 2
build/postinstall.js → build/postinstall.ts

@@ -3,8 +3,8 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-const cp = require('child_process');
-const path = require('path');
+import cp = require('child_process');
+import path = require('path');
 
 function huskyInstall() {
 	console.log(`Installing husky hooks...`);

+ 53 - 106
build/release.js → build/release.ts

@@ -3,24 +3,12 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-/**
- * @typedef { { src:string; built:string; releaseDev:string; releaseMin:string; } } ICorePaths
- * @typedef { { dev:string; min:string; esm: string; } } IPluginPaths
- * @typedef { { name:string; contrib:string; modulePrefix:string; rootPath:string; paths:IPluginPaths } } IPlugin
- * @typedef { { METADATA: {CORE:{paths:ICorePaths}; PLUGINS:IPlugin[];} } } IMetadata
- */
-/** @typedef {import('../build/utils').IFile} IFile */
-
-const path = require('path');
-const fs = require('fs');
-const { REPO_ROOT, readFiles, writeFiles } = require('../build/utils');
-const { removeDir } = require('../build/fs');
-const ts = require('typescript');
-/**@type { IMetadata } */
-const metadata = require('../metadata.js');
-const { generateMetadata } = require('./releaseMetadata');
+import path = require('path');
+import fs = require('fs');
+import { REPO_ROOT, readFiles, writeFiles, IFile } from '../build/utils';
+import { removeDir } from '../build/fs';
+import ts = require('typescript');
+import { generateMetadata } from './releaseMetadata';
 
 removeDir(`release`);
 
@@ -76,33 +64,19 @@ generateMetadata();
 
 /**
  * Release to `dev` or `min`.
- * @param {'dev'|'min'} type
  */
-function AMD_releaseOne(type) {
+function AMD_releaseOne(type: 'dev' | 'min') {
 	const coreFiles = readFiles(`node_modules/monaco-editor-core/${type}/**/*`, {
 		base: `node_modules/monaco-editor-core/${type}`
 	});
 	AMD_addPluginContribs(type, coreFiles);
 	writeFiles(coreFiles, `release/${type}`);
 
-	for (const plugin of metadata.METADATA.PLUGINS) {
-		AMD_releasePlugin(plugin, type, `release/${type}`);
-	}
-}
-
-/**
- * Release a plugin to `dev` or `min`.
- * @param {IPlugin} plugin
- * @param {'dev'|'min'} type
- * @param {string} destinationPath
- */
-function AMD_releasePlugin(plugin, type, destinationPath) {
-	const pluginPath = path.join(plugin.rootPath, plugin.paths[type]); // dev or min
-	const contribPath =
-		path.join(pluginPath, plugin.contrib.substring(plugin.modulePrefix.length)) + '.js';
-
-	const files = readFiles(`${pluginPath}/**/*`, { base: pluginPath, ignore: [contribPath] });
-	writeFiles(files, path.join(destinationPath, plugin.modulePrefix));
+	const pluginFiles = readFiles(`out/release/${type}/**/*`, {
+		base: `out/release/${type}`,
+		ignore: ['**/monaco.contribution.js']
+	});
+	writeFiles(pluginFiles, `release/${type}`);
 }
 
 /**
@@ -110,11 +84,8 @@ function AMD_releasePlugin(plugin, type, destinationPath) {
  * - rename the AMD module 'vs/editor/editor.main' to 'vs/editor/edcore.main'
  * - append monaco.contribution modules from plugins
  * - append new AMD module 'vs/editor/editor.main' that stiches things together
- *
- * @param {'dev'|'min'} type
- * @param {IFile[]} files
  */
-function AMD_addPluginContribs(type, files) {
+function AMD_addPluginContribs(type: 'dev' | 'min', files: IFile[]) {
 	for (const file of files) {
 		if (!/editor\.main\.js$/.test(file.path)) {
 			continue;
@@ -125,25 +96,21 @@ function AMD_addPluginContribs(type, files) {
 		// Rename the AMD module 'vs/editor/editor.main' to 'vs/editor/edcore.main'
 		contents = contents.replace(/"vs\/editor\/editor\.main\"/, '"vs/editor/edcore.main"');
 
-		/** @type {string[]} */
-		let extraContent = [];
-		/** @type {string[]} */
-		let allPluginsModuleIds = [];
-
-		metadata.METADATA.PLUGINS.forEach(function (plugin) {
-			allPluginsModuleIds.push(plugin.contrib);
-			const pluginPath = path.join(plugin.rootPath, plugin.paths[type]); // dev or min
-			const contribPath =
-				path.join(REPO_ROOT, pluginPath, plugin.contrib.substring(plugin.modulePrefix.length)) +
-				'.js';
-			let contribContents = fs.readFileSync(contribPath).toString();
-
-			contribContents = contribContents.replace(
-				/define\((['"][a-z\/\-]+\/fillers\/monaco-editor-core['"]),\[\],/,
-				"define($1,['vs/editor/editor.api'],"
-			);
-
-			extraContent.push(contribContents);
+		const pluginFiles = readFiles(`out/release/${type}/**/monaco.contribution.js`, {
+			base: `out/release/${type}`
+		});
+
+		const extraContent = pluginFiles.map((file) => {
+			return file.contents
+				.toString()
+				.replace(
+					/define\((['"][a-z\/\-]+\/fillers\/monaco-editor-core['"]),\[\],/,
+					"define($1,['vs/editor/editor.api'],"
+				);
+		});
+
+		const allPluginsModuleIds = pluginFiles.map((file) => {
+			return file.path.replace(/\.js$/, '');
 		});
 
 		extraContent.push(
@@ -176,22 +143,16 @@ function ESM_release() {
 	ESM_addPluginContribs(coreFiles);
 	writeFiles(coreFiles, `release/esm`);
 
-	for (const plugin of metadata.METADATA.PLUGINS) {
-		ESM_releasePlugin(plugin, `release/esm`);
-	}
+	ESM_releasePlugins();
 }
 
 /**
  * Release a plugin to `esm`.
  * Adds a dependency to 'vs/editor/editor.api' in contrib files in order for `monaco` to be defined.
  * Rewrites imports for 'monaco-editor-core/**'
- * @param {IPlugin} plugin
- * @param {string} destinationPath
  */
-function ESM_releasePlugin(plugin, destinationPath) {
-	const pluginPath = path.join(plugin.rootPath, plugin.paths['esm']);
-
-	const files = readFiles(`${pluginPath}/**/*`, { base: pluginPath });
+function ESM_releasePlugins() {
+	const files = readFiles(`out/release/esm/**/*`, { base: 'out/release/esm/' });
 
 	for (const file of files) {
 		if (!/(\.js$)|(\.ts$)/.test(file.path)) {
@@ -217,10 +178,9 @@ function ESM_releasePlugin(plugin, destinationPath) {
 					importText = 'monaco-editor-core/esm/vs/editor/editor.api';
 				}
 
-				const myFileDestPath = path.join(plugin.modulePrefix, file.path);
 				const importFilePath = importText.substring('monaco-editor-core/esm/'.length);
 				let relativePath = path
-					.relative(path.dirname(myFileDestPath), importFilePath)
+					.relative(path.dirname(file.path), importFilePath)
 					.replace(/\\/g, '/');
 				if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) {
 					relativePath = './' + relativePath;
@@ -238,9 +198,8 @@ function ESM_releasePlugin(plugin, destinationPath) {
 			continue;
 		}
 
-		const myFileDestPath = path.join(plugin.modulePrefix, file.path);
 		const apiFilePath = 'vs/editor/editor.api';
-		let relativePath = path.relative(path.dirname(myFileDestPath), apiFilePath).replace(/\\/g, '/');
+		let relativePath = path.relative(path.dirname(file.path), apiFilePath).replace(/\\/g, '/');
 		if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) {
 			relativePath = './' + relativePath;
 		}
@@ -251,14 +210,13 @@ function ESM_releasePlugin(plugin, destinationPath) {
 	}
 
 	ESM_addImportSuffix(files);
-	writeFiles(files, path.join(destinationPath, plugin.modulePrefix));
+	writeFiles(files, `release/esm`);
 }
 
 /**
  * Adds `.js` to all import statements.
- * @param {IFile[]} files
  */
-function ESM_addImportSuffix(files) {
+function ESM_addImportSuffix(files: IFile[]) {
 	for (const file of files) {
 		if (!/\.js$/.test(file.path)) {
 			continue;
@@ -272,7 +230,8 @@ function ESM_addImportSuffix(files) {
 			const pos = info.importedFiles[i].pos;
 			const end = info.importedFiles[i].end;
 
-			if (/\.css$/.test(importText)) {
+			if (/(\.css)|(\.js)$/.test(importText)) {
+				// A CSS import or an import already using .js
 				continue;
 			}
 
@@ -286,9 +245,8 @@ function ESM_addImportSuffix(files) {
 /**
  * - Rename esm/vs/editor/editor.main.js to esm/vs/editor/edcore.main.js
  * - Create esm/vs/editor/editor.main.js that that stiches things together
- * @param {IFile[]} files
  */
-function ESM_addPluginContribs(files) {
+function ESM_addPluginContribs(files: IFile[]) {
 	for (const file of files) {
 		if (!/editor\.main\.js$/.test(file.path)) {
 			continue;
@@ -298,20 +256,20 @@ function ESM_addPluginContribs(files) {
 
 	const mainFileDestPath = 'vs/editor/editor.main.js';
 
-	/** @type {string[]} */
-	let mainFileImports = [];
-	for (const plugin of metadata.METADATA.PLUGINS) {
-		const contribDestPath = plugin.contrib;
-
+	const mainFileImports = readFiles(`out/release/esm/**/monaco.contribution.js`, {
+		base: `out/release/esm`
+	}).map((file) => {
 		let relativePath = path
-			.relative(path.dirname(mainFileDestPath), contribDestPath)
-			.replace(/\\/g, '/');
+			.relative(path.dirname(mainFileDestPath), file.path)
+			.replace(/\\/g, '/')
+			.replace(/\.js$/, '');
+
 		if (!/(^\.\/)|(^\.\.\/)/.test(relativePath)) {
 			relativePath = './' + relativePath;
 		}
 
-		mainFileImports.push(relativePath);
-	}
+		return relativePath;
+	});
 
 	const mainFileContents =
 		mainFileImports.map((name) => `import '${name}';`).join('\n') +
@@ -334,17 +292,10 @@ function releaseDTS() {
 
 	let contents = monacodts.contents.toString();
 
-	/** @type {string[]} */
-	const extraContent = [];
-	metadata.METADATA.PLUGINS.forEach(function (plugin) {
-		const dtsPath = path.join(plugin.rootPath, './monaco.d.ts');
-		try {
-			let plugindts = fs.readFileSync(dtsPath).toString();
-			plugindts = plugindts.replace(/\/\/\/ <reference.*\n/m, '');
-			extraContent.push(plugindts);
-		} catch (err) {
-			return;
-		}
+	const extraContent = readFiles('out/release/*.d.ts', {
+		base: 'out/release/'
+	}).map((file) => {
+		return file.contents.toString().replace(/\/\/\/ <reference.*\n/m, '');
 	});
 
 	contents =
@@ -379,10 +330,8 @@ function releaseDTS() {
 /**
  * Transforms a .d.ts which uses internal modules (namespaces) to one which is usable with external modules
  * This function is duplicated in the `vscode` repo.
- * @param {string} contents
- * @returns string
  */
-function toExternalDTS(contents) {
+function toExternalDTS(contents: string): string {
 	let lines = contents.split(/\r\n|\r|\n/);
 	let killNextCloseCurlyBrace = false;
 	for (let i = 0; i < lines.length; i++) {
@@ -426,10 +375,8 @@ function toExternalDTS(contents) {
 
 /**
  * Normalize line endings and ensure consistent 4 spaces indentation
- * @param {string} contents
- * @returns {string}
  */
-function cleanFile(contents) {
+function cleanFile(contents: string): string {
 	return contents
 		.split(/\r\n|\r|\n/)
 		.map(function (line) {

+ 31 - 37
build/releaseMetadata.js → build/releaseMetadata.ts

@@ -3,13 +3,11 @@
  *  Licensed under the MIT License. See LICENSE in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const glob = require('glob');
-const path = require('path');
-const fs = require('fs');
-const { REPO_ROOT } = require('./utils');
-const { ensureDir } = require('./fs');
+import glob = require('glob');
+import path = require('path');
+import fs = require('fs');
+import { REPO_ROOT } from './utils';
+import { ensureDir } from './fs';
 
 const customFeatureLabels = {
 	'vs/editor/browser/controller/coreCommands': 'coreCommands',
@@ -25,10 +23,7 @@ const customFeatureLabels = {
 	'vs/editor/standalone/browser/quickAccess/standaloneHelpQuickAccess': 'quickHelp'
 };
 
-/**
- * @returns { Promise<{ label: string; entry: string; }[]> }
- */
-function getBasicLanguages() {
+function getBasicLanguages(): Promise<{ label: string; entry: string }[]> {
 	return new Promise((resolve, reject) => {
 		glob(
 			'./release/esm/vs/basic-languages/*/*.contribution.js',
@@ -54,10 +49,7 @@ function getBasicLanguages() {
 	});
 }
 
-/**
- * @returns { Promise<string[]> }
- */
-function readAdvancedLanguages() {
+function readAdvancedLanguages(): Promise<string[]> {
 	return new Promise((resolve, reject) => {
 		glob(
 			'./release/esm/vs/language/*/monaco.contribution.js',
@@ -78,10 +70,9 @@ function readAdvancedLanguages() {
 	});
 }
 
-/**
- * @returns { Promise<{ label: string; entry: string; worker: { id: string; entry: string; }; }[]> }
- */
-function getAdvancedLanguages() {
+function getAdvancedLanguages(): Promise<
+	{ label: string; entry: string; worker: { id: string; entry: string } }[]
+> {
 	return readAdvancedLanguages().then((languages) => {
 		let result = [];
 		for (const lang of languages) {
@@ -112,11 +103,11 @@ function getAdvancedLanguages() {
 	}
 }
 
-function generateMetadata() {
+export function generateMetadata() {
 	return Promise.all([getBasicLanguages(), getAdvancedLanguages()]).then(
 		([basicLanguages, advancedLanguages]) => {
-			basicLanguages.sort(strcmp);
-			advancedLanguages.sort(strcmp);
+			basicLanguages.sort((a, b) => strcmp(a.entry, b.entry));
+			advancedLanguages.sort((a, b) => strcmp(a.entry, b.entry));
 
 			let i = 0,
 				len = basicLanguages.length;
@@ -197,13 +188,8 @@ exports.languages = ${JSON.stringify(languages, null, '  ')};
 		}
 	);
 }
-exports.generateMetadata = generateMetadata;
 
-/**
- * @tyoe {string} a
- * @tyoe {string} b
- */
-function strcmp(a, b) {
+function strcmp(a: string, b: string) {
 	if (a < b) {
 		return -1;
 	}
@@ -213,10 +199,7 @@ function strcmp(a, b) {
 	return 0;
 }
 
-/**
- * @returns {{label:string;entry:string|string[];}[]}
- */
-function getFeatures() {
+function getFeatures(): { label: string; entry: string | string[] }[] {
 	const skipImports = [
 		'vs/editor/browser/widget/codeEditorWidget',
 		'vs/editor/browser/widget/diffEditorWidget',
@@ -228,8 +211,7 @@ function getFeatures() {
 		'vs/editor/contrib/gotoSymbol/documentSymbols'
 	];
 
-	/** @type {string[]} */
-	let features = [];
+	let features: string[] = [];
 	const files =
 		fs.readFileSync(path.join(REPO_ROOT, 'release/esm/vs/editor/edcore.main.js')).toString() +
 		fs.readFileSync(path.join(REPO_ROOT, 'release/esm/vs/editor/editor.all.js')).toString();
@@ -243,10 +225,22 @@ function getFeatures() {
 		}
 	});
 
-	/** @type {{label:string;entry:any;}[]} */
-	let result = features.map((feature) => {
+	let result: { label: string; entry: any }[] = features.map((feature) => {
+		/** @type {string} */ let label;
+		if (customFeatureLabels[feature]) {
+			label = customFeatureLabels[feature];
+		} else {
+			const m1 = feature.match(/^vs\/editor\/contrib\/([^\/]+)/);
+			if (m1) {
+				// for editor/contrib features, use the first segment
+				label = m1[1];
+			} else {
+				// for everything else, use the last segment folder
+				label = path.basename(path.dirname(feature));
+			}
+		}
 		return {
-			label: customFeatureLabels[feature] || path.basename(path.dirname(feature)),
+			label: label,
 			entry: feature
 		};
 	});

+ 7 - 15
build/simpleserver.js → build/simpleserver.ts

@@ -3,14 +3,12 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-const fs = require('fs');
-const path = require('path');
-const http = require('http');
-const yaserver = require('yaserver');
-const { REPO_ROOT } = require('./utils');
-const { ensureDir } = require('./fs');
+import fs = require('fs');
+import path = require('path');
+import http = require('http');
+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');
 
@@ -100,7 +98,6 @@ function generateTestSamplesTask() {
 			'</div>',
 			'<div style="clear:both"></div>',
 			'',
-			'<script src="../../metadata.js"></script>',
 			'<script src="dev-setup.js"></script>',
 			'<script>',
 			'loadEditor(function() {',
@@ -148,7 +145,6 @@ function generateTestSamplesTask() {
 				);
 			})
 			.join('<br/>\n'),
-		'<script src="../../metadata.js"></script>',
 		'<script src="dev-setup.js"></script>',
 		'</body>',
 		'</html>'
@@ -159,11 +155,7 @@ function generateTestSamplesTask() {
 	);
 }
 
-/**
- * @param {string} rootDir
- * @param {number} port
- */
-function createSimpleServer(rootDir, port) {
+function createSimpleServer(rootDir: string, port: number) {
 	yaserver
 		.createServer({
 			rootDir: rootDir

+ 7 - 0
build/tsconfig.json

@@ -0,0 +1,7 @@
+{
+	"compilerOptions": {
+		"noEmit": true,
+		"esModuleInterop": true
+	},
+	"files": ["./**/*"]
+}

+ 53 - 84
build/utils.js → build/utils.ts

@@ -3,26 +3,20 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
+import * as fs from 'fs';
+import * as path from 'path';
+import * as cp from 'child_process';
+import * as esbuild from 'esbuild';
+import alias from 'esbuild-plugin-alias';
+import * as glob from 'glob';
+import { ensureDir } from './fs';
 
-const fs = require('fs');
-const path = require('path');
-const cp = require('child_process');
-const esbuild = require('esbuild');
-/** @type {any} */
-const alias = require('esbuild-plugin-alias');
-const glob = require('glob');
-const { ensureDir } = require('./fs');
-
-const REPO_ROOT = path.join(__dirname, '../');
-exports.REPO_ROOT = REPO_ROOT;
+export const REPO_ROOT = path.join(__dirname, '../');
 
 /**
  * Launch the typescript compiler synchronously over a project.
- *
- * @param {string} _projectPath
  */
-function tsc(_projectPath) {
+export function tsc(_projectPath: string) {
 	const projectPath = path.join(REPO_ROOT, _projectPath);
 	console.log(`Launching compiler at ${_projectPath}...`);
 	const res = cp.spawnSync(
@@ -35,14 +29,11 @@ function tsc(_projectPath) {
 		process.exit(res.status);
 	}
 }
-exports.tsc = tsc;
 
 /**
  * Launch prettier on a specific file.
- *
- * @param {string} _filePath
  */
-function prettier(_filePath) {
+export function prettier(_filePath: string) {
 	const filePath = path.join(REPO_ROOT, _filePath);
 	cp.spawnSync(
 		process.execPath,
@@ -52,16 +43,11 @@ function prettier(_filePath) {
 
 	console.log(`Ran prettier over ${_filePath}`);
 }
-exports.prettier = prettier;
 
 /**
  * Transform an external .d.ts file to an internal .d.ts file
- *
- * @param {string} _source
- * @param {string} _destination
- * @param {string} namespace
  */
-function dts(_source, _destination, namespace) {
+export function dts(_source: string, _destination: string, namespace: string) {
 	const source = path.join(REPO_ROOT, _source);
 	const destination = path.join(REPO_ROOT, _destination);
 
@@ -100,12 +86,8 @@ function dts(_source, _destination, namespace) {
 
 	prettier(_destination);
 }
-exports.dts = dts;
 
-/**
- * @param {import('esbuild').BuildOptions} options
- */
-function build(options) {
+export function build(options: import('esbuild').BuildOptions) {
 	esbuild.build(options).then((result) => {
 		if (result.errors.length > 0) {
 			console.error(result.errors);
@@ -115,16 +97,8 @@ function build(options) {
 		}
 	});
 }
-exports.build = build;
 
-/**
- * @param {{
- *   base: string;
- *   entryPoints: string[];
- *   external: string[];
- * }} options
- */
-function buildESM(options) {
+export function buildESM(options: { base: string; entryPoints: string[]; external: string[] }) {
 	build({
 		entryPoints: options.entryPoints,
 		bundle: true,
@@ -138,7 +112,7 @@ function buildESM(options) {
 		},
 		external: options.external,
 		outbase: `src/${options.base}`,
-		outdir: `out/release/${options.base}/esm/`,
+		outdir: `out/release/esm/vs/${options.base}/`,
 		plugins: [
 			alias({
 				'vscode-nls': path.join(__dirname, 'fillers/vscode-nls.ts')
@@ -146,20 +120,23 @@ function buildESM(options) {
 		]
 	});
 }
-exports.buildESM = buildESM;
 
-/**
- * @param {'dev'|'min'} type
- * @param {{
- *   base: string;
- *   entryPoint: string;
- *   amdModuleId: string;
- *   amdDependencies?: string[];
- * }} options
- */
-function buildOneAMD(type, options) {
-	/** @type {import('esbuild').BuildOptions} */
-	const opts = {
+function buildOneAMD(
+	type: 'dev' | 'min',
+	options: {
+		base: string;
+		entryPoint: string;
+		amdModuleId: string;
+		amdDependencies?: string[];
+		external?: string[];
+	}
+) {
+	if (!options.amdDependencies) {
+		options.amdDependencies = [];
+	}
+	options.amdDependencies.unshift('require');
+
+	const opts: esbuild.BuildOptions = {
 		entryPoints: [options.entryPoint],
 		bundle: true,
 		target: 'esnext',
@@ -169,21 +146,22 @@ function buildOneAMD(type, options) {
 		},
 		globalName: 'moduleExports',
 		banner: {
-			js: `${bundledFileHeader}define("${options.amdModuleId}",[${(options.amdDependencies || [])
+			js: `${bundledFileHeader}define("${options.amdModuleId}", [${(options.amdDependencies || [])
 				.map((dep) => `"${dep}"`)
-				.join(',')}],()=>{`
+				.join(',')}],(require)=>{`
 		},
 		footer: {
 			js: 'return moduleExports;\n});'
 		},
 		outbase: `src/${options.base}`,
-		outdir: `out/release/${options.base}/${type}/`,
+		outdir: `out/release/${type}/vs/${options.base}/`,
 		plugins: [
 			alias({
 				'vscode-nls': path.join(__dirname, '../build/fillers/vscode-nls.ts'),
-				'monaco-editor-core': path.join(__dirname, '../build/fillers/monaco-editor-core-amd.ts')
+				'monaco-editor-core': path.join(__dirname, '../src/fillers/monaco-editor-core-amd.ts')
 			})
-		]
+		],
+		external: ['vs/editor/editor.api', ...(options.external || [])]
 	};
 	if (type === 'min') {
 		opts.minify = true;
@@ -191,19 +169,16 @@ function buildOneAMD(type, options) {
 	build(opts);
 }
 
-/**
- * @param {{
- *   base: string;
- *   entryPoint: string;
- *   amdModuleId: string;
- *   amdDependencies?: string[];
- * }} options
- */
-function buildAMD(options) {
+export function buildAMD(options: {
+	base: string;
+	entryPoint: string;
+	amdModuleId: string;
+	amdDependencies?: string[];
+	external?: string[];
+}) {
 	buildOneAMD('dev', options);
 	buildOneAMD('min', options);
 }
-exports.buildAMD = buildAMD;
 
 function getGitVersion() {
 	const git = path.join(REPO_ROOT, '.git');
@@ -255,7 +230,7 @@ function getGitVersion() {
 	return refs[ref];
 }
 
-const bundledFileHeader = (() => {
+export const bundledFileHeader = (() => {
 	const sha1 = getGitVersion();
 	const semver = require('../package.json').version;
 	const headerVersion = semver + '(' + sha1 + ')';
@@ -272,16 +247,16 @@ const bundledFileHeader = (() => {
 
 	return BUNDLED_FILE_HEADER;
 })();
-exports.bundledFileHeader = bundledFileHeader;
 
-/** @typedef {{ path:string; contents:Buffer;}} IFile */
+export interface IFile {
+	path: string;
+	contents: Buffer;
+}
 
-/**
- * @param {string} pattern
- * @param {{ base:string; ignore?:string[]; dot?:boolean; }} options
- * @returns {IFile[]}
- */
-function readFiles(pattern, options) {
+export function readFiles(
+	pattern: string,
+	options: { base: string; ignore?: string[]; dot?: boolean }
+): IFile[] {
 	let files = glob.sync(pattern, { cwd: REPO_ROOT, ignore: options.ignore, dot: options.dot });
 	// remove dirs
 	files = files.filter((file) => {
@@ -302,17 +277,11 @@ function readFiles(pattern, options) {
 		};
 	});
 }
-exports.readFiles = readFiles;
 
-/**
- * @param {IFile[]} files
- * @param {string} dest
- */
-function writeFiles(files, dest) {
+export function writeFiles(files: IFile[], dest: string) {
 	for (const file of files) {
 		const fullPath = path.join(REPO_ROOT, dest, file.path);
 		ensureDir(path.dirname(fullPath));
 		fs.writeFileSync(fullPath, file.contents);
 	}
 }
-exports.writeFiles = writeFiles;

+ 16 - 23
build/website.js → build/website.ts

@@ -3,20 +3,15 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-//@ts-check
-
-/** @typedef {import('../build/utils').IFile} IFile */
-
-const glob = require('glob');
-const path = require('path');
-const fs = require('fs');
-const cp = require('child_process');
-const CleanCSS = require('clean-css');
-const { REPO_ROOT, readFiles, writeFiles } = require('./utils');
-const { removeDir } = require('./fs');
-
-/** @type {string} */
-const MONACO_EDITOR_VERSION = (() => {
+import glob = require('glob');
+import path = require('path');
+import fs = require('fs');
+import cp = require('child_process');
+import CleanCSS from 'clean-css';
+import { REPO_ROOT, readFiles, writeFiles } from './utils';
+import { removeDir } from './fs';
+
+const MONACO_EDITOR_VERSION: string = (() => {
 	const output = cp.execSync(`npm show monaco-editor version`).toString();
 	const version = output.split(/\r\n|\r|\n/g)[0];
 	if (!/\d+\.\d+\.\d+/.test(version)) {
@@ -72,14 +67,12 @@ function checkSamples() {
 	}
 }
 
-/**
- * @param {string} dataPath
- * @param {string} contents
- * @param {RegExp} regex
- * @param {(match:string, fileContents:Buffer)=>string} callback
- * @returns {string}
- */
-function replaceWithRelativeResource(dataPath, contents, regex, callback) {
+function replaceWithRelativeResource(
+	dataPath: string,
+	contents: string,
+	regex: RegExp,
+	callback: (match: string, fileContents: Buffer) => string
+): string {
 	return contents.replace(regex, function (_, m0) {
 		const filePath = path.join(REPO_ROOT, 'website', path.dirname(dataPath), m0);
 		return callback(m0, fs.readFileSync(filePath));
@@ -140,7 +133,7 @@ function generateWebsite() {
 			contents,
 			/<link data-inline="yes-please" href="([^"]+)".*/g,
 			function (m0, fileContents) {
-				const minifiedCSS = new CleanCSS().minify(fileContents.toString('utf8')).styles;
+				const minifiedCSS = (new CleanCSS() as any).minify(fileContents.toString('utf8')).styles;
 				return `<style>${minifiedCSS}</style>`;
 			}
 		);

+ 24 - 18
docs/integrate-esm.md

@@ -192,27 +192,33 @@ Adding monaco editor to [Vite](https://vitejs.dev/) is simple since it has built
 
 ```js
 import * as monaco from 'monaco-editor';
-import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
-import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker';
-import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
-import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
-import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker';
 
 self.MonacoEnvironment = {
-	getWorker(_, label) {
-		if (label === 'json') {
-			return new jsonWorker();
-		}
-		if (label === 'css' || label === 'scss' || label === 'less') {
-			return new cssWorker();
-		}
-		if (label === 'html' || label === 'handlebars' || label === 'razor') {
-			return new htmlWorker();
-		}
-		if (label === 'typescript' || label === 'javascript') {
-			return new tsWorker();
+	getWorker: function (workerId, label) {
+		const getWorkerModule = (moduleUrl, label) => {
+			return new Worker(self.MonacoEnvironment.getWorkerUrl(moduleUrl), {
+				name: label,
+				type: 'module'
+			});
+		};
+
+		switch (label) {
+			case 'json':
+				return getWorkerModule('/monaco-editor/esm/vs/language/json/json.worker?worker', label);
+			case 'css':
+			case 'scss':
+			case 'less':
+				return getWorkerModule('/monaco-editor/esm/vs/language/css/css.worker?worker', label);
+			case 'html':
+			case 'handlebars':
+			case 'razor':
+				return getWorkerModule('/monaco-editor/esm/vs/language/html/html.worker?worker', label);
+			case 'typescript':
+			case 'javascript':
+				return getWorkerModule('/monaco-editor/esm/vs/language/typescript/ts.worker?worker', label);
+			default:
+				return getWorkerModule('/monaco-editor/esm/vs/editor/editor.worker?worker', label);
 		}
-		return new editorWorker();
 	}
 };
 

+ 0 - 82
metadata.js

@@ -1,82 +0,0 @@
-(function () {
-	var METADATA = {
-		CORE: {
-			paths: {
-				src: '/vscode/out/vs',
-				'npm/dev': 'node_modules/monaco-editor-core/dev/vs',
-				'npm/min': 'node_modules/monaco-editor-core/min/vs',
-				built: '/vscode/out-monaco-editor-core/min/vs',
-				releaseDev: 'release/dev/vs',
-				releaseMin: 'release/min/vs'
-			}
-		},
-		PLUGINS: [
-			{
-				name: 'monaco-typescript',
-				contrib: 'vs/language/typescript/monaco.contribution',
-				modulePrefix: 'vs/language/typescript',
-				rootPath: './out/release/typescript',
-				paths: {
-					// use ./ to indicate it is relative to the `rootPath`
-					dev: './dev',
-					min: './min',
-					esm: './esm'
-				}
-			},
-			{
-				name: 'monaco-css',
-				contrib: 'vs/language/css/monaco.contribution',
-				modulePrefix: 'vs/language/css',
-				rootPath: './out/release/css',
-				paths: {
-					// use ./ to indicate it is relative to the `rootPath`
-					dev: './dev',
-					min: './min',
-					esm: './esm'
-				}
-			},
-			{
-				name: 'monaco-json',
-				contrib: 'vs/language/json/monaco.contribution',
-				modulePrefix: 'vs/language/json',
-				rootPath: './out/release/json',
-				paths: {
-					// use ./ to indicate it is relative to the `rootPath`
-					dev: './dev',
-					min: './min',
-					esm: './esm'
-				}
-			},
-			{
-				name: 'monaco-html',
-				contrib: 'vs/language/html/monaco.contribution',
-				modulePrefix: 'vs/language/html',
-				rootPath: './out/release/html',
-				paths: {
-					// use ./ to indicate it is relative to the `rootPath`
-					dev: './dev',
-					min: './min',
-					esm: './esm'
-				}
-			},
-			{
-				name: 'monaco-languages',
-				contrib: 'vs/basic-languages/monaco.contribution',
-				modulePrefix: 'vs/basic-languages',
-				rootPath: './out/release/basic-languages',
-				paths: {
-					// use ./ to indicate it is relative to the `rootPath`
-					dev: './dev',
-					min: './min',
-					esm: './esm'
-				}
-			}
-		]
-	};
-
-	if (typeof exports !== 'undefined') {
-		exports.METADATA = METADATA;
-	} else {
-		self.METADATA = METADATA;
-	}
-})();

File diff suppressed because it is too large
+ 3249 - 2
package-lock.json


+ 29 - 25
package.json

@@ -1,25 +1,28 @@
 {
 	"name": "monaco-editor",
-	"version": "0.31.1",
-	"vscode": "5a1b4999493d49c857497ad481d73a737439f305",
+	"version": "0.33.0",
+	"vscode": "6a4e5cc26b29359472378c2a8951c33f4ea73244",
 	"private": true,
 	"description": "A browser based code editor",
 	"author": "Microsoft Corporation",
 	"license": "MIT",
 	"scripts": {
-		"build-website": "node ./build/website.js && npm run typedoc",
-		"import-typescript": "node ./build/importTypescript.js",
+		"build-website": "ts-node ./build/website && npm run typedoc",
+		"import-typescript": "ts-node ./build/importTypescript",
+		"package-for-smoketest-esbuild": "ts-node ./test/smoke/package-esbuild",
 		"playwright-install": "node ./node_modules/playwright/install.js",
 		"playwright-install-deps": "playwright install-deps",
-		"postinstall": "node ./build/postinstall.js",
+		"postinstall": "ts-node ./build/postinstall",
 		"prettier-check": "prettier --check .",
 		"prettier": "prettier --write .",
 		"pretty-quick": "pretty-quick --staged",
-		"release": "node ./build/build.js && node ./build/release.js",
-		"simpleserver": "node ./build/simpleserver",
+		"release": "ts-node ./build/build && ts-node ./build/release",
+		"simpleserver": "ts-node ./build/simpleserver",
 		"smoketest-debug": "node ./test/smoke/runner.js --debug-tests",
 		"smoketest": "node ./test/smoke/runner.js",
 		"test": "mocha test/unit/all.js",
+		"deps-all-remove": "ts-node ./build/npm/removeAll",
+		"deps-all-install": "ts-node ./build/npm/installAll",
 		"typedoc": "cd website/typedoc && \"../../node_modules/.bin/typedoc\" --options ./typedoc.json",
 		"watch": "tsc -w -p ./src"
 	},
@@ -30,31 +33,32 @@
 		"url": "https://github.com/microsoft/monaco-editor"
 	},
 	"devDependencies": {
-		"@types/mocha": "^9.0.0",
+		"@types/mocha": "^9.1.0",
 		"@typescript/vfs": "^1.3.5",
-		"chai": "^4.3.4",
-		"clean-css": "^5.2.2",
-		"esbuild": "^0.13.13",
+		"chai": "^4.3.6",
+		"clean-css": "^5.2.4",
+		"esbuild": "^0.14.49",
 		"esbuild-plugin-alias": "^0.2.1",
 		"glob": "^7.2.0",
 		"husky": "^7.0.4",
-		"jsdom": "^18.1.0",
+		"jsdom": "^19.0.0",
 		"jsonc-parser": "^3.0.0",
-		"mocha": "^9.1.3",
-		"monaco-editor-core": "0.32.0-dev.20220110",
-		"playwright": "^1.16.3",
-		"prettier": "^2.4.1",
-		"pretty-quick": "^3.1.1",
+		"mocha": "^9.2.0",
+		"monaco-editor-core": "0.34.0-dev.20220720",
+		"playwright": "^1.18.1",
+		"prettier": "^2.5.1",
+		"pretty-quick": "^3.1.3",
 		"requirejs": "^2.3.6",
-		"terser": "^5.10.0",
-		"typedoc": "^0.22.9",
-		"typescript": "4.4.4",
-		"vscode-css-languageservice": "^5.1.8",
-		"vscode-html-languageservice": "^4.1.1",
-		"vscode-json-languageservice": "4.1.10",
-		"vscode-languageserver-textdocument": "^1.0.2",
+		"terser": "^5.14.2",
+		"ts-node": "^10.6.0",
+		"typedoc": "^0.22.11",
+		"typescript": "4.5.5",
+		"vscode-css-languageservice": "5.4.1",
+		"vscode-html-languageservice": "4.2.4",
+		"vscode-json-languageservice": "4.2.1",
+		"vscode-languageserver-textdocument": "^1.0.4",
 		"vscode-languageserver-types": "3.16.0",
-		"vscode-uri": "3.0.2",
+		"vscode-uri": "3.0.3",
 		"yaserver": "^0.4.0"
 	}
 }

+ 74 - 74
samples/browser-amd-diff-editor/modified.txt

@@ -1,74 +1,74 @@
-
-/// <reference path="../../references.js" />
-(function () {
-	"use strict";
-	
-	var deltaDecorations = function (oldDecorations, newDecorations) {
-		/// <summary>
-		///   Update oldDecorations to match newDecorations.
-		///   It will remove old decorations which are not found in new decorations
-		///   and add only the really new decorations.
-		/// </summary>
-		/// <param name="oldDecorations" type="Array">
-		///   An array containing ids of existing decorations
-		/// </param>
-		/// <param name="newDecorations" type="Array">
-		///   An array containing literal objects describing new decorations. A
-		///   literal contains the following two fields:
-		///      range
-		///      options
-		/// </param>
-		/// <returns type="Array">
-		///   Returns an array of decorations ids
-		/// </returns>
-		var hashFunc = function (range, options) {
-			return range.startLineNumber + "," + range.startColumn + "-" + range.endLineNumber + "," + range.endColumn +
-				"-" + options.hoverMessage + "-" + options.className + "-" + options.isOverlay + "-" + options.showInOverviewRuler;
-		};
-		return this.changeDecorations(function (changeAccessor) {
-			var i, len, oldDecorationsMap = {}, hash;
-			
-			// Record old decorations in a map
-			// Two decorations can have the same hash
-			for (i = 0, len = oldDecorations.length; i < len; i++) {
-				hash = hashFunc(this.getDecorationRange(oldDecorations[i]), this.getDecorationOptions(oldDecorations[i]));
-				oldDecorationsMap[hash] = oldDecorationsMap[hash] || [];
-				oldDecorationsMap[hash].push(oldDecorations[i]);
-			}
-			
-			// Add only new decorations & mark reused ones
-			var j, lenJ, result = [], usedOldDecorations = {}, oldDecorationsCandidates, reusedOldDecoration;
-			for (i = 0, len = newDecorations.length; i < len; i++) {
-				hash = hashFunc(newDecorations[i].range, newDecorations[i].options);
-				reusedOldDecoration = false;
-				if (oldDecorationsMap.hasOwnProperty(hash)) {
-					oldDecorationsCandidates = oldDecorationsMap[hash];
-					// We can try reusing an old decoration (if it hasn't been reused before)
-					for (j = 0, lenJ = oldDecorationsCandidates.length; j < lenJ; j++) {
-						if (!usedOldDecorations.hasOwnProperty(oldDecorationsCandidates[j])) {
-							// Found an old decoration which can be reused & it hasn't been reused before
-							reusedOldDecoration = true;
-							usedOldDecorations[oldDecorationsCandidates[j]] = true;
-							result.push(oldDecorationsCandidates[j]);
-							break;
-						}
-					}
-				}
-				
-				if (!reusedOldDecoration) {
-					result.push(changeAccessor.addDecoration(newDecorations[i].range, newDecorations[i].options));
-				}
-			}
-			
-			// Remove unused old decorations
-			for (i = 0, len = oldDecorations.length; i < len; i++) {
-				if (!usedOldDecorations.hasOwnProperty(oldDecorations[i])) {
-					changeAccessor.removeDecoration(oldDecorations[i]);
-				}
-			}
-			
-			return result;
-		}.bind(this));
-	};
-
-})();
+
+/// <reference path="../../references.js" />
+(function () {
+	"use strict";
+	
+	var deltaDecorations = function (oldDecorations, newDecorations) {
+		/// <summary>
+		///   Update oldDecorations to match newDecorations.
+		///   It will remove old decorations which are not found in new decorations
+		///   and add only the really new decorations.
+		/// </summary>
+		/// <param name="oldDecorations" type="Array">
+		///   An array containing ids of existing decorations
+		/// </param>
+		/// <param name="newDecorations" type="Array">
+		///   An array containing literal objects describing new decorations. A
+		///   literal contains the following two fields:
+		///      range
+		///      options
+		/// </param>
+		/// <returns type="Array">
+		///   Returns an array of decorations ids
+		/// </returns>
+		var hashFunc = function (range, options) {
+			return range.startLineNumber + "," + range.startColumn + "-" + range.endLineNumber + "," + range.endColumn +
+				"-" + options.hoverMessage + "-" + options.className + "-" + options.isOverlay + "-" + options.showInOverviewRuler;
+		};
+		return this.changeDecorations(function (changeAccessor) {
+			var i, len, oldDecorationsMap = {}, hash;
+			
+			// Record old decorations in a map
+			// Two decorations can have the same hash
+			for (i = 0, len = oldDecorations.length; i < len; i++) {
+				hash = hashFunc(this.getDecorationRange(oldDecorations[i]), this.getDecorationOptions(oldDecorations[i]));
+				oldDecorationsMap[hash] = oldDecorationsMap[hash] || [];
+				oldDecorationsMap[hash].push(oldDecorations[i]);
+			}
+			
+			// Add only new decorations & mark reused ones
+			var j, lenJ, result = [], usedOldDecorations = {}, oldDecorationsCandidates, reusedOldDecoration;
+			for (i = 0, len = newDecorations.length; i < len; i++) {
+				hash = hashFunc(newDecorations[i].range, newDecorations[i].options);
+				reusedOldDecoration = false;
+				if (oldDecorationsMap.hasOwnProperty(hash)) {
+					oldDecorationsCandidates = oldDecorationsMap[hash];
+					// We can try reusing an old decoration (if it hasn't been reused before)
+					for (j = 0, lenJ = oldDecorationsCandidates.length; j < lenJ; j++) {
+						if (!usedOldDecorations.hasOwnProperty(oldDecorationsCandidates[j])) {
+							// Found an old decoration which can be reused & it hasn't been reused before
+							reusedOldDecoration = true;
+							usedOldDecorations[oldDecorationsCandidates[j]] = true;
+							result.push(oldDecorationsCandidates[j]);
+							break;
+						}
+					}
+				}
+				
+				if (!reusedOldDecoration) {
+					result.push(changeAccessor.addDecoration(newDecorations[i].range, newDecorations[i].options));
+				}
+			}
+			
+			// Remove unused old decorations
+			for (i = 0, len = oldDecorations.length; i < len; i++) {
+				if (!usedOldDecorations.hasOwnProperty(oldDecorations[i])) {
+					changeAccessor.removeDecoration(oldDecorations[i]);
+				}
+			}
+			
+			return result;
+		}.bind(this));
+	};
+
+})();

+ 61 - 61
samples/browser-amd-diff-editor/original.txt

@@ -1,61 +1,61 @@
-/// <reference path="../../references.js" />
-(function () {
-	"use strict";
-	
-	// Some useless comment
-	
-	var deltaDecorations = function (oldDecorations, newDecorations) {
-		/// <summary>
-		///   Update oldDecorations to match newDecorations.
-		///   It will remove old decorations which are not found in new decorations
-		///   and add only the really new decorations.
-		/// </summary>
-		/// <param name="oldDecorations" type="Array">
-		///   An array containing ids of existing decorations
-		/// </param>
-		/// <param name="newDecorations" type="Array">
-		///   An array containing literal objects describing new decorations. A
-		///   literal contains the following two fields:
-		///      range
-		///      options
-		/// </param>
-		/// <returns type="Array">
-		///   Returns an array of decorations ids
-		/// </returns>
-		var hashFunc = function (range, options) {
-			return range.startLineNumber + "," + range.startColumn + "-" + range.endLineNumber + "," + range.endColumn +
-				"-" + options.hoverMessage + "-" + options.className + "-" + options.isOverlay + "-" + options.showInOverviewRuler;
-		};
-		return this.changeDecorations(function (changeAccessor) {
-			var i, len, oldDecorationsMap = {}, hash;
-				
-			// Record old decorations in a map
-			for (i = 0, len = oldDecorations.length; i < len; i++) {
-				hash = hashFunc(this.getDecorationRange(oldDecorations[i]), this.getDecorationOptions(oldDecorations[i]));
-				oldDecorationsMap[hash] = i;
-			}
-			
-			// Add only new decorations & mark reused ones
-			var result = [], usedOldDecorationsMap = {};
-			for (i = 0, len = newDecorations.length; i < len; i++) {
-				hash = hashFunc(newDecorations[i].range, newDecorations[i].options);
-				if (oldDecorationsMap.hasOwnProperty(hash)) {
-					usedOldDecorationsMap[oldDecorationsMap[hash]] = true;
-					result.push(oldDecorations[oldDecorationsMap[hash]]);
-				} else {
-					result.push(changeAccessor.addDecoration(newDecorations[i].range, newDecorations[i].options));
-				}
-			}
-			
-			// Remove unused old decorations
-			for (i = 0, len = oldDecorations.length; i < len; i++) {
-				if (!usedOldDecorationsMap.hasOwnProperty(i)) {
-					changeAccessor.removeDecoration(oldDecorations[i]);
-				}
-			}
-			
-			return result;
-		}.bind(this));
-	};
-
-})();
+/// <reference path="../../references.js" />
+(function () {
+	"use strict";
+	
+	// Some useless comment
+	
+	var deltaDecorations = function (oldDecorations, newDecorations) {
+		/// <summary>
+		///   Update oldDecorations to match newDecorations.
+		///   It will remove old decorations which are not found in new decorations
+		///   and add only the really new decorations.
+		/// </summary>
+		/// <param name="oldDecorations" type="Array">
+		///   An array containing ids of existing decorations
+		/// </param>
+		/// <param name="newDecorations" type="Array">
+		///   An array containing literal objects describing new decorations. A
+		///   literal contains the following two fields:
+		///      range
+		///      options
+		/// </param>
+		/// <returns type="Array">
+		///   Returns an array of decorations ids
+		/// </returns>
+		var hashFunc = function (range, options) {
+			return range.startLineNumber + "," + range.startColumn + "-" + range.endLineNumber + "," + range.endColumn +
+				"-" + options.hoverMessage + "-" + options.className + "-" + options.isOverlay + "-" + options.showInOverviewRuler;
+		};
+		return this.changeDecorations(function (changeAccessor) {
+			var i, len, oldDecorationsMap = {}, hash;
+				
+			// Record old decorations in a map
+			for (i = 0, len = oldDecorations.length; i < len; i++) {
+				hash = hashFunc(this.getDecorationRange(oldDecorations[i]), this.getDecorationOptions(oldDecorations[i]));
+				oldDecorationsMap[hash] = i;
+			}
+			
+			// Add only new decorations & mark reused ones
+			var result = [], usedOldDecorationsMap = {};
+			for (i = 0, len = newDecorations.length; i < len; i++) {
+				hash = hashFunc(newDecorations[i].range, newDecorations[i].options);
+				if (oldDecorationsMap.hasOwnProperty(hash)) {
+					usedOldDecorationsMap[oldDecorationsMap[hash]] = true;
+					result.push(oldDecorations[oldDecorationsMap[hash]]);
+				} else {
+					result.push(changeAccessor.addDecoration(newDecorations[i].range, newDecorations[i].options));
+				}
+			}
+			
+			// Remove unused old decorations
+			for (i = 0, len = oldDecorations.length; i < len; i++) {
+				if (!usedOldDecorationsMap.hasOwnProperty(i)) {
+					changeAccessor.removeDecoration(oldDecorations[i]);
+				}
+			}
+			
+			return result;
+		}.bind(this));
+	};
+
+})();

+ 46 - 2
samples/browser-esm-esbuild/build.js

@@ -7,9 +7,9 @@
 
 const esbuild = require('esbuild');
 const path = require('path');
-const { removeDir } = require('../../build/fs');
+const fs = require('fs');
 
-removeDir('samples/browser-esm-esbuild/dist', (entry) => /index.html$/.test(entry));
+removeDir('dist', (entry) => /index.html$/.test(entry));
 
 const workerEntryPoints = [
 	'vs/language/json/json.worker.js',
@@ -50,3 +50,47 @@ function build(opts) {
 		}
 	});
 }
+
+/**
+ * Remove a directory and all its contents.
+ * @param {string} _dirPath
+ * @param {(filename: string) => boolean} [keep]
+ */
+function removeDir(_dirPath, keep) {
+	if (typeof keep === 'undefined') {
+		keep = () => false;
+	}
+	const dirPath = path.join(__dirname, _dirPath);
+	if (!fs.existsSync(dirPath)) {
+		return;
+	}
+	rmDir(dirPath, _dirPath);
+	console.log(`Deleted ${_dirPath}`);
+
+	/**
+	 * @param {string} dirPath
+	 * @param {string} relativeDirPath
+	 * @returns {boolean}
+	 */
+	function rmDir(dirPath, relativeDirPath) {
+		let keepsFiles = false;
+		const entries = fs.readdirSync(dirPath);
+		for (const entry of entries) {
+			const filePath = path.join(dirPath, entry);
+			const relativeFilePath = path.join(relativeDirPath, entry);
+			if (keep(relativeFilePath)) {
+				keepsFiles = true;
+				continue;
+			}
+			if (fs.statSync(filePath).isFile()) {
+				fs.unlinkSync(filePath);
+			} else {
+				keepsFiles = rmDir(filePath, relativeFilePath) || keepsFiles;
+			}
+		}
+		if (!keepsFiles) {
+			fs.rmdirSync(dirPath);
+		}
+		return keepsFiles;
+	}
+}

File diff suppressed because it is too large
+ 2964 - 4599
samples/browser-esm-parcel/package-lock.json


+ 2 - 2
samples/browser-esm-parcel/package.json

@@ -4,7 +4,7 @@
 		"start": "parcel ./src/index.html"
 	},
 	"devDependencies": {
-		"monaco-editor": "^0.31.0",
-		"parcel": "^2.0.1"
+		"monaco-editor": "^0.32.0",
+		"parcel": "^2.2.1"
 	}
 }

File diff suppressed because it is too large
+ 1592 - 174
samples/browser-esm-vite-react/package-lock.json


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

@@ -8,13 +8,13 @@
 	},
 	"dependencies": {},
 	"devDependencies": {
-		"monaco-editor": "^0.31.0",
+		"monaco-editor": "^0.32.0",
 		"react": "^17.0.2",
 		"react-dom": "^17.0.2",
-		"@types/react": "^17.0.35",
+		"@types/react": "^17.0.39",
 		"@types/react-dom": "^17.0.11",
-		"@vitejs/plugin-react": "^1.0.9",
-		"typescript": "^4.4.4",
-		"vite": "^2.6.14"
+		"@vitejs/plugin-react": "^1.1.4",
+		"typescript": "^4.5.5",
+		"vite": "^2.7.13"
 	}
 }

File diff suppressed because it is too large
+ 3660 - 59
samples/browser-esm-webpack-typescript-react/package-lock.json


+ 6 - 6
samples/browser-esm-webpack-typescript-react/package.json

@@ -6,12 +6,12 @@
 	},
 	"dependencies": {},
 	"devDependencies": {
-		"@babel/core": "^7.16.0",
-		"@babel/preset-env": "^7.16.0",
-		"@babel/preset-react": "^7.16.0",
-		"@babel/preset-typescript": "^7.16.0",
-		"@pmmmwh/react-refresh-webpack-plugin": "^0.5.1",
-		"@types/react": "^17.0.35",
+		"@babel/core": "^7.17.0",
+		"@babel/preset-env": "^7.16.11",
+		"@babel/preset-react": "^7.16.7",
+		"@babel/preset-typescript": "^7.16.7",
+		"@pmmmwh/react-refresh-webpack-plugin": "^0.5.4",
+		"@types/react": "^17.0.39",
 		"@types/react-dom": "^17.0.11",
 		"babel-loader": "^8.2.3",
 		"react": "^17.0.2",

+ 2 - 2
samples/browser-esm-webpack/.gitignore

@@ -1,2 +1,2 @@
-dist/*.js
-dist/*.ttf
+dist/*.js
+dist/*.ttf

+ 2 - 2
samples/electron-esm-webpack/.gitignore

@@ -1,2 +1,2 @@
-/dist/*.js
-/dist/*.ttf
+/dist/*.js
+/dist/*.ttf

File diff suppressed because it is too large
+ 5288 - 4
samples/package-lock.json


+ 7 - 7
samples/package.json

@@ -11,19 +11,19 @@
 	"license": "MIT",
 	"devDependencies": {
 		"css-loader": "^5.2.7",
-		"electron": "^15.3.1",
+		"electron": "^17.2.0",
 		"file-loader": "^6.2.0",
 		"glob": "^7.2.0",
 		"html-webpack-plugin": "^5.5.0",
 		"monaco-editor-webpack-plugin": "^7.0.1",
-		"monaco-editor": "^0.31.1",
+		"monaco-editor": "^0.32.1",
 		"style-loader": "^3.3.1",
-		"terser-webpack-plugin": "^5.2.5",
+		"terser-webpack-plugin": "^5.3.1",
 		"ts-loader": "^9.2.6",
-		"typescript": "^4.4.4",
-		"webpack-cli": "^4.9.1",
-		"webpack-dev-server": "^4.5.0",
-		"webpack": "^5.64.1",
+		"typescript": "^4.5.5",
+		"webpack-cli": "^4.9.2",
+		"webpack-dev-server": "^4.7.4",
+		"webpack": "^5.68.0",
 		"yaserver": "^0.4.0"
 	}
 }

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

@@ -165,7 +165,7 @@ export const language = <languages.IMonarchLanguage>{
 
 		units: [
 			[
-				'(em|ex|ch|rem|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
+				'(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
 				'attribute.value.unit',
 				'@pop'
 			]

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

@@ -10,7 +10,7 @@ declare var require: any;
 
 registerLanguage({
 	id: 'javascript',
-	extensions: ['.js', '.es6', '.jsx', '.mjs'],
+	extensions: ['.js', '.es6', '.jsx', '.mjs', '.cjs'],
 	firstLine: '^#!.*\\bnode',
 	filenames: ['jakefile'],
 	aliases: ['JavaScript', 'javascript', 'js'],

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

@@ -164,7 +164,7 @@ export const language = <languages.IMonarchLanguage>{
 
 		units: [
 			[
-				'(em|ex|ch|rem|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
+				'(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
 				'attribute.value.unit',
 				'@pop'
 			]

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

@@ -187,7 +187,7 @@ export const language = <languages.IMonarchLanguage>{
 
 		units: [
 			[
-				'(em|ex|ch|rem|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
+				'(em|ex|ch|rem|fr|vmin|vmax|vw|vh|vm|cm|mm|in|px|pt|pc|deg|grad|rad|turn|s|ms|Hz|kHz|%)?',
 				'number',
 				'@pop'
 			]

+ 34 - 0
src/basic-languages/shell/shell.test.ts

@@ -33,6 +33,40 @@ testTokenization('shell', [
 				{ startIndex: 14, type: 'white.shell' },
 				{ startIndex: 15, type: '' }
 			]
+		},
+		// Tests for case reported in bug #2851, do not confuse identifier(with dashes) with attribute
+		{
+			line: 'foo-bar --baz gorp -123 --abc-123',
+			tokens: [
+				{ startIndex: 0, type: '' },
+				{ startIndex: 7, type: 'white.shell' },
+				{ startIndex: 8, type: 'attribute.name.shell' },
+				{ startIndex: 13, type: 'white.shell' },
+				{ startIndex: 14, type: '' },
+				{ startIndex: 18, type: 'white.shell' },
+				{ startIndex: 19, type: 'attribute.name.shell' },
+				{ startIndex: 23, type: 'white.shell' },
+				{ startIndex: 24, type: 'attribute.name.shell' }
+			]
+		},
+		// Bug #2851 add new definition 'Identifiers with dashes', here one test
+		{
+			line: 'foo | foo-bar | foo-bar-1 | foo-bar-2021-1',
+			tokens: [
+				{ startIndex: 0, type: '' },
+				{ startIndex: 3, type: 'white.shell' },
+				{ startIndex: 4, type: 'delimiter.shell' },
+				{ startIndex: 5, type: 'white.shell' },
+				{ startIndex: 6, type: '' },
+				{ startIndex: 13, type: 'white.shell' },
+				{ startIndex: 14, type: 'delimiter.shell' },
+				{ startIndex: 15, type: 'white.shell' },
+				{ startIndex: 16, type: '' },
+				{ startIndex: 25, type: 'white.shell' },
+				{ startIndex: 26, type: 'delimiter.shell' },
+				{ startIndex: 27, type: 'white.shell' },
+				{ startIndex: 28, type: '' }
+			]
 		}
 	],
 

+ 9 - 3
src/basic-languages/shell/shell.ts

@@ -134,13 +134,19 @@ export const language = <languages.IMonarchLanguage>{
 		'zsh'
 	],
 
+	startingWithDash: /\-+\w+/,
+
+	identifiersWithDashes: /[a-zA-Z]\w+(?:@startingWithDash)+/,
+
 	// we include these common regular expressions
 	symbols: /[=><!~?&|+\-*\/\^;\.,]+/,
 
 	// The main tokenizer for our languages
 	tokenizer: {
 		root: [
-			{ include: '@whitespace' },
+			[/@identifiersWithDashes/, ''],
+
+			[/(\s)((?:@startingWithDash)+)/, ['white', 'attribute.name']],
 
 			[
 				/[a-zA-Z]\w*/,
@@ -153,14 +159,14 @@ export const language = <languages.IMonarchLanguage>{
 				}
 			],
 
+			{ include: '@whitespace' },
+
 			{ include: '@strings' },
 			{ include: '@parameters' },
 			{ include: '@heredoc' },
 
 			[/[{}\[\]()]/, '@brackets'],
 
-			[/-+\w+/, 'attribute.name'],
-
 			[/@symbols/, 'delimiter'],
 
 			{ include: '@numbers' },

+ 4 - 7
src/basic-languages/swift/swift.ts

@@ -57,8 +57,8 @@ export const language = <languages.IMonarchLanguage>{
 		'@asyncHandler',
 		'@available',
 		'@convention',
-		'@derivative', // Swift for TensorFlow
-		'@differentiable', // Swift for TensorFlow
+		'@derivative',
+		'@differentiable',
 		'@discardableResult',
 		'@dynamicCallable',
 		'@dynamicMemberLookup',
@@ -68,10 +68,12 @@ export const language = <languages.IMonarchLanguage>{
 		'@inlinable',
 		'@inline',
 		'@main',
+		'@noDerivative',
 		'@nonobjc',
 		'@noreturn',
 		'@objc',
 		'@objcMembers',
+		'@preconcurrency',
 		'@propertyWrapper',
 		'@requires_stored_property_inits',
 		'@resultBuilder',
@@ -318,11 +320,6 @@ export const language = <languages.IMonarchLanguage>{
 			[/./, 'identifier']
 		],
 
-		//		symbol: [
-		//			[ /@symbols/, 'operator' ],
-		//			[ /@operators/, 'operator' ]
-		//		],
-
 		invokedmethod: [
 			[
 				/([.])(@identifier)/,

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

@@ -127,6 +127,7 @@ export const language = {
 		'null',
 		'number',
 		'object',
+		'out',
 		'package',
 		'private',
 		'protected',

+ 10 - 2
src/basic-languages/yaml/yaml.ts

@@ -1,4 +1,4 @@
-import type { languages } from '../../fillers/monaco-editor-core';
+import { languages } from '../../fillers/monaco-editor-core';
 
 export const conf: languages.LanguageConfiguration = {
 	comments: {
@@ -25,7 +25,15 @@ export const conf: languages.LanguageConfiguration = {
 	],
 	folding: {
 		offSide: true
-	}
+	},
+	onEnterRules: [
+		{
+			beforeText: /:\s*$/,
+			action: {
+				indentAction: languages.IndentAction.Indent
+			}
+		}
+	]
 };
 
 export const language = <languages.IMonarchLanguage>{

+ 4 - 0
src/fillers/editor.api.d.ts

@@ -0,0 +1,4 @@
+declare module 'vs/editor/editor.api' {
+	const x: any;
+	export = x;
+}

+ 3 - 4
src/fillers/monaco-editor-core-amd.ts

@@ -5,8 +5,7 @@
 
 // Resolves with the global monaco API
 
-declare var define: any;
+/// <reference path="./editor.api.d.ts" />
+import * as api from 'vs/editor/editor.api';
 
-define([], function () {
-	return (<any>self).monaco;
-});
+export = api;

+ 4 - 3
src/common/lspLanguageFeatures.ts → src/language/common/lspLanguageFeatures.ts

@@ -16,7 +16,7 @@ import {
 	IDisposable,
 	MarkerSeverity,
 	IEvent
-} from '../fillers/monaco-editor-core';
+} from '../../fillers/monaco-editor-core';
 
 export interface WorkerAccessor<T> {
 	(...more: Uri[]): Promise<T>;
@@ -627,13 +627,14 @@ function toWorkspaceEdit(edit: lsTypes.WorkspaceEdit | null): languages.Workspac
 	if (!edit || !edit.changes) {
 		return void 0;
 	}
-	let resourceEdits: languages.WorkspaceTextEdit[] = [];
+	let resourceEdits: languages.IWorkspaceTextEdit[] = [];
 	for (let uri in edit.changes) {
 		const _uri = Uri.parse(uri);
 		for (let e of edit.changes[uri]) {
 			resourceEdits.push({
 				resource: _uri,
-				edit: {
+				versionId: undefined,
+				textEdit: {
 					range: toRange(e.range),
 					text: e.newText
 				}

+ 0 - 0
src/css/css.worker.ts → src/language/css/css.worker.ts


+ 17 - 1
src/css/cssMode.ts → src/language/css/cssMode.ts

@@ -7,7 +7,7 @@ import { WorkerManager } from './workerManager';
 import type { CSSWorker } from './cssWorker';
 import { LanguageServiceDefaults } from './monaco.contribution';
 import * as languageFeatures from '../common/lspLanguageFeatures';
-import { Uri, IDisposable, languages } from '../fillers/monaco-editor-core';
+import { Uri, IDisposable, languages } from '../../fillers/monaco-editor-core';
 
 export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
 	const disposables: IDisposable[] = [];
@@ -106,6 +106,22 @@ export function setupMode(defaults: LanguageServiceDefaults): IDisposable {
 				)
 			);
 		}
+		if (modeConfiguration.documentFormattingEdits) {
+			providers.push(
+				languages.registerDocumentFormattingEditProvider(
+					languageId,
+					new languageFeatures.DocumentFormattingEditProvider(worker)
+				)
+			);
+		}
+		if (modeConfiguration.documentRangeFormattingEdits) {
+			providers.push(
+				languages.registerDocumentRangeFormattingEditProvider(
+					languageId,
+					new languageFeatures.DocumentRangeFormattingEditProvider(worker)
+				)
+			);
+		}
 	}
 
 	registerProviders();

+ 55 - 42
src/css/cssWorker.ts → src/language/css/cssWorker.ts

@@ -3,7 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import type { worker } from '../fillers/monaco-editor-core';
+import type { worker } from '../../fillers/monaco-editor-core';
 import * as cssService from 'vscode-css-languageservice';
 import { Options } from './monaco.contribution';
 
@@ -12,7 +12,7 @@ export class CSSWorker {
 
 	private _ctx: worker.IWorkerContext;
 	private _languageService: cssService.LanguageService;
-	private _languageSettings: cssService.LanguageSettings;
+	private _languageSettings: Options;
 	private _languageId: string;
 
 	constructor(ctx: worker.IWorkerContext, createData: ICreateData) {
@@ -53,10 +53,10 @@ export class CSSWorker {
 	// --- language service host ---------------
 
 	async doValidation(uri: string): Promise<cssService.Diagnostic[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (document) {
-			let stylesheet = this._languageService.parseStylesheet(document);
-			let diagnostics = this._languageService.doValidation(document, stylesheet);
+			const stylesheet = this._languageService.parseStylesheet(document);
+			const diagnostics = this._languageService.doValidation(document, stylesheet);
 			return Promise.resolve(diagnostics);
 		}
 		return Promise.resolve([]);
@@ -65,63 +65,63 @@ export class CSSWorker {
 		uri: string,
 		position: cssService.Position
 	): Promise<cssService.CompletionList | null> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return null;
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let completions = this._languageService.doComplete(document, position, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const completions = this._languageService.doComplete(document, position, stylesheet);
 		return Promise.resolve(completions);
 	}
 	async doHover(uri: string, position: cssService.Position): Promise<cssService.Hover | null> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return null;
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let hover = this._languageService.doHover(document, position, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const hover = this._languageService.doHover(document, position, stylesheet);
 		return Promise.resolve(hover);
 	}
 	async findDefinition(
 		uri: string,
 		position: cssService.Position
 	): Promise<cssService.Location | null> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return null;
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let definition = this._languageService.findDefinition(document, position, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const definition = this._languageService.findDefinition(document, position, stylesheet);
 		return Promise.resolve(definition);
 	}
 	async findReferences(uri: string, position: cssService.Position): Promise<cssService.Location[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let references = this._languageService.findReferences(document, position, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const references = this._languageService.findReferences(document, position, stylesheet);
 		return Promise.resolve(references);
 	}
 	async findDocumentHighlights(
 		uri: string,
 		position: cssService.Position
 	): Promise<cssService.DocumentHighlight[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let highlights = this._languageService.findDocumentHighlights(document, position, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const highlights = this._languageService.findDocumentHighlights(document, position, stylesheet);
 		return Promise.resolve(highlights);
 	}
 	async findDocumentSymbols(uri: string): Promise<cssService.SymbolInformation[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let symbols = this._languageService.findDocumentSymbols(document, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const symbols = this._languageService.findDocumentSymbols(document, stylesheet);
 		return Promise.resolve(symbols);
 	}
 	async doCodeActions(
@@ -129,21 +129,21 @@ export class CSSWorker {
 		range: cssService.Range,
 		context: cssService.CodeActionContext
 	): Promise<cssService.Command[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let actions = this._languageService.doCodeActions(document, range, context, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const actions = this._languageService.doCodeActions(document, range, context, stylesheet);
 		return Promise.resolve(actions);
 	}
 	async findDocumentColors(uri: string): Promise<cssService.ColorInformation[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let colorSymbols = this._languageService.findDocumentColors(document, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const colorSymbols = this._languageService.findDocumentColors(document, stylesheet);
 		return Promise.resolve(colorSymbols);
 	}
 	async getColorPresentations(
@@ -151,12 +151,12 @@ export class CSSWorker {
 		color: cssService.Color,
 		range: cssService.Range
 	): Promise<cssService.ColorPresentation[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let colorPresentations = this._languageService.getColorPresentations(
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const colorPresentations = this._languageService.getColorPresentations(
 			document,
 			stylesheet,
 			color,
@@ -168,23 +168,23 @@ export class CSSWorker {
 		uri: string,
 		context?: { rangeLimit?: number }
 	): Promise<cssService.FoldingRange[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let ranges = this._languageService.getFoldingRanges(document, context);
+		const ranges = this._languageService.getFoldingRanges(document, context);
 		return Promise.resolve(ranges);
 	}
 	async getSelectionRanges(
 		uri: string,
 		positions: cssService.Position[]
 	): Promise<cssService.SelectionRange[]> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return [];
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let ranges = this._languageService.getSelectionRanges(document, positions, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const ranges = this._languageService.getSelectionRanges(document, positions, stylesheet);
 		return Promise.resolve(ranges);
 	}
 	async doRename(
@@ -192,17 +192,30 @@ export class CSSWorker {
 		position: cssService.Position,
 		newName: string
 	): Promise<cssService.WorkspaceEdit | null> {
-		let document = this._getTextDocument(uri);
+		const document = this._getTextDocument(uri);
 		if (!document) {
 			return null;
 		}
-		let stylesheet = this._languageService.parseStylesheet(document);
-		let renames = this._languageService.doRename(document, position, newName, stylesheet);
+		const stylesheet = this._languageService.parseStylesheet(document);
+		const renames = this._languageService.doRename(document, position, newName, stylesheet);
 		return Promise.resolve(renames);
 	}
+	async format(
+		uri: string,
+		range: cssService.Range | null,
+		options: cssService.CSSFormatConfiguration
+	): Promise<cssService.TextEdit[]> {
+		const document = this._getTextDocument(uri);
+		if (!document) {
+			return [];
+		}
+		const settings = { ...this._languageSettings.format, ...options };
+		const textEdits = this._languageService.format(document, range! /* TODO */, settings);
+		return Promise.resolve(textEdits);
+	}
 	private _getTextDocument(uri: string): cssService.TextDocument | null {
-		let models = this._ctx.getMirrorModels();
-		for (let model of models) {
+		const models = this._ctx.getMirrorModels();
+		for (const model of models) {
 			if (model.uri.toString() === uri) {
 				return cssService.TextDocument.create(
 					uri,

+ 43 - 3
src/css/monaco.contribution.ts → src/language/css/monaco.contribution.ts

@@ -4,7 +4,22 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as mode from './cssMode';
-import { languages, Emitter, IEvent } from '../fillers/monaco-editor-core';
+import { languages, Emitter, IEvent } from '../../fillers/monaco-editor-core';
+
+export interface CSSFormatConfiguration {
+	/** separate selectors with newline (e.g. "a,\nbr" or "a, br"): Default: true */
+	newlineBetweenSelectors?: boolean;
+	/** add a new line after every css rule: Default: true */
+	newlineBetweenRules?: boolean;
+	/** ensure space around selector separators:  '>', '+', '~' (e.g. "a>b" -> "a > b"): Default: false */
+	spaceAroundSelectorSeparator?: boolean;
+	/** put braces on the same line as rules (`collapse`), or put braces on own line, Allman / ANSI style (`expand`). Default `collapse` */
+	braceStyle?: 'collapse' | 'expand';
+	/** whether existing line breaks before elements should be preserved. Default: true */
+	preserveNewLines?: boolean;
+	/** maximum number of line breaks to be preserved in one chunk. Default: unlimited */
+	maxPreserveNewLines?: number;
+}
 
 export interface Options {
 	readonly validate?: boolean;
@@ -32,6 +47,11 @@ export interface Options {
 	 * Configures the CSS data types known by the langauge service.
 	 */
 	readonly data?: CSSDataConfiguration;
+
+	/**
+	 * Settings for the CSS formatter.
+	 */
+	readonly format?: CSSFormatConfiguration;
 }
 
 export interface ModeConfiguration {
@@ -89,6 +109,16 @@ export interface ModeConfiguration {
 	 * Defines whether the built-in selection range provider is enabled.
 	 */
 	readonly selectionRanges?: boolean;
+
+	/**
+	 * Defines whether the built-in document formatting edit provider is enabled.
+	 */
+	readonly documentFormattingEdits?: boolean;
+
+	/**
+	 * Defines whether the built-in document formatting range edit provider is enabled.
+	 */
+	readonly documentRangeFormattingEdits?: boolean;
 }
 
 export interface LanguageServiceDefaults {
@@ -180,7 +210,15 @@ const optionsDefault: Required<Options> = {
 		float: 'ignore',
 		idSelector: 'ignore'
 	},
-	data: { useDefaultDataProvider: true }
+	data: { useDefaultDataProvider: true },
+	format: {
+		newlineBetweenSelectors: true,
+		newlineBetweenRules: true,
+		spaceAroundSelectorSeparator: false,
+		braceStyle: 'collapse',
+		maxPreserveNewLines: undefined,
+		preserveNewLines: true
+	}
 };
 
 const modeConfigurationDefault: Required<ModeConfiguration> = {
@@ -194,7 +232,9 @@ const modeConfigurationDefault: Required<ModeConfiguration> = {
 	colors: true,
 	foldingRanges: true,
 	diagnostics: true,
-	selectionRanges: true
+	selectionRanges: true,
+	documentFormattingEdits: true,
+	documentRangeFormattingEdits: true
 };
 
 export const cssDefaults: LanguageServiceDefaults = new LanguageServiceDefaultsImpl(

+ 1 - 1
src/css/workerManager.ts → src/language/css/workerManager.ts

@@ -5,7 +5,7 @@
 
 import { LanguageServiceDefaults } from './monaco.contribution';
 import type { CSSWorker } from './cssWorker';
-import { editor, IDisposable, Uri } from '../fillers/monaco-editor-core';
+import { editor, IDisposable, Uri } from '../../fillers/monaco-editor-core';
 
 const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
 

+ 0 - 0
src/html/html.worker.ts → src/language/html/html.worker.ts


+ 1 - 1
src/html/htmlMode.ts → src/language/html/htmlMode.ts

@@ -7,7 +7,7 @@ import { WorkerManager } from './workerManager';
 import type { HTMLWorker } from './htmlWorker';
 import { LanguageServiceDefaults } from './monaco.contribution';
 import * as languageFeatures from '../common/lspLanguageFeatures';
-import { Uri, IDisposable, languages } from '../fillers/monaco-editor-core';
+import { Uri, IDisposable, languages } from '../../fillers/monaco-editor-core';
 
 class HTMLCompletionAdapter extends languageFeatures.CompletionAdapter<HTMLWorker> {
 	constructor(worker: languageFeatures.WorkerAccessor<HTMLWorker>) {

+ 1 - 1
src/html/htmlWorker.ts → src/language/html/htmlWorker.ts

@@ -3,7 +3,7 @@
  *  Licensed under the MIT License. See License.txt in the project root for license information.
  *--------------------------------------------------------------------------------------------*/
 
-import { worker } from '../fillers/monaco-editor-core';
+import { worker } from '../../fillers/monaco-editor-core';
 import * as htmlService from 'vscode-html-languageservice';
 import type { Options } from './monaco.contribution';
 import { IHTMLDataProvider } from 'vscode-html-languageservice';

+ 3 - 3
src/html/monaco.contribution.ts → src/language/html/monaco.contribution.ts

@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as mode from './htmlMode';
-import { languages, Emitter, IEvent, IDisposable } from '../fillers/monaco-editor-core';
+import { languages, Emitter, IEvent, IDisposable } from '../../fillers/monaco-editor-core';
 
 export interface HTMLFormatConfiguration {
 	readonly tabSize: number;
@@ -27,11 +27,11 @@ export interface CompletionConfiguration {
 
 export interface Options {
 	/**
-	 * If set, comments are tolerated. If set to false, syntax errors will be emitted for comments.
+	 * Settings for the HTML formatter.
 	 */
 	readonly format?: HTMLFormatConfiguration;
 	/**
-	 * A list of known schemas and/or associations of schemas to file names.
+	 * Code completion settings.
 	 */
 	readonly suggest?: CompletionConfiguration;
 	/**

+ 1 - 1
src/html/workerManager.ts → src/language/html/workerManager.ts

@@ -5,7 +5,7 @@
 
 import { LanguageServiceDefaults } from './monaco.contribution';
 import type { HTMLWorker } from './htmlWorker';
-import { Uri, IDisposable, editor } from '../fillers/monaco-editor-core';
+import { Uri, IDisposable, editor } from '../../fillers/monaco-editor-core';
 
 const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
 

+ 0 - 0
src/json/json.worker.ts → src/language/json/json.worker.ts


+ 1 - 1
src/json/jsonMode.ts → src/language/json/jsonMode.ts

@@ -8,7 +8,7 @@ import type { JSONWorker } from './jsonWorker';
 import { LanguageServiceDefaults } from './monaco.contribution';
 import * as languageFeatures from '../common/lspLanguageFeatures';
 import { createTokenizationSupport } from './tokenization';
-import { Uri, IDisposable, languages, editor } from '../fillers/monaco-editor-core';
+import { Uri, IDisposable, languages, editor } from '../../fillers/monaco-editor-core';
 
 class JSONDiagnosticsAdapter extends languageFeatures.DiagnosticsAdapter<JSONWorker> {
 	constructor(

+ 1 - 1
src/json/jsonWorker.ts → src/language/json/jsonWorker.ts

@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as jsonService from 'vscode-json-languageservice';
-import type { worker } from '../fillers/monaco-editor-core';
+import type { worker } from '../../fillers/monaco-editor-core';
 import { URI } from 'vscode-uri';
 import { DiagnosticsOptions } from './monaco.contribution';
 

+ 1 - 1
src/json/monaco.contribution.ts → src/language/json/monaco.contribution.ts

@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as mode from './jsonMode';
-import { Emitter, IEvent, languages } from '../fillers/monaco-editor-core';
+import { Emitter, IEvent, languages } from '../../fillers/monaco-editor-core';
 
 // --- JSON configuration and defaults ---------
 

+ 1 - 1
src/json/tokenization.ts → src/language/json/tokenization.ts

@@ -4,7 +4,7 @@
  *--------------------------------------------------------------------------------------------*/
 
 import * as json from 'jsonc-parser';
-import { languages } from '../fillers/monaco-editor-core';
+import { languages } from '../../fillers/monaco-editor-core';
 
 export function createTokenizationSupport(supportComments: boolean): languages.TokensProvider {
 	return {

+ 1 - 1
src/json/workerManager.ts → src/language/json/workerManager.ts

@@ -5,7 +5,7 @@
 
 import { LanguageServiceDefaults } from './monaco.contribution';
 import type { JSONWorker } from './jsonWorker';
-import { IDisposable, Uri, editor } from '../fillers/monaco-editor-core';
+import { IDisposable, Uri, editor } from '../../fillers/monaco-editor-core';
 
 const STOP_WHEN_IDLE_FOR = 2 * 60 * 1000; // 2min
 

+ 8 - 6
src/typescript/languageFeatures.ts → src/language/typescript/languageFeatures.ts

@@ -23,7 +23,7 @@ import {
 	IRange,
 	MarkerTag,
 	MarkerSeverity
-} from '../fillers/monaco-editor-core';
+} from '../../fillers/monaco-editor-core';
 
 //#region utils copied from typescript to prevent loading the entire typescriptServices ---
 
@@ -1124,12 +1124,13 @@ export class CodeActionAdaptor extends FormatHelper implements languages.CodeAct
 		context: languages.CodeActionContext,
 		codeFix: ts.CodeFixAction
 	): languages.CodeAction {
-		const edits: languages.WorkspaceTextEdit[] = [];
+		const edits: languages.IWorkspaceTextEdit[] = [];
 		for (const change of codeFix.changes) {
 			for (const textChange of change.textChanges) {
 				edits.push({
 					resource: model.uri,
-					edit: {
+					versionId: undefined,
+					textEdit: {
 						range: this._textSpanToRange(model, textChange.span),
 						text: textChange.newText
 					}
@@ -1197,13 +1198,14 @@ export class RenameAdapter extends Adapter implements languages.RenameProvider {
 			return;
 		}
 
-		const edits: languages.WorkspaceTextEdit[] = [];
+		const edits: languages.IWorkspaceTextEdit[] = [];
 		for (const renameLocation of renameLocations) {
 			const model = this._libFiles.getOrCreateModel(renameLocation.fileName);
 			if (model) {
 				edits.push({
 					resource: model.uri,
-					edit: {
+					versionId: undefined,
+					textEdit: {
 						range: this._textSpanToRange(model, renameLocation.textSpan),
 						text: newName
 					}
@@ -1259,7 +1261,7 @@ export class InlayHintsAdapter extends Adapter implements languages.InlayHintsPr
 			case 'Type':
 				return languages.InlayHintKind.Type;
 			default:
-				return languages.InlayHintKind.Other;
+				return languages.InlayHintKind.Type;
 		}
 	}
 }

+ 0 - 0
src/typescript/lib/editor.worker.d.ts → src/language/typescript/lib/editor.worker.d.ts


+ 1 - 0
src/typescript/lib/lib.index.ts → src/language/typescript/lib/lib.index.ts

@@ -55,6 +55,7 @@ libFileSet['lib.es2020.string.d.ts'] = true;
 libFileSet['lib.es2020.symbol.wellknown.d.ts'] = true;
 libFileSet['lib.es2021.d.ts'] = true;
 libFileSet['lib.es2021.full.d.ts'] = true;
+libFileSet['lib.es2021.intl.d.ts'] = true;
 libFileSet['lib.es2021.promise.d.ts'] = true;
 libFileSet['lib.es2021.string.d.ts'] = true;
 libFileSet['lib.es2021.weakref.d.ts'] = true;

File diff suppressed because it is too large
+ 12 - 0
src/language/typescript/lib/lib.ts


File diff suppressed because it is too large
+ 349 - 303
src/language/typescript/lib/typescriptServices-amd.js


File diff suppressed because it is too large
+ 237 - 234
src/language/typescript/lib/typescriptServices.d.ts


File diff suppressed because it is too large
+ 349 - 303
src/language/typescript/lib/typescriptServices.js


+ 1 - 1
src/typescript/lib/typescriptServicesMetadata.ts → src/language/typescript/lib/typescriptServicesMetadata.ts

@@ -2,4 +2,4 @@
 // **NOTE**: Do not edit directly! This file is generated using `npm run import-typescript`
 //
 
-export const typescriptVersion = "4.4.4";
+export const typescriptVersion = "4.5.5";

+ 1 - 1
src/typescript/monaco.contribution.ts → src/language/typescript/monaco.contribution.ts

@@ -5,7 +5,7 @@
 
 import type * as mode from './tsMode';
 import { typescriptVersion as tsversion } from './lib/typescriptServicesMetadata'; // do not import the whole typescriptServices here
-import { languages, Emitter, IEvent, IDisposable, Uri } from '../fillers/monaco-editor-core';
+import { languages, Emitter, IEvent, IDisposable, Uri } from '../../fillers/monaco-editor-core';
 
 //#region enums copied from typescript to prevent loading the entire typescriptServices ---
 

+ 1 - 1
src/typescript/ts.worker.ts → src/language/typescript/ts.worker.ts

@@ -5,7 +5,7 @@
 
 import * as edworker from 'monaco-editor-core/esm/vs/editor/editor.worker';
 import { ICreateData, create } from './tsWorker';
-import { worker } from '../fillers/monaco-editor-core';
+import { worker } from '../../fillers/monaco-editor-core';
 
 self.onmessage = () => {
 	// ignore the first message

+ 1 - 1
src/typescript/tsMode.ts → src/language/typescript/tsMode.ts

@@ -7,7 +7,7 @@ import { WorkerManager } from './workerManager';
 import type { TypeScriptWorker } from './tsWorker';
 import { LanguageServiceDefaults } from './monaco.contribution';
 import * as languageFeatures from './languageFeatures';
-import { languages, Uri } from '../fillers/monaco-editor-core';
+import { languages, Uri } from '../../fillers/monaco-editor-core';
 
 let javaScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;
 let typeScriptWorker: (...uris: Uri[]) => Promise<TypeScriptWorker>;

+ 9 - 1
src/typescript/tsWorker.ts → src/language/typescript/tsWorker.ts

@@ -11,7 +11,7 @@ import {
 	IExtraLibs,
 	TypeScriptWorker as ITypeScriptWorker
 } from './monaco.contribution';
-import { Uri, worker } from '../fillers/monaco-editor-core';
+import { Uri, worker } from '../../fillers/monaco-editor-core';
 
 /**
  * Loading a default lib as a source file will mess up TS completely.
@@ -181,6 +181,14 @@ export class TypeScriptWorker implements ts.LanguageServiceHost, ITypeScriptWork
 		return fileName === this.getDefaultLibFileName(this._compilerOptions);
 	}
 
+	readFile(path: string): string | undefined {
+		return this._getScriptText(path);
+	}
+
+	fileExists(path: string): boolean {
+		return this._getScriptText(path) !== undefined;
+	}
+
 	async getLibFiles(): Promise<Record<string, string>> {
 		return libFileMap;
 	}

+ 1 - 1
src/typescript/workerManager.ts → src/language/typescript/workerManager.ts

@@ -5,7 +5,7 @@
 
 import { LanguageServiceDefaults } from './monaco.contribution';
 import type { TypeScriptWorker } from './tsWorker';
-import { editor, Uri, IDisposable } from '../fillers/monaco-editor-core';
+import { editor, Uri, IDisposable } from '../../fillers/monaco-editor-core';
 
 export class WorkerManager {
 	private _modeId: string;

File diff suppressed because it is too large
+ 0 - 12
src/typescript/lib/lib.ts


+ 0 - 1
test/manual/cross-origin.html

@@ -13,7 +13,6 @@
 		></div>
 		<div style="clear: both"></div>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 168 - 194
test/manual/dev-setup.js

@@ -1,188 +1,44 @@
-(function () {
-	let IS_FILE_PROTOCOL = window.location.protocol === 'file:';
-	let DIRNAME = null;
-	if (IS_FILE_PROTOCOL) {
-		let port = window.location.port;
-		if (port.length > 0) {
-			port = ':' + port;
-		}
-		DIRNAME =
-			window.location.protocol +
-			'//' +
-			window.location.hostname +
-			port +
-			window.location.pathname.substr(0, window.location.pathname.lastIndexOf('/'));
-
-		let bases = document.getElementsByTagName('base');
-		if (bases.length > 0) {
-			DIRNAME = DIRNAME + '/' + bases[0].getAttribute('href');
-		}
-	}
+//@ts-check
 
-	let LOADER_OPTS = (function () {
-		function parseQueryString() {
-			let str = window.location.search;
-			str = str.replace(/^\?/, '');
-			let pieces = str.split(/&/);
-			let result = {};
-			pieces.forEach(function (piece) {
-				let config = piece.split(/=/);
-				result[config[0]] = config[1];
-			});
-			return result;
-		}
-		let overwrites = parseQueryString();
-		let result = {};
-		result['editor'] = overwrites['editor'] || 'npm/dev';
-		METADATA.PLUGINS.map(function (plugin) {
-			result[plugin.name] = overwrites[plugin.name] || 'dev';
-		});
-		return result;
-	})();
-	function toHREF(search) {
-		let port = window.location.port;
-		if (port.length > 0) {
-			port = ':' + port;
-		}
-		return (
-			window.location.protocol +
-			'//' +
-			window.location.hostname +
-			port +
-			window.location.pathname +
-			search +
-			window.location.hash
-		);
-	}
-
-	function Component(name, modulePrefix, paths, rootPath, contrib) {
-		this.name = name;
-		this.modulePrefix = modulePrefix;
-		this.paths = paths;
-		this.rootPath = rootPath;
-		this.contrib = contrib;
-		this.selectedPath = LOADER_OPTS[name];
-	}
-	Component.prototype.isRelease = function () {
-		return /release/.test(this.selectedPath);
-	};
-	Component.prototype.getResolvedPath = function (PATH_PREFIX) {
-		let resolvedPath = this.paths[this.selectedPath];
-		if (/\.\//.test(resolvedPath)) {
-			// starts with ./ => treat as relative to the root path
-			if (IS_FILE_PROTOCOL) {
-				resolvedPath = DIRNAME + '/../' + this.rootPath + '/' + resolvedPath;
-			} else {
-				resolvedPath = PATH_PREFIX + '/monaco-editor/' + this.rootPath + '/' + resolvedPath;
-			}
-		} else if (
-			this.selectedPath === 'npm/dev' ||
-			this.selectedPath === 'npm/min' ||
-			this.isRelease()
-		) {
-			if (IS_FILE_PROTOCOL) {
-				resolvedPath = DIRNAME + '/../' + resolvedPath;
-			} else {
-				resolvedPath = PATH_PREFIX + '/monaco-editor/' + resolvedPath;
-			}
-		} else {
-			if (IS_FILE_PROTOCOL) {
-				resolvedPath = DIRNAME + '/../..' + resolvedPath;
-			} else {
-				resolvedPath = PATH_PREFIX + resolvedPath;
-			}
-		}
-		return resolvedPath;
-	};
-	Component.prototype.generateLoaderConfig = function (dest, PATH_PREFIX) {
-		dest[this.modulePrefix] = this.getResolvedPath(PATH_PREFIX);
-	};
-	Component.prototype.generateUrlForPath = function (pathName) {
-		let NEW_LOADER_OPTS = {};
-		Object.keys(LOADER_OPTS).forEach(function (key) {
-			NEW_LOADER_OPTS[key] = LOADER_OPTS[key] === 'npm/dev' ? undefined : LOADER_OPTS[key];
-		});
-		NEW_LOADER_OPTS[this.name] = pathName === 'npm/dev' ? undefined : pathName;
-
-		let search = Object.keys(NEW_LOADER_OPTS)
-			.map(function (key) {
-				let value = NEW_LOADER_OPTS[key];
-				if (value) {
-					return key + '=' + value;
-				}
-				return '';
-			})
-			.filter(function (assignment) {
-				return !!assignment;
-			})
-			.join('&amp;');
-		if (search.length > 0) {
-			search = '?' + search;
-		}
-		return toHREF(search);
+(function () {
+	const corePaths = {
+		src: '/vscode/out/vs',
+		'npm/dev': 'node_modules/monaco-editor-core/dev/vs',
+		'npm/min': 'node_modules/monaco-editor-core/min/vs',
+		built: '/vscode/out-monaco-editor-core/min/vs',
+		releaseDev: 'release/dev/vs',
+		releaseMin: 'release/min/vs'
 	};
-	Component.prototype.renderLoadingOptions = function () {
-		return (
-			'<strong style="width:130px;display:inline-block;">' +
-			this.name +
-			'</strong>:&#160;&#160;&#160;' +
-			Object.keys(this.paths)
-				.map(
-					function (pathName) {
-						if (pathName === this.selectedPath) {
-							return '<strong>' + pathName + '</strong>';
-						}
-						return '<a href="' + this.generateUrlForPath(pathName) + '">' + pathName + '</a>';
-					}.bind(this)
-				)
-				.join('&#160;&#160;&#160;')
-		);
+	const pluginPaths = {
+		src: 'out/amd',
+		dev: 'out/release/dev/vs',
+		min: 'out/release/min/vs'
 	};
-
-	let RESOLVED_CORE = new Component('editor', 'vs', METADATA.CORE.paths);
-	self.RESOLVED_CORE_PATH = RESOLVED_CORE.getResolvedPath('');
-	let RESOLVED_PLUGINS = METADATA.PLUGINS.map(function (plugin) {
-		return new Component(
-			plugin.name,
-			plugin.modulePrefix,
-			plugin.paths,
-			plugin.rootPath,
-			plugin.contrib
-		);
-	});
-	METADATA = null;
-
-	function loadScript(path, callback) {
-		let script = document.createElement('script');
-		script.onload = callback;
-		script.async = true;
-		script.type = 'text/javascript';
-		script.src = path;
-		document.head.appendChild(script);
-	}
+	const parsedQuery = parseQueryString();
+	const editorQueryName = 'editor';
+	const pluginsQueryName = 'plugins';
+	const defaultEditorQueryValue = 'npm/dev';
+	const defaultPluginsQueryValue = 'src';
+	const editorQueryValue = parsedQuery[editorQueryName] || defaultEditorQueryValue;
+	const pluginsQueryValue = parsedQuery[pluginsQueryName] || defaultPluginsQueryValue;
+	const corePath = resolvePath(corePaths[editorQueryValue]);
+	const pluginPath = resolvePath(pluginPaths[pluginsQueryValue]);
+	const isRelease = /release/.test(editorQueryValue);
 
 	(function () {
-		let allComponents = [RESOLVED_CORE];
-		if (!RESOLVED_CORE.isRelease()) {
-			allComponents = allComponents.concat(RESOLVED_PLUGINS);
-		}
-
 		let div = document.createElement('div');
 		div.className = 'dev-setup-control';
 		div.style.position = 'fixed';
-		div.style.top = 0;
-		div.style.right = 0;
+		div.style.top = '0';
+		div.style.right = '0';
 		div.style.background = 'lightgray';
 		div.style.padding = '5px 20px 5px 5px';
 		div.style.zIndex = '1000';
 
 		div.innerHTML =
 			'<ul><li>' +
-			allComponents
-				.map(function (component) {
-					return component.renderLoadingOptions();
-				})
-				.join('</li><li>') +
+			renderLoadingOptions(true) +
+			(isRelease ? '' : `</li><li>${renderLoadingOptions(false)}`) +
 			'</li></ul>';
 
 		document.body.appendChild(div);
@@ -196,28 +52,44 @@
 		}
 	})();
 
-	self.getCodiconPath = function (PATH_PREFIX) {
-		PATH_PREFIX = PATH_PREFIX || '';
-		const result = RESOLVED_CORE.getResolvedPath(PATH_PREFIX);
-		return result + '/base/browser/ui/codicons/codicon/codicon.ttf';
+	/** @type {any} */
+	const global = self;
+
+	global.getCodiconPath = () => {
+		return `${corePath}/base/browser/ui/codicons/codicon/codicon.ttf`;
 	};
 
-	self.loadEditor = function (callback, PATH_PREFIX) {
+	/**
+	 *
+	 * @param {()=>void} callback
+	 * @param {string} [PATH_PREFIX]
+	 */
+	global.loadEditor = (callback, PATH_PREFIX) => {
 		PATH_PREFIX = PATH_PREFIX || '';
 
-		loadScript(RESOLVED_CORE.getResolvedPath(PATH_PREFIX) + '/loader.js', function () {
-			let loaderPathsConfig = {};
-			if (!RESOLVED_CORE.isRelease()) {
-				RESOLVED_PLUGINS.forEach(function (plugin) {
-					plugin.generateLoaderConfig(loaderPathsConfig, PATH_PREFIX);
-				});
+		loadScript(`${PATH_PREFIX}${corePath}/loader.js`, () => {
+			global.AMD = true;
+
+			/** @type {{[name:string]: string;}} */
+			const loaderPathsConfig = {};
+			if (isRelease) {
+				loaderPathsConfig['vs'] = `${PATH_PREFIX}${corePath}`;
+			} else {
+				loaderPathsConfig[
+					'vs/fillers/monaco-editor-core'
+				] = `${PATH_PREFIX}/monaco-editor/out/amd/fillers/monaco-editor-core-amd`;
+				loaderPathsConfig['vs/language'] = `${PATH_PREFIX}${pluginPath}/language`;
+				loaderPathsConfig['vs/basic-language'] = `${PATH_PREFIX}${pluginPath}/basic-language`;
+				loaderPathsConfig['vs'] = `${PATH_PREFIX}${corePath}`;
 			}
-			RESOLVED_CORE.generateLoaderConfig(loaderPathsConfig, PATH_PREFIX);
 
 			console.log('LOADER CONFIG: ');
 			console.log(JSON.stringify(loaderPathsConfig, null, '\t'));
 
-			require.config({
+			/** @type {any} */
+			const req = require;
+
+			req.config({
 				paths: loaderPathsConfig
 				// 'vs/nls' : {
 				// 	availableLanguages: {
@@ -226,19 +98,121 @@
 				// }
 			});
 
-			require(['vs/editor/editor.main'], function () {
-				if (!RESOLVED_CORE.isRelease()) {
-					// At this point we've loaded the monaco-editor-core
-					require(RESOLVED_PLUGINS.map(function (plugin) {
-						return plugin.contrib;
-					}), function () {
-						// At this point we've loaded all the plugins
-						callback();
-					});
-				} else {
+			req(['vs/editor/editor.main'], () => {
+				if (isRelease) {
 					callback();
+					return;
 				}
+				// At this point we've loaded the monaco-editor-core
+				req(
+					[
+						'vs/basic-languages/monaco.contribution',
+						'vs/language/css/monaco.contribution',
+						'vs/language/html/monaco.contribution',
+						'vs/language/json/monaco.contribution',
+						'vs/language/typescript/monaco.contribution'
+					],
+					callback
+				);
 			});
 		});
 	};
+
+	function parseQueryString() {
+		const str = window.location.search.replace(/^\?/, '');
+		const pieces = str.split(/&/);
+		/** @type {{[name:string]: string;}} */
+		const result = {};
+		pieces.forEach((piece) => {
+			const config = piece.split(/=/);
+			result[config[0]] = config[1];
+		});
+		return result;
+	}
+
+	/**
+	 * @param {string} path
+	 */
+	function resolvePath(path) {
+		if (/^\//.test(path)) {
+			return path;
+		}
+		return `/monaco-editor/${path}`;
+	}
+
+	/**
+	 * @param {boolean} isEditor
+	 */
+	function renderLoadingOptions(isEditor) {
+		const name = isEditor ? 'editor' : 'plugins';
+		const paths = isEditor ? corePaths : pluginPaths;
+		const selectedPath = isEditor ? editorQueryValue : pluginsQueryValue;
+		return (
+			'<strong style="width:130px;display:inline-block;">' +
+			name +
+			'</strong>:&#160;&#160;&#160;' +
+			Object.keys(paths)
+				.map((path) => {
+					if (path === selectedPath) {
+						return '<strong>' + path + '</strong>';
+					}
+					return '<a href="' + generateUrlForLoadingOption(isEditor, path) + '">' + path + '</a>';
+				})
+				.join('&#160;&#160;&#160;')
+		);
+	}
+
+	/**
+	 * @param {boolean} isEditor
+	 * @param {string} value
+	 */
+	function generateUrlForLoadingOption(isEditor, value) {
+		/** @type {{[name:string]: string;}} */
+		const newQueryOptions = {};
+		const newEditorQueryValue = isEditor ? value : editorQueryValue;
+		const newPluginsQueryValue = isEditor ? pluginsQueryValue : value;
+		if (newEditorQueryValue !== defaultEditorQueryValue) {
+			newQueryOptions[editorQueryName] = newEditorQueryValue;
+		}
+		if (newPluginsQueryValue !== defaultPluginsQueryValue) {
+			newQueryOptions[pluginsQueryName] = newPluginsQueryValue;
+		}
+
+		let search = Object.keys(newQueryOptions)
+			.map((key) => `${key}=${newQueryOptions[key]}`)
+			.join('&amp;');
+
+		if (search.length > 0) {
+			search = '?' + search;
+		}
+		return toHREF(search);
+	}
+
+	/**
+	 * @param {string} search
+	 */
+	function toHREF(search) {
+		let port = window.location.port;
+		if (port.length > 0) {
+			port = ':' + port;
+		}
+		return (
+			window.location.protocol +
+			'//' +
+			window.location.hostname +
+			port +
+			window.location.pathname +
+			search +
+			window.location.hash
+		);
+	}
+
+	function loadScript(path, callback) {
+		const script = document.createElement('script');
+		script.onload = callback;
+		script.async = true;
+		script.type = 'text/javascript';
+		script.src = path;
+		document.head.appendChild(script);
+	}
 })();

+ 0 - 1
test/manual/diff.html

@@ -10,7 +10,6 @@
 		></div>
 		<div style="clear: both"></div>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 29 - 0
test/manual/iframe-inner.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+	</head>
+	<body style="height: 100%">
+		<div
+			style="
+				position: absolute;
+				left: 10px;
+				top: 10px;
+				width: 400px;
+				height: 200px;
+				border: 1px solid silver;
+			"
+			id="editor"
+		></div>
+
+		<script src="dev-setup.js"></script>
+		<script>
+			loadEditor(function () {
+				monaco.editor.create(document.getElementById('editor'), {
+					value: `function hello()\n{\treturn 5;\n}`,
+					language: 'javascript'
+				});
+			});
+		</script>
+	</body>
+</html>

+ 23 - 0
test/manual/iframe.html

@@ -0,0 +1,23 @@
+<!DOCTYPE html>
+<html>
+	<head>
+		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+	</head>
+	<body>
+		<h2>Monaco Editor in iframe</h2>
+
+		<input type="text" style="position: absolute; top: 60px; left: 20px" />
+
+		<iframe
+			src="./iframe-inner.html"
+			style="
+				position: absolute;
+				left: 20px;
+				top: 100px;
+				width: calc(100% - 40px);
+				height: 300px;
+				border: 1px solid silver;
+			"
+		></iframe>
+	</body>
+</html>

+ 2 - 1
test/manual/index.html

@@ -11,6 +11,8 @@
 		<a class="loading-opts" href="./diff.html">[Diff]</a> &#160;|&#160;
 		<a class="loading-opts" href="./typescript/index.html">[TypeScript]</a> &#160;|&#160;
 		<a class="loading-opts" href="./typescript/custom-worker.html">[TS Worker]</a>
+		&#160;|&#160;
+		<a class="loading-opts" href="./iframe.html">[iframe]</a>
 		<br />&#160;|&#160;
 		<a class="loading-opts" href="./cross-origin.html">[cross origin]</a> &#160;|&#160;
 		<a class="loading-opts" href="./mouse-fixed.html">[fixed element]</a> &#160;|&#160;
@@ -32,7 +34,6 @@
 		></div>
 		<div style="clear: both"></div>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 2 - 2
test/manual/index.js

@@ -1,8 +1,8 @@
 /// <reference path="../../release/monaco.d.ts" />
 define(['require', './samples'], function (require, SAMPLES) {
-	var domutils = require('vs/base/browser/dom');
+	const domutils = require('vs/base/browser/dom');
 
-	var model = monaco.editor.createModel('', 'plaintext');
+	let model = monaco.editor.createModel('', 'plaintext');
 
 	monaco.languages.typescript.typescriptDefaults.setInlayHintsOptions({
 		includeInlayParameterNameHints: 'all',

+ 0 - 1
test/manual/mouse-fixed.html

@@ -18,7 +18,6 @@
 			id="Editor"
 		></div>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 0 - 1
test/manual/mouse-scrollable-body.html

@@ -273,7 +273,6 @@
 			non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
 		</p>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 0 - 1
test/manual/mouse-scrollable-element.html

@@ -191,7 +191,6 @@
 
 		<div style="clear: both"></div>
 
-		<script src="../../metadata.js"></script>
 		<script src="dev-setup.js"></script>
 		<script>
 			loadEditor(function () {

+ 33 - 33
test/manual/samples/run-editor-intellisense-js.txt

@@ -1,33 +1,33 @@
-
-"use strict";
-function Person(age) {
-	if (age) {
-		this.age = age;
-	}
-}
-Person.prototype.getAge = function () {
-	return this.age;
-};
-
-function Student(age, grade) {
-	Person.call(this, age);
-	this.grade = grade;
-}
-Student.prototype = new Person();
-Student.prototype.getGrade = function () {
-	return this.grade;
-};
-
-var s = new Student(24, 5.75);
-//var age = s.
-
-//delete s.age;
-//s.getAge = function() { return {foo:"bar"}; };
-//s.
-//s.getAge().
-
-
-
-
-
-
+
+"use strict";
+function Person(age) {
+	if (age) {
+		this.age = age;
+	}
+}
+Person.prototype.getAge = function () {
+	return this.age;
+};
+
+function Student(age, grade) {
+	Person.call(this, age);
+	this.grade = grade;
+}
+Student.prototype = new Person();
+Student.prototype.getGrade = function () {
+	return this.grade;
+};
+
+var s = new Student(24, 5.75);
+//var age = s.
+
+//delete s.age;
+//s.getAge = function() { return {foo:"bar"}; };
+//s.
+//s.getAge().
+
+
+
+
+
+

File diff suppressed because it is too large
+ 0 - 20
test/manual/samples/run-editor-jquery-min-js.txt


+ 9 - 9
test/manual/samples/run-editor-korean.txt

@@ -1,10 +1,10 @@
-/*
-
-전문
-유구한 역사와 전통에 빛나는 우리 대한 국민은 3·1 운동으로 건립된 대한민국 임시 정부의 법통과 불의에 항거한 4·19 민주 이념을 계승하고, 조국의 민주 개혁과 평화적 통일의 사명에 입각하여 정의·인도와 동포애로써 민족의 단결을 공고히 하고, 모든 사회적 폐습과 불의를 타파하며, 자율과 조화를 바탕으로 자유 민주적 기본 질서를 더욱 확고히 하여 정치·경제·사회·문화의 모든 영역에 있어서 각인의 기회를 균등히 하고, 능력을 최고도로 발휘하게 하며, 자유와 권리에 따르는 책임과 의무를 완수하게 하여, 안으로는 국민 생활의 균등한 향상을 기하고 밖으로는 항구적인 세계 평화와 인류 공영에 이바지함으로써 우리들과 우리들의 자손의 안전과 자유와 행복을 영원히 확보할 것을 다짐하면서 1948년 7월 12일에 제정되고 8차에 걸쳐 개정된 헌법을 이제 국회의 의결을 거쳐 국민 투표에 의하여 개정한다.
-1987년 10월 29일
-前文
-悠久한 歷史와 傳統에 빛나는 우리 大韓國民은 3·1 運動으로 建立된 大韓民國臨時政府의 法統과 不義에 抗拒한 4·19 民主理念을 繼承하고, 祖國의 民主改革과 平和的統一의 使命에 立脚하여 正義·人道와 同胞愛로써 民族의 團結을 鞏固히 하고, 모든 社會的弊習과 不義를 打破하며, 自律과 調和를 바탕으로 自由民主的基本秩序를 더욱 確固히 하여 政治·經濟·社會·文化의 모든 領域에 있어서 各人의 機會를 均等히 하고, 能力을 最高度로 發揮하게 하며, 自由와 權利에 따르는 責任과 義務를 完遂하게 하여, 안으로는 國民生活의 均等한 向上을 基하고 밖으로는 恒久的인 世界平和와 人類共榮에 이바지함으로써 우리들과 우리들의 子孫의 安全과 自由와 幸福을 永遠히 確保할 것을 다짐하면서 1948年 7月 12日에 制定되고 8次에 걸쳐 改正된 憲法을 이제 國會의 議決을 거쳐 國民投票에 依하여 改正한다.
-1987年 10月 29日
-
+/*
+
+전문
+유구한 역사와 전통에 빛나는 우리 대한 국민은 3·1 운동으로 건립된 대한민국 임시 정부의 법통과 불의에 항거한 4·19 민주 이념을 계승하고, 조국의 민주 개혁과 평화적 통일의 사명에 입각하여 정의·인도와 동포애로써 민족의 단결을 공고히 하고, 모든 사회적 폐습과 불의를 타파하며, 자율과 조화를 바탕으로 자유 민주적 기본 질서를 더욱 확고히 하여 정치·경제·사회·문화의 모든 영역에 있어서 각인의 기회를 균등히 하고, 능력을 최고도로 발휘하게 하며, 자유와 권리에 따르는 책임과 의무를 완수하게 하여, 안으로는 국민 생활의 균등한 향상을 기하고 밖으로는 항구적인 세계 평화와 인류 공영에 이바지함으로써 우리들과 우리들의 자손의 안전과 자유와 행복을 영원히 확보할 것을 다짐하면서 1948년 7월 12일에 제정되고 8차에 걸쳐 개정된 헌법을 이제 국회의 의결을 거쳐 국민 투표에 의하여 개정한다.
+1987년 10월 29일
+前文
+悠久한 歷史와 傳統에 빛나는 우리 大韓國民은 3·1 運動으로 建立된 大韓民國臨時政府의 法統과 不義에 抗拒한 4·19 民主理念을 繼承하고, 祖國의 民主改革과 平和的統一의 使命에 立脚하여 正義·人道와 同胞愛로써 民族의 團結을 鞏固히 하고, 모든 社會的弊習과 不義를 打破하며, 自律과 調和를 바탕으로 自由民主的基本秩序를 더욱 確固히 하여 政治·經濟·社會·文化의 모든 領域에 있어서 各人의 機會를 均等히 하고, 能力을 最高度로 發揮하게 하며, 自由와 權利에 따르는 責任과 義務를 完遂하게 하여, 안으로는 國民生活의 均等한 向上을 基하고 밖으로는 恒久的인 世界平和와 人類共榮에 이바지함으로써 우리들과 우리들의 子孫의 安全과 自由와 幸福을 永遠히 確保할 것을 다짐하면서 1948年 7月 12日에 制定되고 8次에 걸쳐 改正된 憲法을 이제 國會의 議決을 거쳐 國民投票에 依하여 改正한다.
+1987年 10月 29日
+
 */

+ 493 - 493
test/manual/samples/run-editor-sample-bom-cs.txt

@@ -1,493 +1,493 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
-using System.Security.Claims;
-using System.Security.Cryptography;
-using System.Threading.Tasks;
-using System.Web;
-using System.Web.Http;
-using System.Web.Http.ModelBinding;
-using Microsoft.AspNet.Identity;
-using Microsoft.AspNet.Identity.EntityFramework;
-using Microsoft.AspNet.Identity.Owin;
-using Microsoft.Owin.Security;
-using Microsoft.Owin.Security.Cookies;
-using Microsoft.Owin.Security.OAuth;
-using WebApplication.Models;
-using WebApplication.Providers;
-using WebApplication.Results;
-
-namespace WebApplication.Controllers
-{
-    [Authorize]
-    [RoutePrefix("api/Account")]
-    public class AccountController : ApiController
-    {
-        private const string LocalLoginProvider = "Local";
-        private ApplicationUserManager _userManager;
-
-        public AccountController()
-        {
-        }
-
-        public AccountController(ApplicationUserManager userManager,
-            ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
-        {
-            UserManager = userManager;
-            AccessTokenFormat = accessTokenFormat;
-        }
-
-        public ApplicationUserManager UserManager
-        {
-            get
-            {
-                return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
-            }
-            private set
-            {
-                _userManager = value;
-            }
-        }
-
-        public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; }
-
-        // GET api/Account/UserInfo
-        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
-        [Route("UserInfo")]
-        public UserInfoViewModel GetUserInfo()
-        {
-            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
-
-            return new UserInfoViewModel
-            {
-                Email = User.Identity.GetUserName(),
-                HasRegistered = externalLogin == null,
-                LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
-            };
-        }
-
-        // POST api/Account/Logout
-        [Route("Logout")]
-        public IHttpActionResult Logout()
-        {
-            Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
-            return Ok();
-        }
-
-        // GET api/Account/ManageInfo?returnUrl=%2F&generateState=true
-        [Route("ManageInfo")]
-        public async Task<ManageInfoViewModel> GetManageInfo(string returnUrl, bool generateState = false)
-        {
-            IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
-
-            if (user == null)
-            {
-                return null;
-            }
-
-            List<UserLoginInfoViewModel> logins = new List<UserLoginInfoViewModel>();
-            
-            foreach (IdentityUserLogin linkedAccount in user.Logins)
-            {
-                logins.Add(new UserLoginInfoViewModel
-                {
-                    LoginProvider = linkedAccount.LoginProvider,
-                    ProviderKey = linkedAccount.ProviderKey
-                });
-            }
-
-            if (user.PasswordHash != null)
-            {
-                logins.Add(new UserLoginInfoViewModel
-                {
-                    LoginProvider = LocalLoginProvider,
-                    ProviderKey = user.UserName,
-                });
-            }
-
-            return new ManageInfoViewModel
-            {
-                LocalLoginProvider = LocalLoginProvider,
-                Email = user.UserName,
-                Logins = logins,
-                ExternalLoginProviders = GetExternalLogins(returnUrl, generateState)
-            };
-        }
-
-        // POST api/Account/ChangePassword
-        [Route("ChangePassword")]
-        public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-            
-            IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
-                model.NewPassword);
-            
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            return Ok();
-        }
-
-        // POST api/Account/SetPassword
-        [Route("SetPassword")]
-        public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-
-            IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
-
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            return Ok();
-        }
-
-        // POST api/Account/AddExternalLogin
-        [Route("AddExternalLogin")]
-        public async Task<IHttpActionResult> AddExternalLogin(AddExternalLoginBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-
-            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
-
-            AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken);
-
-            if (ticket == null || ticket.Identity == null || (ticket.Properties != null
-                && ticket.Properties.ExpiresUtc.HasValue
-                && ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow))
-            {
-                return BadRequest("External login failure.");
-            }
-
-            ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity);
-
-            if (externalData == null)
-            {
-                return BadRequest("The external login is already associated with an account.");
-            }
-
-            IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(),
-                new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey));
-
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            return Ok();
-        }
-
-        // POST api/Account/RemoveLogin
-        [Route("RemoveLogin")]
-        public async Task<IHttpActionResult> RemoveLogin(RemoveLoginBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-
-            IdentityResult result;
-
-            if (model.LoginProvider == LocalLoginProvider)
-            {
-                result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId());
-            }
-            else
-            {
-                result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(),
-                    new UserLoginInfo(model.LoginProvider, model.ProviderKey));
-            }
-
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            return Ok();
-        }
-
-        // GET api/Account/ExternalLogin
-        [OverrideAuthentication]
-        [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
-        [AllowAnonymous]
-        [Route("ExternalLogin", Name = "ExternalLogin")]
-        public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
-        {
-            if (error != null)
-            {
-                return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
-            }
-
-            if (!User.Identity.IsAuthenticated)
-            {
-                return new ChallengeResult(provider, this);
-            }
-
-            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
-
-            if (externalLogin == null)
-            {
-                return InternalServerError();
-            }
-
-            if (externalLogin.LoginProvider != provider)
-            {
-                Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
-                return new ChallengeResult(provider, this);
-            }
-
-            ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
-                externalLogin.ProviderKey));
-
-            bool hasRegistered = user != null;
-
-            if (hasRegistered)
-            {
-                Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
-                
-                 ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
-                    OAuthDefaults.AuthenticationType);
-                ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
-                    CookieAuthenticationDefaults.AuthenticationType);
-
-                AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
-                Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
-            }
-            else
-            {
-                IEnumerable<Claim> claims = externalLogin.GetClaims();
-                ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
-                Authentication.SignIn(identity);
-            }
-
-            return Ok();
-        }
-
-        // GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true
-        [AllowAnonymous]
-        [Route("ExternalLogins")]
-        public IEnumerable<ExternalLoginViewModel> GetExternalLogins(string returnUrl, bool generateState = false)
-        {
-            IEnumerable<AuthenticationDescription> descriptions = Authentication.GetExternalAuthenticationTypes();
-            List<ExternalLoginViewModel> logins = new List<ExternalLoginViewModel>();
-
-            string state;
-
-            if (generateState)
-            {
-                const int strengthInBits = 256;
-                state = RandomOAuthStateGenerator.Generate(strengthInBits);
-            }
-            else
-            {
-                state = null;
-            }
-
-            foreach (AuthenticationDescription description in descriptions)
-            {
-                ExternalLoginViewModel login = new ExternalLoginViewModel
-                {
-                    Name = description.Caption,
-                    Url = Url.Route("ExternalLogin", new
-                    {
-                        provider = description.AuthenticationType,
-                        response_type = "token",
-                        client_id = Startup.PublicClientId,
-                        redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri,
-                        state = state
-                    }),
-                    State = state
-                };
-                logins.Add(login);
-            }
-
-            return logins;
-        }
-
-        // POST api/Account/Register
-        [AllowAnonymous]
-        [Route("Register")]
-        public async Task<IHttpActionResult> Register(RegisterBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-
-            var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
-
-            IdentityResult result = await UserManager.CreateAsync(user, model.Password);
-
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            return Ok();
-        }
-
-        // POST api/Account/RegisterExternal
-        [OverrideAuthentication]
-        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
-        [Route("RegisterExternal")]
-        public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
-        {
-            if (!ModelState.IsValid)
-            {
-                return BadRequest(ModelState);
-            }
-
-            var info = await Authentication.GetExternalLoginInfoAsync();
-            if (info == null)
-            {
-                return InternalServerError();
-            }
-
-            var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
-
-            IdentityResult result = await UserManager.CreateAsync(user);
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result);
-            }
-
-            result = await UserManager.AddLoginAsync(user.Id, info.Login);
-            if (!result.Succeeded)
-            {
-                return GetErrorResult(result); 
-            }
-            return Ok();
-        }
-
-        protected override void Dispose(bool disposing)
-        {
-            if (disposing)
-            {
-                UserManager.Dispose();
-            }
-
-            base.Dispose(disposing);
-        }
-
-        #region Helpers
-
-        private IAuthenticationManager Authentication
-        {
-            get { return Request.GetOwinContext().Authentication; }
-        }
-
-        private IHttpActionResult GetErrorResult(IdentityResult result)
-        {
-            if (result == null)
-            {
-                return InternalServerError();
-            }
-
-            if (!result.Succeeded)
-            {
-                if (result.Errors != null)
-                {
-                    foreach (string error in result.Errors)
-                    {
-                        ModelState.AddModelError("", error);
-                    }
-                }
-
-                if (ModelState.IsValid)
-                {
-                    // No ModelState errors are available to send, so just return an empty BadRequest.
-                    return BadRequest();
-                }
-
-                return BadRequest(ModelState);
-            }
-
-            return null;
-        }
-
-        private class ExternalLoginData
-        {
-            public string LoginProvider { get; set; }
-            public string ProviderKey { get; set; }
-            public string UserName { get; set; }
-
-            public IList<Claim> GetClaims()
-            {
-                IList<Claim> claims = new List<Claim>();
-                claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
-
-                if (UserName != null)
-                {
-                    claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
-                }
-
-                return claims;
-            }
-
-            public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
-            {
-                if (identity == null)
-                {
-                    return null;
-                }
-
-                Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
-
-                if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
-                    || String.IsNullOrEmpty(providerKeyClaim.Value))
-                {
-                    return null;
-                }
-
-                if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
-                {
-                    return null;
-                }
-
-                return new ExternalLoginData
-                {
-                    LoginProvider = providerKeyClaim.Issuer,
-                    ProviderKey = providerKeyClaim.Value,
-                    UserName = identity.FindFirstValue(ClaimTypes.Name)
-                };
-            }
-        }
-
-        private static class RandomOAuthStateGenerator
-        {
-            private static RandomNumberGenerator _random = new RNGCryptoServiceProvider();
-
-            public static string Generate(int strengthInBits)
-            {
-                const int bitsPerByte = 8;
-
-                if (strengthInBits % bitsPerByte != 0)
-                {
-                    throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits");
-                }
-
-                int strengthInBytes = strengthInBits / bitsPerByte;
-
-                byte[] data = new byte[strengthInBytes];
-                _random.GetBytes(data);
-                return HttpServerUtility.UrlTokenEncode(data);
-            }
-        }
-
-        #endregion
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Net.Http;
+using System.Security.Claims;
+using System.Security.Cryptography;
+using System.Threading.Tasks;
+using System.Web;
+using System.Web.Http;
+using System.Web.Http.ModelBinding;
+using Microsoft.AspNet.Identity;
+using Microsoft.AspNet.Identity.EntityFramework;
+using Microsoft.AspNet.Identity.Owin;
+using Microsoft.Owin.Security;
+using Microsoft.Owin.Security.Cookies;
+using Microsoft.Owin.Security.OAuth;
+using WebApplication.Models;
+using WebApplication.Providers;
+using WebApplication.Results;
+
+namespace WebApplication.Controllers
+{
+    [Authorize]
+    [RoutePrefix("api/Account")]
+    public class AccountController : ApiController
+    {
+        private const string LocalLoginProvider = "Local";
+        private ApplicationUserManager _userManager;
+
+        public AccountController()
+        {
+        }
+
+        public AccountController(ApplicationUserManager userManager,
+            ISecureDataFormat<AuthenticationTicket> accessTokenFormat)
+        {
+            UserManager = userManager;
+            AccessTokenFormat = accessTokenFormat;
+        }
+
+        public ApplicationUserManager UserManager
+        {
+            get
+            {
+                return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
+            }
+            private set
+            {
+                _userManager = value;
+            }
+        }
+
+        public ISecureDataFormat<AuthenticationTicket> AccessTokenFormat { get; private set; }
+
+        // GET api/Account/UserInfo
+        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
+        [Route("UserInfo")]
+        public UserInfoViewModel GetUserInfo()
+        {
+            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
+
+            return new UserInfoViewModel
+            {
+                Email = User.Identity.GetUserName(),
+                HasRegistered = externalLogin == null,
+                LoginProvider = externalLogin != null ? externalLogin.LoginProvider : null
+            };
+        }
+
+        // POST api/Account/Logout
+        [Route("Logout")]
+        public IHttpActionResult Logout()
+        {
+            Authentication.SignOut(CookieAuthenticationDefaults.AuthenticationType);
+            return Ok();
+        }
+
+        // GET api/Account/ManageInfo?returnUrl=%2F&generateState=true
+        [Route("ManageInfo")]
+        public async Task<ManageInfoViewModel> GetManageInfo(string returnUrl, bool generateState = false)
+        {
+            IdentityUser user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
+
+            if (user == null)
+            {
+                return null;
+            }
+
+            List<UserLoginInfoViewModel> logins = new List<UserLoginInfoViewModel>();
+            
+            foreach (IdentityUserLogin linkedAccount in user.Logins)
+            {
+                logins.Add(new UserLoginInfoViewModel
+                {
+                    LoginProvider = linkedAccount.LoginProvider,
+                    ProviderKey = linkedAccount.ProviderKey
+                });
+            }
+
+            if (user.PasswordHash != null)
+            {
+                logins.Add(new UserLoginInfoViewModel
+                {
+                    LoginProvider = LocalLoginProvider,
+                    ProviderKey = user.UserName,
+                });
+            }
+
+            return new ManageInfoViewModel
+            {
+                LocalLoginProvider = LocalLoginProvider,
+                Email = user.UserName,
+                Logins = logins,
+                ExternalLoginProviders = GetExternalLogins(returnUrl, generateState)
+            };
+        }
+
+        // POST api/Account/ChangePassword
+        [Route("ChangePassword")]
+        public async Task<IHttpActionResult> ChangePassword(ChangePasswordBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+            
+            IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword,
+                model.NewPassword);
+            
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            return Ok();
+        }
+
+        // POST api/Account/SetPassword
+        [Route("SetPassword")]
+        public async Task<IHttpActionResult> SetPassword(SetPasswordBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+
+            IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
+
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            return Ok();
+        }
+
+        // POST api/Account/AddExternalLogin
+        [Route("AddExternalLogin")]
+        public async Task<IHttpActionResult> AddExternalLogin(AddExternalLoginBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+
+            Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
+
+            AuthenticationTicket ticket = AccessTokenFormat.Unprotect(model.ExternalAccessToken);
+
+            if (ticket == null || ticket.Identity == null || (ticket.Properties != null
+                && ticket.Properties.ExpiresUtc.HasValue
+                && ticket.Properties.ExpiresUtc.Value < DateTimeOffset.UtcNow))
+            {
+                return BadRequest("External login failure.");
+            }
+
+            ExternalLoginData externalData = ExternalLoginData.FromIdentity(ticket.Identity);
+
+            if (externalData == null)
+            {
+                return BadRequest("The external login is already associated with an account.");
+            }
+
+            IdentityResult result = await UserManager.AddLoginAsync(User.Identity.GetUserId(),
+                new UserLoginInfo(externalData.LoginProvider, externalData.ProviderKey));
+
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            return Ok();
+        }
+
+        // POST api/Account/RemoveLogin
+        [Route("RemoveLogin")]
+        public async Task<IHttpActionResult> RemoveLogin(RemoveLoginBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+
+            IdentityResult result;
+
+            if (model.LoginProvider == LocalLoginProvider)
+            {
+                result = await UserManager.RemovePasswordAsync(User.Identity.GetUserId());
+            }
+            else
+            {
+                result = await UserManager.RemoveLoginAsync(User.Identity.GetUserId(),
+                    new UserLoginInfo(model.LoginProvider, model.ProviderKey));
+            }
+
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            return Ok();
+        }
+
+        // GET api/Account/ExternalLogin
+        [OverrideAuthentication]
+        [HostAuthentication(DefaultAuthenticationTypes.ExternalCookie)]
+        [AllowAnonymous]
+        [Route("ExternalLogin", Name = "ExternalLogin")]
+        public async Task<IHttpActionResult> GetExternalLogin(string provider, string error = null)
+        {
+            if (error != null)
+            {
+                return Redirect(Url.Content("~/") + "#error=" + Uri.EscapeDataString(error));
+            }
+
+            if (!User.Identity.IsAuthenticated)
+            {
+                return new ChallengeResult(provider, this);
+            }
+
+            ExternalLoginData externalLogin = ExternalLoginData.FromIdentity(User.Identity as ClaimsIdentity);
+
+            if (externalLogin == null)
+            {
+                return InternalServerError();
+            }
+
+            if (externalLogin.LoginProvider != provider)
+            {
+                Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
+                return new ChallengeResult(provider, this);
+            }
+
+            ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(externalLogin.LoginProvider,
+                externalLogin.ProviderKey));
+
+            bool hasRegistered = user != null;
+
+            if (hasRegistered)
+            {
+                Authentication.SignOut(DefaultAuthenticationTypes.ExternalCookie);
+                
+                 ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
+                    OAuthDefaults.AuthenticationType);
+                ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
+                    CookieAuthenticationDefaults.AuthenticationType);
+
+                AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
+                Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
+            }
+            else
+            {
+                IEnumerable<Claim> claims = externalLogin.GetClaims();
+                ClaimsIdentity identity = new ClaimsIdentity(claims, OAuthDefaults.AuthenticationType);
+                Authentication.SignIn(identity);
+            }
+
+            return Ok();
+        }
+
+        // GET api/Account/ExternalLogins?returnUrl=%2F&generateState=true
+        [AllowAnonymous]
+        [Route("ExternalLogins")]
+        public IEnumerable<ExternalLoginViewModel> GetExternalLogins(string returnUrl, bool generateState = false)
+        {
+            IEnumerable<AuthenticationDescription> descriptions = Authentication.GetExternalAuthenticationTypes();
+            List<ExternalLoginViewModel> logins = new List<ExternalLoginViewModel>();
+
+            string state;
+
+            if (generateState)
+            {
+                const int strengthInBits = 256;
+                state = RandomOAuthStateGenerator.Generate(strengthInBits);
+            }
+            else
+            {
+                state = null;
+            }
+
+            foreach (AuthenticationDescription description in descriptions)
+            {
+                ExternalLoginViewModel login = new ExternalLoginViewModel
+                {
+                    Name = description.Caption,
+                    Url = Url.Route("ExternalLogin", new
+                    {
+                        provider = description.AuthenticationType,
+                        response_type = "token",
+                        client_id = Startup.PublicClientId,
+                        redirect_uri = new Uri(Request.RequestUri, returnUrl).AbsoluteUri,
+                        state = state
+                    }),
+                    State = state
+                };
+                logins.Add(login);
+            }
+
+            return logins;
+        }
+
+        // POST api/Account/Register
+        [AllowAnonymous]
+        [Route("Register")]
+        public async Task<IHttpActionResult> Register(RegisterBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+
+            var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
+
+            IdentityResult result = await UserManager.CreateAsync(user, model.Password);
+
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            return Ok();
+        }
+
+        // POST api/Account/RegisterExternal
+        [OverrideAuthentication]
+        [HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
+        [Route("RegisterExternal")]
+        public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
+        {
+            if (!ModelState.IsValid)
+            {
+                return BadRequest(ModelState);
+            }
+
+            var info = await Authentication.GetExternalLoginInfoAsync();
+            if (info == null)
+            {
+                return InternalServerError();
+            }
+
+            var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
+
+            IdentityResult result = await UserManager.CreateAsync(user);
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result);
+            }
+
+            result = await UserManager.AddLoginAsync(user.Id, info.Login);
+            if (!result.Succeeded)
+            {
+                return GetErrorResult(result); 
+            }
+            return Ok();
+        }
+
+        protected override void Dispose(bool disposing)
+        {
+            if (disposing)
+            {
+                UserManager.Dispose();
+            }
+
+            base.Dispose(disposing);
+        }
+
+        #region Helpers
+
+        private IAuthenticationManager Authentication
+        {
+            get { return Request.GetOwinContext().Authentication; }
+        }
+
+        private IHttpActionResult GetErrorResult(IdentityResult result)
+        {
+            if (result == null)
+            {
+                return InternalServerError();
+            }
+
+            if (!result.Succeeded)
+            {
+                if (result.Errors != null)
+                {
+                    foreach (string error in result.Errors)
+                    {
+                        ModelState.AddModelError("", error);
+                    }
+                }
+
+                if (ModelState.IsValid)
+                {
+                    // No ModelState errors are available to send, so just return an empty BadRequest.
+                    return BadRequest();
+                }
+
+                return BadRequest(ModelState);
+            }
+
+            return null;
+        }
+
+        private class ExternalLoginData
+        {
+            public string LoginProvider { get; set; }
+            public string ProviderKey { get; set; }
+            public string UserName { get; set; }
+
+            public IList<Claim> GetClaims()
+            {
+                IList<Claim> claims = new List<Claim>();
+                claims.Add(new Claim(ClaimTypes.NameIdentifier, ProviderKey, null, LoginProvider));
+
+                if (UserName != null)
+                {
+                    claims.Add(new Claim(ClaimTypes.Name, UserName, null, LoginProvider));
+                }
+
+                return claims;
+            }
+
+            public static ExternalLoginData FromIdentity(ClaimsIdentity identity)
+            {
+                if (identity == null)
+                {
+                    return null;
+                }
+
+                Claim providerKeyClaim = identity.FindFirst(ClaimTypes.NameIdentifier);
+
+                if (providerKeyClaim == null || String.IsNullOrEmpty(providerKeyClaim.Issuer)
+                    || String.IsNullOrEmpty(providerKeyClaim.Value))
+                {
+                    return null;
+                }
+
+                if (providerKeyClaim.Issuer == ClaimsIdentity.DefaultIssuer)
+                {
+                    return null;
+                }
+
+                return new ExternalLoginData
+                {
+                    LoginProvider = providerKeyClaim.Issuer,
+                    ProviderKey = providerKeyClaim.Value,
+                    UserName = identity.FindFirstValue(ClaimTypes.Name)
+                };
+            }
+        }
+
+        private static class RandomOAuthStateGenerator
+        {
+            private static RandomNumberGenerator _random = new RNGCryptoServiceProvider();
+
+            public static string Generate(int strengthInBits)
+            {
+                const int bitsPerByte = 8;
+
+                if (strengthInBits % bitsPerByte != 0)
+                {
+                    throw new ArgumentException("strengthInBits must be evenly divisible by 8.", "strengthInBits");
+                }
+
+                int strengthInBytes = strengthInBits / bitsPerByte;
+
+                byte[] data = new byte[strengthInBytes];
+                _random.GetBytes(data);
+                return HttpServerUtility.UrlTokenEncode(data);
+            }
+        }
+
+        #endregion
+    }
+}

+ 49 - 49
test/manual/samples/run-editor-sample-dynamic.txt

@@ -1,50 +1,50 @@
-[Sun Mar 7 16:02:00 2004] [notice] Apache/1.3.29 (Unix) configured -- resuming normal operations
-[Sun Mar 7 16:02:00 2004] [info] Server built: Feb 27 2004 13:56:37
-[Sun Mar 7 16:02:00 2004] [notice] Accept mutex: sysvsem (Default: sysvsem)
-[Sun Mar 7 16:05:49 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 16:45:56 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 17:13:50 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 17:21:44 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 17:23:53 2004] statistics: Use of uninitialized value in concatenation (.) or string at /home/httpd/twiki/lib/TWiki.pm line 528.
-[Sun Mar 7 17:23:53 2004] statistics: Can't create file /home/httpd/twiki/data/Main/WebStatistics.txt - Permission denied
-[Sun Mar 7 17:27:37 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 17:31:39 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 17:58:00 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:00:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:10:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:19:01 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:42:29 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:52:30 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 18:58:52 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 19:03:58 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 19:08:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:04:35 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:11:33 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:12:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:25:31 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:44:48 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 20:58:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome
-[Sun Mar 7 21:20:14 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 21:31:12 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 21:39:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Sun Mar 7 21:44:10 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 01:35:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 01:47:06 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 01:59:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 02:12:24 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 02:54:54 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 03:46:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 03:48:18 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 03:52:17 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 03:55:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 04:22:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 04:24:47 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 04:40:32 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 04:55:40 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 04:59:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 05:22:57 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 05:24:29 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-[Mon Mar 8 05:31:47 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
-<11>httpd[31628]: [error] [client xx.xx.xx.xx] File does not exist: /usr/local/installed/apache/htdocs/squirrelmail/_vti_inf.html in 29-Mar 15:18:20.50 from xx.xx.xx.xx
+[Sun Mar 7 16:02:00 2004] [notice] Apache/1.3.29 (Unix) configured -- resuming normal operations
+[Sun Mar 7 16:02:00 2004] [info] Server built: Feb 27 2004 13:56:37
+[Sun Mar 7 16:02:00 2004] [notice] Accept mutex: sysvsem (Default: sysvsem)
+[Sun Mar 7 16:05:49 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 16:45:56 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 17:13:50 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 17:21:44 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 17:23:53 2004] statistics: Use of uninitialized value in concatenation (.) or string at /home/httpd/twiki/lib/TWiki.pm line 528.
+[Sun Mar 7 17:23:53 2004] statistics: Can't create file /home/httpd/twiki/data/Main/WebStatistics.txt - Permission denied
+[Sun Mar 7 17:27:37 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 17:31:39 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 17:58:00 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:00:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:10:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:19:01 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:42:29 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:52:30 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 18:58:52 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 19:03:58 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 19:08:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:04:35 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:11:33 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:12:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:25:31 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:44:48 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 20:58:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 21:16:17 2004] [error] [client xx.xx.xx.xx] File does not exist: /home/httpd/twiki/view/Main/WebHome
+[Sun Mar 7 21:20:14 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 21:31:12 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 21:39:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Sun Mar 7 21:44:10 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 01:35:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 01:47:06 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 01:59:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 02:12:24 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 02:54:54 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 03:46:27 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 03:48:18 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 03:52:17 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 03:55:09 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 04:22:55 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 04:24:47 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 04:40:32 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 04:55:40 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 04:59:13 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 05:22:57 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 05:24:29 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+[Mon Mar 8 05:31:47 2004] [info] [client xx.xx.xx.xx] (104)Connection reset by peer: client stopped connection before send body completed
+<11>httpd[31628]: [error] [client xx.xx.xx.xx] File does not exist: /usr/local/installed/apache/htdocs/squirrelmail/_vti_inf.html in 29-Mar 15:18:20.50 from xx.xx.xx.xx
 <11>httpd[25859]: [error] [client xx.xx.xx.xx] File does not exist: /usr/local/installed/apache/htdocs/squirrelmail/_vti_bin/shtml.exe/_vti_rpc in 29-Mar 15:18:20.54 from xx.xx.xx.xx

Some files were not shown because too many files changed in this diff