pxt-core 9.1.2 → 9.1.3

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.
@@ -13656,6 +13656,51 @@ var pxtblockly;
13656
13656
  if (value === "CREATE") {
13657
13657
  promptAndCreateKind(this.sourceBlock_.workspace, this.opts, lf("New {0}:", this.opts.memberName), newName => newName && this.setValue(newName));
13658
13658
  }
13659
+ else if (value === "RENAME") {
13660
+ const ws = this.sourceBlock_.workspace;
13661
+ const toRename = ws.getVariable(this.value_, kindType(this.opts.name));
13662
+ const oldName = toRename.name;
13663
+ if (this.opts.initialMembers.indexOf(oldName) !== -1) {
13664
+ Blockly.alert(lf("The built-in {0} '{1}' cannot be renamed. Try creating a new kind instead!", this.opts.memberName, oldName));
13665
+ return;
13666
+ }
13667
+ promptAndRenameKind(ws, Object.assign(Object.assign({}, this.opts), { toRename }), lf("Rename '{0}':", oldName), newName => {
13668
+ // Update the values of all existing field instances
13669
+ const allFields = pxtblockly.getAllFields(ws, field => field instanceof FieldKind);
13670
+ for (const field of allFields) {
13671
+ if (field.ref.getValue() === oldName) {
13672
+ field.ref.setValue(newName);
13673
+ }
13674
+ }
13675
+ });
13676
+ }
13677
+ else if (value === "DELETE") {
13678
+ const ws = this.sourceBlock_.workspace;
13679
+ const toDelete = ws.getVariable(this.value_, kindType(this.opts.name));
13680
+ const varName = toDelete.name;
13681
+ if (this.opts.initialMembers.indexOf(varName) !== -1) {
13682
+ Blockly.alert(lf("The built-in {0} '{1}' cannot be deleted.", this.opts.memberName, varName));
13683
+ return;
13684
+ }
13685
+ const uses = pxtblockly.getAllFields(ws, field => field instanceof FieldKind && field.getValue() === varName);
13686
+ if (uses.length > 1) {
13687
+ Blockly.confirm(lf("Delete {0} uses of the \"{1}\" {2}?", uses.length, varName, this.opts.memberName), response => {
13688
+ if (!response)
13689
+ return;
13690
+ Blockly.Events.setGroup(true);
13691
+ for (const use of uses) {
13692
+ use.block.dispose(true);
13693
+ }
13694
+ ws.deleteVariableById(toDelete.getId());
13695
+ this.setValue(this.opts.initialMembers[0]);
13696
+ Blockly.Events.setGroup(false);
13697
+ });
13698
+ }
13699
+ else {
13700
+ ws.deleteVariableById(toDelete.getId());
13701
+ this.setValue(this.opts.initialMembers[0]);
13702
+ }
13703
+ }
13659
13704
  else {
13660
13705
  super.onItemSelected_(menu, menuItem);
13661
13706
  }
@@ -13680,7 +13725,7 @@ var pxtblockly;
13680
13725
  createVariableForKind(ws, this.opts, memberName);
13681
13726
  }
13682
13727
  });
13683
- if (this.getValue() === "CREATE") {
13728
+ if (this.getValue() === "CREATE" || this.getValue() === "RENAME" || this.getValue() === "DELETE") {
13684
13729
  if (this.opts.initialMembers.length) {
13685
13730
  this.setValue(this.opts.initialMembers[0]);
13686
13731
  }
@@ -13704,10 +13749,13 @@ var pxtblockly;
13704
13749
  opts.initialMembers.forEach((e) => res.push([e, e]));
13705
13750
  }
13706
13751
  res.push([lf("Add a new {0}...", opts.memberName), "CREATE"]);
13752
+ res.push([undefined, "SEPARATOR"]);
13753
+ res.push([lf("Rename {0}...", opts.memberName), "RENAME"]);
13754
+ res.push([lf("Delete {0}...", opts.memberName), "DELETE"]);
13707
13755
  return res;
13708
13756
  };
13709
13757
  }
