diff --git a/localtypings/pxteditor.d.ts b/localtypings/pxteditor.d.ts
index 26dd274455a3..6ac5336fd374 100644
--- a/localtypings/pxteditor.d.ts
+++ b/localtypings/pxteditor.d.ts
@@ -1,6 +1,7 @@
///
///
///
+///
declare namespace pxt.editor {
export interface EditorMessage {
@@ -1155,6 +1156,7 @@ declare namespace pxt.editor {
onCodeStop?: () => void;
experiments?: Experiment[];
+ monacoFieldEditors?: MonacoFieldEditorDefinition[];
}
export interface Experiment {
@@ -1368,6 +1370,47 @@ declare namespace pxt.editor {
}
type AssetEditorEvent = AssetEditorRequestSaveEvent | AssetEditorReadyEvent;
+
+ export interface TextEdit {
+ range: monaco.Range;
+ replacement: string;
+ }
+
+ export interface MonacoFieldEditorHost {
+ contentDiv(): HTMLDivElement;
+ getText(range: monaco.Range): string;
+ blocksInfo(): pxtc.BlocksInfo;
+
+ package(): pxt.MainPackage;
+ writeFileAsync(filename: string, content: string): Promise;
+ readFile(filename: string): string;
+ }
+
+ export interface MonacoFieldEditor {
+ getId(): string;
+ showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise;
+ onClosed(): void;
+ dispose(): void;
+ }
+
+ export interface MonacoFieldEditorDefinition {
+ id: string;
+ matcher: MonacoFindArguments;
+ foldMatches?: boolean;
+ alwaysBuildOnClose?: boolean;
+ glyphCssClass?: string;
+ weight?: number; // higher weight will override lower weight when on same line
+ proto: { new(): MonacoFieldEditor };
+ heightInPixels?: number;
+ }
+
+ export interface MonacoFindArguments {
+ searchString: string;
+ isRegex: boolean;
+ matchWholeWord: boolean;
+ matchCase: boolean;
+ validateRange?: (range: monaco.Range, model: monaco.editor.ITextModel) => monaco.Range;
+ }
}
declare namespace pxt.workspace {
diff --git a/pxteditor/monaco-fields/field_musiceditor.ts b/pxteditor/monaco-fields/field_musiceditor.ts
index 6306a1179c88..5b87b73fcdf9 100644
--- a/pxteditor/monaco-fields/field_musiceditor.ts
+++ b/pxteditor/monaco-fields/field_musiceditor.ts
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
-import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
+import { registerMonacoFieldEditor } from "./monacoFieldEditor";
const fieldEditorId = "music-editor";
@@ -91,7 +91,7 @@ function createFakeAsset(song: pxt.assets.music.Song): pxt.Song {
}
}
-export const songEditorDefinition: MonacoFieldEditorDefinition = {
+export const songEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "fas fa-music sprite-focus-hover",
diff --git a/pxteditor/monaco-fields/field_react.ts b/pxteditor/monaco-fields/field_react.ts
index 9bb9049af571..a155501f0419 100644
--- a/pxteditor/monaco-fields/field_react.ts
+++ b/pxteditor/monaco-fields/field_react.ts
@@ -1,21 +1,19 @@
-import { MonacoFieldEditor, TextEdit, MonacoFieldEditorHost } from "./monacoFieldEditor";
-
const fieldEditorId = "image-editor";
-export class MonacoReactFieldEditor implements MonacoFieldEditor {
- private resolver: (edit: TextEdit) => void;
+export class MonacoReactFieldEditor implements pxt.editor.MonacoFieldEditor {
+ private resolver: (edit: pxt.editor.TextEdit) => void;
private rejecter: (err?: any) => void;
protected fileType: pxt.editor.FileType;
protected editrange: monaco.Range;
- protected host: MonacoFieldEditorHost;
+ protected host: pxt.editor.MonacoFieldEditorHost;
protected fv: pxt.react.FieldEditorView;
getId() {
return fieldEditorId;
}
- showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise {
+ showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: pxt.editor.MonacoFieldEditorHost): Promise {
this.fileType = fileType;
this.editrange = editrange;
this.host = host;
diff --git a/pxteditor/monaco-fields/field_soundEffect.ts b/pxteditor/monaco-fields/field_soundEffect.ts
index 4b6bdc1bd7b0..cd746a2cb839 100644
--- a/pxteditor/monaco-fields/field_soundEffect.ts
+++ b/pxteditor/monaco-fields/field_soundEffect.ts
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
-import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
+import { registerMonacoFieldEditor } from "./monacoFieldEditor";
const fieldEditorId = "soundeffect-editor";
@@ -205,7 +205,7 @@ function defaultSound(): pxt.assets.Sound {
}
}
-export const soundEditorDefinition: MonacoFieldEditorDefinition = {
+export const soundEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "fas fa-music sprite-focus-hover",
diff --git a/pxteditor/monaco-fields/field_sprite.ts b/pxteditor/monaco-fields/field_sprite.ts
index 3cd8be6ac4f9..e3f172aee639 100644
--- a/pxteditor/monaco-fields/field_sprite.ts
+++ b/pxteditor/monaco-fields/field_sprite.ts
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
-import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
+import { registerMonacoFieldEditor } from "./monacoFieldEditor";
const fieldEditorId = "image-editor";
@@ -76,7 +76,7 @@ function createFakeAsset(bitmap: pxt.sprite.Bitmap): pxt.ProjectImage {
}
}
-export const spriteEditorDefinition: MonacoFieldEditorDefinition = {
+export const spriteEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
glyphCssClass: "sprite-editor-glyph sprite-focus-hover",
diff --git a/pxteditor/monaco-fields/field_tilemap.ts b/pxteditor/monaco-fields/field_tilemap.ts
index a207108be603..85b74758c75e 100644
--- a/pxteditor/monaco-fields/field_tilemap.ts
+++ b/pxteditor/monaco-fields/field_tilemap.ts
@@ -1,5 +1,5 @@
import { MonacoReactFieldEditor } from "./field_react";
-import { MonacoFieldEditorDefinition, registerMonacoFieldEditor } from "./monacoFieldEditor";
+import { registerMonacoFieldEditor } from "./monacoFieldEditor";
const fieldEditorId = "tilemap-editor";
@@ -139,7 +139,7 @@ function createFakeAsset(data: pxt.sprite.TilemapData): pxt.ProjectTilemap {
}
}
-export const tilemapEditorDefinition: MonacoFieldEditorDefinition = {
+export const tilemapEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = {
id: fieldEditorId,
foldMatches: true,
alwaysBuildOnClose: true,
diff --git a/pxteditor/monaco-fields/monacoFieldEditor.ts b/pxteditor/monaco-fields/monacoFieldEditor.ts
index 981935d83b35..fb52900e267b 100644
--- a/pxteditor/monaco-fields/monacoFieldEditor.ts
+++ b/pxteditor/monaco-fields/monacoFieldEditor.ts
@@ -1,49 +1,9 @@
///
-export interface TextEdit {
- range: monaco.Range;
- replacement: string;
-}
-
-export interface MonacoFieldEditorHost {
- contentDiv(): HTMLDivElement;
- getText(range: monaco.Range): string;
- blocksInfo(): pxtc.BlocksInfo;
-
- package(): pxt.MainPackage;
- writeFileAsync(filename: string, content: string): Promise;
- readFile(filename: string): string;
-}
-
-export interface MonacoFieldEditor {
- getId(): string;
- showEditorAsync(fileType: pxt.editor.FileType, editrange: monaco.Range, host: MonacoFieldEditorHost): Promise;
- onClosed(): void;
- dispose(): void;
-}
-
-export interface MonacoFieldEditorDefinition {
- id: string;
- matcher: MonacoFindArguments;
- foldMatches?: boolean;
- alwaysBuildOnClose?: boolean;
- glyphCssClass?: string;
- weight?: number; // higher weight will override lower weight when on same line
- proto: { new(): MonacoFieldEditor };
- heightInPixels?: number;
-}
-
-export interface MonacoFindArguments {
- searchString: string;
- isRegex: boolean;
- matchWholeWord: boolean;
- matchCase: boolean;
- validateRange?: (range: monaco.Range, model: monaco.editor.ITextModel) => monaco.Range;
-}
-const definitions: pxt.Map = {};
+const definitions: pxt.Map = {};
-export function registerMonacoFieldEditor(name: string, definition: MonacoFieldEditorDefinition) {
+export function registerMonacoFieldEditor(name: string, definition: pxt.editor.MonacoFieldEditorDefinition) {
definitions[name] = definition;
}
diff --git a/webapp/src/cmds.ts b/webapp/src/cmds.ts
index 273c714b031b..c2c8c95421f7 100644
--- a/webapp/src/cmds.ts
+++ b/webapp/src/cmds.ts
@@ -13,6 +13,7 @@ import * as pxtblockly from "../../pxtblocks";
import ExtensionResult = pxt.editor.ExtensionResult;
import NativeHostMessage = pxt.editor.NativeHostMessage;
import { setEditorExtensionExperiments } from "../../pxteditor/experiments";
+import { registerMonacoFieldEditor } from "../../pxteditor";
function log(msg: string) {
@@ -401,6 +402,11 @@ function applyExtensionResult() {
if (res.experiments) {
setEditorExtensionExperiments(res.experiments);
}
+ if (res.monacoFieldEditors) {
+ for (const def of res.monacoFieldEditors) {
+ registerMonacoFieldEditor(def.id, def);
+ }
+ }
}
export async function initAsync() {
diff --git a/webapp/src/monaco.tsx b/webapp/src/monaco.tsx
index 01177842f525..1db2e5f10040 100644
--- a/webapp/src/monaco.tsx
+++ b/webapp/src/monaco.tsx
@@ -1606,7 +1606,7 @@ export class Editor extends toolboxeditor.ToolboxEditor {
}
}
- showFieldEditor(range: monaco.Range, fe: pxteditor.MonacoFieldEditor, viewZoneHeight: number, buildAfter: boolean) {
+ showFieldEditor(range: monaco.Range, fe: pxt.editor.MonacoFieldEditor, viewZoneHeight: number, buildAfter: boolean) {
if (this.feWidget) {
this.feWidget.close();
}
diff --git a/webapp/src/monacoFieldEditorHost.ts b/webapp/src/monacoFieldEditorHost.ts
index ec38bda8ccd5..21e26787efec 100644
--- a/webapp/src/monacoFieldEditorHost.ts
+++ b/webapp/src/monacoFieldEditorHost.ts
@@ -1,6 +1,5 @@
///
-import { MonacoFieldEditor, MonacoFieldEditorDefinition, MonacoFieldEditorHost, TextEdit } from "../../pxteditor";
import * as compiler from "./compiler";
import * as pkg from "./package";
@@ -11,7 +10,7 @@ interface OwnedRange {
id: number;
}
-export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.IViewZone {
+export class ViewZoneEditorHost implements pxt.editor.MonacoFieldEditorHost, monaco.editor.IViewZone {
domNode: HTMLDivElement;
afterLineNumber: number;
heightInPx = 520;
@@ -26,7 +25,7 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.
suppressMouseDown = false;
- constructor(protected fe: MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
+ constructor(protected fe: pxt.editor.MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
this.afterLineNumber = range.endLineNumber;
const outer = document.createElement("div");
@@ -52,7 +51,7 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.
return this.content;
}
- showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise {
+ showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise {
this.fileType = fileType;
this.editor = editor;
return compiler.getBlocksAsync()
@@ -132,10 +131,10 @@ export class ViewZoneEditorHost implements MonacoFieldEditorHost, monaco.editor.
}
}
-export class ModalEditorHost implements MonacoFieldEditorHost {
+export class ModalEditorHost implements pxt.editor.MonacoFieldEditorHost {
protected blocks: pxtc.BlocksInfo;
- constructor(protected fe: MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
+ constructor(protected fe: pxt.editor.MonacoFieldEditor, protected range: monaco.Range, protected model: monaco.editor.IModel) {
}
contentDiv(): HTMLDivElement {
@@ -164,7 +163,7 @@ export class ModalEditorHost implements MonacoFieldEditorHost {
return this.package().host().readFile(pkg.mainPkg, filename);
}
- showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise {
+ showAsync(fileType: pxt.editor.FileType, editor: monaco.editor.IStandaloneCodeEditor): Promise {
return compiler.getBlocksAsync()
.then(bi => {
this.blocks = bi;
@@ -179,7 +178,7 @@ export class ModalEditorHost implements MonacoFieldEditorHost {
}
export class FieldEditorManager implements monaco.languages.FoldingRangeProvider {
- protected fieldEditors: MonacoFieldEditorDefinition[] = [];
+ protected fieldEditors: pxt.editor.MonacoFieldEditorDefinition[] = [];
protected decorations: pxt.Map = {};
protected liveRanges: OwnedRange[] = [];
protected fieldEditorsEnabled = true;
@@ -213,7 +212,7 @@ export class FieldEditorManager implements monaco.languages.FoldingRangeProvider
}
}
- addFieldEditor(definition: MonacoFieldEditorDefinition) {
+ addFieldEditor(definition: pxt.editor.MonacoFieldEditorDefinition) {
for (const f of this.fieldEditors) {
if (f.id === definition.id) return;
}