pxt-core 8.2.5 → 8.2.8
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 +1 -0
- package/built/pxt.js +69 -26
- package/built/pxtblockly.js +18 -2
- package/built/pxtblocks.d.ts +1 -0
- package/built/pxtblocks.js +18 -2
- package/built/pxtcompiler.js +3 -3
- package/built/pxteditor.js +5 -0
- package/built/pxtlib.js +26 -7
- package/built/pxtpy.d.ts +1 -0
- package/built/pxtpy.js +39 -16
- package/built/pxtrunner.js +13 -0
- package/built/target.js +1 -1
- package/built/web/blockly.css +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtcompiler.js +1 -1
- package/built/web/pxteditor.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtpy.js +1 -1
- package/built/web/pxtrunner.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/react-common-authcode.css +98 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlblockly.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/css/main.3684f34d.chunk.css +1 -0
- package/built/web/skillmap/js/2.26325281.chunk.js +2 -0
- package/built/web/skillmap/js/main.b87a119c.chunk.js +1 -0
- package/localtypings/pxtarget.d.ts +16 -0
- package/localtypings/react.d.ts +5 -0
- package/package.json +1 -1
- package/react-common/components/controls/Checkbox.tsx +1 -1
- package/react-common/components/palette/ColorPickerField.tsx +65 -0
- package/react-common/components/palette/PaletteEditor.tsx +66 -0
- package/react-common/components/palette/PalettePicker.tsx +52 -0
- package/react-common/components/palette/PaletteSwatch.tsx +27 -0
- package/react-common/components/palette/Palettes.ts +289 -0
- package/react-common/components/profile/SignInModal.tsx +100 -0
- package/react-common/components/profile/UserPane.tsx +17 -9
- package/react-common/styles/palette/ColorPickerField.less +21 -0
- package/react-common/styles/palette/PalettePicker.less +10 -0
- package/react-common/styles/palette/PaletteSwatch.less +27 -0
- package/react-common/styles/palette/palette.less +3 -0
- package/react-common/styles/profile/profile.less +64 -1
- package/react-common/styles/react-common.less +1 -0
- package/theme/blockly-core.less +1 -1
- package/theme/common.less +13 -2
- package/theme/image-editor/bottomBar.less +1 -1
- package/theme/tutorial-sidebar.less +2 -2
- package/webapp/public/skillmap.html +2 -2
- package/built/web/skillmap/css/main.c5811548.chunk.css +0 -1
- package/built/web/skillmap/js/2.26b9a6f6.chunk.js +0 -2
- package/built/web/skillmap/js/main.98eed582.chunk.js +0 -1
package/built/cli.js
CHANGED
|
@@ -2029,6 +2029,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
2029
2029
|
updateTOC(cfg);
|
|
2030
2030
|
cfg.bundledpkgs = {};
|
|
2031
2031
|
pxt.setAppTarget(cfg);
|
|
2032
|
+
pxt.reloadAppTargetVariant();
|
|
2032
2033
|
dirsToWatch = cfg.bundleddirs.slice();
|
|
2033
2034
|
if (pxt.appTarget.id != "core") {
|
|
2034
2035
|
if (fs.existsSync("theme")) {
|
package/built/pxt.js
CHANGED
|
@@ -101796,7 +101796,7 @@ var pxt;
|
|
|
101796
101796
|
MATH_ADDITION_SYMBOL: pxt.Util.lf("{id:op}+"),
|
|
101797
101797
|
MATH_SUBTRACTION_SYMBOL: pxt.Util.lf("{id:op}-"),
|
|
101798
101798
|
MATH_MULTIPLICATION_SYMBOL: pxt.Util.lf("{id:op}×"),
|
|
101799
|
-
MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}
|
|
101799
|
+
MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}/"),
|
|
101800
101800
|
MATH_POWER_SYMBOL: pxt.Util.lf("{id:op}**")
|
|
101801
101801
|
}
|
|
101802
101802
|
},
|
|
@@ -101806,7 +101806,7 @@ var pxt;
|
|
|
101806
101806
|
url: '/blocks/math',
|
|
101807
101807
|
category: 'math',
|
|
101808
101808
|
block: {
|
|
101809
|
-
MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1
|
|
101809
|
+
MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1 / %2")
|
|
101810
101810
|
}
|
|
101811
101811
|
},
|
|
101812
101812
|
'math_js_op': {
|
|
@@ -101835,7 +101835,7 @@ var pxt;
|
|
|
101835
101835
|
"acos": pxt.Util.lf("{id:op}acos"),
|
|
101836
101836
|
"tan": pxt.Util.lf("{id:op}tan"),
|
|
101837
101837
|
"atan2": pxt.Util.lf("{id:op}atan2"),
|
|
101838
|
-
"idiv": pxt.Util.lf("{id:op}integer
|
|
101838
|
+
"idiv": pxt.Util.lf("{id:op}integer /"),
|
|
101839
101839
|
"imul": pxt.Util.lf("{id:op}integer ×"),
|
|
101840
101840
|
}
|
|
101841
101841
|
},
|
|
@@ -117004,6 +117004,7 @@ var pxt;
|
|
|
117004
117004
|
diffify(steps, activities);
|
|
117005
117005
|
}
|
|
117006
117006
|
const assetFiles = parseAssetJson(assetJson);
|
|
117007
|
+
const globalBlockConfig = parseTutorialBlockConfig("global", tutorialmd);
|
|
117007
117008
|
// strip hidden snippets
|
|
117008
117009
|
steps.forEach(step => {
|
|
117009
117010
|
step.contentMd = stripHiddenSnippets(step.contentMd);
|
|
@@ -117023,7 +117024,8 @@ var pxt;
|
|
|
117023
117024
|
jres,
|
|
117024
117025
|
assetFiles,
|
|
117025
117026
|
customTs,
|
|
117026
|
-
tutorialValidationRules
|
|
117027
|
+
tutorialValidationRules,
|
|
117028
|
+
globalBlockConfig
|
|
117027
117029
|
};
|
|
117028
117030
|
}
|
|
117029
117031
|
tutorial.parseTutorial = parseTutorial;
|
|
@@ -117050,6 +117052,8 @@ var pxt;
|
|
|
117050
117052
|
switch (m1) {
|
|
117051
117053
|
case "block":
|
|
117052
117054
|
case "blocks":
|
|
117055
|
+
case "blockconfig.local":
|
|
117056
|
+
case "blockconfig.global":
|
|
117053
117057
|
case "requiredTutorialBlock":
|
|
117054
117058
|
case "filterblocks":
|
|
117055
117059
|
if (!checkTutorialEditor(pxt.BLOCKS_PROJECT_NAME))
|
|
@@ -117202,6 +117206,7 @@ ${code}
|
|
|
117202
117206
|
markdown.replace(stepRegex, function (match, flags, step) {
|
|
117203
117207
|
step = step.trim();
|
|
117204
117208
|
let { header, hint, requiredBlocks } = parseTutorialHint(step, metadata && metadata.explicitHints, metadata.tutorialCodeValidation);
|
|
117209
|
+
const blockConfig = parseTutorialBlockConfig("local", step);
|
|
117205
117210
|
// if title is not hidden ("{TITLE HERE}"), strip flags
|
|
117206
117211
|
const title = !flags.match(/^\{.*\}$/)
|
|
117207
117212
|
? flags.replace(/@(fullscreen|unplugged|showdialog|showhint|tutorialCompleted|resetDiff)/gi, "").trim()
|
|
@@ -117209,7 +117214,8 @@ ${code}
|
|
|
117209
117214
|
let info = {
|
|
117210
117215
|
title,
|
|
117211
117216
|
contentMd: step,
|
|
117212
|
-
headerContentMd: header
|
|
117217
|
+
headerContentMd: header,
|
|
117218
|
+
localBlockConfig: blockConfig
|
|
117213
117219
|
};
|
|
117214
117220
|
if (/@(fullscreen|unplugged|showdialog|showhint)/i.test(flags))
|
|
117215
117221
|
info.showHint = true;
|
|
@@ -117264,6 +117270,18 @@ ${code}
|
|
|
117264
117270
|
}
|
|
117265
117271
|
return { header, hint, requiredBlocks };
|
|
117266
117272
|
}
|
|
117273
|
+
function parseTutorialBlockConfig(scope, content) {
|
|
117274
|
+
let blockConfig = {
|
|
117275
|
+
md: "",
|
|
117276
|
+
blocks: [],
|
|
117277
|
+
};
|
|
117278
|
+
const regex = new RegExp(`\`\`\`\\s*blockconfig\\.${scope}\\s*\\n([\\s\\S]*?)\\n\`\`\``, "gmi");
|
|
117279
|
+
content.replace(regex, (m0, m1) => {
|
|
117280
|
+
blockConfig.md += `${m1}\n`;
|
|
117281
|
+
return "";
|
|
117282
|
+
});
|
|
117283
|
+
return blockConfig;
|
|
117284
|
+
}
|
|
117267
117285
|
function categorizingValidationRules(listOfRules, title) {
|
|
117268
117286
|
const ruleNames = Object.keys(listOfRules);
|
|
117269
117287
|
for (let i = 0; i < ruleNames.length; i++) {
|
|
@@ -117279,7 +117297,7 @@ ${code}
|
|
|
117279
117297
|
function stripHiddenSnippets(str) {
|
|
117280
117298
|
if (!str)
|
|
117281
117299
|
return str;
|
|
117282
|
-
const hiddenSnippetRegex = /```(filterblocks|package|ghost|config|template|jres|assetjson|customts)\s*\n([\s\S]*?)\n```/gmi;
|
|
117300
|
+
const hiddenSnippetRegex = /```(filterblocks|package|ghost|config|template|jres|assetjson|customts|blockconfig\.local|blockconfig\.global)\s*\n([\s\S]*?)\n```/gmi;
|
|
117283
117301
|
return str.replace(hiddenSnippetRegex, '').trim();
|
|
117284
117302
|
}
|
|
117285
117303
|
/*
|
|
@@ -117361,7 +117379,8 @@ ${code}
|
|
|
117361
117379
|
jres: tutorialInfo.jres,
|
|
117362
117380
|
assetFiles: tutorialInfo.assetFiles,
|
|
117363
117381
|
customTs: tutorialInfo.customTs,
|
|
117364
|
-
tutorialValidationRules: tutorialInfo.tutorialValidationRules
|
|
117382
|
+
tutorialValidationRules: tutorialInfo.tutorialValidationRules,
|
|
117383
|
+
globalBlockConfig: tutorialInfo.globalBlockConfig
|
|
117365
117384
|
};
|
|
117366
117385
|
return { options: tutorialOptions, editor: tutorialInfo.editor };
|
|
117367
117386
|
}
|
|
@@ -127519,7 +127538,7 @@ ${output}</xml>`;
|
|
|
127519
127538
|
if (alias) {
|
|
127520
127539
|
info.decompilerBlockAlias = env.aliasBlocks[info.qName];
|
|
127521
127540
|
}
|
|
127522
|
-
else {
|
|
127541
|
+
else if (!env.opts.snippetMode) {
|
|
127523
127542
|
return pxtc.Util.lf("No output expressions as statements");
|
|
127524
127543
|
}
|
|
127525
127544
|
}
|
|
@@ -135078,7 +135097,7 @@ var ts;
|
|
|
135078
135097
|
snippetMode: opts.snippetMode || false,
|
|
135079
135098
|
alwaysEmitOnStart: opts.alwaysDecompileOnStart,
|
|
135080
135099
|
includeGreyBlockMessages,
|
|
135081
|
-
generateSourceMap: !!opts.ast,
|
|
135100
|
+
generateSourceMap: opts.generateSourceMap !== undefined ? opts.generateSourceMap : !!opts.ast,
|
|
135082
135101
|
allowedArgumentTypes: opts.allowedArgumentTypes || ["number", "boolean", "string"],
|
|
135083
135102
|
errorOnGreyBlocks: !!opts.errorOnGreyBlocks
|
|
135084
135103
|
};
|
|
@@ -135096,7 +135115,7 @@ var ts;
|
|
|
135096
135115
|
snippetMode: opts.snippetMode || false,
|
|
135097
135116
|
alwaysEmitOnStart: opts.alwaysDecompileOnStart,
|
|
135098
135117
|
includeGreyBlockMessages,
|
|
135099
|
-
generateSourceMap: !!opts.ast,
|
|
135118
|
+
generateSourceMap: opts.generateSourceMap !== undefined ? opts.generateSourceMap : !!opts.ast,
|
|
135100
135119
|
allowedArgumentTypes: opts.allowedArgumentTypes || ["number", "boolean", "string"],
|
|
135101
135120
|
errorOnGreyBlocks: !!opts.errorOnGreyBlocks
|
|
135102
135121
|
};
|
|
@@ -140897,6 +140916,13 @@ var pxt;
|
|
|
140897
140916
|
error(a, 9503, pxt.U.lf("No module named '{0}'", name));
|
|
140898
140917
|
return sym;
|
|
140899
140918
|
}
|
|
140919
|
+
function getHelperVariableName() {
|
|
140920
|
+
const scope = currentScope();
|
|
140921
|
+
if (scope.nextHelperVariableId === undefined) {
|
|
140922
|
+
scope.nextHelperVariableId = 0;
|
|
140923
|
+
}
|
|
140924
|
+
return "___tempvar" + scope.nextHelperVariableId++;
|
|
140925
|
+
}
|
|
140900
140926
|
function defvar(name, opts, modifier, scope) {
|
|
140901
140927
|
if (!scope)
|
|
140902
140928
|
scope = currentScope();
|
|
@@ -142203,20 +142229,7 @@ var pxt;
|
|
|
142203
142229
|
return B.mkStmt(B.mkText(pref), B.mkInfix(expr(target), "=", expr(value)));
|
|
142204
142230
|
}
|
|
142205
142231
|
if (!pref && target.kind == "Tuple") {
|
|
142206
|
-
|
|
142207
|
-
let targs = [B.mkText("let "), B.mkText("[")];
|
|
142208
|
-
let nonNames = tup.elts.filter(e => e.kind !== "Name");
|
|
142209
|
-
if (nonNames.length) {
|
|
142210
|
-
error(n, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
|
|
142211
|
-
return stmtTODO(n);
|
|
142212
|
-
}
|
|
142213
|
-
let tupNames = tup.elts
|
|
142214
|
-
.map(e => e)
|
|
142215
|
-
.map(convertName);
|
|
142216
|
-
targs.push(B.mkCommaSep(tupNames));
|
|
142217
|
-
targs.push(B.mkText("]"));
|
|
142218
|
-
let res = B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
|
|
142219
|
-
return res;
|
|
142232
|
+
return convertDestructuring(n, target, value);
|
|
142220
142233
|
}
|
|
142221
142234
|
if (target.kind === "Name") {
|
|
142222
142235
|
const scopeSym = currentScope().vars[nm];
|
|
@@ -142244,12 +142257,41 @@ var pxt;
|
|
|
142244
142257
|
if (!lExp)
|
|
142245
142258
|
lExp = expr(target);
|
|
142246
142259
|
return B.mkStmt(B.mkText(pref), B.mkInfix(lExp, "=", expr(value)));
|
|
142247
|
-
|
|
142260
|
+
}
|
|
142261
|
+
function convertDestructuring(parent, targets, value) {
|
|
142262
|
+
let nonNames = targets.elts.filter(e => e.kind !== "Name");
|
|
142263
|
+
if (nonNames.length) {
|
|
142264
|
+
error(parent, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
|
|
142265
|
+
return stmtTODO(parent);
|
|
142266
|
+
}
|
|
142267
|
+
const names = targets.elts.map(tryGetName);
|
|
142268
|
+
const symbols = names
|
|
142269
|
+
.map(nm => nm ? currentScope().vars[nm] : undefined);
|
|
142270
|
+
if (symbols.some(s => (s === null || s === void 0 ? void 0 : s.modifier) !== undefined)) {
|
|
142271
|
+
const helperVar = getHelperVariableName();
|
|
142272
|
+
const valueAssign = B.mkStmt(B.mkInfix(B.mkGroup([B.mkText("let "), B.mkText(helperVar)]), "=", expr(value)));
|
|
142273
|
+
const assignStatements = [valueAssign];
|
|
142274
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
142275
|
+
const name = convertName(targets.elts[i]);
|
|
142276
|
+
assignStatements.push(B.mkStmt(B.mkInfix(name, "=", B.mkGroup([B.mkText(helperVar), B.mkText(`[${i}]`)]))));
|
|
142277
|
+
}
|
|
142278
|
+
return B.mkGroup(assignStatements);
|
|
142279
|
+
}
|
|
142280
|
+
else {
|
|
142281
|
+
let targs = [B.mkText("let "), B.mkText("[")];
|
|
142282
|
+
let tupNames = targets.elts
|
|
142283
|
+
.map(e => e)
|
|
142284
|
+
.map(e => convertName(e, true));
|
|
142285
|
+
targs.push(B.mkCommaSep(tupNames));
|
|
142286
|
+
targs.push(B.mkText("]"));
|
|
142287
|
+
return B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
|
|
142288
|
+
}
|
|
142289
|
+
function convertName(n, excludeLet = false) {
|
|
142248
142290
|
// TODO resuse with Name expr
|
|
142249
142291
|
markInfoNode(n, "identifierCompletion");
|
|
142250
142292
|
typeOf(n);
|
|
142251
142293
|
let v = lookupName(n);
|
|
142252
|
-
return possibleDef(n,
|
|
142294
|
+
return possibleDef(n, excludeLet);
|
|
142253
142295
|
}
|
|
142254
142296
|
}
|
|
142255
142297
|
function possibleDef(n, excludeLet = false) {
|
|
@@ -159815,6 +159857,7 @@ async function buildTargetCoreAsync(options = {}) {
|
|
|
159815
159857
|
updateTOC(cfg);
|
|
159816
159858
|
cfg.bundledpkgs = {};
|
|
159817
159859
|
pxt.setAppTarget(cfg);
|
|
159860
|
+
pxt.reloadAppTargetVariant();
|
|
159818
159861
|
dirsToWatch = cfg.bundleddirs.slice();
|
|
159819
159862
|
if (pxt.appTarget.id != "core") {
|
|
159820
159863
|
if (fs.existsSync("theme")) {
|
package/built/pxtblockly.js
CHANGED
|
@@ -6747,6 +6747,22 @@ var pxt;
|
|
|
6747
6747
|
}
|
|
6748
6748
|
});
|
|
6749
6749
|
}
|
|
6750
|
+
function validateAllReferencedBlocksExist(xml) {
|
|
6751
|
+
pxt.U.assert(!!(Blockly === null || Blockly === void 0 ? void 0 : Blockly.Blocks), "Called validateAllReferencedBlocksExist before initializing Blockly");
|
|
6752
|
+
const dom = Blockly.Xml.textToDom(xml);
|
|
6753
|
+
const blocks = dom.querySelectorAll("block");
|
|
6754
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
6755
|
+
if (!Blockly.Blocks[blocks.item(i).getAttribute("type")])
|
|
6756
|
+
return false;
|
|
6757
|
+
}
|
|
6758
|
+
const shadows = dom.querySelectorAll("shadow");
|
|
6759
|
+
for (let i = 0; i < shadows.length; i++) {
|
|
6760
|
+
if (!Blockly.Blocks[shadows.item(i).getAttribute("type")])
|
|
6761
|
+
return false;
|
|
6762
|
+
}
|
|
6763
|
+
return true;
|
|
6764
|
+
}
|
|
6765
|
+
blocks_2.validateAllReferencedBlocksExist = validateAllReferencedBlocksExist;
|
|
6750
6766
|
})(blocks = pxt.blocks || (pxt.blocks = {}));
|
|
6751
6767
|
})(pxt || (pxt = {}));
|
|
6752
6768
|
var pxt;
|
|
@@ -6768,6 +6784,7 @@ var pxt;
|
|
|
6768
6784
|
const newDom = Blockly.Xml.workspaceToDom(newWs, true);
|
|
6769
6785
|
pxt.Util.toArray(oldDom.childNodes)
|
|
6770
6786
|
.filter((n) => n.nodeType == Node.ELEMENT_NODE && n.localName == "block" && n.getAttribute("disabled") == "true")
|
|
6787
|
+
.filter((n) => !!Blockly.Blocks[n.getAttribute("type")])
|
|
6771
6788
|
.forEach(n => newDom.appendChild(newDom.ownerDocument.importNode(n, true)));
|
|
6772
6789
|
const updatedXml = Blockly.Xml.domToText(newDom);
|
|
6773
6790
|
return updatedXml;
|
|
@@ -11951,7 +11968,6 @@ var pxtblockly;
|
|
|
11951
11968
|
this.fieldGroup_.appendChild(bg.el);
|
|
11952
11969
|
const icon = new svg.Text("\uf008")
|
|
11953
11970
|
.at(X_PADDING, 5 + (TOTAL_HEIGHT >> 1))
|
|
11954
|
-
.fill(this.sourceBlock_.getColourSecondary())
|
|
11955
11971
|
.setClass("semanticIcon");
|
|
11956
11972
|
this.fieldGroup_.appendChild(icon.el);
|
|
11957
11973
|
if (this.asset) {
|
|
@@ -13469,7 +13485,7 @@ var pxtblockly;
|
|
|
13469
13485
|
return function () {
|
|
13470
13486
|
const res = [];
|
|
13471
13487
|
const that = this;
|
|
13472
|
-
if (that.sourceBlock_ && that.sourceBlock_.workspace) {
|
|
13488
|
+
if (that.sourceBlock_ && that.sourceBlock_.workspace && !that.sourceBlock_.isInFlyout) {
|
|
13473
13489
|
const options = that.sourceBlock_.workspace.getVariablesOfType(kindType(opts.name));
|
|
13474
13490
|
options.forEach(model => {
|
|
13475
13491
|
res.push([model.name, model.name]);
|
package/built/pxtblocks.d.ts
CHANGED
|
@@ -157,6 +157,7 @@ declare namespace pxt.blocks {
|
|
|
157
157
|
*/
|
|
158
158
|
let extensionBlocklyPatch: (pkgTargetVersion: string, dom: Element) => void;
|
|
159
159
|
function importXml(pkgTargetVersion: string, xml: string, info: pxtc.BlocksInfo, skipReport?: boolean): string;
|
|
160
|
+
function validateAllReferencedBlocksExist(xml: string): boolean;
|
|
160
161
|
}
|
|
161
162
|
declare namespace pxt.blocks.layout {
|
|
162
163
|
interface FlowOptions {
|
package/built/pxtblocks.js
CHANGED
|
@@ -3185,6 +3185,22 @@ var pxt;
|
|
|
3185
3185
|
}
|
|
3186
3186
|
});
|
|
3187
3187
|
}
|
|
3188
|
+
function validateAllReferencedBlocksExist(xml) {
|
|
3189
|
+
pxt.U.assert(!!(Blockly === null || Blockly === void 0 ? void 0 : Blockly.Blocks), "Called validateAllReferencedBlocksExist before initializing Blockly");
|
|
3190
|
+
const dom = Blockly.Xml.textToDom(xml);
|
|
3191
|
+
const blocks = dom.querySelectorAll("block");
|
|
3192
|
+
for (let i = 0; i < blocks.length; i++) {
|
|
3193
|
+
if (!Blockly.Blocks[blocks.item(i).getAttribute("type")])
|
|
3194
|
+
return false;
|
|
3195
|
+
}
|
|
3196
|
+
const shadows = dom.querySelectorAll("shadow");
|
|
3197
|
+
for (let i = 0; i < shadows.length; i++) {
|
|
3198
|
+
if (!Blockly.Blocks[shadows.item(i).getAttribute("type")])
|
|
3199
|
+
return false;
|
|
3200
|
+
}
|
|
3201
|
+
return true;
|
|
3202
|
+
}
|
|
3203
|
+
blocks_2.validateAllReferencedBlocksExist = validateAllReferencedBlocksExist;
|
|
3188
3204
|
})(blocks = pxt.blocks || (pxt.blocks = {}));
|
|
3189
3205
|
})(pxt || (pxt = {}));
|
|
3190
3206
|
var pxt;
|
|
@@ -3206,6 +3222,7 @@ var pxt;
|
|
|
3206
3222
|
const newDom = Blockly.Xml.workspaceToDom(newWs, true);
|
|
3207
3223
|
pxt.Util.toArray(oldDom.childNodes)
|
|
3208
3224
|
.filter((n) => n.nodeType == Node.ELEMENT_NODE && n.localName == "block" && n.getAttribute("disabled") == "true")
|
|
3225
|
+
.filter((n) => !!Blockly.Blocks[n.getAttribute("type")])
|
|
3209
3226
|
.forEach(n => newDom.appendChild(newDom.ownerDocument.importNode(n, true)));
|
|
3210
3227
|
const updatedXml = Blockly.Xml.domToText(newDom);
|
|
3211
3228
|
return updatedXml;
|
|
@@ -8389,7 +8406,6 @@ var pxtblockly;
|
|
|
8389
8406
|
this.fieldGroup_.appendChild(bg.el);
|
|
8390
8407
|
const icon = new svg.Text("\uf008")
|
|
8391
8408
|
.at(X_PADDING, 5 + (TOTAL_HEIGHT >> 1))
|
|
8392
|
-
.fill(this.sourceBlock_.getColourSecondary())
|
|
8393
8409
|
.setClass("semanticIcon");
|
|
8394
8410
|
this.fieldGroup_.appendChild(icon.el);
|
|
8395
8411
|
if (this.asset) {
|
|
@@ -9907,7 +9923,7 @@ var pxtblockly;
|
|
|
9907
9923
|
return function () {
|
|
9908
9924
|
const res = [];
|
|
9909
9925
|
const that = this;
|
|
9910
|
-
if (that.sourceBlock_ && that.sourceBlock_.workspace) {
|
|
9926
|
+
if (that.sourceBlock_ && that.sourceBlock_.workspace && !that.sourceBlock_.isInFlyout) {
|
|
9911
9927
|
const options = that.sourceBlock_.workspace.getVariablesOfType(kindType(opts.name));
|
|
9912
9928
|
options.forEach(model => {
|
|
9913
9929
|
res.push([model.name, model.name]);
|
package/built/pxtcompiler.js
CHANGED
|
@@ -6258,7 +6258,7 @@ ${output}</xml>`;
|
|
|
6258
6258
|
if (alias) {
|
|
6259
6259
|
info.decompilerBlockAlias = env.aliasBlocks[info.qName];
|
|
6260
6260
|
}
|
|
6261
|
-
else {
|
|
6261
|
+
else if (!env.opts.snippetMode) {
|
|
6262
6262
|
return pxtc.Util.lf("No output expressions as statements");
|
|
6263
6263
|
}
|
|
6264
6264
|
}
|
|
@@ -13817,7 +13817,7 @@ var ts;
|
|
|
13817
13817
|
snippetMode: opts.snippetMode || false,
|
|
13818
13818
|
alwaysEmitOnStart: opts.alwaysDecompileOnStart,
|
|
13819
13819
|
includeGreyBlockMessages,
|
|
13820
|
-
generateSourceMap: !!opts.ast,
|
|
13820
|
+
generateSourceMap: opts.generateSourceMap !== undefined ? opts.generateSourceMap : !!opts.ast,
|
|
13821
13821
|
allowedArgumentTypes: opts.allowedArgumentTypes || ["number", "boolean", "string"],
|
|
13822
13822
|
errorOnGreyBlocks: !!opts.errorOnGreyBlocks
|
|
13823
13823
|
};
|
|
@@ -13835,7 +13835,7 @@ var ts;
|
|
|
13835
13835
|
snippetMode: opts.snippetMode || false,
|
|
13836
13836
|
alwaysEmitOnStart: opts.alwaysDecompileOnStart,
|
|
13837
13837
|
includeGreyBlockMessages,
|
|
13838
|
-
generateSourceMap: !!opts.ast,
|
|
13838
|
+
generateSourceMap: opts.generateSourceMap !== undefined ? opts.generateSourceMap : !!opts.ast,
|
|
13839
13839
|
allowedArgumentTypes: opts.allowedArgumentTypes || ["number", "boolean", "string"],
|
|
13840
13840
|
errorOnGreyBlocks: !!opts.errorOnGreyBlocks
|
|
13841
13841
|
};
|
package/built/pxteditor.js
CHANGED
|
@@ -558,6 +558,11 @@ var pxt;
|
|
|
558
558
|
name: lf("Blocks Error List"),
|
|
559
559
|
description: lf("Show an error list panel for Blocks")
|
|
560
560
|
},
|
|
561
|
+
{
|
|
562
|
+
id: "palettePicker",
|
|
563
|
+
name: lf("Change Color Palette"),
|
|
564
|
+
description: lf("Change the game palette in project settings")
|
|
565
|
+
},
|
|
561
566
|
].filter(experiment => ids.indexOf(experiment.id) > -1 && !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline));
|
|
562
567
|
}
|
|
563
568
|
experiments_1.all = all;
|
package/built/pxtlib.js
CHANGED
|
@@ -4110,7 +4110,7 @@ var pxt;
|
|
|
4110
4110
|
MATH_ADDITION_SYMBOL: pxt.Util.lf("{id:op}+"),
|
|
4111
4111
|
MATH_SUBTRACTION_SYMBOL: pxt.Util.lf("{id:op}-"),
|
|
4112
4112
|
MATH_MULTIPLICATION_SYMBOL: pxt.Util.lf("{id:op}×"),
|
|
4113
|
-
MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}
|
|
4113
|
+
MATH_DIVISION_SYMBOL: pxt.Util.lf("{id:op}/"),
|
|
4114
4114
|
MATH_POWER_SYMBOL: pxt.Util.lf("{id:op}**")
|
|
4115
4115
|
}
|
|
4116
4116
|
},
|
|
@@ -4120,7 +4120,7 @@ var pxt;
|
|
|
4120
4120
|
url: '/blocks/math',
|
|
4121
4121
|
category: 'math',
|
|
4122
4122
|
block: {
|
|
4123
|
-
MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1
|
|
4123
|
+
MATH_MODULO_TITLE: pxt.Util.lf("remainder of %1 / %2")
|
|
4124
4124
|
}
|
|
4125
4125
|
},
|
|
4126
4126
|
'math_js_op': {
|
|
@@ -4149,7 +4149,7 @@ var pxt;
|
|
|
4149
4149
|
"acos": pxt.Util.lf("{id:op}acos"),
|
|
4150
4150
|
"tan": pxt.Util.lf("{id:op}tan"),
|
|
4151
4151
|
"atan2": pxt.Util.lf("{id:op}atan2"),
|
|
4152
|
-
"idiv": pxt.Util.lf("{id:op}integer
|
|
4152
|
+
"idiv": pxt.Util.lf("{id:op}integer /"),
|
|
4153
4153
|
"imul": pxt.Util.lf("{id:op}integer ×"),
|
|
4154
4154
|
}
|
|
4155
4155
|
},
|
|
@@ -19318,6 +19318,7 @@ var pxt;
|
|
|
19318
19318
|
diffify(steps, activities);
|
|
19319
19319
|
}
|
|
19320
19320
|
const assetFiles = parseAssetJson(assetJson);
|
|
19321
|
+
const globalBlockConfig = parseTutorialBlockConfig("global", tutorialmd);
|
|
19321
19322
|
// strip hidden snippets
|
|
19322
19323
|
steps.forEach(step => {
|
|
19323
19324
|
step.contentMd = stripHiddenSnippets(step.contentMd);
|
|
@@ -19337,7 +19338,8 @@ var pxt;
|
|
|
19337
19338
|
jres,
|
|
19338
19339
|
assetFiles,
|
|
19339
19340
|
customTs,
|
|
19340
|
-
tutorialValidationRules
|
|
19341
|
+
tutorialValidationRules,
|
|
19342
|
+
globalBlockConfig
|
|
19341
19343
|
};
|
|
19342
19344
|
}
|
|
19343
19345
|
tutorial.parseTutorial = parseTutorial;
|
|
@@ -19364,6 +19366,8 @@ var pxt;
|
|
|
19364
19366
|
switch (m1) {
|
|
19365
19367
|
case "block":
|
|
19366
19368
|
case "blocks":
|
|
19369
|
+
case "blockconfig.local":
|
|
19370
|
+
case "blockconfig.global":
|
|
19367
19371
|
case "requiredTutorialBlock":
|
|
19368
19372
|
case "filterblocks":
|
|
19369
19373
|
if (!checkTutorialEditor(pxt.BLOCKS_PROJECT_NAME))
|
|
@@ -19516,6 +19520,7 @@ ${code}
|
|
|
19516
19520
|
markdown.replace(stepRegex, function (match, flags, step) {
|
|
19517
19521
|
step = step.trim();
|
|
19518
19522
|
let { header, hint, requiredBlocks } = parseTutorialHint(step, metadata && metadata.explicitHints, metadata.tutorialCodeValidation);
|
|
19523
|
+
const blockConfig = parseTutorialBlockConfig("local", step);
|
|
19519
19524
|
// if title is not hidden ("{TITLE HERE}"), strip flags
|
|
19520
19525
|
const title = !flags.match(/^\{.*\}$/)
|
|
19521
19526
|
? flags.replace(/@(fullscreen|unplugged|showdialog|showhint|tutorialCompleted|resetDiff)/gi, "").trim()
|
|
@@ -19523,7 +19528,8 @@ ${code}
|
|
|
19523
19528
|
let info = {
|
|
19524
19529
|
title,
|
|
19525
19530
|
contentMd: step,
|
|
19526
|
-
headerContentMd: header
|
|
19531
|
+
headerContentMd: header,
|
|
19532
|
+
localBlockConfig: blockConfig
|
|
19527
19533
|
};
|
|
19528
19534
|
if (/@(fullscreen|unplugged|showdialog|showhint)/i.test(flags))
|
|
19529
19535
|
info.showHint = true;
|
|
@@ -19578,6 +19584,18 @@ ${code}
|
|
|
19578
19584
|
}
|
|
19579
19585
|
return { header, hint, requiredBlocks };
|
|
19580
19586
|
}
|
|
19587
|
+
function parseTutorialBlockConfig(scope, content) {
|
|
19588
|
+
let blockConfig = {
|
|
19589
|
+
md: "",
|
|
19590
|
+
blocks: [],
|
|
19591
|
+
};
|
|
19592
|
+
const regex = new RegExp(`\`\`\`\\s*blockconfig\\.${scope}\\s*\\n([\\s\\S]*?)\\n\`\`\``, "gmi");
|
|
19593
|
+
content.replace(regex, (m0, m1) => {
|
|
19594
|
+
blockConfig.md += `${m1}\n`;
|
|
19595
|
+
return "";
|
|
19596
|
+
});
|
|
19597
|
+
return blockConfig;
|
|
19598
|
+
}
|
|
19581
19599
|
function categorizingValidationRules(listOfRules, title) {
|
|
19582
19600
|
const ruleNames = Object.keys(listOfRules);
|
|
19583
19601
|
for (let i = 0; i < ruleNames.length; i++) {
|
|
@@ -19593,7 +19611,7 @@ ${code}
|
|
|
19593
19611
|
function stripHiddenSnippets(str) {
|
|
19594
19612
|
if (!str)
|
|
19595
19613
|
return str;
|
|
19596
|
-
const hiddenSnippetRegex = /```(filterblocks|package|ghost|config|template|jres|assetjson|customts)\s*\n([\s\S]*?)\n```/gmi;
|
|
19614
|
+
const hiddenSnippetRegex = /```(filterblocks|package|ghost|config|template|jres|assetjson|customts|blockconfig\.local|blockconfig\.global)\s*\n([\s\S]*?)\n```/gmi;
|
|
19597
19615
|
return str.replace(hiddenSnippetRegex, '').trim();
|
|
19598
19616
|
}
|
|
19599
19617
|
/*
|
|
@@ -19675,7 +19693,8 @@ ${code}
|
|
|
19675
19693
|
jres: tutorialInfo.jres,
|
|
19676
19694
|
assetFiles: tutorialInfo.assetFiles,
|
|
19677
19695
|
customTs: tutorialInfo.customTs,
|
|
19678
|
-
tutorialValidationRules: tutorialInfo.tutorialValidationRules
|
|
19696
|
+
tutorialValidationRules: tutorialInfo.tutorialValidationRules,
|
|
19697
|
+
globalBlockConfig: tutorialInfo.globalBlockConfig
|
|
19679
19698
|
};
|
|
19680
19699
|
return { options: tutorialOptions, editor: tutorialInfo.editor };
|
|
19681
19700
|
}
|
package/built/pxtpy.d.ts
CHANGED
package/built/pxtpy.js
CHANGED
|
@@ -342,6 +342,13 @@ var pxt;
|
|
|
342
342
|
error(a, 9503, pxt.U.lf("No module named '{0}'", name));
|
|
343
343
|
return sym;
|
|
344
344
|
}
|
|
345
|
+
function getHelperVariableName() {
|
|
346
|
+
const scope = currentScope();
|
|
347
|
+
if (scope.nextHelperVariableId === undefined) {
|
|
348
|
+
scope.nextHelperVariableId = 0;
|
|
349
|
+
}
|
|
350
|
+
return "___tempvar" + scope.nextHelperVariableId++;
|
|
351
|
+
}
|
|
345
352
|
function defvar(name, opts, modifier, scope) {
|
|
346
353
|
if (!scope)
|
|
347
354
|
scope = currentScope();
|
|
@@ -1648,20 +1655,7 @@ var pxt;
|
|
|
1648
1655
|
return B.mkStmt(B.mkText(pref), B.mkInfix(expr(target), "=", expr(value)));
|
|
1649
1656
|
}
|
|
1650
1657
|
if (!pref && target.kind == "Tuple") {
|
|
1651
|
-
|
|
1652
|
-
let targs = [B.mkText("let "), B.mkText("[")];
|
|
1653
|
-
let nonNames = tup.elts.filter(e => e.kind !== "Name");
|
|
1654
|
-
if (nonNames.length) {
|
|
1655
|
-
error(n, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
|
|
1656
|
-
return stmtTODO(n);
|
|
1657
|
-
}
|
|
1658
|
-
let tupNames = tup.elts
|
|
1659
|
-
.map(e => e)
|
|
1660
|
-
.map(convertName);
|
|
1661
|
-
targs.push(B.mkCommaSep(tupNames));
|
|
1662
|
-
targs.push(B.mkText("]"));
|
|
1663
|
-
let res = B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
|
|
1664
|
-
return res;
|
|
1658
|
+
return convertDestructuring(n, target, value);
|
|
1665
1659
|
}
|
|
1666
1660
|
if (target.kind === "Name") {
|
|
1667
1661
|
const scopeSym = currentScope().vars[nm];
|
|
@@ -1689,12 +1683,41 @@ var pxt;
|
|
|
1689
1683
|
if (!lExp)
|
|
1690
1684
|
lExp = expr(target);
|
|
1691
1685
|
return B.mkStmt(B.mkText(pref), B.mkInfix(lExp, "=", expr(value)));
|
|
1692
|
-
|
|
1686
|
+
}
|
|
1687
|
+
function convertDestructuring(parent, targets, value) {
|
|
1688
|
+
let nonNames = targets.elts.filter(e => e.kind !== "Name");
|
|
1689
|
+
if (nonNames.length) {
|
|
1690
|
+
error(parent, 9556, pxt.U.lf("non-trivial tuple assignment unsupported"));
|
|
1691
|
+
return stmtTODO(parent);
|
|
1692
|
+
}
|
|
1693
|
+
const names = targets.elts.map(tryGetName);
|
|
1694
|
+
const symbols = names
|
|
1695
|
+
.map(nm => nm ? currentScope().vars[nm] : undefined);
|
|
1696
|
+
if (symbols.some(s => (s === null || s === void 0 ? void 0 : s.modifier) !== undefined)) {
|
|
1697
|
+
const helperVar = getHelperVariableName();
|
|
1698
|
+
const valueAssign = B.mkStmt(B.mkInfix(B.mkGroup([B.mkText("let "), B.mkText(helperVar)]), "=", expr(value)));
|
|
1699
|
+
const assignStatements = [valueAssign];
|
|
1700
|
+
for (let i = 0; i < symbols.length; i++) {
|
|
1701
|
+
const name = convertName(targets.elts[i]);
|
|
1702
|
+
assignStatements.push(B.mkStmt(B.mkInfix(name, "=", B.mkGroup([B.mkText(helperVar), B.mkText(`[${i}]`)]))));
|
|
1703
|
+
}
|
|
1704
|
+
return B.mkGroup(assignStatements);
|
|
1705
|
+
}
|
|
1706
|
+
else {
|
|
1707
|
+
let targs = [B.mkText("let "), B.mkText("[")];
|
|
1708
|
+
let tupNames = targets.elts
|
|
1709
|
+
.map(e => e)
|
|
1710
|
+
.map(e => convertName(e, true));
|
|
1711
|
+
targs.push(B.mkCommaSep(tupNames));
|
|
1712
|
+
targs.push(B.mkText("]"));
|
|
1713
|
+
return B.mkStmt(B.mkInfix(B.mkGroup(targs), "=", expr(value)));
|
|
1714
|
+
}
|
|
1715
|
+
function convertName(n, excludeLet = false) {
|
|
1693
1716
|
// TODO resuse with Name expr
|
|
1694
1717
|
markInfoNode(n, "identifierCompletion");
|
|
1695
1718
|
typeOf(n);
|
|
1696
1719
|
let v = lookupName(n);
|
|
1697
|
-
return possibleDef(n,
|
|
1720
|
+
return possibleDef(n, excludeLet);
|
|
1698
1721
|
}
|
|
1699
1722
|
}
|
|
1700
1723
|
function possibleDef(n, excludeLet = false) {
|
package/built/pxtrunner.js
CHANGED
|
@@ -1319,6 +1319,18 @@ var pxt;
|
|
|
1319
1319
|
c = c.parent();
|
|
1320
1320
|
c.remove();
|
|
1321
1321
|
}
|
|
1322
|
+
function renderBlockConfig(options) {
|
|
1323
|
+
function render(scope) {
|
|
1324
|
+
$(`code.lang-blockconfig.${scope}`).each((i, c) => {
|
|
1325
|
+
let $c = $(c);
|
|
1326
|
+
if (options.snippetReplaceParent)
|
|
1327
|
+
$c = $c.parent();
|
|
1328
|
+
$c.remove();
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1331
|
+
render("local");
|
|
1332
|
+
render("global");
|
|
1333
|
+
}
|
|
1322
1334
|
function renderSims(options) {
|
|
1323
1335
|
if (!options.simulatorClass)
|
|
1324
1336
|
return;
|
|
@@ -1359,6 +1371,7 @@ var pxt;
|
|
|
1359
1371
|
readAssetJson(options);
|
|
1360
1372
|
renderQueue = [];
|
|
1361
1373
|
renderGhost(options);
|
|
1374
|
+
renderBlockConfig(options);
|
|
1362
1375
|
renderSims(options);
|
|
1363
1376
|
renderTypeScript(options);
|
|
1364
1377
|
renderDirectPython(options);
|