pxt-core 8.0.5 → 8.1.3

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.
@@ -4926,6 +4926,101 @@ ${output}</xml>`;
4926
4926
  }
4927
4927
  return undefined;
4928
4928
  }
4929
+ /**
4930
+ * We split up comments according to the following rules:
4931
+ * 1. If the comment is not top-level:
4932
+ * a. Combine it with all comments for the following statement
4933
+ * b. If there is no following statement in the current block, group it with the previous statement
4934
+ * c. If there are no statements inside the block, group it with the parent block
4935
+ * d. If trailing the same line as the statement, group it with the comments for that statement
4936
+ * 2. If the comment is top-level:
4937
+ * b. If the comment is followed by an empty line, it becomes a workspace comment
4938
+ * c. If the comment is followed by a multi-line comment, it becomes a workspace comment
4939
+ * a. If the comment is a single-line comment, combine it with the next single-line comment
4940
+ * d. If the comment is not followed with an empty line, group it with the next statement or event
4941
+ * e. All other comments are workspace comments
4942
+ *
4943
+ * The below function gathers any comments associated to the Node, and attaches them
4944
+ * to the StatementNode.
4945
+ */
4946
+ function getNodeComments(commented, stmt) {
4947
+ let comments = [];
4948
+ let current;
4949
+ for (let i = 0; i < commentMap.length; i++) {
4950
+ current = commentMap[i];
4951
+ if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
4952
+ current.owner = commented;
4953
+ current.ownerStatement = stmt;
4954
+ comments.push(current);
4955
+ }
4956
+ if (current.start > commented.end)
4957
+ break;
4958
+ }
4959
+ if (current && current.isTrailingComment) {
4960
+ const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
4961
+ const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
4962
+ if (endLine.line === commentLine.line) {
4963
+ // If the comment is trailing and on the same line as the statement, it probably belongs
4964
+ // to this statement. Remove it from any statement it's already assigned to and any workspace
4965
+ // comments
4966
+ if (current.ownerStatement) {
4967
+ current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
4968
+ for (const wsComment of workspaceComments) {
4969
+ wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
4970
+ }
4971
+ }
4972
+ current.owner = commented;
4973
+ current.ownerStatement = stmt;
4974
+ comments.push(current);
4975
+ }
4976
+ }
4977
+ if (comments.length) {
4978
+ const wsCommentRefs = [];
4979
+ if (isTopLevelComment(commented)) {
4980
+ let currentWorkspaceComment = [];
4981
+ const localWorkspaceComments = [];
4982
+ comments.forEach((comment, index) => {
4983
+ let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
4984
+ if (comment.kind === CommentKind.MultiLine && beforeStatement) {
4985
+ if (currentWorkspaceComment.length) {
4986
+ localWorkspaceComments.push(currentWorkspaceComment);
4987
+ currentWorkspaceComment = [];
4988
+ }
4989
+ if (index != comments.length - 1) {
4990
+ localWorkspaceComments.push([comment]);
4991
+ return;
4992
+ }
4993
+ }
4994
+ currentWorkspaceComment.push(comment);
4995
+ if (comment.followedByEmptyLine && beforeStatement) {
4996
+ localWorkspaceComments.push(currentWorkspaceComment);
4997
+ currentWorkspaceComment = [];
4998
+ }
4999
+ });
5000
+ comments = currentWorkspaceComment;
5001
+ localWorkspaceComments.forEach(comment => {
5002
+ const refId = getCommentRef();
5003
+ wsCommentRefs.push(refId);
5004
+ workspaceComments.push({ comment, refId });
5005
+ });
5006
+ }
5007
+ // Attach comments to StatementNode
5008
+ if (stmt) {
5009
+ if (wsCommentRefs.length) {
5010
+ if (stmt.data)
5011
+ stmt.data += ";" + wsCommentRefs.join(";");
5012
+ else
5013
+ stmt.data = wsCommentRefs.join(";");
5014
+ }
5015
+ if (comments && comments.length) {
5016
+ if (stmt.comment)
5017
+ stmt.comment = stmt.comment.concat(comments);
5018
+ else
5019
+ stmt.comment = comments;
5020
+ }
5021
+ }
5022
+ }
5023
+ }
4929
5024
  function getStatementBlock(n, next, parent, asExpression = false, topLevel = false) {
4930
5025
  const node = n;
4931
5026
  let stmt;
@@ -5028,7 +5123,7 @@ ${output}</xml>`;
5028
5123
  }
