pxt-core 11.3.54 → 11.3.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/built/pxt.js CHANGED
@@ -117607,6 +117607,11 @@ var pxt;
117607
117607
  if (this.takenNames[id]) {
117608
117608
  const existing = this.lookupByID(id);
117609
117609
  if (!assetEquals(existing, newValue)) {
117610
+ if (!validateAsset(newValue) && validateAsset(existing)) {
117611
+ pxt.warn("Refusing to overwrite asset with invalid version");
117612
+ pxt.tickEvent("assets.invalidAssetOverwrite", { assetType: newValue.type });
117613
+ return existing;
117614
+ }
117610
117615
  this.removeByID(id);
117611
117616
  asset = this.add(newValue);
117612
117617
  this.notifyListener(newValue.internalID);
@@ -118870,6 +118875,9 @@ var pxt;
118870
118875
  }
118871
118876
  function cloneAsset(asset) {
118872
118877
  asset.meta = Object.assign({}, asset.meta);
118878
+ if (asset.meta.temporaryInfo) {
118879
+ asset.meta.temporaryInfo = Object.assign({}, asset.meta.temporaryInfo);
118880
+ }
118873
118881
  switch (asset.type) {
118874
118882
  case "tile" /* AssetType.Tile */:
118875
118883
  case "image" /* AssetType.Image */:
@@ -119070,6 +119078,62 @@ var pxt;
119070
119078
  return getShortIDCore(asset.type, asset.id);
119071
119079
  }
119072
119080
  pxt.getShortIDForAsset = getShortIDForAsset;
119081
+ function validateAsset(asset) {
119082
+ if (!asset)
119083
+ return false;
119084
+ switch (asset.type) {
119085
+ case "image" /* AssetType.Image */:
119086
+ case "tile" /* AssetType.Tile */:
119087
+ return validateImageAsset(asset);
119088
+ case "tilemap" /* AssetType.Tilemap */:
119089
+ return validateTilemap(asset);
119090
+ case "animation" /* AssetType.Animation */:
119091
+ return validateAnimation(asset);
119092
+ case "song" /* AssetType.Song */:
119093
+ return validateSong(asset);
119094
+ }
119095
+ }
119096
+ pxt.validateAsset = validateAsset;
119097
+ function validateImageAsset(asset) {
119098
+ if (!asset.bitmap)
119099
+ return false;
119100
+ return validateBitmap(pxt.sprite.Bitmap.fromData(asset.bitmap));
119101
+ }
119102
+ function validateTilemap(tilemap) {
119103
+ var _a;
119104
+ if (!tilemap.data ||
119105
+ !tilemap.data.tilemap ||
119106
+ !tilemap.data.tileset ||
119107
+ !tilemap.data.tileset.tileWidth ||
119108
+ !((_a = tilemap.data.tileset.tiles) === null || _a === void 0 ? void 0 : _a.length) ||
119109
+ !tilemap.data.layers) {
119110
+ return false;
119111
+ }
119112
+ return validateBitmap(pxt.sprite.Bitmap.fromData(tilemap.data.layers)) &&
119113
+ validateBitmap(tilemap.data.tilemap);
119114
+ }
119115
+ function validateAnimation(animation) {
119116
+ var _a;
119117
+ if (!((_a = animation.frames) === null || _a === void 0 ? void 0 : _a.length) || animation.interval <= 0) {
119118
+ return false;
119119
+ }
119120
+ return !animation.frames.some(frame => !validateBitmap(pxt.sprite.Bitmap.fromData(frame)));
119121
+ }
119122
+ function validateBitmap(bitmap) {
119123
+ return bitmap.width > 0 &&
119124
+ bitmap.height > 0 &&
119125
+ !Number.isNaN(bitmap.x0) &&
119126
+ !Number.isNaN(bitmap.y0) &&
119127
+ bitmap.data().data.length === bitmap.dataLength();
119128
+ }
119129
+ function validateSong(song) {
119130
+ return song.song &&
119131
+ song.song.ticksPerBeat > 0 &&
119132
+ song.song.beatsPerMeasure > 0 &&
119133
+ song.song.measures > 0 &&
119134
+ song.song.beatsPerMinute > 0 &&
119135
+ !!song.song.tracks;
119136
+ }
119073
119137
  function getShortIDCore(assetType, id, allowNoPrefix = false) {
119074
119138
  let prefix;
119075
119139
  switch (assetType) {
@@ -119170,10 +119234,6 @@ var pxt;
119170
119234
  }
119171
119235
  };
119172
119236
  }
119173
- function set16Bit(buf, offset, value) {
119174
- buf[offset] = value & 0xff;
119175
- buf[offset + 1] = (value >> 8) & 0xff;
119176
- }
119177
119237
  function read16Bit(buf, offset) {
119178
119238
  return buf[offset] | (buf[offset + 1] << 8);
119179
119239
  }
@@ -119186,6 +119246,21 @@ var pxt;
119186
119246
  case "song" /* AssetType.Song */: return snapshot.songs;
119187
119247
  }
