pxt-core 9.1.2 → 9.1.5
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/cli.js +11 -10
- package/built/pxt.js +11 -10
- package/built/pxtblockly.js +71 -8
- package/built/pxtblocks.js +71 -8
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/package.json +1 -1
- package/react-common/components/controls/VerticalResizeContainer.tsx +1 -1
- package/theme/common.less +4 -3
package/built/cli.js
CHANGED
|
@@ -2077,7 +2077,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
2077
2077
|
if (pxt.appTarget.cacheusedblocksdirs)
|
|
2078
2078
|
cfg.tutorialInfo = await internalCacheUsedBlocksAsync();
|
|
2079
2079
|
await forEachBundledPkgAsync(async (pkg, dirname) => {
|
|
2080
|
-
var _a, _b;
|
|
2080
|
+
var _a, _b, _c;
|
|
2081
2081
|
pxt.log(`building bundled ${dirname}`);
|
|
2082
2082
|
let isPrj = /prj$/.test(dirname);
|
|
2083
2083
|
const isHw = /hw---/.test(dirname);
|
|
@@ -2111,12 +2111,12 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
2111
2111
|
}
|
|
2112
2112
|
}
|
|
2113
2113
|
// For the projects, we need to save the base HEX file to the offline HEX cache
|
|
2114
|
-
if (isPrj && pxt.appTarget.compile
|
|
2114
|
+
if (isPrj && ((_a = pxt.appTarget.compile) === null || _a === void 0 ? void 0 : _a.hasHex)) {
|
|
2115
2115
|
if (!pkgOptions) {
|
|
2116
2116
|
pxt.debug(`Failed to extract native image for project ${dirname}`);
|
|
2117
2117
|
return;
|
|
2118
2118
|
}
|
|
2119
|
-
const hexFileExtInfo = [pkgOptions.extinfo, ...(((
|
|
2119
|
+
const hexFileExtInfo = [pkgOptions.extinfo, ...(((_b = pkgOptions.otherMultiVariants) === null || _b === void 0 ? void 0 : _b.map(el => el.extinfo)) || [])];
|
|
2120
2120
|
for (const extinfo of hexFileExtInfo) {
|
|
2121
2121
|
// Place the base HEX image in the hex cache if necessary
|
|
2122
2122
|
let sha = extinfo.sha;
|
|
@@ -2137,24 +2137,25 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
2137
2137
|
// We want to cache a hex file for each of the native packages in case they are added to a project.
|
|
2138
2138
|
// This won't cover the whole matrix, but handles the common case of projects that add one extra
|
|
2139
2139
|
// extension in the offline app.
|
|
2140
|
-
const allDeps = pkg.sortedDeps(true)
|
|
2140
|
+
const allDeps = pkg.sortedDeps(true)
|
|
2141
|
+
.map(dep => path.resolve(path.join(dirname, dep.verArgument())))
|
|
2141
2142
|
.map(dep => path.resolve(dep).replace(/---.*/, "")); // keep path format (/ vs \\) consistent, trim --- suffix to avoid duplicate imports.
|
|
2142
2143
|
const config = nodeutil.readPkgConfig(dirname);
|
|
2143
2144
|
const host = pkg.host();
|
|
2144
2145
|
const pkgsToBuildWith = packageDirs.filter(dirname => !allDeps.some(el => el.indexOf(dirname.replace(/---.*/, "")) !== -1));
|
|
2145
|
-
pxt.log(`Dependencies of
|
|
2146
|
-
pxt.log(`Attemping to bundle necessary hexfiles to compile with: ${pkgsToBuildWith}`);
|
|
2146
|
+
pxt.log(`Dependencies of base pkgs: ${allDeps.map(el => path.basename(el)).join(", ")}`);
|
|
2147
2147
|
for (const extraPackage of pkgsToBuildWith) {
|
|
2148
|
+
const extraPathBaseName = path.basename(extraPackage);
|
|
2148
2149
|
process.chdir(path.join(rootDir, dirname));
|
|
2149
|
-
const deps = Object.assign(Object.assign({}, config.dependencies), {
|
|
2150
|
+
const deps = Object.assign(Object.assign({}, config.dependencies), { [extraPathBaseName]: "file:" + path.relative(path.resolve("."), extraPackage) });
|
|
2150
2151
|
host.fileOverrides["pxt.json"] = JSON.stringify(Object.assign(Object.assign({}, config), { dependencies: deps }));
|
|
2151
|
-
pxt.log(`Building hex cache for ${
|
|
2152
|
+
pxt.log(`Building hex cache for ${extraPathBaseName} with dependencies:`);
|
|
2152
2153
|
console.dir(deps);
|
|
2153
2154
|
mainPkg = new pxt.MainPackage(host);
|
|
2154
2155
|
try {
|
|
2155
2156
|
const extraRes = await testForBuildTargetAsync(true, null);
|
|
2156
2157
|
if (extraRes) {
|
|
2157
|
-
const hexFileExtInfo = [extraRes.options.extinfo, ...(((
|
|
2158
|
+
const hexFileExtInfo = [extraRes.options.extinfo, ...(((_c = extraRes.options.otherMultiVariants) === null || _c === void 0 ? void 0 : _c.map(el => el.extinfo)) || [])];
|
|
2158
2159
|
for (const extinfo of hexFileExtInfo) {
|
|
2159
2160
|
// Place the base HEX image in the hex cache if necessary
|
|
2160
2161
|
let sha = extinfo.sha;
|
|
@@ -2165,7 +2166,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
2165
2166
|
}
|
|
2166
2167
|
else {
|
|
2167
2168
|
nodeutil.writeFileSync(hexFile, hex.join(os.EOL));
|
|
2168
|
-
pxt.
|
|
2169
|
+
pxt.log(`created native image in offline cache for project ${dirname}: ${hexFile}`);
|
|
2169
2170
|
}
|
|
2170
2171
|
}
|
|
2171
2172
|
}
|
package/built/pxt.js
CHANGED
|
@@ -162729,7 +162729,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
162729
162729
|
if (pxt.appTarget.cacheusedblocksdirs)
|
|
162730
162730
|
cfg.tutorialInfo = await internalCacheUsedBlocksAsync();
|
|
162731
162731
|
await forEachBundledPkgAsync(async (pkg, dirname) => {
|
|
162732
|
-
var _a, _b;
|
|
162732
|
+
var _a, _b, _c;
|
|
162733
162733
|
pxt.log(`building bundled ${dirname}`);
|
|
162734
162734
|
let isPrj = /prj$/.test(dirname);
|
|
162735
162735
|
const isHw = /hw---/.test(dirname);
|
|
@@ -162763,12 +162763,12 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
162763
162763
|
}
|
|
162764
162764
|
}
|
|
162765
162765
|
// For the projects, we need to save the base HEX file to the offline HEX cache
|
|
162766
|
-
if (isPrj && pxt.appTarget.compile
|
|
162766
|
+
if (isPrj && ((_a = pxt.appTarget.compile) === null || _a === void 0 ? void 0 : _a.hasHex)) {
|
|
162767
162767
|
if (!pkgOptions) {
|
|
162768
162768
|
pxt.debug(`Failed to extract native image for project ${dirname}`);
|
|
162769
162769
|
return;
|
|
162770
162770
|
}
|
|
162771
|
-
const hexFileExtInfo = [pkgOptions.extinfo, ...(((
|
|
162771
|
+
const hexFileExtInfo = [pkgOptions.extinfo, ...(((_b = pkgOptions.otherMultiVariants) === null || _b === void 0 ? void 0 : _b.map(el => el.extinfo)) || [])];
|
|
162772
162772
|
for (const extinfo of hexFileExtInfo) {
|
|
162773
162773
|
// Place the base HEX image in the hex cache if necessary
|
|
162774
162774
|
let sha = extinfo.sha;
|
|
@@ -162789,24 +162789,25 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
162789
162789
|
// We want to cache a hex file for each of the native packages in case they are added to a project.
|
|
162790
162790
|
// This won't cover the whole matrix, but handles the common case of projects that add one extra
|
|
162791
162791
|
// extension in the offline app.
|
|
162792
|
-
const allDeps = pkg.sortedDeps(true)
|
|
162792
|
+
const allDeps = pkg.sortedDeps(true)
|
|
162793
|
+
.map(dep => path.resolve(path.join(dirname, dep.verArgument())))
|
|
162793
162794
|
.map(dep => path.resolve(dep).replace(/---.*/, "")); // keep path format (/ vs \\) consistent, trim --- suffix to avoid duplicate imports.
|
|
162794
162795
|
const config = nodeutil.readPkgConfig(dirname);
|
|
162795
162796
|
const host = pkg.host();
|
|
162796
162797
|
const pkgsToBuildWith = packageDirs.filter(dirname => !allDeps.some(el => el.indexOf(dirname.replace(/---.*/, "")) !== -1));
|
|
162797
|
-
pxt.log(`Dependencies of
|
|
162798
|
-
pxt.log(`Attemping to bundle necessary hexfiles to compile with: ${pkgsToBuildWith}`);
|
|
162798
|
+
pxt.log(`Dependencies of base pkgs: ${allDeps.map(el => path.basename(el)).join(", ")}`);
|
|
162799
162799
|
for (const extraPackage of pkgsToBuildWith) {
|
|
162800
|
+
const extraPathBaseName = path.basename(extraPackage);
|
|
162800
162801
|
process.chdir(path.join(rootDir, dirname));
|
|
162801
|
-
const deps = Object.assign(Object.assign({}, config.dependencies), {
|
|
162802
|
+
const deps = Object.assign(Object.assign({}, config.dependencies), { [extraPathBaseName]: "file:" + path.relative(path.resolve("."), extraPackage) });
|
|
162802
162803
|
host.fileOverrides["pxt.json"] = JSON.stringify(Object.assign(Object.assign({}, config), { dependencies: deps }));
|
|
162803
|
-
pxt.log(`Building hex cache for ${
|
|
162804
|
+
pxt.log(`Building hex cache for ${extraPathBaseName} with dependencies:`);
|
|
162804
162805
|
console.dir(deps);
|
|
162805
162806
|
mainPkg = new pxt.MainPackage(host);
|
|
162806
162807
|
try {
|
|
162807
162808
|
const extraRes = await testForBuildTargetAsync(true, null);
|
|
162808
162809
|
if (extraRes) {
|
|
162809
|
-
const hexFileExtInfo = [extraRes.options.extinfo, ...(((
|
|
162810
|
+
const hexFileExtInfo = [extraRes.options.extinfo, ...(((_c = extraRes.options.otherMultiVariants) === null || _c === void 0 ? void 0 : _c.map(el => el.extinfo)) || [])];
|
|
162810
162811
|
for (const extinfo of hexFileExtInfo) {
|
|
162811
162812
|
// Place the base HEX image in the hex cache if necessary
|
|
162812
162813
|
let sha = extinfo.sha;
|
|
@@ -162817,7 +162818,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
162817
162818
|
}
|
|
162818
162819
|
else {
|
|
162819
162820
|
nodeutil.writeFileSync(hexFile, hex.join(os.EOL));
|
|
162820
|
-
pxt.
|
|
162821
|
+
pxt.log(`created native image in offline cache for project ${dirname}: ${hexFile}`);
|
|
162821
162822
|
}
|
|
162822
162823
|
}
|
|
162823
162824
|
}
|
package/built/pxtblockly.js
CHANGED
|
@@ -13656,6 +13656,53 @@ 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
|
+
&& field.getValue() === oldName
|
|
13671
|
+
&& field.opts.name === this.opts.name);
|
|
13672
|
+
for (const field of allFields) {
|
|
13673
|
+
field.ref.setValue(newName);
|
|
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
|
|
13686
|
+
&& field.getValue() === varName
|
|
13687
|
+
&& field.opts.name === this.opts.name);
|
|
13688
|
+
if (uses.length > 1) {
|
|
13689
|
+
Blockly.confirm(lf("Delete {0} uses of the \"{1}\" {2}?", uses.length, varName, this.opts.memberName), response => {
|
|
13690
|
+
if (!response)
|
|
13691
|
+
return;
|
|
13692
|
+
Blockly.Events.setGroup(true);
|
|
13693
|
+
for (const use of uses) {
|
|
13694
|
+
use.block.dispose(true);
|
|
13695
|
+
}
|
|
13696
|
+
ws.deleteVariableById(toDelete.getId());
|
|
13697
|
+
this.setValue(this.opts.initialMembers[0]);
|
|
13698
|
+
Blockly.Events.setGroup(false);
|
|
13699
|
+
});
|
|
13700
|
+
}
|
|
13701
|
+
else {
|
|
13702
|
+
ws.deleteVariableById(toDelete.getId());
|
|
13703
|
+
this.setValue(this.opts.initialMembers[0]);
|
|
13704
|
+
}
|
|
13705
|
+
}
|
|
13659
13706
|
else {
|
|
13660
13707
|
super.onItemSelected_(menu, menuItem);
|
|
13661
13708
|
}
|
|
@@ -13680,7 +13727,7 @@ var pxtblockly;
|
|
|
13680
13727
|
createVariableForKind(ws, this.opts, memberName);
|
|
13681
13728
|
}
|
|
13682
13729
|
});
|
|
13683
|
-
if (this.getValue() === "CREATE") {
|
|
13730
|
+
if (this.getValue() === "CREATE" || this.getValue() === "RENAME" || this.getValue() === "DELETE") {
|
|
13684
13731
|
if (this.opts.initialMembers.length) {
|
|
13685
13732
|
this.setValue(this.opts.initialMembers[0]);
|
|
13686
13733
|
}
|
|
@@ -13704,10 +13751,13 @@ var pxtblockly;
|
|
|
13704
13751
|
opts.initialMembers.forEach((e) => res.push([e, e]));
|
|
13705
13752
|
}
|
|
13706
13753
|
res.push([lf("Add a new {0}...", opts.memberName), "CREATE"]);
|
|
13754
|
+
res.push([undefined, "SEPARATOR"]);
|
|
13755
|
+
res.push([lf("Rename {0}...", opts.memberName), "RENAME"]);
|
|
13756
|
+
res.push([lf("Delete {0}...", opts.memberName), "DELETE"]);
|
|
13707
13757
|
return res;
|
|
13708
13758
|
};
|
|
13709
13759
|
}
|
|
13710
|
-
function
|
|
13760
|
+
function promptForName(ws, opts, message, cb, prompt) {
|
|
13711
13761
|
Blockly.prompt(message, null, response => {
|
|
13712
13762
|
if (response) {
|
|
13713
13763
|
let nameIsValid = false;
|
|
@@ -13720,28 +13770,41 @@ var pxtblockly;
|
|
|
13720
13770
|
}
|
|
13721
13771
|
}
|
|
13722
13772
|
if (!nameIsValid) {
|
|
13723
|
-
Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () =>
|
|
13773
|
+
Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptForName(ws, opts, message, cb, prompt));
|
|
13724
13774
|
return;
|
|
13725
13775
|
}
|
|
13726
|
-
if (pxt.blocks.isReservedWord(response)) {
|
|
13727
|
-
Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () =>
|
|
13776
|
+
if (pxt.blocks.isReservedWord(response) || response === "CREATE" || response === "RENAME" || response === "DELETE") {
|
|
13777
|
+
Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptForName(ws, opts, message, cb, prompt));
|
|
13728
13778
|
return;
|
|
13729
13779
|
}
|
|
13730
13780
|
const existing = getExistingKindMembers(ws, opts.name);
|
|
13731
13781
|
for (let i = 0; i < existing.length; i++) {
|
|
13732
13782
|
const name = existing[i];
|
|
13733
13783
|
if (name === response) {
|
|
13734
|
-
Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () =>
|
|
13784
|
+
Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptForName(ws, opts, message, cb, prompt));
|
|
13735
13785
|
return;
|
|
13736
13786
|
}
|
|
13737
13787
|
}
|
|
13738
13788
|
if (response === opts.createFunctionName) {
|
|
13739
|
-
Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () =>
|
|
13789
|
+
Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptForName(ws, opts, message, cb, prompt));
|
|
13740
13790
|
}
|
|
13741
|
-
cb(
|
|
13791
|
+
cb(response);
|
|
13742
13792
|
}
|
|
13743
13793
|
}, { placeholder: opts.promptHint });
|
|
13744
13794
|
}
|
|
13795
|
+
function promptAndCreateKind(ws, opts, message, cb) {
|
|
13796
|
+
const responseHandler = (response) => {
|
|
13797
|
+
cb(createVariableForKind(ws, opts, response));
|
|
13798
|
+
};
|
|
13799
|
+
promptForName(ws, opts, message, responseHandler, promptAndCreateKind);
|
|
13800
|
+
}
|
|
13801
|
+
function promptAndRenameKind(ws, opts, message, cb) {
|
|
13802
|
+
const responseHandler = (response) => {
|
|
13803
|
+
ws.getVariableMap().renameVariable(opts.toRename, response);
|
|
13804
|
+
cb(response);
|
|
13805
|
+
};
|
|
13806
|
+
promptForName(ws, opts, message, responseHandler, promptAndRenameKind);
|
|
13807
|
+
}
|
|
13745
13808
|
function getExistingKindMembers(ws, kindName) {
|
|
13746
13809
|
const existing = ws.getVariablesOfType(kindType(kindName));
|
|
13747
13810
|
if (existing && existing.length) {
|
package/built/pxtblocks.js
CHANGED
|
@@ -10094,6 +10094,53 @@ 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
|
+
&& field.getValue() === oldName
|
|
10109
|
+
&& field.opts.name === this.opts.name);
|
|
10110
|
+
for (const field of allFields) {
|
|
10111
|
+
field.ref.setValue(newName);
|
|
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
|
|
10124
|
+
&& field.getValue() === varName
|
|
10125
|
+
&& field.opts.name === this.opts.name);
|
|
10126
|
+
if (uses.length > 1) {
|
|
10127
|
+
Blockly.confirm(lf("Delete {0} uses of the \"{1}\" {2}?", uses.length, varName, this.opts.memberName), response => {
|
|
10128
|
+
if (!response)
|
|
10129
|
+
return;
|
|
10130
|
+
Blockly.Events.setGroup(true);
|
|
10131
|
+
for (const use of uses) {
|
|
10132
|
+
use.block.dispose(true);
|
|
10133
|
+
}
|
|
10134
|
+
ws.deleteVariableById(toDelete.getId());
|
|
10135
|
+
this.setValue(this.opts.initialMembers[0]);
|
|
10136
|
+
Blockly.Events.setGroup(false);
|
|
10137
|
+
});
|
|
10138
|
+
}
|
|
10139
|
+
else {
|
|
10140
|
+
ws.deleteVariableById(toDelete.getId());
|
|
10141
|
+
this.setValue(this.opts.initialMembers[0]);
|
|
10142
|
+
}
|
|
10143
|
+
}
|
|
10097
10144
|
else {
|
|
10098
10145
|
super.onItemSelected_(menu, menuItem);
|
|
10099
10146
|
}
|
|
@@ -10118,7 +10165,7 @@ var pxtblockly;
|
|
|
10118
10165
|
createVariableForKind(ws, this.opts, memberName);
|
|
10119
10166
|
}
|
|
10120
10167
|
});
|
|
10121
|
-
if (this.getValue() === "CREATE") {
|
|
10168
|
+
if (this.getValue() === "CREATE" || this.getValue() === "RENAME" || this.getValue() === "DELETE") {
|
|
10122
10169
|
if (this.opts.initialMembers.length) {
|
|
10123
10170
|
this.setValue(this.opts.initialMembers[0]);
|
|
10124
10171
|
}
|
|
@@ -10142,10 +10189,13 @@ var pxtblockly;
|
|
|
10142
10189
|
opts.initialMembers.forEach((e) => res.push([e, e]));
|
|
10143
10190
|
}
|
|
10144
10191
|
res.push([lf("Add a new {0}...", opts.memberName), "CREATE"]);
|
|
10192
|
+
res.push([undefined, "SEPARATOR"]);
|
|
10193
|
+
res.push([lf("Rename {0}...", opts.memberName), "RENAME"]);
|
|
10194
|
+
res.push([lf("Delete {0}...", opts.memberName), "DELETE"]);
|
|
10145
10195
|
return res;
|
|
10146
10196
|
};
|
|
10147
10197
|
}
|
|
10148
|
-
function
|
|
10198
|
+
function promptForName(ws, opts, message, cb, prompt) {
|
|
10149
10199
|
Blockly.prompt(message, null, response => {
|
|
10150
10200
|
if (response) {
|
|
10151
10201
|
let nameIsValid = false;
|
|
@@ -10158,28 +10208,41 @@ var pxtblockly;
|
|
|
10158
10208
|
}
|
|
10159
10209
|
}
|
|
10160
10210
|
if (!nameIsValid) {
|
|
10161
|
-
Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () =>
|
|
10211
|
+
Blockly.alert(lf("Names must start with a letter and can only contain letters, numbers, '$', and '_'."), () => promptForName(ws, opts, message, cb, prompt));
|
|
10162
10212
|
return;
|
|
10163
10213
|
}
|
|
10164
|
-
if (pxt.blocks.isReservedWord(response)) {
|
|
10165
|
-
Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () =>
|
|
10214
|
+
if (pxt.blocks.isReservedWord(response) || response === "CREATE" || response === "RENAME" || response === "DELETE") {
|
|
10215
|
+
Blockly.alert(lf("'{0}' is a reserved word and cannot be used.", response), () => promptForName(ws, opts, message, cb, prompt));
|
|
10166
10216
|
return;
|
|
10167
10217
|
}
|
|
10168
10218
|
const existing = getExistingKindMembers(ws, opts.name);
|
|
10169
10219
|
for (let i = 0; i < existing.length; i++) {
|
|
10170
10220
|
const name = existing[i];
|
|
10171
10221
|
if (name === response) {
|
|
10172
|
-
Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () =>
|
|
10222
|
+
Blockly.alert(lf("A {0} named '{1}' already exists.", opts.memberName, response), () => promptForName(ws, opts, message, cb, prompt));
|
|
10173
10223
|
return;
|
|
10174
10224
|
}
|
|
10175
10225
|
}
|
|
10176
10226
|
if (response === opts.createFunctionName) {
|
|
10177
|
-
Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () =>
|
|
10227
|
+
Blockly.alert(lf("'{0}' is a reserved name.", opts.createFunctionName), () => promptForName(ws, opts, message, cb, prompt));
|
|
10178
10228
|
}
|
|
10179
|
-
cb(
|
|
10229
|
+
cb(response);
|
|
10180
10230
|
}
|
|
10181
10231
|
}, { placeholder: opts.promptHint });
|
|
10182
10232
|
}
|
|
10233
|
+
function promptAndCreateKind(ws, opts, message, cb) {
|
|
10234
|
+
const responseHandler = (response) => {
|
|
10235
|
+
cb(createVariableForKind(ws, opts, response));
|
|
10236
|
+
};
|
|
10237
|
+
promptForName(ws, opts, message, responseHandler, promptAndCreateKind);
|
|
10238
|
+
}
|
|
10239
|
+
function promptAndRenameKind(ws, opts, message, cb) {
|
|
10240
|
+
const responseHandler = (response) => {
|
|
10241
|
+
ws.getVariableMap().renameVariable(opts.toRename, response);
|
|
10242
|
+
cb(response);
|
|
10243
|
+
};
|
|
10244
|
+
promptForName(ws, opts, message, responseHandler, promptAndRenameKind);
|
|
10245
|
+
}
|
|
10183
10246
|
function getExistingKindMembers(ws, kindName) {
|
|
10184
10247
|
const existing = ws.getVariablesOfType(kindType(kindName));
|
|
10185
10248
|
if (existing && existing.length) {
|