13710
- function promptAndCreateKind(ws, opts, message, cb) {
13758
+ function promptForName(ws, opts, message, cb, prompt) {
13711
13759
  Blockly.prompt(message, null, response => {
13712
13760
  if (response) {
13713
13761
  let nameIsValid = false;
@@ -13720,28 +13768,41 @@ var pxtblockly;
13720
13768
  }
13721
13769
  }
13722
13770
  if (!nameIsValid) {
13723
- Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptAndCreateKind(ws, opts, message, cb));
13771
+ Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptForName(ws, opts, message, cb, prompt));
13724
13772
  return;
13725
13773
  }
13726
- if (pxt.blocks.isReservedWord(response)) {
13727
- Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptAndCreateKind(ws, opts, message, cb));
13774
+ if (pxt.blocks.isReservedWord(response) || response === "CREATE" || response === "RENAME" || response === "DELETE") {
13775
+ Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptForName(ws, opts, message, cb, prompt));
13728
13776
  return;
13729
13777
  }
13730
13778
  const existing = getExistingKindMembers(ws, opts.name);
13731
13779
  for (let i = 0; i < existing.length; i++) {
13732
13780
  const name = existing[i];
13733
13781
  if (name === response) {
13734
- Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptAndCreateKind(ws, opts, message, cb));
13782
+ Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptForName(ws, opts, message, cb, prompt));
13735
13783
  return;
13736
13784
  }
13737
13785
  }
13738
13786
  if (response === opts.createFunctionName) {
13739
- Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptAndCreateKind(ws, opts, message, cb));
13787
+ Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptForName(ws, opts, message, cb, prompt));
13740
13788
  }
13741
- cb(createVariableForKind(ws, opts, response));
13789
+ cb(response);
13742
13790
  }
13743
13791
  }, { placeholder: opts.promptHint });
13744
13792
  }
13793
+ function promptAndCreateKind(ws, opts, message, cb) {
13794
+ const responseHandler = (response) => {
13795
+ cb(createVariableForKind(ws, opts, response));
13796
+ };
13797
+ promptForName(ws, opts, message, responseHandler, promptAndCreateKind);
13798
+ }
13799
+ function promptAndRenameKind(ws, opts, message, cb) {
13800
+ const responseHandler = (response) => {
13801
+ ws.getVariableMap().renameVariable(opts.toRename, response);
13802
+ cb(response);
13803
+ };
13804
+ promptForName(ws, opts, message, responseHandler, promptAndRenameKind);
13805
+ }
13745
13806
  function getExistingKindMembers(ws, kindName) {
13746
13807
  const existing = ws.getVariablesOfType(kindType(kindName));
13747
13808
  if (existing && existing.length) {
@@ -10094,6 +10094,51 @@ var pxtblockly;
10094
10094
  if (value === "CREATE") {
10095
10095
  promptAndCreateKind(this.sourceBlock_.workspace, this.opts, lf("New {0}:", this.opts.memberName), newName => newName && this.setValue(newName));
10096
10096
  }
10097
+ else if (value === "RENAME") {
10098
+ const ws = this.sourceBlock_.workspace;
10099
+ const toRename = ws.getVariable(this.value_, kindType(this.opts.name));
10100
+ const oldName = toRename.name;
10101
+ if (this.opts.initialMembers.indexOf(oldName) !== -1) {
10102
+ Blockly.alert(lf("The built-in {0} '{1}' cannot be renamed. Try creating a new kind instead!", this.opts.memberName, oldName));
10103
+ return;
10104
+ }
10105
+ promptAndRenameKind(ws, Object.assign(Object.assign({}, this.opts), { toRename }), lf("Rename '{0}':", oldName), newName => {
10106
+ // Update the values of all existing field instances
10107
+ const allFields = pxtblockly.getAllFields(ws, field => field instanceof FieldKind);
10108
+ for (const field of allFields) {
10109
+ if (field.ref.getValue() === oldName) {
10110
+ field.ref.setValue(newName);
10111
+ }
10112
+ }
10113
+ });
10114
+ }
10115
+ else if (value === "DELETE") {
10116
+ const ws = this.sourceBlock_.workspace;
10117
+ const toDelete = ws.getVariable(this.value_, kindType(this.opts.name));
10118
+ const varName = toDelete.name;
10119
+ if (this.opts.initialMembers.indexOf(varName) !== -1) {
10120
+ Blockly.alert(lf("The built-in {0} '{1}' cannot be deleted.", this.opts.memberName, varName));
10121
+ return;
10122
+ }
10123
+ const uses = pxtblockly.getAllFields(ws, field => field instanceof FieldKind && field.getValue() === varName);
10124
+ if (uses.length > 1) {
10125
+ Blockly.confirm(lf("Delete {0} uses of the \"{1}\" {2}?", uses.length, varName, this.opts.memberName), response => {
10126
+ if (!response)
10127
+ return;
10128
+ Blockly.Events.setGroup(true);
10129
+ for (const use of uses) {
10130
+ use.block.dispose(true);
10131
+ }
10132
+ ws.deleteVariableById(toDelete.getId());
10133
+ this.setValue(this.opts.initialMembers[0]);
10134
+ Blockly.Events.setGroup(false);
10135
+ });
10136
+ }
10137
+ else {
10138
+ ws.deleteVariableById(toDelete.getId());
10139
+ this.setValue(this.opts.initialMembers[0]);
10140
+ }
10141
+ }
10097
10142
  else {
10098
10143
  super.onItemSelected_(menu, menuItem);
10099
10144
  }
@@ -10118,7 +10163,7 @@ var pxtblockly;
10118
10163
  createVariableForKind(ws, this.opts, memberName);
10119
10164
  }
10120
10165
  });