119188
119248
  }
119249
+ function patchTemporaryAsset(oldValue, newValue, project) {
119250
+ if (!oldValue || assetEquals(oldValue, newValue))
119251
+ return newValue;
119252
+ newValue = cloneAsset(newValue);
119253
+ const wasTemporary = !oldValue.meta.displayName;
119254
+ const isTemporary = !newValue.meta.displayName;
119255
+ // if we went from being temporary to no longer being temporary,
119256
+ // make sure we replace the junk id with a new value
119257
+ if (wasTemporary && !isTemporary) {
119258
+ newValue.id = project.generateNewID(newValue.type);
119259
+ newValue.internalID = project.getNewInternalId();
119260
+ }
119261
+ return newValue;
119262
+ }
119263
+ pxt.patchTemporaryAsset = patchTemporaryAsset;
119189
119264
  })(pxt || (pxt = {}));
119190
119265
  var pxt;
119191
119266
  (function (pxt) {
@@ -52,6 +52,7 @@ export declare abstract class FieldAssetEditor<U extends FieldAssetEditorOptions
52
52
  protected updateAssetListener(): void;
53
53
  protected assetChangeListener: () => void;
54
54
  protected isFullscreen(): boolean;
55
+ protected temporaryAssetId(): string;
55
56
  }
56
57
  export declare class BlocklyTilemapChange extends Blockly.Events.BlockChange {
57
58
  protected oldRevision: number;
package/built/pxtlib.d.ts CHANGED
@@ -1834,7 +1834,7 @@ declare namespace pxt.sprite {
1834
1834
  protected coordToIndex(col: number, row: number): number;
1835
1835
  protected getCore(index: number): number;
1836
1836
  protected setCore(index: number, value: number): void;
1837
- protected dataLength(): number;
1837
+ dataLength(): number;
1838
1838
  }
1839
1839
  class Tilemap extends Bitmap {
1840
1840
  static fromData(data: BitmapData): Tilemap;
@@ -1842,7 +1842,7 @@ declare namespace pxt.sprite {
1842
1842
  resize(width: number, height: number): Tilemap;
1843
1843
  protected getCore(index: number): number;
1844
1844
  protected setCore(index: number, value: number): void;
1845
- protected dataLength(): number;
1845
+ dataLength(): number;
1846
1846
  }
1847
1847
  class TilemapData {
1848
1848
  tilemap: Tilemap;
@@ -3143,6 +3143,8 @@ declare namespace pxt {
3143
3143
  export function lookupProjectAssetByTSReference(ts: string, project: TilemapProject): Tile | ProjectImage | Animation | ProjectTilemap | Song;
3144
3144
  export function getDefaultAssetDisplayName(type: pxt.AssetType): string;
3145
3145
  export function getShortIDForAsset(asset: pxt.Asset): string;
3146
+ export function validateAsset(asset: pxt.Asset): boolean;
3147
+ export function patchTemporaryAsset(oldValue: pxt.Asset, newValue: pxt.Asset, project: TilemapProject): Asset;
3146
3148
  export {};
3147
3149
  }
3148
3150
  declare namespace pxt.toolbox {
package/built/pxtlib.js CHANGED
@@ -19921,6 +19921,11 @@ var pxt;
19921
19921
  if (this.takenNames[id]) {
19922
19922
  const existing = this.lookupByID(id);
19923
19923
  if (!assetEquals(existing, newValue)) {
19924
+ if (!validateAsset(newValue) && validateAsset(existing)) {
19925
+ pxt.warn("Refusing to overwrite asset with invalid version");
19926
+ pxt.tickEvent("assets.invalidAssetOverwrite", { assetType: newValue.type });
19927
+ return existing;
19928
+ }
19924
19929
  this.removeByID(id);
19925
19930
  asset = this.add(newValue);
19926
19931
  this.notifyListener(newValue.internalID);
@@ -21184,6 +21189,9 @@ var pxt;
21184
21189
  }
21185
21190
  function cloneAsset(asset) {
21186
21191
  asset.meta = Object.assign({}, asset.meta);
21192
+ if (asset.meta.temporaryInfo) {
21193
+ asset.meta.temporaryInfo = Object.assign({}, asset.meta.temporaryInfo);
21194
+ }
21187
21195
  switch (asset.type) {
21188
21196
  case "tile" /* AssetType.Tile */:
21189
21197
  case "image" /* AssetType.Image */:
@@ -21384,6 +21392,62 @@ var pxt;
21384
21392
  return getShortIDCore(asset.type, asset.id);
21385
21393
  }
21386
21394
  pxt.getShortIDForAsset = getShortIDForAsset;
21395
+ function validateAsset(asset) {
21396
+ if (!asset)
21397
+ return false;
21398
+ switch (asset.type) {
21399
+ case "image" /* AssetType.Image */:
21400
+ case "tile" /* AssetType.Tile */:
21401
+ return validateImageAsset(asset);
21402
+ case "tilemap" /* AssetType.Tilemap */:
21403
+ return validateTilemap(asset);
21404
+ case "animation" /* AssetType.Animation */:
21405
+ return validateAnimation(asset);
21406
+ case "song" /* AssetType.Song */:
21407
+ return validateSong(asset);
21408
+ }
21409
+ }
21410
+ pxt.validateAsset = validateAsset;
21411
+ function validateImageAsset(asset) {
21412
+ if (!asset.bitmap)
21413
+ return false;
21414
+ return validateBitmap(pxt.sprite.Bitmap.fromData(asset.bitmap));
21415
+ }
21416
+ function validateTilemap(tilemap) {
21417
+ var _a;
21418
+ if (!tilemap.data ||
21419
+ !tilemap.data.tilemap ||
21420
+ !tilemap.data.tileset ||
21421
+ !tilemap.data.tileset.tileWidth ||
21422
+ !((_a = tilemap.data.tileset.tiles) === null || _a === void 0 ? void 0 : _a.length) ||
21423
+ !tilemap.data.layers) {
21424
+ return false;
21425
+ }
21426
+ return validateBitmap(pxt.sprite.Bitmap.fromData(tilemap.data.layers)) &&
21427
+ validateBitmap(tilemap.data.tilemap);
21428
+ }
21429
+ function validateAnimation(animation) {
21430
+ var _a;
21431
+ if (!((_a = animation.frames) === null || _a === void 0 ? void 0 : _a.length) || animation.interval <= 0) {
21432
+ return false;
21433
+ }
21434
+ return !animation.frames.some(frame => !validateBitmap(pxt.sprite.Bitmap.fromData(frame)));
21435
+ }
21436
+ function validateBitmap(bitmap) {
21437
+ return bitmap.width > 0 &&
21438
+ bitmap.height > 0 &&
21439
+ !Number.isNaN(bitmap.x0) &&
21440
+ !Number.isNaN(bitmap.y0) &&
21441
+ bitmap.data().data.length === bitmap.dataLength();
21442
+ }
21443
+ function validateSong(song) {
21444
+ return song.song &&
21445
+ song.song.ticksPerBeat > 0 &&
21446
+ song.song.beatsPerMeasure > 0 &&
21447
+ song.song.measures > 0 &&
21448
+ song.song.beatsPerMinute > 0 &&
21449
+ !!song.song.tracks;
21450
+ }
21387
21451
  function getShortIDCore(assetType, id, allowNoPrefix = false) {
21388
21452
  let prefix;
21389
21453
  switch (assetType) {
@@ -21484,10 +21548,6 @@ var pxt;
21484
21548
  }
21485
21549
  };
21486
21550
  }
21487
- function set16Bit(buf, offset, value) {
21488
- buf[offset] = value & 0xff;
21489
- buf[offset + 1] = (value >> 8) & 0xff;
21490
- }
21491
21551
  function read16Bit(buf, offset) {
21492
21552
  return buf[offset] | (buf[offset + 1] << 8);
21493
21553
  }
@@ -21500,6 +21560,21 @@ var pxt;
21500
21560
  case "song" /* AssetType.Song */: return snapshot.songs;
21501
21561
  }
21502
21562
  }
21563
+ function patchTemporaryAsset(oldValue, newValue, project) {
21564
+ if (!oldValue || assetEquals(oldValue, newValue))
21565
+ return newValue;
21566
+ newValue = cloneAsset(newValue);
21567
+ const wasTemporary = !oldValue.meta.displayName;
21568
+ const isTemporary = !newValue.meta.displayName;
21569
+ // if we went from being temporary to no longer being temporary,
21570
+ // make sure we replace the junk id with a new value
21571
+ if (wasTemporary && !isTemporary) {
21572
+ newValue.id = project.generateNewID(newValue.type);
21573
+ newValue.internalID = project.getNewInternalId();
21574
+ }
21575
+ return newValue;
21576
+ }
21577
+ pxt.patchTemporaryAsset = patchTemporaryAsset;
21503
21578
  })(pxt || (pxt = {}));
21504
21579
  var pxt;
21505
21580
  (function (pxt) {