pxt-core 8.5.3 → 8.5.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.
Files changed (48) hide show
  1. package/built/cli.js +54 -26
  2. package/built/pxt.js +92 -57
  3. package/built/pxtblockly.js +11 -7
  4. package/built/pxtblocks.d.ts +4 -1
  5. package/built/pxtblocks.js +11 -7
  6. package/built/pxteditor.js +0 -5
  7. package/built/pxtlib.d.ts +2 -3
  8. package/built/pxtlib.js +38 -31
  9. package/built/target.js +1 -1
  10. package/built/web/main.js +1 -1
  11. package/built/web/pxtapp.js +1 -1
  12. package/built/web/pxtasseteditor.js +1 -1
  13. package/built/web/pxtblockly.js +1 -1
  14. package/built/web/pxtblocks.js +1 -1
  15. package/built/web/pxteditor.js +1 -1
  16. package/built/web/pxtembed.js +2 -2
  17. package/built/web/pxtlib.js +1 -1
  18. package/built/web/pxtweb.js +1 -1
  19. package/built/web/pxtworker.js +1 -1
  20. package/built/web/react-common-authcode.css +1 -1
  21. package/built/web/react-common-multiplayer.css +1 -1
  22. package/built/web/react-common-skillmap.css +1 -1
  23. package/built/web/rtlreact-common-authcode.css +1 -1
  24. package/built/web/rtlreact-common-multiplayer.css +1 -1
  25. package/built/web/rtlreact-common-skillmap.css +1 -1
  26. package/built/web/rtlsemantic.css +1 -1
  27. package/built/web/semantic.css +1 -1
  28. package/built/web/serviceworker.js +1 -1
  29. package/common-docs/release-tests.md +0 -1
  30. package/common-docs/testplan.md +0 -1
  31. package/docfiles/docs.js +0 -2
  32. package/docfiles/pxtweb/cookieCompliance.ts +2 -7
  33. package/localtypings/pxtarget.d.ts +1 -4
  34. package/package.json +1 -1
  35. package/react-common/components/palette/ColorPickerField.tsx +14 -29
  36. package/react-common/components/palette/PaletteEditor.tsx +24 -23
  37. package/react-common/components/palette/PalettePicker.tsx +0 -22
  38. package/react-common/components/palette/PaletteSwatch.tsx +1 -2
  39. package/react-common/styles/palette/ColorPickerField.less +1 -1
  40. package/react-common/styles/palette/PaletteSwatch.less +1 -0
  41. package/theme/asset-editor.less +10 -6
  42. package/theme/monaco.less +0 -20
  43. package/webapp/public/release.manifest +0 -1
  44. package/built/pxtwinrt.d.ts +0 -72
  45. package/built/pxtwinrt.js +0 -804
  46. package/built/web/pxtwinrt.js +0 -1
  47. package/common-docs/release-tests/windowsapp.md +0 -42
  48. package/common-docs/windows-app.md +0 -29
package/built/cli.js CHANGED
@@ -1243,14 +1243,16 @@ function ghpPushAsync(builtPackaged, minify = false) {
1243
1243
  .then(() => ghpGitAsync("push"));
1244
1244
  }
1245
1245
  exports.ghpPushAsync = ghpPushAsync;