10121
- if (this.getValue() === "CREATE") {
10166
+ if (this.getValue() === "CREATE" || this.getValue() === "RENAME" || this.getValue() === "DELETE") {
10122
10167
  if (this.opts.initialMembers.length) {
10123
10168
  this.setValue(this.opts.initialMembers[0]);
10124
10169
  }
@@ -10142,10 +10187,13 @@ var pxtblockly;
10142
10187
  opts.initialMembers.forEach((e) => res.push([e, e]));
10143
10188
  }
10144
10189
  res.push([lf("Add a new {0}...", opts.memberName), "CREATE"]);
10190
+ res.push([undefined, "SEPARATOR"]);
10191
+ res.push([lf("Rename {0}...", opts.memberName), "RENAME"]);
10192
+ res.push([lf("Delete {0}...", opts.memberName), "DELETE"]);
10145
10193
  return res;
10146
10194
  };
10147
10195
  }
10148
- function promptAndCreateKind(ws, opts, message, cb) {
10196
+ function promptForName(ws, opts, message, cb, prompt) {
10149
10197
  Blockly.prompt(message, null, response => {
10150
10198
  if (response) {
10151
10199
  let nameIsValid = false;
@@ -10158,28 +10206,41 @@ var pxtblockly;
10158
10206
  }
10159
10207
  }
10160
10208
  if (!nameIsValid) {
10161
- Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptAndCreateKind(ws, opts, message, cb));
10209
+ Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptForName(ws, opts, message, cb, prompt));
10162
10210
  return;
10163
10211
  }
10164
- if (pxt.blocks.isReservedWord(response)) {
10165
- Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptAndCreateKind(ws, opts, message, cb));
10212
+ if (pxt.blocks.isReservedWord(response) || response === "CREATE" || response === "RENAME" || response === "DELETE") {
10213
+ Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptForName(ws, opts, message, cb, prompt));
10166
10214
  return;
10167
10215
  }
10168
10216
  const existing = getExistingKindMembers(ws, opts.name);
10169
10217
  for (let i = 0; i < existing.length; i++) {
10170
10218
  const name = existing[i];
10171
10219
  if (name === response) {
10172
- Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptAndCreateKind(ws, opts, message, cb));
10220
+ Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptForName(ws, opts, message, cb, prompt));
10173
10221
  return;
10174
10222
  }
10175
10223
  }
10176
10224
  if (response === opts.createFunctionName) {
10177
- Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptAndCreateKind(ws, opts, message, cb));
10225
+ Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptForName(ws, opts, message, cb, prompt));
10178
10226
  }
10179
- cb(createVariableForKind(ws, opts, response));
10227
+ cb(response);
10180
10228
  }
10181
10229
  }, { placeholder: opts.promptHint });
10182
10230
  }
10231
+ function promptAndCreateKind(ws, opts, message, cb) {
10232
+ const responseHandler = (response) => {
10233
+ cb(createVariableForKind(ws, opts, response));
10234
+ };
10235
+ promptForName(ws, opts, message, responseHandler, promptAndCreateKind);
10236
+ }
10237
+ function promptAndRenameKind(ws, opts, message, cb) {
10238
+ const responseHandler = (response) => {
10239
+ ws.getVariableMap().renameVariable(opts.toRename, response);
10240
+ cb(response);
10241
+ };
10242
+ promptForName(ws, opts, message, responseHandler, promptAndRenameKind);
10243
+ }
10183
10244
  function getExistingKindMembers(ws, kindName) {
10184
10245
  const existing = ws.getVariablesOfType(kindType(kindName));
10185
10246
  if (existing && existing.length) {