pxt-core 7.5.39 → 7.5.42

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 CHANGED
@@ -5053,6 +5053,7 @@ function checkFileSize(files) {
5053
5053
  return maxSize;
5054
5054
  }
5055
5055
  function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
5056
+ var _a;
5056
5057
  if (!nodeutil.existsDirSync("docs"))
5057
5058
  return Promise.resolve();
5058
5059
  const docsRoot = nodeutil.targetDir;
@@ -5230,6 +5231,13 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
5230
5231
  // test targetconfig
5231
5232
  if (nodeutil.fileExistsSync("targetconfig.json")) {
5232
5233
  const targetConfig = nodeutil.readJson("targetconfig.json");
5234
+ if ((_a = targetConfig === null || targetConfig === void 0 ? void 0 : targetConfig.packages) === null || _a === void 0 ? void 0 : _a.approvedRepoLib) {
5235
+ for (const repoSlug of Object.keys(targetConfig.packages.approvedRepoLib)) {
5236
+ if (repoSlug !== repoSlug.toLocaleLowerCase()) {
5237
+ U.userError(`targetconfig.json: repo slugs in approvedRepoLib must be lowercased.\n\tError: ${repoSlug}`);
5238
+ }
5239
+ }
5240
+ }
5233
5241
  if (targetConfig && targetConfig.galleries) {
5234
5242
  Object.keys(targetConfig.galleries).forEach(k => {
5235
5243
  pxt.log(`gallery ${k}`);
@@ -5741,7 +5749,7 @@ function testGithubPackagesAsync(parsed) {
5741
5749
  .then(() => nodeutil.mkdirP(pkgsroot))
5742
5750
  .then(() => pxt.github.searchAsync("", packages))
5743
5751
  .then(ghrepos => ghrepos.filter(ghrepo => ghrepo.status == pxt.github.GitRepoStatus.Approved)
5744
- .map(ghrepo => ghrepo.fullName).concat(packages.approvedRepos || []))
5752
+ .map(ghrepo => ghrepo.fullName).concat(Object.keys(packages.approvedRepoLib || {})))
5745
5753
  .then(fullnames => {
5746
5754
  // remove dups
5747
5755
  fullnames = U.unique(fullnames, f => f.toLowerCase());
package/built/pxt.js CHANGED
@@ -108170,13 +108170,13 @@ var pxt;
108170
108170
  return false;
108171
108171
  }
108172
108172
  function isRepoApproved(repo, config) {
108173
+ var _a;
108173
108174
  if (isOrgApproved(repo, config))
108174
108175
  return true;
108175
108176
  if (!repo || !config)
108176
108177
  return false;
108177
108178
  if (repo.fullName
108178
- && config.approvedRepos
108179
- && config.approvedRepos.some(fn => fn.toLowerCase() == repo.fullName.toLowerCase()))
108179
+ && ((_a = config.approvedRepoLib) === null || _a === void 0 ? void 0 : _a[repo.fullName.toLowerCase()]))
108180
108180
  return true;
108181
108181
  return false;
108182
108182
  }
@@ -108309,52 +108309,60 @@ var pxt;
108309
108309
  return parts.filter(p => !!p).join('/');
108310
108310
  }
108311
108311
  github.join = join;
108312
- function upgradeRule(cfg, id) {
108313
- if (!cfg || !cfg.upgrades)
108312
+ function upgradeRules(cfg, id) {
108313
+ var _a;
108314
+ if (!cfg)
108314
108315
  return null;
108315
108316
  const parsed = parseRepoId(id);
108316
108317
  if (!parsed)
108317
108318
  return null;
108318
- // lookup base repo for upgrade rules
108319
+ const repoData = cfg.approvedRepoLib;
108320
+ // lookup base repo for upgrade rules
108319
108321
  // (since nested repoes share the same version number)
108320
- return pxt.U.lookup(cfg.upgrades, parsed.slug.toLowerCase());
108322
+ return cfg.approvedRepoLib && ((_a = pxt.U.lookup(cfg.approvedRepoLib, parsed.slug.toLowerCase())) === null || _a === void 0 ? void 0 : _a.upgrades);
108321
108323
  }
108322
108324
  function upgradedDisablesVariants(cfg, id) {
108323
- const upgr = upgradeRule(cfg, id);
108324
- const m = /^dv:(.*)/.exec(upgr);
108325
- if (m) {
108326
- const disabled = m[1].split(/,/);
108327
- if (disabled.some(d => !/^\w+$/.test(d)))
108328
- return null;
108329
- return disabled;
108325
+ const rules = upgradeRules(cfg, id) || [];
108326
+ if (!rules)
108327
+ return null;
108328
+ for (const upgr of rules) {
108329
+ const m = /^dv:(.*)/.exec(upgr);
108330
+ if (m) {
108331
+ const disabled = m[1].split(/,/);
108332
+ if (disabled.some(d => !/^\w+$/.test(d)))
108333
+ return null;
108334
+ return disabled;
108335
+ }
108330
108336
  }
108331
108337
  return null;
108332
108338
  }
108333
108339
  function upgradedPackageReference(cfg, id) {
108334
- const upgr = upgradeRule(cfg, id);
108335
- if (!upgr)
108340
+ const rules = upgradeRules(cfg, id);
108341
+ if (!rules)
108336
108342
  return null;
108337
- const m = /^min:(.*)/.exec(upgr);
108338
- const minV = m && pxt.semver.tryParse(m[1]);
108339
- if (minV) {
108340
- const parsed = parseRepoId(id);
108341
- const currV = pxt.semver.tryParse(parsed.tag);
108342
- if (currV && pxt.semver.cmp(currV, minV) < 0) {
108343
- parsed.tag = m[1];
108344
- pxt.debug(`upgrading ${id} to ${m[1]}`);
108345
- return stringifyRepo(parsed);
108343
+ for (const upgr of rules) {
108344
+ const m = /^min:(.*)/.exec(upgr);
108345
+ const minV = m && pxt.semver.tryParse(m[1]);
108346
+ if (minV) {
108347
+ const parsed = parseRepoId(id);
108348
+ const currV = pxt.semver.tryParse(parsed.tag);
108349
+ if (currV && pxt.semver.cmp(currV, minV) < 0) {
108350
+ parsed.tag = m[1];
108351
+ pxt.debug(`upgrading ${id} to ${m[1]}`);
108352
+ return stringifyRepo(parsed);
108353
+ }
108354
+ else {
108355
+ if (!currV)
108356
+ pxt.log(`not upgrading ${id} - cannot parse version`);
108357
+ return null;
108358
+ }
108346
108359
  }
108347
108360
  else {
108348
- if (!currV)
108349
- pxt.log(`not upgrading ${id} - cannot parse version`);
108350
- return null;
108361
+ // check if the rule looks valid at all
108362
+ if (!upgradedDisablesVariants(cfg, id))
108363
+ pxt.log(`invalid upgrade rule: ${id} -> ${upgr}`);
108351
108364
  }
108352
108365
  }
108353
- else {
108354
- // check if the rule looks valid at all
108355
- if (!upgradedDisablesVariants(cfg, id))
108356
- pxt.log(`invalid upgrade rule: ${id} -> ${upgr}`);
108357
- }
108358
108366
  return id;
108359
108367
  }
108360
108368
  github.upgradedPackageReference = upgradedPackageReference;
@@ -108684,6 +108692,7 @@ var pxt;
108684
108692
  constructor(io) {
108685
108693
  var _a;
108686
108694
  this.io = io;
108695
+ this.initialized = false;
108687
108696
  this.cmdSeq = pxt.U.randomUint32();
108688
108697
  this.lock = new pxt.U.PromiseQueue();
108689
108698
  this.flashing = false;
@@ -108698,6 +108707,7 @@ var pxt;
108698
108707
  this.jacdacAvailable = false;
108699
108708
  this.onSerial = (buf, isStderr) => { };
108700
108709
  this.onCustomEvent = (type, payload) => { };
108710
+ this.onConnectionChanged = () => { };
108701
108711
  let frames = [];
108702
108712
  io.onDeviceConnectionChanged = connect => this.disconnectAsync()
108703
108713
  .then(() => connect && this.reconnectAsync());
@@ -108765,6 +108775,7 @@ var pxt;
108765
108775
  });
108766
108776
  }
108767
108777
  resetState() {
108778
+ this.initialized = false;
108768
108779
  this.lock = new pxt.U.PromiseQueue();
108769
108780
  this.info = null;
108770
108781
  this.infoRaw = null;
@@ -108787,6 +108798,12 @@ var pxt;
108787
108798
  return Promise.resolve(); // ignore
108788
108799
  return Promise.reject(new Error("invalid custom event type"));
108789
108800
  }
108801
+ isConnected() {
108802
+ return this.io.isConnected() && this.initialized;
108803
+ }
108804
+ isConnecting() {
108805
+ return this.io.isConnecting() || (this.io.isConnected() && !this.initialized);
108806
+ }
108790
108807
  reconnectAsync() {
108791
108808
  this.resetState();
108792
108809
  log(`reconnect raw=${this.rawMode}`);
@@ -108995,8 +109012,10 @@ var pxt;
108995
109012
  .then(() => { });
108996
109013
  }
108997
109014
  initAsync() {
108998
- if (this.rawMode)
109015
+ if (this.rawMode) {
109016
+ this.initialized = true;
108999
109017
  return Promise.resolve();
109018
+ }
109000
109019
  return Promise.resolve()
109001
109020
  .then(() => this.talkAsync(HF2.HF2_CMD_BININFO))
109002
109021
  .then(binfo => {
@@ -109030,13 +109049,16 @@ var pxt;
109030
109049
  };
109031
109050
  log(`Board-ID: ${this.info.BoardID} v${this.info.Parsed.Version} f${this.info.Parsed.Features}`);
109032
109051
  })
109033
- .then(() => this.talkAsync(HF2.HF2_CMD_JDS_CONFIG, new Uint8Array([1])).then(() => {
109052
+ .then(() => this.talkAsync(HF2.HF2_CMD_JDS_CONFIG, new Uint8Array([1]))
109053
+ .then(() => {
109034
109054
  this.jacdacAvailable = true;
109035
109055
  }, _err => {
109036
109056
  this.jacdacAvailable = false;
109037
109057
  }))
109038
109058
  .then(() => {
109039
109059
  this.reconnectTries = 0;
109060
+ this.initialized = true;
109061
+ this.io.onConnectionChanged();
109040
109062
  });
109041
109063
  }
109042
109064
  }
@@ -112538,11 +112560,11 @@ var pxt;
112538
112560
  * The DAP wrapper is active and the device is connected
112539
112561
  */
112540
112562
  function isConnected() {
112541
- return !!wrapper && wrapper.io.isConnected();
112563
+ return !!(wrapper === null || wrapper === void 0 ? void 0 : wrapper.isConnected());
112542
112564
  }
112543
112565
  packetio.isConnected = isConnected;
112544
112566
  function isConnecting() {
112545
- return !!wrapper && wrapper.io.isConnecting();
112567
+ return !!(wrapper === null || wrapper === void 0 ? void 0 : wrapper.isConnecting());
112546
112568
  }
112547
112569
  packetio.isConnecting = isConnecting;
112548
112570
  function icon() {
@@ -162202,6 +162224,7 @@ function checkFileSize(files) {
162202
162224
  return maxSize;
162203
162225
  }
162204
162226
  function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162227
+ var _a;
162205
162228
  if (!nodeutil.existsDirSync("docs"))
162206
162229
  return Promise.resolve();
162207
162230
  const docsRoot = nodeutil.targetDir;
@@ -162379,6 +162402,13 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162379
162402
  // test targetconfig
162380
162403
  if (nodeutil.fileExistsSync("targetconfig.json")) {
162381
162404
  const targetConfig = nodeutil.readJson("targetconfig.json");
162405
+ if ((_a = targetConfig === null || targetConfig === void 0 ? void 0 : targetConfig.packages) === null || _a === void 0 ? void 0 : _a.approvedRepoLib) {
162406
+ for (const repoSlug of Object.keys(targetConfig.packages.approvedRepoLib)) {
162407
+ if (repoSlug !== repoSlug.toLocaleLowerCase()) {
162408
+ U.userError(`targetconfig.json: repo slugs in approvedRepoLib must be lowercased.\n\tError: ${repoSlug}`);
162409
+ }
162410
+ }
162411
+ }
162382
162412
  if (targetConfig && targetConfig.galleries) {
162383
162413
  Object.keys(targetConfig.galleries).forEach(k => {
162384
162414
  pxt.log(`gallery ${k}`);
@@ -162890,7 +162920,7 @@ function testGithubPackagesAsync(parsed) {
162890
162920
  .then(() => nodeutil.mkdirP(pkgsroot))
162891
162921
  .then(() => pxt.github.searchAsync("", packages))
162892
162922
  .then(ghrepos => ghrepos.filter(ghrepo => ghrepo.status == pxt.github.GitRepoStatus.Approved)
162893
- .map(ghrepo => ghrepo.fullName).concat(packages.approvedRepos || []))
162923
+ .map(ghrepo => ghrepo.fullName).concat(Object.keys(packages.approvedRepoLib || {})))
162894
162924
  .then(fullnames => {
162895
162925
  // remove dups
162896
162926
  fullnames = U.unique(fullnames, f => f.toLowerCase());
@@ -5962,6 +5962,7 @@ var pxt;
5962
5962
  registerFieldEditor('position', pxtblockly.FieldPosition);
5963
5963
  registerFieldEditor('melody', pxtblockly.FieldCustomMelody);
5964
5964
  registerFieldEditor('soundeffect', pxtblockly.FieldSoundEffect);
5965
+ registerFieldEditor('autocomplete', pxtblockly.FieldAutoComplete);
5965
5966
  }
5966
5967
  blocks.initFieldEditors = initFieldEditors;
5967
5968
  function registerFieldEditor(selector, field, validator) {
@@ -12037,6 +12038,156 @@ var pxtblockly;
12037
12038
  }
12038
12039
  pxtblockly.FieldArgumentVariable = FieldArgumentVariable;
12039
12040
  })(pxtblockly || (pxtblockly = {}));
12041
+ /// <reference path="../../localtypings/pxtblockly.d.ts" />
12042
+ var pxtblockly;
12043
+ (function (pxtblockly) {
12044
+ class FieldTextDropdown extends Blockly.FieldTextDropdown {
12045
+ constructor(text, options, opt_validator) {
12046
+ super(text, options.values, opt_validator);
12047
+ this.isFieldCustom_ = true;
12048
+ }
12049
+ }
12050
+ pxtblockly.FieldTextDropdown = FieldTextDropdown;
12051
+ })(pxtblockly || (pxtblockly = {}));
12052
+ /// <reference path="../../localtypings/pxtblockly.d.ts" />
12053
+ /// <reference path="./field_textdropdown.ts" />
12054
+ var pxtblockly;
12055
+ (function (pxtblockly) {
12056
+ class FieldAutoComplete extends Blockly.FieldTextDropdown {
12057
+ constructor(text, options, opt_validator) {
12058
+ super(text, () => [], opt_validator);
12059
+ this.isFieldCustom_ = true;
12060
+ this.key = options.key;
12061
+ this.isTextValid_ = true;
12062
+ }
12063
+ isOptionListDynamic() {
12064
+ return true;
12065
+ }
12066
+ getDisplayText_() {
12067
+ return this.parsedValue || "";
12068
+ }
12069
+ doValueUpdate_(newValue) {
12070
+ if (newValue === null)
12071
+ return;
12072
+ if (/['"`].*['"`]/.test(newValue)) {
12073
+ this.parsedValue = JSON.parse(newValue);
12074
+ }
12075
+ else {
12076
+ this.parsedValue = newValue;
12077
+ }
12078
+ this.value_ = this.parsedValue;
12079
+ }
12080
+ getValue() {
12081
+ if (this.parsedValue) {
12082
+ return JSON.stringify(this.parsedValue);
12083
+ }
12084
+ else
12085
+ return '""';
12086
+ }
12087
+ getOptions() {
12088
+ var _a;
12089
+ const workspace = (_a = this.sourceBlock_) === null || _a === void 0 ? void 0 : _a.workspace;
12090
+ if (!workspace)
12091
+ return [];
12092
+ const res = [];
12093
+ const fields = pxtblockly.getAllFields(workspace, field => field instanceof FieldAutoComplete && field.getKey() === this.key);
12094
+ const options = fields.map(field => field.ref.getDisplayText_());
12095
+ for (const option of options) {
12096
+ if (!option.trim() || res.some(tuple => tuple[0] === option))
12097
+ continue;
12098
+ res.push([option, option]);
12099
+ }
12100
+ res.sort((a, b) => a[0].localeCompare(b[0]));
12101
+ return res;
12102
+ }
12103
+ showDropdown_() {
12104
+ const options = this.getOptions();
12105
+ if (options.length)
12106
+ super.showDropdown_();
12107
+ }
12108
+ getKey() {
12109
+ if (this.key)
12110
+ return this.key;
12111
+ if (this.sourceBlock_)
12112
+ return this.sourceBlock_.type;
12113
+ return undefined;
12114
+ }
12115
+ // Copied from field_string in pxt-blockly
12116
+ initView() {
12117
+ // Add quotes around the string
12118
+ // Positioned on updatSize, after text size is calculated.
12119
+ this.quoteSize_ = 16;
12120
+ this.quoteWidth_ = 8;
12121
+ this.quoteLeftX_ = 0;
12122
+ this.quoteRightX_ = 0;
12123
+ this.quoteY_ = 10;
12124
+ if (this.quoteLeft_)
12125
+ this.quoteLeft_.parentNode.removeChild(this.quoteLeft_);
12126
+ this.quoteLeft_ = Blockly.utils.dom.createSvgElement('text', {
12127
+ 'font-size': this.quoteSize_ + 'px',
12128
+ 'class': 'field-text-quote'
12129
+ }, this.fieldGroup_);
12130
+ super.initView();
12131
+ if (this.quoteRight_)
12132
+ this.quoteRight_.parentNode.removeChild(this.quoteRight_);
12133
+ this.quoteRight_ = Blockly.utils.dom.createSvgElement('text', {
12134
+ 'font-size': this.quoteSize_ + 'px',
12135
+ 'class': 'field-text-quote'
12136
+ }, this.fieldGroup_);
12137
+ this.quoteLeft_.appendChild(document.createTextNode('"'));
12138
+ this.quoteRight_.appendChild(document.createTextNode('"'));
12139
+ }
12140
+ // Copied from field_string in pxt-blockly
12141
+ updateSize_() {
12142
+ super.updateSize_();
12143
+ const sWidth = Math.max(this.size_.width, 1);
12144
+ const xPadding = 3;
12145
+ let addedWidth = this.positionLeft(sWidth + xPadding);
12146
+ this.textElement_.setAttribute('x', addedWidth.toString());
12147
+ addedWidth += this.positionRight(addedWidth + sWidth + xPadding);
12148
+ this.size_.width = sWidth + addedWidth;
12149
+ }
12150
+ // Copied from field_string in pxt-blockly
12151
+ positionRight(x) {
12152
+ if (!this.quoteRight_) {
12153
+ return 0;
12154
+ }
12155
+ let addedWidth = 0;
12156
+ if (this.sourceBlock_.RTL) {
12157
+ this.quoteRightX_ = Blockly.FieldString.quotePadding;
12158
+ addedWidth = this.quoteWidth_ + Blockly.FieldString.quotePadding;
12159
+ }
12160
+ else {
12161
+ this.quoteRightX_ = x + Blockly.FieldString.quotePadding;
12162
+ addedWidth = this.quoteWidth_ + Blockly.FieldString.quotePadding;
12163
+ }
12164
+ this.quoteRight_.setAttribute('transform', 'translate(' + this.quoteRightX_ + ',' + this.quoteY_ + ')');
12165
+ return addedWidth;
12166
+ }
12167
+ // Copied from field_string in pxt-blockly
12168
+ positionLeft(x) {
12169
+ if (!this.quoteLeft_) {
12170
+ return 0;
12171
+ }
12172
+ let addedWidth = 0;
12173
+ if (this.sourceBlock_.RTL) {
12174
+ this.quoteLeftX_ = x + this.quoteWidth_ + Blockly.FieldString.quotePadding * 2;
12175
+ addedWidth = this.quoteWidth_ + Blockly.FieldString.quotePadding;
12176
+ }
12177
+ else {
12178
+ this.quoteLeftX_ = 0;
12179
+ addedWidth = this.quoteWidth_ + Blockly.FieldString.quotePadding;
12180
+ }
12181
+ this.quoteLeft_.setAttribute('transform', 'translate(' + this.quoteLeftX_ + ',' + this.quoteY_ + ')');
12182
+ return addedWidth;
12183
+ }
12184
+ createSVGArrow_() {
12185
+ // This creates the little arrow for dropdown fields. Intentionally
12186
+ // do nothing
12187
+ }
12188
+ }
12189
+ pxtblockly.FieldAutoComplete = FieldAutoComplete;
12190
+ })(pxtblockly || (pxtblockly = {}));
12040
12191
  /// <reference path="../../localtypings/blockly.d.ts" />
12041
12192
  /// <reference path="../../built/pxtsim.d.ts" />
12042
12193
  var pxtblockly;
@@ -15729,17 +15880,6 @@ var pxtblockly;
15729
15880
  })(pxtblockly || (pxtblockly = {}));
15730
15881
  /// <reference path="../../localtypings/pxtblockly.d.ts" />
15731
15882
  var pxtblockly;
15732
- (function (pxtblockly) {
15733
- class FieldTextDropdown extends Blockly.FieldTextDropdown {
15734
- constructor(text, options, opt_validator) {
15735
- super(text, options.values, opt_validator);
15736
- this.isFieldCustom_ = true;
15737
- }
15738
- }
15739
- pxtblockly.FieldTextDropdown = FieldTextDropdown;
15740
- })(pxtblockly || (pxtblockly = {}));
15741
- /// <reference path="../../localtypings/pxtblockly.d.ts" />
15742
- var pxtblockly;
15743
15883
  (function (pxtblockly) {
15744
15884
  class FieldTextInput extends Blockly.FieldTextInput {
15745
15885
  constructor(value, options, opt_validator) {
@@ -16851,11 +16991,11 @@ var pxtblockly;
16851
16991
  }
16852
16992
  }
16853
16993
  function getAllBlocksWithTilemaps(ws) {
16854
- return getAllFieldsCore(ws, f => f instanceof pxtblockly.FieldTilemap && !f.isGreyBlock);
16994
+ return getAllFields(ws, f => f instanceof pxtblockly.FieldTilemap && !f.isGreyBlock);
16855
16995
  }
16856
16996
  pxtblockly.getAllBlocksWithTilemaps = getAllBlocksWithTilemaps;
16857
16997
  function getAllBlocksWithTilesets(ws) {
16858
- return getAllFieldsCore(ws, f => f instanceof pxtblockly.FieldTileset);
16998
+ return getAllFields(ws, f => f instanceof pxtblockly.FieldTileset);
16859
16999
  }
16860
17000
  pxtblockly.getAllBlocksWithTilesets = getAllBlocksWithTilesets;
16861
17001
  function needsTilemapUpgrade(ws) {
@@ -16911,7 +17051,7 @@ var pxtblockly;
16911
17051
  }
16912
17052
  }
16913
17053
  pxtblockly.upgradeTilemapsInWorkspace = upgradeTilemapsInWorkspace;
16914
- function getAllFieldsCore(ws, predicate) {
17054
+ function getAllFields(ws, predicate) {
16915
17055
  const result = [];
16916
17056
  const top = ws.getTopBlocks(false);
16917
17057
  top.forEach(block => getAllFieldsRecursive(block));
@@ -16932,6 +17072,7 @@ var pxtblockly;
16932
17072
  }
16933
17073
  }
16934
17074
  }
17075
+ pxtblockly.getAllFields = getAllFields;
16935
17076
  function getAllReferencedTiles(workspace, excludeBlockID) {
16936
17077
  var _a;
16937
17078
  let all = {};
@@ -16970,10 +17111,10 @@ var pxtblockly;
16970
17111
  function getTemporaryAssets(workspace, type) {
16971
17112
  switch (type) {
16972
17113
  case "image" /* Image */:
16973
- return getAllFieldsCore(workspace, field => field instanceof pxtblockly.FieldSpriteEditor && field.isTemporaryAsset())
17114
+ return getAllFields(workspace, field => field instanceof pxtblockly.FieldSpriteEditor && field.isTemporaryAsset())
16974
17115
  .map(f => f.ref.getAsset());
16975
17116
  case "animation" /* Animation */:
16976
- return getAllFieldsCore(workspace, field => field instanceof pxtblockly.FieldAnimationEditor && field.isTemporaryAsset())
17117
+ return getAllFields(workspace, field => field instanceof pxtblockly.FieldAnimationEditor && field.isTemporaryAsset())
16977
17118
  .map(f => f.ref.getAsset());
16978
17119
  default: return [];
16979
17120
  }
@@ -515,6 +515,51 @@ declare namespace pxtblockly {
515
515
  dropdownCreate(): any;
516
516
  }
517
517
  }
518
+ declare namespace pxtblockly {
519
+ interface FieldTextDropdownOptions extends Blockly.FieldCustomOptions {
520
+ values: any;
521
+ }
522
+ class FieldTextDropdown extends Blockly.FieldTextDropdown implements Blockly.FieldCustom {
523
+ isFieldCustom_: boolean;
524
+ constructor(text: string, options: FieldTextDropdownOptions, opt_validator?: Function);
525
+ }
526
+ }
527
+ declare namespace Blockly {
528
+ interface FieldTextDropdown {
529
+ showDropdown_(): void;
530
+ isTextValid_: boolean;
531
+ }
532
+ }
533
+ declare namespace pxtblockly {
534
+ interface FieldAutoCompleteOptions extends Blockly.FieldCustomOptions {
535
+ key: string;
536
+ }
537
+ class FieldAutoComplete extends Blockly.FieldTextDropdown implements Blockly.FieldCustom {
538
+ isFieldCustom_: boolean;
539
+ protected key: string;
540
+ protected parsedValue: string;
541
+ protected quoteSize_: number;
542
+ protected quoteWidth_: number;
543
+ protected quoteLeftX_: number;
544
+ protected quoteRightX_: number;
545
+ protected quoteY_: number;
546
+ protected quoteLeft_: SVGTextElement;
547
+ protected quoteRight_: SVGTextElement;
548
+ constructor(text: string, options: FieldAutoCompleteOptions, opt_validator?: Function);
549
+ isOptionListDynamic(): boolean;
550
+ getDisplayText_(): string;
551
+ doValueUpdate_(newValue: string): void;
552
+ getValue(): string;
553
+ getOptions(): [string, string][];
554
+ showDropdown_(): void;
555
+ getKey(): string;
556
+ initView(): void;
557
+ updateSize_(): void;
558
+ positionRight(x: number): number;
559
+ positionLeft(x: number): number;
560
+ createSVGArrow_(): void;
561
+ }
562
+ }
518
563
  declare namespace pxtblockly {
519
564
  class FieldBreakpoint extends Blockly.FieldNumber implements Blockly.FieldCustom {
520
565
  isFieldCustom_: boolean;
@@ -1231,15 +1276,6 @@ declare namespace pxtblockly {
1231
1276
  constructor(value: string, options?: StyleOptions, opt_validator?: Function);
1232
1277
  }
1233
1278
  }
1234
- declare namespace pxtblockly {
1235
- interface FieldTextDropdownOptions extends Blockly.FieldCustomOptions {
1236
- values: any;
1237
- }
1238
- class FieldTextDropdown extends Blockly.FieldTextDropdown implements Blockly.FieldCustom {
1239
- isFieldCustom_: boolean;
1240
- constructor(text: string, options: FieldTextDropdownOptions, opt_validator?: Function);
1241
- }
1242
- }
1243
1279
  declare namespace pxtblockly {
1244
1280
  class FieldTextInput extends Blockly.FieldTextInput implements Blockly.FieldCustom {
1245
1281
  isFieldCustom_: boolean;
@@ -1469,6 +1505,7 @@ declare namespace pxtblockly {
1469
1505
  function getAllBlocksWithTilesets(ws: Blockly.Workspace): FieldEditorReference<FieldTileset>[];
1470
1506
  function needsTilemapUpgrade(ws: Blockly.Workspace): boolean;
1471
1507
  function upgradeTilemapsInWorkspace(ws: Blockly.Workspace, proj: pxt.TilemapProject): void;
1508
+ function getAllFields<U extends Blockly.Field>(ws: Blockly.Workspace, predicate: (field: Blockly.Field) => boolean): FieldEditorReference<U>[];
1472
1509
  function getAllReferencedTiles(workspace: Blockly.Workspace, excludeBlockID?: string): pxt.Tile[];
1473
1510
  function getTemporaryAssets(workspace: Blockly.Workspace, type: pxt.AssetType): pxt.Asset[];
1474
1511
  function workspaceToScreenCoordinates(ws: Blockly.WorkspaceSvg, wsCoordinates: Blockly.utils.Coordinate): Blockly.utils.Coordinate;