From 3abf835c6ab2b1ce83652d8baa4edcb5b5bcbc1b Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Thu, 20 Nov 2025 10:03:13 -0800 Subject: [PATCH 1/4] Improve perf for field editor regexes and fix music editor bug (#10955) * fix the image monaco field editor regex * fix music regex and bug with converting hex to named asset --- pxteditor/monaco-fields/field_musiceditor.ts | 39 ++++++++++++-------- pxteditor/monaco-fields/field_sprite.ts | 17 ++++++++- 2 files changed, 39 insertions(+), 17 deletions(-) diff --git a/pxteditor/monaco-fields/field_musiceditor.ts b/pxteditor/monaco-fields/field_musiceditor.ts index 629f5461311c..d821f027d748 100644 --- a/pxteditor/monaco-fields/field_musiceditor.ts +++ b/pxteditor/monaco-fields/field_musiceditor.ts @@ -66,8 +66,16 @@ export class MonacoSongEditor extends MonacoReactFieldEditor { } else { result = project.createNewSong(result.song, result.meta.displayName); } - this.isAsset = true; - return pxt.getTSReferenceForAsset(result, this.isPython); + let out = pxt.getTSReferenceForAsset(result, this.isPython); + if (!this.isAsset) { + if (this.isPython) { + out = `music.create_song(${out})`; + } + else { + out = `music.createSong(${out})`; + } + } + return out; } let hexString = pxt.assets.music.encodeSongToHex(result.song); @@ -101,25 +109,26 @@ function createFakeAsset(song: pxt.assets.music.Song): pxt.Song { } } +const regexes = [ + // typescript + "music\\s*\\.\\s*createSong\\s*\\(\\s*hex`[a-fA-F0-9\\s\\n]*`\\s*\\)", + "assets\\s*\\.\\s*song\\s*`[a-zA-Z_\\s\\n]*`", + + // python + 'music\\s*\\.\\s*create_song\\s*\\(\\s*hex\\s*\\(\\s*"""[a-fA-F0-9\\s\\n]*"""\\s*\\)\\s*\\)', + 'music\\s*\\.\\s*createSong\\s*\\(\\s*hex\\s*\\(\\s*"""[a-fA-F0-9\\s\\n]*"""\\s*\\)\\s*\\)', + 'assets\\s*\\.\\s*song\\s*\\(\\s*"""[a-zA-Z_\\s\\n]*"""\\s*\\)' +]; + +const searchString = regexes.map(r => `(?:${r})`).join("|"); + export const songEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = { id: fieldEditorId, foldMatches: true, glyphCssClass: "fas fa-music sprite-focus-hover", heightInPixels: 510, matcher: { - /** - * This is horrendous-looking regex matches both the asset reference syntax: - * assets.song`name` - * assets.song("""name""") - * - * and the hex-literal syntax: - * music.createSong(hex`01234` - * music.create_song(hex("""01234""") - * - * For the hex literal matches, it includes the call to music.createSong since - * hex buffers can also be used for other things - */ - searchString: "(?:(?:assets\\s*\\.\\s*song)|(?:music\\s*\\.\\s*create(?:S|_s)ong\\s*\\(\\s*hex))\\s*(?:`|\\(\\s*\"\"\")(?:(?:[^(){}:\\[\\]\"';?/,+\\-=*&|^%!`~]|\\n)*)\\s*(?:`|\"\"\"\\s*\\))", + searchString: searchString, isRegex: true, matchCase: true, matchWholeWord: false diff --git a/pxteditor/monaco-fields/field_sprite.ts b/pxteditor/monaco-fields/field_sprite.ts index d81b34d5d396..6af4a6020a27 100644 --- a/pxteditor/monaco-fields/field_sprite.ts +++ b/pxteditor/monaco-fields/field_sprite.ts @@ -85,14 +85,27 @@ function createFakeAsset(bitmap: pxt.sprite.Bitmap): pxt.ProjectImage { } } +const regexes = [ + // typescript + "img\\s*`[\\.a-zA-Z0-9#\\n\\s]*`", + "bmp\\s*`[\\.a-zA-Z0-9#\\n\\s]*`", + "assets\\s*\\.\\s*image\\s*`[a-zA-Z_\\s\\n]*`", + + // python + 'img\\s*\\(\\s*"""[\\.a-zA-Z0-9#\\n\\s]*"""\\s*\\)', + 'bmp\\s*\\(\\s*"""[\\.a-zA-Z0-9#\\n\\s]*"""\\s*\\)', + 'assets\\s*\\.\\s*image\\s*\\(\\s*"""[a-zA-Z_\\s\\n]*"""\\s*\\)' +]; + +const searchString = regexes.map(r => `(?:${r})`).join("|"); + export const spriteEditorDefinition: pxt.editor.MonacoFieldEditorDefinition = { id: fieldEditorId, foldMatches: true, glyphCssClass: "sprite-editor-glyph sprite-focus-hover", heightInPixels: 510, matcher: { - // match both JS and python - searchString: "(?:img|bmp|assets\\s*\\.\\s*image)\\s*(?:`|\\(\\s*\"\"\")(?:(?:[^(){}:\\[\\]\"';?/,+\\-=*&|^%!`~]|\\n)*)\\s*(?:`|\"\"\"\\s*\\))", + searchString: searchString, isRegex: true, matchCase: true, matchWholeWord: false From 2a61801fe8de16791781c9c4d2f8009a21fa2e93 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Thu, 20 Nov 2025 10:31:41 -0800 Subject: [PATCH 2/4] fix focus outline for asset fields (#10958) --- pxtblocks/fields/field_asset.ts | 2 +- pxtblocks/fields/field_musiceditor.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pxtblocks/fields/field_asset.ts b/pxtblocks/fields/field_asset.ts index d780315a95d3..e4f07e51b85e 100644 --- a/pxtblocks/fields/field_asset.ts +++ b/pxtblocks/fields/field_asset.ts @@ -403,7 +403,7 @@ export abstract class FieldAssetEditor Date: Thu, 20 Nov 2025 14:34:51 -0800 Subject: [PATCH 3/4] fix header for code eval tool in arcade (#10963) --- teachertool/src/components/HeaderBar.tsx | 22 ++++++++++++------- .../components/styling/HeaderBar.module.scss | 21 ++++++++++++++++++ 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/teachertool/src/components/HeaderBar.tsx b/teachertool/src/components/HeaderBar.tsx index 826b1c30b231..5c3388f60a88 100644 --- a/teachertool/src/components/HeaderBar.tsx +++ b/teachertool/src/components/HeaderBar.tsx @@ -52,7 +52,7 @@ export const HeaderBar: React.FC = () => { )} ) : ( - {appTheme.organization} + {appTheme.organization} )} ); @@ -67,14 +67,20 @@ export const HeaderBar: React.FC = () => { onClick={onBrandIconClick} > {appTheme.useTextLogo ? ( - [ - + <> + {appTheme.organizationText} - , - + + {appTheme.organizationShortText || appTheme.organizationText} - , - ] + + ) : appTheme.logo || appTheme.portraitLogo ? ( <> {appTheme.logo && ( @@ -93,7 +99,7 @@ export const HeaderBar: React.FC = () => { )} ) : ( - {appTheme.boardName} + {appTheme.boardName} )} ); diff --git a/teachertool/src/components/styling/HeaderBar.module.scss b/teachertool/src/components/styling/HeaderBar.module.scss index 4754987453b4..b5dc51cc7974 100644 --- a/teachertool/src/components/styling/HeaderBar.module.scss +++ b/teachertool/src/components/styling/HeaderBar.module.scss @@ -28,6 +28,14 @@ } } + .organization-name { + font-size: 1.125rem; + font-weight: 600; + margin-left: 1rem; + color: var(--pxt-header-foreground); + white-space: nowrap; + } + .brand { display: flex; align-items: center; @@ -43,6 +51,19 @@ height: 1.1rem; margin: 0 1rem; } + + .brand-text, + .brand-text-short { + font-size: 1.25rem; + font-weight: 600; + color: var(--pxt-header-foreground); + margin-left: 1rem; + white-space: nowrap; + } + + .brand-text-short { + font-size: 1.125rem; + } } .centered-panel { From 1142e3f951ad94da42be70f9cf0cba6fcf9a47a9 Mon Sep 17 00:00:00 2001 From: Richard Knoll Date: Thu, 20 Nov 2025 15:00:56 -0800 Subject: [PATCH 4/4] fix rendering of sidedocs (#10961) --- pxtlib/docsrender.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pxtlib/docsrender.ts b/pxtlib/docsrender.ts index ef75a00edee2..b28a17340837 100644 --- a/pxtlib/docsrender.ts +++ b/pxtlib/docsrender.ts @@ -30,6 +30,7 @@ namespace pxt.docs { lexer: (src: string, options?: any) => any[]; setOptions: (options: any) => void; parseInline?: (src: string, options?: any) => string; + parse?: (src: string, options?: any) => string; } interface MarkedImageToken { @@ -690,7 +691,7 @@ ${opts.repo.name.replace(/^pxt-/, '')}=github:${opts.repo.fullName}#${opts.repo. return macro || 'unknown macro' }); - let html = markedInstance(markdown); + let html = markedInstance.parse(markdown); const coerceToString = (value: unknown, fallback: string = "") => { if (typeof value === "string") return value; if (value && typeof (value as any).toString === "function") {