5029
5124
  }
5030
5125
  if (!skipComments) {
5031
- getComments(parent || node);
5126
+ getNodeComments(parent || node, stmt);
5032
5127
  }
5033
5128
  return stmt;
5034
5129
  function getNext() {
@@ -5037,97 +5132,6 @@ ${output}</xml>`;
5037
5132
  }
5038
5133
  return undefined;
5039
5134
  }
5040
- /**
5041
- * We split up comments according to the following rules:
5042
- * 1. If the comment is not top-level:
5043
- * a. Combine it with all comments for the following statement
5044
- * b. If there is no following statement in the current block, group it with the previous statement
5045
- * c. If there are no statements inside the block, group it with the parent block
5046
- * d. If trailing the same line as the statement, group it with the comments for that statement
5047
- * 2. If the comment is top-level:
5048
- * b. If the comment is followed by an empty line, it becomes a workspace comment
5049
- * c. If the comment is followed by a multi-line comment, it becomes a workspace comment
5050
- * a. If the comment is a single-line comment, combine it with the next single-line comment
5051
- * d. If the comment is not followed with an empty line, group it with the next statement or event
5052
- * e. All other comments are workspace comments
5053
- */
5054
- function getComments(commented) {
5055
- let comments = [];
5056
- let current;
5057
- for (let i = 0; i < commentMap.length; i++) {
5058
- current = commentMap[i];
5059
- if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
5060
- current.owner = commented;
5061
- current.ownerStatement = stmt;
5062
- comments.push(current);
5063
- }
5064
- if (current.start > commented.end)
5065
- break;
5066
- }
5067
- if (current && current.isTrailingComment) {
5068
- const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
5069
- const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
5070
- if (endLine.line === commentLine.line) {
5071
- // If the comment is trailing and on the same line as the statement, it probably belongs
5072
- // to this statement. Remove it from any statement it's already assigned to and any workspace
5073
- // comments
5074
- if (current.ownerStatement) {
5075
- current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
5076
- for (const wsComment of workspaceComments) {
5077
- wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
5078
- }
5079
- }
5080
- current.owner = commented;
5081
- current.ownerStatement = stmt;
5082
- comments.push(current);
5083
- }
5084
- }
5085
- if (comments.length) {
5086
- const wsCommentRefs = [];
5087
- if (isTopLevelComment(commented)) {
5088
- let currentWorkspaceComment = [];
5089
- const localWorkspaceComments = [];
5090
- comments.forEach((comment, index) => {
5091
- let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
5092
- if (comment.kind === CommentKind.MultiLine && beforeStatement) {
5093
- if (currentWorkspaceComment.length) {
5094
- localWorkspaceComments.push(currentWorkspaceComment);
5095
- currentWorkspaceComment = [];
5096
- }
5097
- if (index != comments.length - 1) {
5098
- localWorkspaceComments.push([comment]);
5099
- return;
5100
- }
5101
- }
5102
- currentWorkspaceComment.push(comment);
5103
- if (comment.followedByEmptyLine && beforeStatement) {
5104
- localWorkspaceComments.push(currentWorkspaceComment);
5105
- currentWorkspaceComment = [];
5106
- }
5107
- });
5108
- comments = currentWorkspaceComment;
5109
- localWorkspaceComments.forEach(comment => {
5110
- const refId = getCommentRef();
5111
- wsCommentRefs.push(refId);
5112
- workspaceComments.push({ comment, refId });
5113
- });
5114
- }
5115
- if (stmt) {
5116
- if (wsCommentRefs.length) {
5117
- if (stmt.data)
5118
- stmt.data += ";" + wsCommentRefs.join(";");
5119
- else
5120
- stmt.data = wsCommentRefs.join(";");
5121
- }
5122
- if (comments && comments.length) {
5123
- if (stmt.comment)
5124
- stmt.comment = stmt.comment.concat(comments);
5125
- else
5126
- stmt.comment = comments;
5127
- }
5128
- }
5129
- }
5130
- }
5131
5135
  }
5132
5136
  function getTypeScriptStatementBlock(node, prefix, err) {
5133
5137
  if (options.errorOnGreyBlocks)
@@ -5897,12 +5901,13 @@ ${output}</xml>`;
5897
5901
  eventStatements.map(n => getStatementBlock(n, undefined, undefined, false, topLevel)).forEach(emitStatementNode);
5898
5902
  if (blockStatements.length) {
5899
5903
  // wrap statement in "on start" if top level
5900
- const stmtNode = blockStatements.shift();
5901
- const stmt = getStatementBlock(stmtNode, blockStatements, parent, false, topLevel);
5904
+ const blockNode = blockStatements.shift();
5905
+ const stmt = getStatementBlock(blockNode, blockStatements, parent, false, topLevel);
5902
5906
  if (emitOnStart) {
5903
5907
  // Preserve any variable edeclarations that were never used
5904
- let current = stmt;
5905
- let currentNode = stmtNode;
5908
+ // stmt and blockNode will not yet align if there was an auto-declared variable.
5909
+ let currentStmtNode = stmt;
5910
+ let currentBlockNode = blockNode;
5906
5911
  autoDeclarations.forEach(([name, node]) => {
5907
5912
  if (varUsages[name] === ReferenceType.InBlocksOnly) {
5908
5913
  return;
@@ -5916,17 +5921,21 @@ ${output}</xml>`;
5916
5921
  v = getTypeScriptStatementBlock(node, "let ");
5917
5922
  }
5918
5923
  else {
5919
- v = getVariableSetOrChangeBlock(stmtNode, node.name, node.initializer, false, true);
5924
+ v = getVariableSetOrChangeBlock(blockNode, node.name, node.initializer, false, true);
5920
5925
  }
5921
- v.next = current;
5922
- current = v;
5923
- currentNode = node;
5926
+ // Auto-declared variables were not previously inserted into the stmt linked-list.
5927
+ // Insert auto-declared 'v' as the currentStmtNode.
5928
+ v.next = currentStmtNode;
5929
+ currentStmtNode = v;
5930
+ currentBlockNode = node;
5931
+ // Attach to currentStmtNode any associated comments
5932
+ getNodeComments(currentBlockNode.parent, currentStmtNode);
5924
5933
  });
5925
- if (current) {
5926
- const r = mkStmt(ts.pxtc.ON_START_TYPE, currentNode);
5934
+ if (currentStmtNode) {
5935
+ const r = mkStmt(ts.pxtc.ON_START_TYPE, currentBlockNode);
5927
5936
  r.handlers = [{
5928
5937
  name: "HANDLER",
5929
- statement: current
5938
+ statement: currentStmtNode
5930
5939
  }];
5931
5940
  return r;
5932
5941
  }
@@ -18441,6 +18450,7 @@ var ts;
18441
18450
  let snippet;
18442
18451
  if (preDefinedSnippet) {
18443
18452
  snippet = [preDefinedSnippet];
18453
+ snippetPrefix = undefined;
18444
18454
  }
18445
18455
  else {
18446
18456
  snippet = [fnName];
@@ -1245,8 +1245,8 @@ var pxt;
1245
1245
  let proj;
1246
1246
  let id;
1247
1247
  if (name) {
1248
- let id = ts.pxtc.escapeIdentifier(name);
1249
- proj = project.getTilemap(id);
1248
+ id = ts.pxtc.escapeIdentifier(name);
1249
+ proj = project.getTilemap(id) || project.lookupAssetByName("tilemap" /* Tilemap */, name);
1250
1250
  }
1251
1251
  if (!proj) {
1252
1252
  let tileWidth = 16;
package/built/pxtlib.js CHANGED
@@ -8698,13 +8698,20 @@ var pxt;
8698
8698
  docs.prepTemplate = prepTemplate;
8699
8699
  function setupRenderer(renderer) {
8700
8700
  renderer.image = function (href, title, text) {
8701
- let out = '<img class="ui image" src="' + href + '" alt="' + text + '"';
8702
- if (title) {
8703
- out += ' title="' + title + '"';
8701
+ if (href.startsWith("youtube:")) {
8702
+ let out = '<div class="tutorial-video-embed"><iframe src="https://www.youtube.com/embed/' + href.split(":").pop()
8703
+ + '" title="' + title + '" frameborder="0" ' + 'allowFullScreen ' + 'allow="autoplay; picture-in-picture"></iframe></div>';
8704
+ return out;
8705
+ }
8706
+ else {
8707
+ let out = '<img class="ui image" src="' + href + '" alt="' + text + '"';
8708
+ if (title) {
8709
+ out += ' title="' + title + '"';
8710
+ }
8711
+ out += ' loading="lazy"';
8712
+ out += this.options.xhtml ? '/>' : '>';
8713
+ return out;
8704
8714
  }
8705
- out += ' loading="lazy"';
8706
- out += this.options.xhtml ? '/>' : '>';
8707
- return out;
8708
8715
  };
8709
8716
  renderer.listitem = function (text) {
8710
8717
  const m = /^\s*\[( |x)\]/i.exec(text);
@@ -18002,7 +18009,7 @@ var pxt;
18002
18009
  id,
18003
18010
  type: "tilemap" /* Tilemap */,
18004
18011
  meta: {
18005
- displayName: id
18012
+ displayName: name || id
18006
18013
  },
18007
18014
  data: data
18008
18015
  });
@@ -97,6 +97,7 @@ declare namespace pxt.runner {
97
97
  dependencies?: string[];
98
98
  builtJsInfo?: pxtc.BuiltSimJsInfo;
99
99
  single?: boolean;
100
+ autofocus?: boolean;
100
101
  }
101
102
  let mainPkg: pxt.MainPackage;
102
103
  function initFooter(footer: HTMLElement, shareId?: string): void;
@@ -1749,7 +1749,8 @@ var pxt;
1749
1749
  highContrast: simOptions.highContrast,
1750
1750
  storedState: storedState,
1751
1751
  light: simOptions.light,
1752
- single: simOptions.single
1752
+ single: simOptions.single,
1753
+ autofocus: simOptions.autofocus
1753
1754
  };
1754
1755
  if (pxt.appTarget.simulator && !simOptions.fullScreen)
1755
1756
  runOptions.aspectRatio = parts.length && pxt.appTarget.simulator.partsAspectRatio
package/built/pxtsim.d.ts CHANGED
@@ -1268,6 +1268,7 @@ declare namespace pxsim {
1268
1268
  ipc?: boolean;
1269
1269
  dependencies?: Map<string>;
1270
1270
  single?: boolean;
1271
+ autofocus?: boolean;
1271
1272
  }
1272
1273
  interface HwDebugger {
1273
1274
  postMessage: (msg: pxsim.SimulatorMessage) => void;
package/built/pxtsim.js CHANGED
@@ -6295,6 +6295,7 @@ var pxsim;
6295
6295
  }
6296
6296
  }
6297
6297
  createFrame(url) {
6298
+ var _a;
6298
6299
  const wrapper = document.createElement("div");
6299
6300
  wrapper.className = `simframe ui embed`;
6300
6301
  const frame = document.createElement('iframe');
@@ -6309,6 +6310,8 @@ var pxsim;
6309
6310
  frame.frameBorder = "0";
6310
6311
  frame.dataset['runid'] = this.runId;
6311
6312
  frame.dataset['origin'] = new URL(furl).origin || "*";
6313
+ if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
6314
+ frame.setAttribute("autofocus", "true");
6312
6315
  wrapper.appendChild(frame);
6313
6316
  const i = document.createElement("i");
6314
6317
  i.className = "videoplay xicon icon";
@@ -6562,11 +6565,14 @@ var pxsim;
6562
6565
  return true;
6563
6566
  }
6564
6567
  handleMessage(msg, source) {
6568
+ var _a;
6565
6569
  switch (msg.type || '') {
6566
6570
  case 'ready': {
6567
6571
  const frameid = msg.frameid;
6568
6572
  const frame = document.getElementById(frameid);
6569
6573
  if (frame) {
6574
+ if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
6575
+ frame.focus();
6570
6576
  this.startFrame(frame);
6571
6577
  if (this.options.revealElement)
6572
6578
  this.options.revealElement(frame);
package/built/server.js CHANGED
@@ -1026,7 +1026,7 @@ function serveAsync(options) {
1026
1026
  return;
1027
1027
  }
1028
1028
  let publicDir = path.join(nodeutil.pxtCoreDir, "webapp/public");
1029
- if (pathname == "/--embed") {
1029
+ if (pathname == "/--embed" || pathname === "/---embed") {
1030
1030
  sendFile(path.join(publicDir, 'embed.js'));
1031
1031
  return;
1032
1032
  }