pxt-core 8.5.16 → 8.5.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/built/pxt.js CHANGED
@@ -114909,6 +114909,22 @@ var ts;
114909
114909
  res._shadowOverrides = {};
114910
114910
  res._shadowOverrides[n.slice(0, n.length - 7)] = v;
114911
114911
  }
114912
+ else if (pxtc.U.endsWith(n, ".snippet")) {
114913
+ if (!res.paramSnippets)
114914
+ res.paramSnippets = {};
114915
+ const paramName = n.slice(0, n.length - 8);
114916
+ if (!res.paramSnippets[paramName])
114917
+ res.paramSnippets[paramName] = {};
114918
+ res.paramSnippets[paramName].ts = v;
114919
+ }
114920
+ else if (pxtc.U.endsWith(n, ".pySnippet")) {
114921
+ if (!res.paramSnippets)
114922
+ res.paramSnippets = {};
114923
+ const paramName = n.slice(0, n.length - 10);
114924
+ if (!res.paramSnippets[paramName])
114925
+ res.paramSnippets[paramName] = {};
114926
+ res.paramSnippets[paramName].python = v;
114927
+ }
114912
114928
  else if (pxtc.U.endsWith(n, ".fieldEditor")) {
114913
114929
  if (!res.paramFieldEditor)
114914
114930
  res.paramFieldEditor = {};
@@ -141244,13 +141260,22 @@ var ts;
141244
141260
  return inName;
141245
141261
  }