1246
- function maxMTimeAsync(dirs) {
1246
+ async function maxMTimeAsync(dirs, maxDepth) {
1247
1247
  let max = 0;
1248
- return U.promiseMapAll(dirs, dn => readDirAsync(dn)
1249
- .then(files => U.promiseMapAll(files, fn => statAsync(path.join(dn, fn))
1250
- .then(st => {
1251
- max = Math.max(st.mtime.getTime(), max);
1252
- }))))
1253
- .then(() => max);
1248
+ await U.promiseMapAll(dirs, async (dir) => {
1249
+ const files = nodeutil.allFiles(dir, { allowMissing: true, maxDepth });
1250
+ await U.promiseMapAll(files, async (file) => {
1251
+ const st = await statAsync(file);
1252
+ max = Math.max(st.mtime.getTime(), max);
1253
+ });
1254
+ });
1255
+ return max;
1254
1256
  }
1255
1257
  function buildTargetAsync(parsed) {
1256
1258
  parseBuildInfo(parsed);
@@ -1701,6 +1703,18 @@ ${gcards.map(gcard => `[${gcard.name}](${gcard.url})`).join(',\n')}
1701
1703
  nodeutil.writeFileSync("built/target-strings.json", nodeutil.stringify(targetStringsSorted));
1702
1704
  pxt.log(`target-strings.json built`);
1703
1705
  }
1706
+ function lessFilePaths() {
1707
+ return [
1708
+ "node_modules/semantic-ui-less",
1709
+ "node_modules/pxt-core/theme",
1710
+ "theme/foo/bar",
1711
+ "theme",
1712
+ "node_modules/pxt-core/react-common/styles",
1713
+ "react-common/styles",
1714
+ "node_modules/@fortawesome",
1715
+ "node_modules/pxt-core/node_modules/@fortawesome"
1716
+ ];
1717
+ }
1704
1718
  async function buildSemanticUIAsync(parsed) {
1705
1719
  if (!fs.existsSync(path.join("theme", "style.less")) || !fs.existsSync(path.join("theme", "theme.config"))) {
1706
1720
  return;
@@ -1710,16 +1724,7 @@ async function buildSemanticUIAsync(parsed) {
1710
1724
  nodeutil.mkdirP(path.join("built", "web"));
1711
1725
  const lessPath = require.resolve('less');
1712
1726
  const lessCPath = path.join(path.dirname(lessPath), '/bin/lessc');
1713
- const lessIncludePaths = [
1714
- "node_modules/semantic-ui-less",
1715
- "node_modules/pxt-core/theme",
1716
- "theme/foo/bar",
1717
- "theme",
1718
- "node_modules/pxt-core/react-common/styles",
1719
- "react-common/styles",
1720
- "node_modules/@fortawesome",
1721
- "node_modules/pxt-core/node_modules/@fortawesome" // for locally linked dev environment
1722
- ].join(":");
1727
+ const lessIncludePaths = lessFilePaths().join(":");
1723
1728
  // Build semantic css
1724
1729
  await nodeutil.spawnAsync({
1725
1730
  cmd: "node",
@@ -2275,7 +2280,7 @@ function targetCrowdinBranch() {
2275
2280
  const theme = readJson("pxtarget.json").appTheme;
2276
2281
  return theme ? theme.crowdinBranch : undefined;
2277
2282
  }
2278
- function buildAndWatchAsync(f) {
2283
+ function buildAndWatchAsync(f, maxDepth) {
2279
2284
  let currMtime = Date.now();
2280
2285
  return f()
2281
2286
  .then(dirs => {
@@ -2284,7 +2289,7 @@ function buildAndWatchAsync(f) {
2284
2289
  pxt.debug('watching ' + dirs.join(', ') + '...');
2285
2290
  let loop = () => {
2286
2291
  U.delay(1000)
2287
- .then(() => maxMTimeAsync(dirs))
2292
+ .then(() => maxMTimeAsync(dirs, maxDepth))
2288
2293
  .then(num => {
2289
2294
  if (num > currMtime) {
2290
2295
  currMtime = num;
@@ -2310,7 +2315,7 @@ function buildFailed(msg, e) {
2310
2315
  console.log("***");
2311
2316
  console.log("");
2312
2317
  }
2313
- function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
2318
+ async function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
2314
2319
  if (fs.existsSync("pxt.json") &&
2315
2320
  !(fs.existsSync(path.join(simDir(), "tsconfig.json")) || nodeutil.existsDirSync(path.join(simDir(), "public")))) {
2316
2321
  console.log("No sim/tsconfig.json nor sim/public/; assuming npm installed package");
@@ -2323,17 +2328,40 @@ function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
2323
2328
  simDirectories = fs.readdirSync(libsdir).map(fn => path.join(libsdir, fn, "sim"));
2324
2329
  simDirectories = simDirectories.filter(fn => fs.existsSync(fn));
2325
2330
  }
2326
- return buildAndWatchAsync(() => buildCommonSimAsync()
2327
- .catch(e => buildFailed("common sim build failed: " + e.message, e))
2328
- .then(() => internalBuildTargetAsync({ localDir: true, rebundle }))
2329
- .catch(e => buildFailed("target build failed: " + e.message, e))
2330
- .then(() => {
2331
+ const buildTarget = async () => {
2332
+ let currentlyBuilding = "common sim";
2333
+ try {
2334
+ await buildCommonSimAsync();
2335
+ currentlyBuilding = "target";
2336
+ await internalBuildTargetAsync({ localDir: true, rebundle });
2337
+ }
2338
+ catch (e) {
2339
+ buildFailed(`${currentlyBuilding} build failed: ${e === null || e === void 0 ? void 0 : e.message}`, e);
2340
+ }
2331
2341
  let toWatch = dirsToWatch.slice();
2332
2342
  if (hasCommonPackages) {
2333
2343
  toWatch = toWatch.concat(simDirectories);
2334
2344
  }
2335
2345
  return toWatch.filter(d => fs.existsSync(d));
2336
- }));
2346
+ };
2347
+ const lessFiles = lessFilePaths().filter(p => fs.existsSync(p));
2348
+ // css build already occurs midway through internalBuildTargetAsync, so skip first rerun
2349
+ let skipFirstCssBuild = true;
2350
+ const buildCss = async () => {
2351
+ if (skipFirstCssBuild) {
2352
+ skipFirstCssBuild = false;
2353
+ }
2354
+ else {
2355
+ console.log("rebuilding css");
2356
+ await buildSemanticUIAsync();
2357
+ console.log("css build complete");
2358
+ }
2359
+ return lessFiles;
2360
+ };
2361
+ // some of the watched targets for buildTarget include nested built files,
2362
+ // such as libs/game/_locales/*, so can't just grab subdirectories
2363
+ await buildAndWatchAsync(buildTarget, 1);
2364
+ await buildAndWatchAsync(buildCss, 6);
2337
2365
  }
2338
2366
  function buildCommonSimAsync() {
2339
2367
  const simPath = path.resolve("node_modules/pxt-common-packages/sim");
package/built/pxt.js CHANGED
@@ -102218,11 +102218,6 @@ var pxt;
102218
102218
  return hasNavigator() && /arm/i.test(navigator.platform);
102219
102219
  }
102220
102220
  BrowserUtils.isARM = isARM;
102221
- // Detects if we are running inside the UWP runtime (Microsoft Edge)
102222
- function isUwpEdge() {
102223
- return typeof window !== "undefined" && !!window.Windows;
102224
- }
102225
- BrowserUtils.isUwpEdge = isUwpEdge;
102226
102221
  /*
102227
102222
  Notes on browser detection
102228
102223
 
@@ -102306,8 +102301,7 @@ var pxt;
102306
102301
  return isPxtElectron() || isIpcRenderer();
102307
102302
  }
102308
102303
  BrowserUtils.isElectron = isElectron;
102309
- // this function gets overriden when loading pxtwinrt.js
102310
- BrowserUtils.isWinRT = () => false;
102304
+ BrowserUtils.isWinRT = () => typeof Windows !== "undefined";
102311
102305
  function isLocalHost(ignoreFlags) {
102312
102306
  var _a;
102313
102307
  try {
@@ -113654,7 +113648,7 @@ var pxt;
113654
113648
  v = { data: v };
113655
113649
  }
113656
113650
  let ns = v.namespace || base.namespace || "";
113657
- if (ns)
113651
+ if (ns && !ns.endsWith("."))
113658
113652
  ns += ".";
113659
113653
  let id = v.id || ns + k;
113660
113654
  let icon = v.icon;
@@ -117245,28 +117239,36 @@ var pxt;
117245
117239
  this.undoStack = [];
117246
117240
  this.redoStack = [];
117247
117241
  }
117248
- loadTilemapJRes(jres, skipDuplicates = false) {
117242
+ loadTilemapJRes(jres, skipDuplicates = false, gallery = false) {
117249
117243
  jres = pxt.inflateJRes(jres);
117250
- const tiles = this.readImages(jres, true).filter(im => im.type === "tile" /* pxt.AssetType.Tile */);
117244
+ const tiles = this.readImages(jres, !gallery).filter(im => im.type === "tile" /* pxt.AssetType.Tile */);
117251
117245
  // If we are loading JRES into an existing project (i.e. in multipart tutorials)
117252
117246
  // we need to correct the tile ids because the user may have created new tiles
117253
117247
  // and taken some of the ids that were used by the tutorial author
117254
117248
  let tileMapping = {};
117255
- for (const tile of tiles) {
117256
- if (skipDuplicates) {
117257
- const existing = this.resolveTileByBitmap(tile.bitmap);
117258
- if (existing) {
117259
- tileMapping[tile.id] = existing.id;
117260
- continue;
117261
- }
117249
+ if (gallery) {
117250
+ for (const tile of tiles) {
117251
+ this.gallery.tiles.add(tile);
117262
117252
  }
117263
- const newTile = this.createNewTile(tile.bitmap, tile.id, tile.meta.displayName);
117264
- if (newTile.id !== tile.id) {
117265
- tileMapping[tile.id] = newTile.id;
117253
+ }
117254
+ else {
117255
+ for (const tile of tiles) {
117256
+ if (skipDuplicates) {
117257
+ const existing = this.resolveTileByBitmap(tile.bitmap);
117258
+ if (existing) {
117259
+ tileMapping[tile.id] = existing.id;
117260
+ continue;
117261
+ }
117262
+ }
117263
+ const newTile = this.createNewTile(tile.bitmap, tile.id, tile.meta.displayName);
117264
+ if (newTile.id !== tile.id) {
117265
+ tileMapping[tile.id] = newTile.id;
117266
+ }
117266
117267
  }
117267
117268
  }
117269
+ const state = gallery ? this.gallery : this.state;
117268
117270
  for (const tm of getTilemaps(jres)) {
117269
- this.state.tilemaps.add({
117271
+ state.tilemaps.add({
117270
117272
  internalID: this.getNewInternalId(),
117271
117273
  type: "tilemap" /* AssetType.Tilemap */,
117272
117274
  id: tm.id,
@@ -117283,16 +117285,17 @@ var pxt;
117283
117285
  });
117284
117286
  }
117285
117287
  }
117286
- loadAssetsJRes(jres) {
117288
+ loadAssetsJRes(jres, gallery = false) {
117287
117289
  jres = pxt.inflateJRes(jres);
117288
117290
  const toInflate = [];
117291
+ const state = gallery ? this.gallery : this.state;
117289
117292
  for (const key of Object.keys(jres)) {
117290
117293
  const entry = jres[key];
117291
117294
  if (entry.tilemapTile) {
117292
- this.state.tiles.add(this.generateImage(entry, "tile" /* AssetType.Tile */));
117295
+ state.tiles.add(this.generateImage(entry, "tile" /* AssetType.Tile */));
117293
117296
  }
117294
117297
  else if (entry.mimeType === pxt.IMAGE_MIME_TYPE) {
117295
- this.state.images.add(this.generateImage(entry, "image" /* AssetType.Image */));
117298
+ state.images.add(this.generateImage(entry, "image" /* AssetType.Image */));
117296
117299
  }
117297
117300
  else if (entry.mimeType === pxt.ANIMATION_MIME_TYPE) {
117298
117301
  const [animation, needsInflation] = this.generateAnimation(entry);
@@ -117300,15 +117303,15 @@ var pxt;
117300
117303
  toInflate.push(animation);
117301
117304
  }
117302
117305
  else {
117303
- this.state.animations.add(animation);
117306
+ state.animations.add(animation);
117304
117307
  }
117305
117308
  }
117306
117309
  else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
117307
- this.state.songs.add(this.generateSong(entry));
117310
+ state.songs.add(this.generateSong(entry));
117308
117311
  }
117309
117312
  }
117310
117313
  for (const animation of toInflate) {
117311
- this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
117314
+ state.animations.add(this.inflateAnimation(animation, state.images.getSnapshot()));
117312
117315
  }
117313
117316
  }
117314
117317
  removeInactiveBlockAssets(activeBlockIDs) {
@@ -117488,8 +117491,12 @@ var pxt;
117488
117491
  const entry = jres[key];
117489
117492
  if (entry.tilemapTile) {
117490
117493
  // FIXME: we should get the "image.ofBuffer" and blockIdentity from pxtarget probably
117494
+ let varName = key;
117495
+ if (varName.indexOf(".") !== -1) {
117496
+ varName = varName.split(".").slice(-1)[0];
117497
+ }
117491
117498
  out += `${indent}//% fixedInstance jres blockIdentity=images._tile\n`;
117492
- out += `${indent}export const ${key} = image.ofBuffer(hex\`\`);\n`;
117499
+ out += `${indent}export const ${varName} = image.ofBuffer(hex\`\`);\n`;
117493
117500
  tileEntries.push({ keys: [entry.displayName, getShortIDCore("tile" /* AssetType.Tile */, key, true)], expression: key });
117494
117501
  }
117495
117502
  if (entry.mimeType === pxt.TILEMAP_MIME_TYPE) {
@@ -120002,9 +120009,9 @@ var pxt;
120002
120009
  _available = false;
120003
120010
  return;
120004
120011
  }
120005
- if (pxt.BrowserUtils.isElectron() || pxt.BrowserUtils.isWinRT()) {
120006
- pxt.debug(`webusb: off, electron or winrt`);
120007
- pxt.tickEvent('webusb.off', { 'reason': 'electronwinrt' });
120012
+ if (pxt.BrowserUtils.isElectron()) {
120013
+ pxt.debug(`webusb: off, electron`);
120014
+ pxt.tickEvent('webusb.off', { 'reason': 'electron' });
120008
120015
  _available = false;
120009
120016
  return;
120010
120017
  }
@@ -160249,14 +160256,16 @@ function ghpPushAsync(builtPackaged, minify = false) {
160249
160256
  .then(() => ghpGitAsync("push"));
160250
160257
  }
160251
160258
  exports.ghpPushAsync = ghpPushAsync;
160252
- function maxMTimeAsync(dirs) {
160259
+ async function maxMTimeAsync(dirs, maxDepth) {
160253
160260
  let max = 0;
160254
- return U.promiseMapAll(dirs, dn => readDirAsync(dn)
160255
- .then(files => U.promiseMapAll(files, fn => statAsync(path.join(dn, fn))
160256
- .then(st => {
160257
- max = Math.max(st.mtime.getTime(), max);
160258
- }))))
160259
- .then(() => max);
160261
+ await U.promiseMapAll(dirs, async (dir) => {
160262
+ const files = nodeutil.allFiles(dir, { allowMissing: true, maxDepth });
160263
+ await U.promiseMapAll(files, async (file) => {
160264
+ const st = await statAsync(file);
160265
+ max = Math.max(st.mtime.getTime(), max);
160266
+ });
160267
+ });
160268
+ return max;
160260
160269
  }
160261
160270
  function buildTargetAsync(parsed) {
160262
160271
  parseBuildInfo(parsed);
@@ -160707,6 +160716,18 @@ ${gcards.map(gcard => `[${gcard.name}](${gcard.url})`).join(',\n')}
160707
160716
  nodeutil.writeFileSync("built/target-strings.json", nodeutil.stringify(targetStringsSorted));
160708
160717
  pxt.log(`target-strings.json built`);
160709
160718
  }
160719
+ function lessFilePaths() {
160720
+ return [
160721
+ "node_modules/semantic-ui-less",
160722
+ "node_modules/pxt-core/theme",
160723
+ "theme/foo/bar",
160724
+ "theme",
160725
+ "node_modules/pxt-core/react-common/styles",
160726
+ "react-common/styles",
160727
+ "node_modules/@fortawesome",
160728
+ "node_modules/pxt-core/node_modules/@fortawesome"
160729
+ ];
160730
+ }
160710
160731
  async function buildSemanticUIAsync(parsed) {
160711
160732
  if (!fs.existsSync(path.join("theme", "style.less")) || !fs.existsSync(path.join("theme", "theme.config"))) {
160712
160733
  return;
@@ -160716,16 +160737,7 @@ async function buildSemanticUIAsync(parsed) {
160716
160737
  nodeutil.mkdirP(path.join("built", "web"));
160717
160738
  const lessPath = require.resolve('less');
160718
160739
  const lessCPath = path.join(path.dirname(lessPath), '/bin/lessc');
160719
- const lessIncludePaths = [
160720
- "node_modules/semantic-ui-less",
160721
- "node_modules/pxt-core/theme",
160722
- "theme/foo/bar",
160723
- "theme",
160724
- "node_modules/pxt-core/react-common/styles",
160725
- "react-common/styles",
160726
- "node_modules/@fortawesome",
160727
- "node_modules/pxt-core/node_modules/@fortawesome" // for locally linked dev environment
160728
- ].join(":");
160740
+ const lessIncludePaths = lessFilePaths().join(":");
160729
160741
  // Build semantic css
160730
160742
  await nodeutil.spawnAsync({
160731
160743
  cmd: "node",
@@ -161281,7 +161293,7 @@ function targetCrowdinBranch() {
161281
161293
  const theme = readJson("pxtarget.json").appTheme;
161282
161294
  return theme ? theme.crowdinBranch : undefined;
161283
161295
  }
161284
- function buildAndWatchAsync(f) {
161296
+ function buildAndWatchAsync(f, maxDepth) {
161285
161297
  let currMtime = Date.now();
161286
161298
  return f()
161287
161299
  .then(dirs => {
@@ -161290,7 +161302,7 @@ function buildAndWatchAsync(f) {
161290
161302
  pxt.debug('watching ' + dirs.join(', ') + '...');
161291
161303
  let loop = () => {
161292
161304
  U.delay(1000)
161293
- .then(() => maxMTimeAsync(dirs))
161305
+ .then(() => maxMTimeAsync(dirs, maxDepth))
161294
161306
  .then(num => {
161295
161307
  if (num > currMtime) {
161296
161308
  currMtime = num;
@@ -161316,7 +161328,7 @@ function buildFailed(msg, e) {
161316
161328
  console.log("***");
161317
161329
  console.log("");
161318
161330
  }
161319
- function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
161331
+ async function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
161320
161332
  if (fs.existsSync("pxt.json") &&
161321
161333
  !(fs.existsSync(path.join(simDir(), "tsconfig.json")) || nodeutil.existsDirSync(path.join(simDir(), "public")))) {
161322
161334
  console.log("No sim/tsconfig.json nor sim/public/; assuming npm installed package");
@@ -161329,17 +161341,40 @@ function buildAndWatchTargetAsync(includeSourceMaps, rebundle) {
161329
161341
  simDirectories = fs.readdirSync(libsdir).map(fn => path.join(libsdir, fn, "sim"));
161330
161342
  simDirectories = simDirectories.filter(fn => fs.existsSync(fn));
161331
161343
  }
161332
- return buildAndWatchAsync(() => buildCommonSimAsync()
161333
- .catch(e => buildFailed("common sim build failed: " + e.message, e))
161334
- .then(() => internalBuildTargetAsync({ localDir: true, rebundle }))
161335
- .catch(e => buildFailed("target build failed: " + e.message, e))
161336
- .then(() => {
161344
+ const buildTarget = async () => {
161345
+ let currentlyBuilding = "common sim";
161346
+ try {
161347
+ await buildCommonSimAsync();
161348
+ currentlyBuilding = "target";
161349
+ await internalBuildTargetAsync({ localDir: true, rebundle });
161350
+ }
161351
+ catch (e) {
161352
+ buildFailed(`${currentlyBuilding} build failed: ${e === null || e === void 0 ? void 0 : e.message}`, e);
161353
+ }
161337
161354
  let toWatch = dirsToWatch.slice();
161338
161355
  if (hasCommonPackages) {
161339
161356
  toWatch = toWatch.concat(simDirectories);
161340
161357
  }
161341
161358
  return toWatch.filter(d => fs.existsSync(d));
161342
- }));
161359
+ };
161360
+ const lessFiles = lessFilePaths().filter(p => fs.existsSync(p));
161361
+ // css build already occurs midway through internalBuildTargetAsync, so skip first rerun
161362
+ let skipFirstCssBuild = true;
161363
+ const buildCss = async () => {
161364
+ if (skipFirstCssBuild) {
161365
+ skipFirstCssBuild = false;
161366
+ }
161367
+ else {
161368
+ console.log("rebuilding css");
161369
+ await buildSemanticUIAsync();
161370
+ console.log("css build complete");
161371
+ }
161372
+ return lessFiles;
161373
+ };
161374
+ // some of the watched targets for buildTarget include nested built files,
161375
+ // such as libs/game/_locales/*, so can't just grab subdirectories
161376
+ await buildAndWatchAsync(buildTarget, 1);
161377
+ await buildAndWatchAsync(buildCss, 6);
161343
161378
  }
161344
161379
  function buildCommonSimAsync() {
161345
161380
  const simPath = path.resolve("node_modules/pxt-common-packages/sim");
@@ -6471,13 +6471,15 @@ var pxt;
6471
6471
  * @param dom
6472
6472
  * @param workspace
6473
6473
  */
6474
- function domToWorkspaceNoEvents(dom, workspace) {
6474
+ function domToWorkspaceNoEvents(dom, workspace, opts) {
6475
6475
  pxt.tickEvent(`blocks.domtow`);
6476
6476
  let newBlockIds = [];
6477
6477
  try {
6478
6478
  Blockly.Events.disable();
6479
6479
  newBlockIds = Blockly.Xml.domToWorkspace(dom, workspace);
6480
- applyMetaComments(workspace);
6480
+ if (opts === null || opts === void 0 ? void 0 : opts.applyMetaComments) {
6481
+ applyMetaComments(workspace);
6482
+ }
6481
6483
  }
6482
6484
  catch (e) {
6483
6485
  pxt.reportException(e);
@@ -6485,7 +6487,7 @@ var pxt;
6485
6487
  finally {
6486
6488
  Blockly.Events.enable();
6487
6489
  }
6488
- return newBlockIds;
6490
+ return newBlockIds.filter(id => !!workspace.getBlockById(id));
6489
6491
  }
6490
6492
  blocks_2.domToWorkspaceNoEvents = domToWorkspaceNoEvents;
6491
6493
  function applyMetaComments(workspace) {
@@ -6499,7 +6501,10 @@ var pxt;
6499
6501
  if (/@highlight/.test(c)) {
6500
6502
  const cc = c.replace(/@highlight/g, '').trim();
6501
6503
  b.setCommentText(cc || null);
6502
- (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id);
6504
+ (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id, true);
6505
+ }
6506
+ if (/@hide/.test(c)) {
6507
+ b.dispose(true);
6503
6508
  }
6504
6509
  });
6505
6510
  }
@@ -6921,8 +6926,7 @@ var pxt;
6921
6926
  }
6922
6927
  layout.flow = flow;
6923
6928
  function screenshotEnabled() {
6924
- return !pxt.BrowserUtils.isIE()
6925
- && !pxt.BrowserUtils.isUwpEdge(); // TODO figure out why screenshots are not working in UWP; disable for now
6929
+ return !pxt.BrowserUtils.isIE();
6926
6930
  }
6927
6931
  layout.screenshotEnabled = screenshotEnabled;
6928
6932
  function screenshotAsync(ws, pixelDensity, encodeBlocks) {
@@ -10662,7 +10666,7 @@ var pxt;
10662
10666
  try {
10663
10667
  let text = blocksXml || `<xml xmlns="http://www.w3.org/1999/xhtml"></xml>`;
10664
10668
  let xml = Blockly.Xml.textToDom(text);
10665
- pxt.blocks.domToWorkspaceNoEvents(xml, workspace);
10669
+ pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyMetaComments: true });
10666
10670
  return renderWorkspace(options);
10667
10671
  }
10668
10672
  catch (e) {
@@ -133,12 +133,15 @@ declare namespace pxt.blocks {
133
133
  xml: string[];
134
134
  extensions?: string[];
135
135
  }
136
+ interface DomToWorkspaceOptions {
137
+ applyMetaComments?: boolean;
138
+ }
136
139
  /**
137
140
  * Converts a DOM into workspace without triggering any Blockly event. Returns the new block ids
138
141
  * @param dom
139
142
  * @param workspace
140
143
  */
141
- function domToWorkspaceNoEvents(dom: Element, workspace: Blockly.Workspace): string[];
144
+ function domToWorkspaceNoEvents(dom: Element, workspace: Blockly.Workspace, opts?: DomToWorkspaceOptions): string[];
142
145
  function clearWithoutEvents(workspace: Blockly.Workspace): void;
143
146
  function saveWorkspaceXml(ws: Blockly.Workspace, keepIds?: boolean): string;
144
147
  function saveBlocksXml(ws: Blockly.Workspace, keepIds?: boolean): string[];
@@ -2909,13 +2909,15 @@ var pxt;
2909
2909
  * @param dom
2910
2910
  * @param workspace
2911
2911
  */
2912
- function domToWorkspaceNoEvents(dom, workspace) {
2912
+ function domToWorkspaceNoEvents(dom, workspace, opts) {
2913
2913
  pxt.tickEvent(`blocks.domtow`);
2914
2914
  let newBlockIds = [];
2915
2915
  try {
2916
2916
  Blockly.Events.disable();
2917
2917
  newBlockIds = Blockly.Xml.domToWorkspace(dom, workspace);
2918
- applyMetaComments(workspace);
2918
+ if (opts === null || opts === void 0 ? void 0 : opts.applyMetaComments) {
2919
+ applyMetaComments(workspace);
2920
+ }
2919
2921
  }
2920
2922
  catch (e) {
2921
2923
  pxt.reportException(e);
@@ -2923,7 +2925,7 @@ var pxt;
2923
2925
  finally {
2924
2926
  Blockly.Events.enable();
2925
2927
  }
2926
- return newBlockIds;
2928
+ return newBlockIds.filter(id => !!workspace.getBlockById(id));
2927
2929
  }
2928
2930
  blocks_2.domToWorkspaceNoEvents = domToWorkspaceNoEvents;
2929
2931
  function applyMetaComments(workspace) {
@@ -2937,7 +2939,10 @@ var pxt;
2937
2939
  if (/@highlight/.test(c)) {
2938
2940
  const cc = c.replace(/@highlight/g, '').trim();
2939
2941
  b.setCommentText(cc || null);
2940
- (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id);
2942
+ (_b = (_a = workspace).highlightBlock) === null || _b === void 0 ? void 0 : _b.call(_a, b.id, true);
2943
+ }
2944
+ if (/@hide/.test(c)) {
2945
+ b.dispose(true);
2941
2946
  }
2942
2947
  });
2943
2948
  }
@@ -3359,8 +3364,7 @@ var pxt;
3359
3364
  }
3360
3365
  layout.flow = flow;
3361
3366
  function screenshotEnabled() {
3362
- return !pxt.BrowserUtils.isIE()
3363
- && !pxt.BrowserUtils.isUwpEdge(); // TODO figure out why screenshots are not working in UWP; disable for now
3367
+ return !pxt.BrowserUtils.isIE();
3364
3368
  }
3365
3369
  layout.screenshotEnabled = screenshotEnabled;
3366
3370
  function screenshotAsync(ws, pixelDensity, encodeBlocks) {
@@ -7100,7 +7104,7 @@ var pxt;
7100
7104
  try {
7101
7105
  let text = blocksXml || `<xml xmlns="http://www.w3.org/1999/xhtml"></xml>`;
7102
7106
  let xml = Blockly.Xml.textToDom(text);
7103
- pxt.blocks.domToWorkspaceNoEvents(xml, workspace);
7107
+ pxt.blocks.domToWorkspaceNoEvents(xml, workspace, { applyMetaComments: true });
7104
7108
  return renderWorkspace(options);
7105
7109
  }
7106
7110
  catch (e) {
@@ -558,11 +558,6 @@ 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
- },
566
561
  ].filter(experiment => ids.indexOf(experiment.id) > -1 && !(pxt.BrowserUtils.isPxtElectron() && experiment.enableOnline));
567
562
  }
568
563
  experiments_1.all = all;
package/built/pxtlib.d.ts CHANGED
@@ -705,7 +705,6 @@ declare namespace pxt.BrowserUtils {
705
705
  export function isMac(): boolean;
706
706
  export function isLinux(): boolean;
707
707
  export function isARM(): boolean;
708
- export function isUwpEdge(): boolean;
709
708
  export function isEdge(): boolean;
710
709
  export function isChromiumEdge(): boolean;
711
710
  export function isIE(): boolean;
@@ -2910,8 +2909,8 @@ declare namespace pxt {
2910
2909
  addChangeListener(asset: Asset, listener: () => void): void;
2911
2910
  removeChangeListener(type: AssetType, listener: () => void): void;
2912
2911
  loadPackage(pack: MainPackage): void;
2913
- loadTilemapJRes(jres: Map<JRes>, skipDuplicates?: boolean): void;
2914
- loadAssetsJRes(jres: Map<JRes>): void;
2912
+ loadTilemapJRes(jres: Map<JRes>, skipDuplicates?: boolean, gallery?: boolean): void;
2913
+ loadAssetsJRes(jres: Map<JRes>, gallery?: boolean): void;
2915
2914
  removeInactiveBlockAssets(activeBlockIDs: string[]): void;
2916
2915
  protected generateImage(entry: JRes, type: AssetType.Image): ProjectImage;
2917
2916
  protected generateImage(entry: JRes, type: AssetType.Tile): Tile;