141246
141262
  function getParameterDefault(param) {
141247
- var _a;
141263
+ var _a, _b;
141248
141264
  const typeNode = param.type;
141249
141265
  if (!typeNode)
141250
141266
  return python ? "None" : "null";
141251
141267
  const name = param.name.kind === pxtc.SK.Identifier ? param.name.text : undefined;
141268
+ const override = (_a = attrs.paramSnippets) === null || _a === void 0 ? void 0 : _a[name];
141269
+ if (override) {
141270
+ if (python) {
141271
+ if (override.python)
141272
+ return override.python;
141273
+ }
141274
+ else if (override.ts)
141275
+ return override.ts;
141276
+ }
141252
141277
  // check for explicit default in the attributes
141253
- const paramDefl = (_a = attrs === null || attrs === void 0 ? void 0 : attrs.paramDefl) === null || _a === void 0 ? void 0 : _a[name];
141278
+ const paramDefl = (_b = attrs === null || attrs === void 0 ? void 0 : attrs.paramDefl) === null || _b === void 0 ? void 0 : _b[name];
141254
141279
  if (paramDefl) {
141255
141280
  let deflKind;
141256
141281
  if (typeNode.kind == pxtc.SK.AnyKeyword) {
@@ -6477,9 +6477,7 @@ var pxt;
6477
6477
  try {
6478
6478
  Blockly.Events.disable();
6479
6479
  newBlockIds = Blockly.Xml.domToWorkspace(dom, workspace);
6480
- if (opts === null || opts === void 0 ? void 0 : opts.applyMetaComments) {
6481
- applyMetaComments(workspace);
6482
- }
6480
+ applyMetaComments(workspace, opts);
6483
6481
  }
6484
6482
  catch (e) {
6485
6483
  pxt.reportException(e);
@@ -6490,21 +6488,29 @@ var pxt;
6490
6488
  return newBlockIds.filter(id => !!workspace.getBlockById(id));
6491
6489
  }
6492
6490
  blocks_2.domToWorkspaceNoEvents = domToWorkspaceNoEvents;
6493
- function applyMetaComments(workspace) {
6491
+ function applyMetaComments(workspace, opts) {
6494
6492
  // process meta comments
6495
6493
  // @highlight -> highlight block
6496
6494
  workspace.getAllBlocks(false)
6497
6495
  .filter(b => !!b.getCommentText())
6498
6496
  .forEach(b => {
6499
6497
  var _a, _b;
6500
- const c = b.getCommentText();
6501
- if (/@highlight/.test(c)) {
6502
- const cc = c.replace(/@highlight/g, '').trim();
6503
- b.setCommentText(cc || null);
6498
+ const initialCommentText = b.getCommentText();
6499
+ if (/@hide/.test(initialCommentText) && (opts === null || opts === void 0 ? void 0 : opts.applyHideMetaComment)) {
6500
+ b.dispose(true);
6501
+ return;
6502
+ }
6503
+ let newCommentText = initialCommentText;
6504
+ if (/@highlight/.test(newCommentText)) {
6505
+ newCommentText = newCommentText.replace(/@highlight/g, '').trim();
6504
6506
  (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id, true);
6505
6507
  }
6506
- if (/@hide/.test(c)) {
6507
- b.dispose(true);
6508
+ if (/@collapsed/.test(newCommentText) && !b.getParent()) {
6509
+ newCommentText = newCommentText.replace(/@collapsed/g, '').trim();
6510
+ b.setCollapsed(true);
6511
+ }
6512
+ if (initialCommentText !== newCommentText && !(opts === null || opts === void 0 ? void 0 : opts.keepMetaComments)) {
6513
+ b.setCommentText(newCommentText || null);
6508
6514
  }
6509
6515
  });
6510
6516
  }
@@ -6574,11 +6580,11 @@ var pxt;
6574
6580
  /**
6575
6581
  * Loads the xml into a off-screen workspace (not suitable for size computations)
6576
6582
  */
6577
- function loadWorkspaceXml(xml, skipReport = false) {
6583
+ function loadWorkspaceXml(xml, skipReport = false, opts) {
6578
6584
  const workspace = new Blockly.Workspace();
6579
6585
  try {
6580
6586
  const dom = Blockly.Xml.textToDom(xml);
6581
- pxt.blocks.domToWorkspaceNoEvents(dom, workspace);
6587
+ pxt.blocks.domToWorkspaceNoEvents(dom, workspace, opts);
6582
6588
  return workspace;
6583
6589
  }
6584
6590
  catch (e) {
@@ -10666,7 +10672,7 @@ var pxt;
10666
10672
  try {
10667
10673
  let text = blocksXml || `<xml xmlns="http://www.w3.org/1999/xhtml"></xml>`;
10668
10674
  let xml = Blockly.Xml.textToDom(text);
10669
- pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyMetaComments: true });
10675
+ pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyHideMetaComment: true });
10670
10676
  return renderWorkspace(options);
10671
10677
  }
10672
10678
  catch (e) {
@@ -14950,8 +14956,8 @@ var pxtblockly;
14950
14956
  else {
14951
14957
  const note = +this.value_;
14952
14958
  for (let i = 0; i < this.nKeys_; i++) {
14953
- if (Math.abs(this.getKeyFreq(i) - note) < this.eps) {
14954
- return this.getKeyName(i);
14959
+ if (Math.abs(this.getKeyFreq(i + this.minNote_) - note) < this.eps) {
14960
+ return this.getKeyName(i + this.minNote_);
14955
14961
  }
14956
14962
  }
14957
14963
  let text = note.toString();
@@ -15021,15 +15027,15 @@ var pxtblockly;
15021
15027
  let startingPage = 0;
15022
15028
  for (let i = 0; i < this.nKeys_; i++) {
15023
15029
  const currentOctave = Math.floor(i / FieldNote.notesPerOctave);
15024
- let position = this.getPosition(i);
15030
+ let position = this.getPosition(i + this.minNote_);
15025
15031
  // modify original position in pagination
15026
15032
  if (pagination && i >= FieldNote.notesPerOctave)
15027
15033
  position -= whiteKeysPerOctave * currentOctave * FieldNote.keyWidth;
15028
- const key = this.getKeyDiv(i, position);
15034
+ const key = this.getKeyDiv(i + this.minNote_, position);
15029
15035
  this.piano.push(key);
15030
15036
  pianoDiv.appendChild(key);
15031
15037
  // if the current value is within eps of this note, select it.
15032
- if (Math.abs(this.getKeyFreq(i) - Number(this.getValue())) < this.eps) {
15038
+ if (Math.abs(this.getKeyFreq(i + this.minNote_) - Number(this.getValue())) < this.eps) {
15033
15039
  pxt.BrowserUtils.addClass(key, "selected");
15034
15040
  this.currentSelectedKey = key;
15035
15041
  startingPage = currentOctave;
@@ -15135,6 +15141,7 @@ var pxtblockly;
15135
15141
  * @return true if idx is white
15136
15142
  */
15137
15143
  isWhite(idx) {
15144
+ idx += 8;
15138
15145
  switch (idx % 12) {
15139
15146
  case 1:
15140
15147
  case 3:
@@ -15146,6 +15153,30 @@ var pxtblockly;
15146
15153
  return true;
15147
15154
  }
15148
15155
  }
15156
+ whiteKeysBefore(idx) {
15157
+ idx += 8;
15158
+ switch (idx % 12) {
15159
+ case 0: return 0;
15160
+ case 1:
15161
+ case 2:
15162
+ return 1;
15163
+ case 3:
15164
+ case 4:
15165
+ return 2;
15166
+ case 5:
15167
+ return 3;
15168
+ case 6:
15169
+ case 7:
15170
+ return 4;
15171
+ case 8:
15172
+ case 9:
15173
+ return 5;
15174
+ case 10:
15175
+ case 11:
15176
+ return 6;
15177
+ }
15178
+ return -1;
15179
+ }
15149
15180
  /**
15150
15181
  * get width of the piano key
15151
15182
  * @param idx index of the key
@@ -15183,7 +15214,7 @@ var pxtblockly;
15183
15214
  return name;
15184
15215
  }
15185
15216
  getKeyNoteData(keyIndex) {
15186
- return FieldNote.Notes[keyIndex + this.minNote_];
15217
+ return FieldNote.Notes[keyIndex];
15187
15218
  }
15188
15219
  /**
15189
15220
  * get the position of the key in the piano
@@ -15191,11 +15222,24 @@ var pxtblockly;
15191
15222
  * @return position of the key
15192
15223
  */
15193
15224
  getPosition(idx) {
15194
- const whiteKeyCount = idx - Math.floor((idx + 1) / FieldNote.notesPerOctave * FieldNote.blackKeysPerOctave);
15195
- const pos = whiteKeyCount * FieldNote.keyWidth;
15196
- if (this.isWhite(idx))
15197
- return pos;
15198
- return pos - (FieldNote.keyWidth / 4);
15225
+ if (idx === this.minNote_)
15226
+ return 0;
15227
+ const blackKeyOffset = (FieldNote.keyWidth / 4);
15228
+ const startOctave = Math.floor((this.minNote_ + 8) / FieldNote.notesPerOctave);
15229
+ const currentOctave = Math.floor((idx + 8) / FieldNote.notesPerOctave);
15230
+ let startOffset = this.whiteKeysBefore(this.minNote_) * FieldNote.keyWidth;
15231
+ if (!this.isWhite(this.minNote_)) {
15232
+ startOffset -= blackKeyOffset;
15233
+ }
15234
+ if (currentOctave > startOctave) {
15235
+ const octaveWidth = FieldNote.keyWidth * 7;
15236
+ const firstOctaveWidth = octaveWidth - startOffset;
15237
+ const octaveStart = firstOctaveWidth + (currentOctave - startOctave - 1) * octaveWidth;
15238
+ return this.whiteKeysBefore(idx) * FieldNote.keyWidth + octaveStart - (this.isWhite(idx) ? 0 : blackKeyOffset);
15239
+ }
15240
+ else {
15241
+ return this.whiteKeysBefore(idx) * FieldNote.keyWidth - startOffset - (this.isWhite(idx) ? 0 : blackKeyOffset);
15242
+ }
15199
15243
  }
15200
15244
  prepareNotes() {
15201
15245
  if (!FieldNote.Notes) {
@@ -134,7 +134,8 @@ declare namespace pxt.blocks {
134
134
  extensions?: string[];
135
135
  }
136
136
  interface DomToWorkspaceOptions {
137
- applyMetaComments?: boolean;
137
+ applyHideMetaComment?: boolean;
138
+ keepMetaComments?: boolean;
138
139
  }
139
140
  /**
140
141
  * Converts a DOM into workspace without triggering any Blockly event. Returns the new block ids
@@ -153,7 +154,7 @@ declare namespace pxt.blocks {
153
154
  /**
154
155
  * Loads the xml into a off-screen workspace (not suitable for size computations)
155
156
  */
156
- function loadWorkspaceXml(xml: string, skipReport?: boolean): Blockly.Workspace;
157
+ function loadWorkspaceXml(xml: string, skipReport?: boolean, opts?: DomToWorkspaceOptions): Blockly.Workspace;
157
158
  /**
158
159
  * This callback is populated from the editor extension result.
159
160
  * Allows a target to provide version specific blockly updates
@@ -1096,6 +1097,7 @@ declare namespace pxtblockly {
1096
1097
  * @return true if idx is white
1097
1098
  */
1098
1099
  protected isWhite(idx: number): boolean;
1100
+ protected whiteKeysBefore(idx: number): number;
1099
1101
  /**
1100
1102
  * get width of the piano key
1101
1103
  * @param idx index of the key
@@ -2915,9 +2915,7 @@ var pxt;
2915
2915
  try {
2916
2916
  Blockly.Events.disable();
2917
2917
  newBlockIds = Blockly.Xml.domToWorkspace(dom, workspace);
2918
- if (opts === null || opts === void 0 ? void 0 : opts.applyMetaComments) {
2919
- applyMetaComments(workspace);
2920
- }
2918
+ applyMetaComments(workspace, opts);
2921
2919
  }
2922
2920
  catch (e) {
2923
2921
  pxt.reportException(e);
@@ -2928,21 +2926,29 @@ var pxt;
2928
2926
  return newBlockIds.filter(id => !!workspace.getBlockById(id));
2929
2927
  }
2930
2928
  blocks_2.domToWorkspaceNoEvents = domToWorkspaceNoEvents;
2931
- function applyMetaComments(workspace) {
2929
+ function applyMetaComments(workspace, opts) {
2932
2930
  // process meta comments
2933
2931
  // @highlight -> highlight block
2934
2932
  workspace.getAllBlocks(false)
2935
2933
  .filter(b => !!b.getCommentText())
2936
2934
  .forEach(b => {
2937
2935
  var _a, _b;
2938
- const c = b.getCommentText();
2939
- if (/@highlight/.test(c)) {
2940
- const cc = c.replace(/@highlight/g, '').trim();
2941
- b.setCommentText(cc || null);
2936
+ const initialCommentText = b.getCommentText();
2937
+ if (/@hide/.test(initialCommentText) && (opts === null || opts === void 0 ? void 0 : opts.applyHideMetaComment)) {
2938
+ b.dispose(true);
2939
+ return;
2940
+ }
2941
+ let newCommentText = initialCommentText;
2942
+ if (/@highlight/.test(newCommentText)) {
2943
+ newCommentText = newCommentText.replace(/@highlight/g, '').trim();
2942
2944
  (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id, true);
2943
2945
  }
2944
- if (/@hide/.test(c)) {
2945
- b.dispose(true);
2946
+ if (/@collapsed/.test(newCommentText) && !b.getParent()) {
2947
+ newCommentText = newCommentText.replace(/@collapsed/g, '').trim();
2948
+ b.setCollapsed(true);
2949
+ }
2950
+ if (initialCommentText !== newCommentText && !(opts === null || opts === void 0 ? void 0 : opts.keepMetaComments)) {
2951
+ b.setCommentText(newCommentText || null);
2946
2952
  }
2947
2953
  });
2948
2954
  }
@@ -3012,11 +3018,11 @@ var pxt;
3012
3018
  /**
3013
3019
  * Loads the xml into a off-screen workspace (not suitable for size computations)
3014
3020
  */
3015
- function loadWorkspaceXml(xml, skipReport = false) {
3021
+ function loadWorkspaceXml(xml, skipReport = false, opts) {
3016
3022
  const workspace = new Blockly.Workspace();
3017
3023
  try {
3018
3024
  const dom = Blockly.Xml.textToDom(xml);
3019
- pxt.blocks.domToWorkspaceNoEvents(dom, workspace);
3025
+ pxt.blocks.domToWorkspaceNoEvents(dom, workspace, opts);
3020
3026
  return workspace;
3021
3027
  }
3022
3028
  catch (e) {
@@ -7104,7 +7110,7 @@ var pxt;
7104
7110
  try {
7105
7111
  let text = blocksXml || `<xml xmlns="http://www.w3.org/1999/xhtml"></xml>`;
7106
7112
  let xml = Blockly.Xml.textToDom(text);
7107
- pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyMetaComments: true });
7113
+ pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyHideMetaComment: true });
7108
7114
  return renderWorkspace(options);
7109
7115
  }
7110
7116
  catch (e) {
@@ -11388,8 +11394,8 @@ var pxtblockly;
11388
11394
  else {
11389
11395
  const note = +this.value_;
11390
11396
  for (let i = 0; i < this.nKeys_; i++) {
11391
- if (Math.abs(this.getKeyFreq(i) - note) < this.eps) {
11392
- return this.getKeyName(i);
11397
+ if (Math.abs(this.getKeyFreq(i + this.minNote_) - note) < this.eps) {
11398
+ return this.getKeyName(i + this.minNote_);
11393
11399
  }
11394
11400
  }
11395
11401
  let text = note.toString();
@@ -11459,15 +11465,15 @@ var pxtblockly;
11459
11465
  let startingPage = 0;
11460
11466
  for (let i = 0; i < this.nKeys_; i++) {
11461
11467
  const currentOctave = Math.floor(i / FieldNote.notesPerOctave);
11462
- let position = this.getPosition(i);
11468
+ let position = this.getPosition(i + this.minNote_);
11463
11469
  // modify original position in pagination
11464
11470
  if (pagination && i >= FieldNote.notesPerOctave)
11465
11471
  position -= whiteKeysPerOctave * currentOctave * FieldNote.keyWidth;
11466
- const key = this.getKeyDiv(i, position);
11472
+ const key = this.getKeyDiv(i + this.minNote_, position);
11467
11473
  this.piano.push(key);
11468
11474
  pianoDiv.appendChild(key);
11469
11475
  // if the current value is within eps of this note, select it.
11470
- if (Math.abs(this.getKeyFreq(i) - Number(this.getValue())) < this.eps) {
11476
+ if (Math.abs(this.getKeyFreq(i + this.minNote_) - Number(this.getValue())) < this.eps) {
11471
11477
  pxt.BrowserUtils.addClass(key, "selected");
11472
11478
  this.currentSelectedKey = key;
11473
11479
  startingPage = currentOctave;
@@ -11573,6 +11579,7 @@ var pxtblockly;
11573
11579
  * @return true if idx is white
11574
11580
  */
11575
11581
  isWhite(idx) {
11582
+ idx += 8;
11576
11583
  switch (idx % 12) {
11577
11584
  case 1:
11578
11585
  case 3:
@@ -11584,6 +11591,30 @@ var pxtblockly;
11584
11591
  return true;
11585
11592
  }
11586
11593
  }
11594
+ whiteKeysBefore(idx) {
11595
+ idx += 8;
11596
+ switch (idx % 12) {
11597
+ case 0: return 0;
11598
+ case 1:
11599
+ case 2:
11600
+ return 1;
11601
+ case 3:
11602
+ case 4:
11603
+ return 2;
11604
+ case 5:
11605
+ return 3;
11606
+ case 6:
11607
+ case 7:
11608
+ return 4;
11609
+ case 8:
11610
+ case 9:
11611
+ return 5;
11612
+ case 10:
11613
+ case 11:
11614
+ return 6;
11615
+ }
11616
+ return -1;
11617
+ }
11587
11618
  /**
11588
11619
  * get width of the piano key
11589
11620
  * @param idx index of the key
@@ -11621,7 +11652,7 @@ var pxtblockly;
11621
11652
  return name;
11622
11653
  }
11623
11654
  getKeyNoteData(keyIndex) {
11624
- return FieldNote.Notes[keyIndex + this.minNote_];
11655
+ return FieldNote.Notes[keyIndex];
11625
11656
  }
11626
11657
  /**
11627
11658
  * get the position of the key in the piano
@@ -11629,11 +11660,24 @@ var pxtblockly;
11629
11660
  * @return position of the key
11630
11661
  */
11631
11662
  getPosition(idx) {
11632
- const whiteKeyCount = idx - Math.floor((idx + 1) / FieldNote.notesPerOctave * FieldNote.blackKeysPerOctave);
11633
- const pos = whiteKeyCount * FieldNote.keyWidth;
11634
- if (this.isWhite(idx))
11635
- return pos;
11636
- return pos - (FieldNote.keyWidth / 4);
11663
+ if (idx === this.minNote_)
11664
+ return 0;
11665
+ const blackKeyOffset = (FieldNote.keyWidth / 4);
11666
+ const startOctave = Math.floor((this.minNote_ + 8) / FieldNote.notesPerOctave);
11667
+ const currentOctave = Math.floor((idx + 8) / FieldNote.notesPerOctave);
11668
+ let startOffset = this.whiteKeysBefore(this.minNote_) * FieldNote.keyWidth;
11669
+ if (!this.isWhite(this.minNote_)) {
11670
+ startOffset -= blackKeyOffset;
11671
+ }
11672
+ if (currentOctave > startOctave) {
11673
+ const octaveWidth = FieldNote.keyWidth * 7;
11674
+ const firstOctaveWidth = octaveWidth - startOffset;
11675
+ const octaveStart = firstOctaveWidth + (currentOctave - startOctave - 1) * octaveWidth;
11676
+ return this.whiteKeysBefore(idx) * FieldNote.keyWidth + octaveStart - (this.isWhite(idx) ? 0 : blackKeyOffset);
11677
+ }
11678
+ else {
11679
+ return this.whiteKeysBefore(idx) * FieldNote.keyWidth - startOffset - (this.isWhite(idx) ? 0 : blackKeyOffset);
11680
+ }
11637
11681
  }
11638
11682
  prepareNotes() {
11639
11683
  if (!FieldNote.Notes) {
@@ -18600,13 +18600,22 @@ var ts;
18600
18600
  return inName;
18601
18601
  }
18602
18602
  function getParameterDefault(param) {
18603
- var _a;
18603
+ var _a, _b;
18604
18604
  const typeNode = param.type;
18605
18605
  if (!typeNode)
18606
18606
  return python ? "None" : "null";
18607
18607
  const name = param.name.kind === pxtc.SK.Identifier ? param.name.text : undefined;
18608
+ const override = (_a = attrs.paramSnippets) === null || _a === void 0 ? void 0 : _a[name];
18609
+ if (override) {
18610
+ if (python) {
18611
+ if (override.python)
18612
+ return override.python;
18613
+ }
18614
+ else if (override.ts)
18615
+ return override.ts;
18616
+ }
18608
18617
  // check for explicit default in the attributes
18609
- const paramDefl = (_a = attrs === null || attrs === void 0 ? void 0 : attrs.paramDefl) === null || _a === void 0 ? void 0 : _a[name];
18618
+ const paramDefl = (_b = attrs === null || attrs === void 0 ? void 0 : attrs.paramDefl) === null || _b === void 0 ? void 0 : _b[name];
18610
18619
  if (paramDefl) {
18611
18620
  let deflKind;
18612
18621
  if (typeNode.kind == pxtc.SK.AnyKeyword) {
@@ -1086,6 +1086,18 @@ declare namespace pxt.editor {
1086
1086
  protected getOptions(): any;
1087
1087
  }
1088
1088
  }
1089
+ declare namespace pxt.editor {
1090
+ class MonacoSongEditor extends MonacoReactFieldEditor<pxt.Song> {
1091
+ protected isPython: boolean;
1092
+ protected isAsset: boolean;
1093
+ protected text: string;
1094
+ protected textToValue(text: string): pxt.Song;
1095
+ protected resultToText(result: pxt.Song): string;
1096
+ protected getFieldEditorId(): string;
1097
+ protected getOptions(): any;
1098
+ }
1099
+ const songEditorDefinition: MonacoFieldEditorDefinition;
1100
+ }
1089
1101
  declare namespace pxt.editor {
1090
1102
  class MonacoSoundEffectEditor extends MonacoReactFieldEditor<pxt.assets.Sound> {
1091
1103
  protected value: pxt.assets.Sound;
@@ -930,6 +930,114 @@ var pxt;
930
930
  /// <reference path="./monacoFieldEditor.ts" />
931
931
  /// <reference path="./field_react.ts" />
932
932
  var pxt;
933
+ (function (pxt) {
934
+ var editor;
935
+ (function (editor) {
936
+ const fieldEditorId = "music-editor";
937
+ class MonacoSongEditor extends editor.MonacoReactFieldEditor {
938
+ textToValue(text) {
939
+ this.isPython = text.indexOf("`") === -1;
940
+ this.text = text;
941
+ const match = pxt.parseAssetTSReference(text);
942
+ if (match) {
943
+ const { type, name: matchedName } = match;
944
+ const name = matchedName.trim();
945
+ const project = pxt.react.getTilemapProject();
946
+ this.isAsset = true;
947
+ const asset = project.lookupAssetByName("song" /* pxt.AssetType.Song */, name);
948
+ if (asset) {
949
+ return asset;
950
+ }
951
+ else {
952
+ const newAsset = project.createNewSong(pxt.assets.music.getEmptySong(2));
953
+ if (name && !project.isNameTaken("song" /* pxt.AssetType.Song */, name) && pxt.validateAssetName(name)) {
954
+ newAsset.meta.displayName = name;
955
+ }
956
+ return newAsset;
957
+ }
958
+ }
959
+ const hexLiteralMatch = /hex\s*(?:`|\(""")\s*([a-fA-F0-9]*)\s*(?:`|"""\))\s*(?:;?)/m.exec(text);
960
+ if (hexLiteralMatch) {
961
+ const contents = hexLiteralMatch[1].trim();
962
+ if (contents) {
963
+ return createFakeAsset(pxt.assets.music.decodeSongFromHex(contents));
964
+ }
965
+ return createFakeAsset(pxt.assets.music.getEmptySong(2));
966
+ }
967
+ return undefined; // never
968
+ }
969
+ resultToText(result) {
970
+ var _a;
971
+ if ((_a = result.meta) === null || _a === void 0 ? void 0 : _a.displayName) {
972
+ const project = pxt.react.getTilemapProject();
973
+ if (this.isAsset || project.lookupAsset(result.type, result.id)) {
974
+ result = project.updateAsset(result);
975
+ }
976
+ else {
977
+ result = project.createNewSong(result.song, result.meta.displayName);
978
+ }
979
+ this.isAsset = true;
980
+ return pxt.getTSReferenceForAsset(result, this.isPython);
981
+ }
982
+ let hexString = pxt.assets.music.encodeSongToHex(result.song);
983
+ if (this.isPython) {
984
+ hexString = `hex("""${hexString}""")`;
985
+ }
986
+ else {
987
+ hexString = "hex`" + hexString + "`";
988
+ }
989
+ return this.text.replace(/hex\s*(?:`|\(""")\s*([a-fA-F0-9]*)\s*(?:`|"""\))\s*(?:;?)/m, hexString);
990
+ }
991
+ getFieldEditorId() {
992
+ return fieldEditorId;
993
+ }
994
+ getOptions() {
995
+ return {
996
+ blocksInfo: this.host.blocksInfo()
997
+ };
998
+ }
999
+ }
1000
+ editor.MonacoSongEditor = MonacoSongEditor;
1001
+ function createFakeAsset(song) {
1002
+ return {
1003
+ type: "song" /* pxt.AssetType.Song */,
1004
+ id: "",
1005
+ internalID: 0,
1006
+ meta: {},
1007
+ song
1008
+ };
1009
+ }
1010
+ editor.songEditorDefinition = {
1011
+ id: fieldEditorId,
1012
+ foldMatches: true,
1013
+ glyphCssClass: "fas fa-music sprite-focus-hover",
1014
+ heightInPixels: 510,
1015
+ matcher: {
1016
+ /**
1017
+ * This is horrendous-looking regex matches both the asset reference syntax:
1018
+ * assets.song`name`
1019
+ * assets.song("""name""")
1020
+ *
1021
+ * and the hex-literal syntax:
1022
+ * music.startSong(hex`01234`
1023
+ * music.start_song(hex("""01234""")
1024
+ *
1025
+ * For the hex literal matches, it includes the call to music.startSong since
1026
+ * hex buffers can also be used for other things
1027
+ */
1028
+ searchString: "(?:(?:assets\\s*\\.\\s*song)|(?:music\\s*\\.\\s*start(?:S|_s)ong\\s*\\(\\s*hex))\\s*(?:`|\\(\\s*\"\"\")(?:(?:[^(){}:\\[\\]\"';?/,+\\-=*&|^%!`~]|\\n)*)\\s*(?:`|\"\"\"\\s*\\))",
1029
+ isRegex: true,
1030
+ matchCase: true,
1031
+ matchWholeWord: false
1032
+ },
1033
+ proto: MonacoSongEditor
1034
+ };
1035
+ editor.registerMonacoFieldEditor(fieldEditorId, editor.songEditorDefinition);
1036
+ })(editor = pxt.editor || (pxt.editor = {}));
1037
+ })(pxt || (pxt = {}));
1038
+ /// <reference path="./monacoFieldEditor.ts" />
1039
+ /// <reference path="./field_react.ts" />
1040
+ var pxt;
933
1041
  (function (pxt) {
934
1042
  var editor;
935
1043
  (function (editor) {
package/built/pxtlib.js CHANGED
@@ -17223,6 +17223,22 @@ var ts;
17223
17223
  res._shadowOverrides = {};
17224
17224
  res._shadowOverrides[n.slice(0, n.length - 7)] = v;
17225
17225
  }
17226
+ else if (pxtc.U.endsWith(n, ".snippet")) {
17227
+ if (!res.paramSnippets)
17228
+ res.paramSnippets = {};
17229
+ const paramName = n.slice(0, n.length - 8);
17230
+ if (!res.paramSnippets[paramName])
17231
+ res.paramSnippets[paramName] = {};
17232
+ res.paramSnippets[paramName].ts = v;
17233
+ }
17234
+ else if (pxtc.U.endsWith(n, ".pySnippet")) {
17235
+ if (!res.paramSnippets)
17236
+ res.paramSnippets = {};
17237
+ const paramName = n.slice(0, n.length - 10);
17238
+ if (!res.paramSnippets[paramName])
17239
+ res.paramSnippets[paramName] = {};
17240
+ res.paramSnippets[paramName].python = v;
17241
+ }
17226
17242
  else if (pxtc.U.endsWith(n, ".fieldEditor")) {
17227
17243
  if (!res.paramFieldEditor)
17228
17244
  res.paramFieldEditor = {};