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.
- package/built/backendutils.js +13 -6
- package/built/buildengine.js +3 -3
- package/built/cli.js +35 -18
- package/built/nodeutil.d.ts +9 -1
- package/built/nodeutil.js +5 -4
- package/built/pxt.js +168 -128
- package/built/pxtcompiler.js +113 -103
- package/built/pxteditor.js +2 -2
- package/built/pxtlib.js +14 -7
- package/built/pxtrunner.d.ts +1 -0
- package/built/pxtrunner.js +2 -1
- package/built/pxtsim.d.ts +1 -0
- package/built/pxtsim.js +6 -0
- package/built/server.js +1 -1
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.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/pxtrunner.js +1 -1
- package/built/web/pxtsim.js +1 -1
- package/built/web/pxtworker.js +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/common-docs/release-tests/editor.md +2 -1
- package/package.json +2 -1
- package/react-common/components/controls/EmbedVideo.tsx +45 -0
- package/react-common/styles/controls/EmbedVideo.less +4 -0
- package/theme/tutorial-sidebar.less +6 -0
- package/webapp/public/index.html +2 -1
- package/webapp/public/run.html +3 -1
- package/webapp/public/zip.js/zip.min.js +28 -0
package/built/pxt.js
CHANGED
|
@@ -106384,13 +106384,20 @@ var pxt;
|
|
|
106384
106384
|
docs.prepTemplate = prepTemplate;
|
|
106385
106385
|
function setupRenderer(renderer) {
|
|
106386
106386
|
renderer.image = function (href, title, text) {
|
|
106387
|
-
|
|
106388
|
-
|
|
106389
|
-
|
|
106387
|
+
if (href.startsWith("youtube:")) {
|
|
106388
|
+
let out = '<div class="tutorial-video-embed"><iframe src="https://www.youtube.com/embed/' + href.split(":").pop()
|
|
106389
|
+
+ '" title="' + title + '" frameborder="0" ' + 'allowFullScreen ' + 'allow="autoplay; picture-in-picture"></iframe></div>';
|
|
106390
|
+
return out;
|
|
106391
|
+
}
|
|
106392
|
+
else {
|
|
106393
|
+
let out = '<img class="ui image" src="' + href + '" alt="' + text + '"';
|
|
106394
|
+
if (title) {
|
|
106395
|
+
out += ' title="' + title + '"';
|
|
106396
|
+
}
|
|
106397
|
+
out += ' loading="lazy"';
|
|
106398
|
+
out += this.options.xhtml ? '/>' : '>';
|
|
106399
|
+
return out;
|
|
106390
106400
|
}
|
|
106391
|
-
out += ' loading="lazy"';
|
|
106392
|
-
out += this.options.xhtml ? '/>' : '>';
|
|
106393
|
-
return out;
|
|
106394
106401
|
};
|
|
106395
106402
|
renderer.listitem = function (text) {
|
|
106396
106403
|
const m = /^\s*\[( |x)\]/i.exec(text);
|
|
@@ -115688,7 +115695,7 @@ var pxt;
|
|
|
115688
115695
|
id,
|
|
115689
115696
|
type: "tilemap" /* Tilemap */,
|
|
115690
115697
|
meta: {
|
|
115691
|
-
displayName: id
|
|
115698
|
+
displayName: name || id
|
|
115692
115699
|
},
|
|
115693
115700
|
data: data
|
|
115694
115701
|
});
|
|
@@ -125956,6 +125963,101 @@ ${output}</xml>`;
|
|
|
125956
125963
|
}
|
|
125957
125964
|
return undefined;
|
|
125958
125965
|
}
|
|
125966
|
+
/**
|
|
125967
|
+
* We split up comments according to the following rules:
|
|
125968
|
+
* 1. If the comment is not top-level:
|
|
125969
|
+
* a. Combine it with all comments for the following statement
|
|
125970
|
+
* b. If there is no following statement in the current block, group it with the previous statement
|
|
125971
|
+
* c. If there are no statements inside the block, group it with the parent block
|
|
125972
|
+
* d. If trailing the same line as the statement, group it with the comments for that statement
|
|
125973
|
+
* 2. If the comment is top-level:
|
|
125974
|
+
* b. If the comment is followed by an empty line, it becomes a workspace comment
|
|
125975
|
+
* c. If the comment is followed by a multi-line comment, it becomes a workspace comment
|
|
125976
|
+
* a. If the comment is a single-line comment, combine it with the next single-line comment
|
|
125977
|
+
* d. If the comment is not followed with an empty line, group it with the next statement or event
|
|
125978
|
+
* e. All other comments are workspace comments
|
|
125979
|
+
*
|
|
125980
|
+
* The below function gathers any comments associated to the Node, and attaches them
|
|
125981
|
+
* to the StatementNode.
|
|
125982
|
+
*/
|
|
125983
|
+
function getNodeComments(commented, stmt) {
|
|
125984
|
+
let comments = [];
|
|
125985
|
+
let current;
|
|
125986
|
+
for (let i = 0; i < commentMap.length; i++) {
|
|
125987
|
+
current = commentMap[i];
|
|
125988
|
+
if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
|
|
125989
|
+
current.owner = commented;
|
|
125990
|
+
current.ownerStatement = stmt;
|
|
125991
|
+
comments.push(current);
|
|
125992
|
+
}
|
|
125993
|
+
if (current.start > commented.end)
|
|
125994
|
+
break;
|
|
125995
|
+
}
|
|
125996
|
+
if (current && current.isTrailingComment) {
|
|
125997
|
+
const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
|
|
125998
|
+
const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
|
|
125999
|
+
if (endLine.line === commentLine.line) {
|
|
126000
|
+
// If the comment is trailing and on the same line as the statement, it probably belongs
|
|
126001
|
+
// to this statement. Remove it from any statement it's already assigned to and any workspace
|
|
126002
|
+
// comments
|
|
126003
|
+
if (current.ownerStatement) {
|
|
126004
|
+
current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
|
|
126005
|
+
for (const wsComment of workspaceComments) {
|
|
126006
|
+
wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
|
|
126007
|
+
}
|
|
126008
|
+
}
|
|
126009
|
+
current.owner = commented;
|
|
126010
|
+
current.ownerStatement = stmt;
|
|
126011
|
+
comments.push(current);
|
|
126012
|
+
}
|
|
126013
|
+
}
|
|
126014
|
+
if (comments.length) {
|
|
126015
|
+
const wsCommentRefs = [];
|
|
126016
|
+
if (isTopLevelComment(commented)) {
|
|
126017
|
+
let currentWorkspaceComment = [];
|
|
126018
|
+
const localWorkspaceComments = [];
|
|
126019
|
+
comments.forEach((comment, index) => {
|
|
126020
|
+
let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
|
|
126021
|
+
if (comment.kind === CommentKind.MultiLine && beforeStatement) {
|
|
126022
|
+
if (currentWorkspaceComment.length) {
|
|
126023
|
+
localWorkspaceComments.push(currentWorkspaceComment);
|
|
126024
|
+
currentWorkspaceComment = [];
|
|
126025
|
+
}
|
|
126026
|
+
if (index != comments.length - 1) {
|
|
126027
|
+
localWorkspaceComments.push([comment]);
|
|
126028
|
+
return;
|
|
126029
|
+
}
|
|
126030
|
+
}
|
|
126031
|
+
currentWorkspaceComment.push(comment);
|
|
126032
|
+
if (comment.followedByEmptyLine && beforeStatement) {
|
|
126033
|
+
localWorkspaceComments.push(currentWorkspaceComment);
|
|
126034
|
+
currentWorkspaceComment = [];
|
|
126035
|
+
}
|
|
126036
|
+
});
|
|
126037
|
+
comments = currentWorkspaceComment;
|
|
126038
|
+
localWorkspaceComments.forEach(comment => {
|
|
126039
|
+
const refId = getCommentRef();
|
|
126040
|
+
wsCommentRefs.push(refId);
|
|
126041
|
+
workspaceComments.push({ comment, refId });
|
|
126042
|
+
});
|
|
126043
|
+
}
|
|
126044
|
+
// Attach comments to StatementNode
|
|
126045
|
+
if (stmt) {
|
|
126046
|
+
if (wsCommentRefs.length) {
|
|
126047
|
+
if (stmt.data)
|
|
126048
|
+
stmt.data += ";" + wsCommentRefs.join(";");
|
|
126049
|
+
else
|
|
126050
|
+
stmt.data = wsCommentRefs.join(";");
|
|
126051
|
+
}
|
|
126052
|
+
if (comments && comments.length) {
|
|
126053
|
+
if (stmt.comment)
|
|
126054
|
+
stmt.comment = stmt.comment.concat(comments);
|
|
126055
|
+
else
|
|
126056
|
+
stmt.comment = comments;
|
|
126057
|
+
}
|
|
126058
|
+
}
|
|
126059
|
+
}
|
|
126060
|
+
}
|
|
125959
126061
|
function getStatementBlock(n, next, parent, asExpression = false, topLevel = false) {
|
|
125960
126062
|
const node = n;
|
|
125961
126063
|
let stmt;
|
|
@@ -126058,7 +126160,7 @@ ${output}</xml>`;
|
|
|
126058
126160
|
}
|
|
126059
126161
|
}
|
|
126060
126162
|
if (!skipComments) {
|
|
126061
|
-
|
|
126163
|
+
getNodeComments(parent || node, stmt);
|
|
126062
126164
|
}
|
|
126063
126165
|
return stmt;
|
|
126064
126166
|
function getNext() {
|
|
@@ -126067,97 +126169,6 @@ ${output}</xml>`;
|
|
|
126067
126169
|
}
|
|
126068
126170
|
return undefined;
|
|
126069
126171
|
}
|
|
126070
|
-
/**
|
|
126071
|
-
* We split up comments according to the following rules:
|
|
126072
|
-
* 1. If the comment is not top-level:
|
|
126073
|
-
* a. Combine it with all comments for the following statement
|
|
126074
|
-
* b. If there is no following statement in the current block, group it with the previous statement
|
|
126075
|
-
* c. If there are no statements inside the block, group it with the parent block
|
|
126076
|
-
* d. If trailing the same line as the statement, group it with the comments for that statement
|
|
126077
|
-
* 2. If the comment is top-level:
|
|
126078
|
-
* b. If the comment is followed by an empty line, it becomes a workspace comment
|
|
126079
|
-
* c. If the comment is followed by a multi-line comment, it becomes a workspace comment
|
|
126080
|
-
* a. If the comment is a single-line comment, combine it with the next single-line comment
|
|
126081
|
-
* d. If the comment is not followed with an empty line, group it with the next statement or event
|
|
126082
|
-
* e. All other comments are workspace comments
|
|
126083
|
-
*/
|
|
126084
|
-
function getComments(commented) {
|
|
126085
|
-
let comments = [];
|
|
126086
|
-
let current;
|
|
126087
|
-
for (let i = 0; i < commentMap.length; i++) {
|
|
126088
|
-
current = commentMap[i];
|
|
126089
|
-
if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
|
|
126090
|
-
current.owner = commented;
|
|
126091
|
-
current.ownerStatement = stmt;
|
|
126092
|
-
comments.push(current);
|
|
126093
|
-
}
|
|
126094
|
-
if (current.start > commented.end)
|
|
126095
|
-
break;
|
|
126096
|
-
}
|
|
126097
|
-
if (current && current.isTrailingComment) {
|
|
126098
|
-
const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
|
|
126099
|
-
const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
|
|
126100
|
-
if (endLine.line === commentLine.line) {
|
|
126101
|
-
// If the comment is trailing and on the same line as the statement, it probably belongs
|
|
126102
|
-
// to this statement. Remove it from any statement it's already assigned to and any workspace
|
|
126103
|
-
// comments
|
|
126104
|
-
if (current.ownerStatement) {
|
|
126105
|
-
current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
|
|
126106
|
-
for (const wsComment of workspaceComments) {
|
|
126107
|
-
wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
|
|
126108
|
-
}
|
|
126109
|
-
}
|
|
126110
|
-
current.owner = commented;
|
|
126111
|
-
current.ownerStatement = stmt;
|
|
126112
|
-
comments.push(current);
|
|
126113
|
-
}
|
|
126114
|
-
}
|
|
126115
|
-
if (comments.length) {
|
|
126116
|
-
const wsCommentRefs = [];
|
|
126117
|
-
if (isTopLevelComment(commented)) {
|
|
126118
|
-
let currentWorkspaceComment = [];
|
|
126119
|
-
const localWorkspaceComments = [];
|
|
126120
|
-
comments.forEach((comment, index) => {
|
|
126121
|
-
let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
|
|
126122
|
-
if (comment.kind === CommentKind.MultiLine && beforeStatement) {
|
|
126123
|
-
if (currentWorkspaceComment.length) {
|
|
126124
|
-
localWorkspaceComments.push(currentWorkspaceComment);
|
|
126125
|
-
currentWorkspaceComment = [];
|
|
126126
|
-
}
|
|
126127
|
-
if (index != comments.length - 1) {
|
|
126128
|
-
localWorkspaceComments.push([comment]);
|
|
126129
|
-
return;
|
|
126130
|
-
}
|
|
126131
|
-
}
|
|
126132
|
-
currentWorkspaceComment.push(comment);
|
|
126133
|
-
if (comment.followedByEmptyLine && beforeStatement) {
|
|
126134
|
-
localWorkspaceComments.push(currentWorkspaceComment);
|
|
126135
|
-
currentWorkspaceComment = [];
|
|
126136
|
-
}
|
|
126137
|
-
});
|
|
126138
|
-
comments = currentWorkspaceComment;
|
|
126139
|
-
localWorkspaceComments.forEach(comment => {
|
|
126140
|
-
const refId = getCommentRef();
|
|
126141
|
-
wsCommentRefs.push(refId);
|
|
126142
|
-
workspaceComments.push({ comment, refId });
|
|
126143
|
-
});
|
|
126144
|
-
}
|
|
126145
|
-
if (stmt) {
|
|
126146
|
-
if (wsCommentRefs.length) {
|
|
126147
|
-
if (stmt.data)
|
|
126148
|
-
stmt.data += ";" + wsCommentRefs.join(";");
|
|
126149
|
-
else
|
|
126150
|
-
stmt.data = wsCommentRefs.join(";");
|
|
126151
|
-
}
|
|
126152
|
-
if (comments && comments.length) {
|
|
126153
|
-
if (stmt.comment)
|
|
126154
|
-
stmt.comment = stmt.comment.concat(comments);
|
|
126155
|
-
else
|
|
126156
|
-
stmt.comment = comments;
|
|
126157
|
-
}
|
|
126158
|
-
}
|
|
126159
|
-
}
|
|
126160
|
-
}
|
|
126161
126172
|
}
|
|
126162
126173
|
function getTypeScriptStatementBlock(node, prefix, err) {
|
|
126163
126174
|
if (options.errorOnGreyBlocks)
|
|
@@ -126927,12 +126938,13 @@ ${output}</xml>`;
|
|
|
126927
126938
|
eventStatements.map(n => getStatementBlock(n, undefined, undefined, false, topLevel)).forEach(emitStatementNode);
|
|
126928
126939
|
if (blockStatements.length) {
|
|
126929
126940
|
// wrap statement in "on start" if top level
|
|
126930
|
-
const
|
|
126931
|
-
const stmt = getStatementBlock(
|
|
126941
|
+
const blockNode = blockStatements.shift();
|
|
126942
|
+
const stmt = getStatementBlock(blockNode, blockStatements, parent, false, topLevel);
|
|
126932
126943
|
if (emitOnStart) {
|
|
126933
126944
|
// Preserve any variable edeclarations that were never used
|
|
126934
|
-
|
|
126935
|
-
let
|
|
126945
|
+
// stmt and blockNode will not yet align if there was an auto-declared variable.
|
|
126946
|
+
let currentStmtNode = stmt;
|
|
126947
|
+
let currentBlockNode = blockNode;
|
|
126936
126948
|
autoDeclarations.forEach(([name, node]) => {
|
|
126937
126949
|
if (varUsages[name] === ReferenceType.InBlocksOnly) {
|
|
126938
126950
|
return;
|
|
@@ -126946,17 +126958,21 @@ ${output}</xml>`;
|
|
|
126946
126958
|
v = getTypeScriptStatementBlock(node, "let ");
|
|
126947
126959
|
}
|
|
126948
126960
|
else {
|
|
126949
|
-
v = getVariableSetOrChangeBlock(
|
|
126961
|
+
v = getVariableSetOrChangeBlock(blockNode, node.name, node.initializer, false, true);
|
|
126950
126962
|
}
|
|
126951
|
-
|
|
126952
|
-
|
|
126953
|
-
|
|
126963
|
+
// Auto-declared variables were not previously inserted into the stmt linked-list.
|
|
126964
|
+
// Insert auto-declared 'v' as the currentStmtNode.
|
|
126965
|
+
v.next = currentStmtNode;
|
|
126966
|
+
currentStmtNode = v;
|
|
126967
|
+
currentBlockNode = node;
|
|
126968
|
+
// Attach to currentStmtNode any associated comments
|
|
126969
|
+
getNodeComments(currentBlockNode.parent, currentStmtNode);
|
|
126954
126970
|
});
|
|
126955
|
-
if (
|
|
126956
|
-
const r = mkStmt(ts.pxtc.ON_START_TYPE,
|
|
126971
|
+
if (currentStmtNode) {
|
|
126972
|
+
const r = mkStmt(ts.pxtc.ON_START_TYPE, currentBlockNode);
|
|
126957
126973
|
r.handlers = [{
|
|
126958
126974
|
name: "HANDLER",
|
|
126959
|
-
statement:
|
|
126975
|
+
statement: currentStmtNode
|
|
126960
126976
|
}];
|
|
126961
126977
|
return r;
|
|
126962
126978
|
}
|
|
@@ -139471,6 +139487,7 @@ var ts;
|
|
|
139471
139487
|
let snippet;
|
|
139472
139488
|
if (preDefinedSnippet) {
|
|
139473
139489
|
snippet = [preDefinedSnippet];
|
|
139490
|
+
snippetPrefix = undefined;
|
|
139474
139491
|
}
|
|
139475
139492
|
else {
|
|
139476
139493
|
snippet = [fnName];
|
|
@@ -153172,6 +153189,7 @@ var pxsim;
|
|
|
153172
153189
|
}
|
|
153173
153190
|
}
|
|
153174
153191
|
createFrame(url) {
|
|
153192
|
+
var _a;
|
|
153175
153193
|
const wrapper = document.createElement("div");
|
|
153176
153194
|
wrapper.className = `simframe ui embed`;
|
|
153177
153195
|
const frame = document.createElement('iframe');
|
|
@@ -153186,6 +153204,8 @@ var pxsim;
|
|
|
153186
153204
|
frame.frameBorder = "0";
|
|
153187
153205
|
frame.dataset['runid'] = this.runId;
|
|
153188
153206
|
frame.dataset['origin'] = new URL(furl).origin || "*";
|
|
153207
|
+
if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
|
|
153208
|
+
frame.setAttribute("autofocus", "true");
|
|
153189
153209
|
wrapper.appendChild(frame);
|
|
153190
153210
|
const i = document.createElement("i");
|
|
153191
153211
|
i.className = "videoplay xicon icon";
|
|
@@ -153439,11 +153459,14 @@ var pxsim;
|
|
|
153439
153459
|
return true;
|
|
153440
153460
|
}
|
|
153441
153461
|
handleMessage(msg, source) {
|
|
153462
|
+
var _a;
|
|
153442
153463
|
switch (msg.type || '') {
|
|
153443
153464
|
case 'ready': {
|
|
153444
153465
|
const frameid = msg.frameid;
|
|
153445
153466
|
const frame = document.getElementById(frameid);
|
|
153446
153467
|
if (frame) {
|
|
153468
|
+
if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
|
|
153469
|
+
frame.focus();
|
|
153447
153470
|
this.startFrame(frame);
|
|
153448
153471
|
if (this.options.revealElement)
|
|
153449
153472
|
this.options.revealElement(frame);
|
|
@@ -157709,11 +157732,11 @@ function onlyExts(files, exts) {
|
|
|
157709
157732
|
}
|
|
157710
157733
|
function pxtFileList(pref) {
|
|
157711
157734
|
return nodeutil.allFiles(pref + "webapp/public")
|
|
157712
|
-
.concat(onlyExts(nodeutil.allFiles(pref + "built/web", 1), [".js", ".css"]))
|
|
157713
|
-
.concat(nodeutil.allFiles(pref + "built/web/fonts", 1))
|
|
157714
|
-
.concat(nodeutil.allFiles(pref + "built/web/vs", 4))
|
|
157715
|
-
.concat(nodeutil.allFiles(pref + "built/web/skillmap", 4))
|
|
157716
|
-
.concat(nodeutil.allFiles(pref + "built/web/authcode", 4));
|
|
157735
|
+
.concat(onlyExts(nodeutil.allFiles(pref + "built/web", { maxDepth: 1 }), [".js", ".css"]))
|
|
157736
|
+
.concat(nodeutil.allFiles(pref + "built/web/fonts", { maxDepth: 1 }))
|
|
157737
|
+
.concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
|
|
157738
|
+
.concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
|
|
157739
|
+
.concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }));
|
|
157717
157740
|
}
|
|
157718
157741
|
function semverCmp(a, b) {
|
|
157719
157742
|
let parse = (s) => {
|
|
@@ -158025,7 +158048,7 @@ function targetFileList() {
|
|
|
158025
158048
|
let lst = onlyExts(nodeutil.allFiles("built"), [".js", ".css", ".json", ".webmanifest"])
|
|
158026
158049
|
.concat(nodeutil.allFiles(path.join(simDir(), "public")));
|
|
158027
158050
|
if (simDir() != "sim")
|
|
158028
|
-
lst = lst.concat(nodeutil.allFiles(path.join("sim", "public"), 5, true));
|
|
158051
|
+
lst = lst.concat(nodeutil.allFiles(path.join("sim", "public"), { maxDepth: 5, allowMissing: true }));
|
|
158029
158052
|
pxt.debug(`target files (on disk): ${lst.join('\r\n ')}`);
|
|
158030
158053
|
return lst;
|
|
158031
158054
|
}
|
|
@@ -158540,7 +158563,7 @@ function forEachBundledPkgAsync(f, includeProjects = false) {
|
|
|
158540
158563
|
let prev = process.cwd();
|
|
158541
158564
|
let folders = pxt.appTarget.bundleddirs;
|
|
158542
158565
|
if (includeProjects) {
|
|
158543
|
-
let projects = nodeutil.allFiles("libs",
|
|
158566
|
+
let projects = nodeutil.allFiles("libs", { maxDepth: 1, includeDirs: true }).filter(f => /prj$/.test(f));
|
|
158544
158567
|
folders = folders.concat(projects);
|
|
158545
158568
|
}
|
|
158546
158569
|
return U.promiseMapAllSeries(folders, (dirname) => {
|
|
@@ -158705,7 +158728,7 @@ function buildEditorExtensionAsync(dirname, optionName) {
|
|
|
158705
158728
|
else
|
|
158706
158729
|
p = buildFolderAsync(dirname, true, dirname);
|
|
158707
158730
|
return p.then(() => {
|
|
158708
|
-
const prepends = nodeutil.allFiles(path.join(dirname, "prepend"), 1, true)
|
|
158731
|
+
const prepends = nodeutil.allFiles(path.join(dirname, "prepend"), { maxDepth: 1, allowMissing: true })
|
|
158709
158732
|
.filter(f => /\.js$/.test(f));
|
|
158710
158733
|
if (prepends && prepends.length) {
|
|
158711
158734
|
const editorjs = path.join("built", dirname + ".js");
|
|
@@ -159306,7 +159329,7 @@ function updateDefaultProjects(cfg) {
|
|
|
159306
159329
|
pxt.BLOCKS_PROJECT_NAME,
|
|
159307
159330
|
pxt.JAVASCRIPT_PROJECT_NAME
|
|
159308
159331
|
];
|
|
159309
|
-
nodeutil.allFiles("libs",
|
|
159332
|
+
nodeutil.allFiles("libs", { maxDepth: 1, includeDirs: true })
|
|
159310
159333
|
.filter((f) => {
|
|
159311
159334
|
return defaultProjects.indexOf(path.basename(f)) !== -1;
|
|
159312
159335
|
})
|
|
@@ -159767,7 +159790,7 @@ function renderDocs(builtPackaged, localDir) {
|
|
|
159767
159790
|
docFolders.push(...nodeutil.getBundledPackagesDocs());
|
|
159768
159791
|
docFolders.push("docs");
|
|
159769
159792
|
for (const docFolder of docFolders) {
|
|
159770
|
-
for (const f of nodeutil.allFiles(docFolder, 8)) {
|
|
159793
|
+
for (const f of nodeutil.allFiles(docFolder, { maxDepth: 8 })) {
|
|
159771
159794
|
pxt.log(`rendering ${f}`);
|
|
159772
159795
|
const pathUnderDocs = f.slice(docFolder.length + 1);
|
|
159773
159796
|
let outputFile = path.join(dst, "docs", pathUnderDocs);
|
|
@@ -161891,7 +161914,7 @@ function buildJResSpritesDirectoryAsync(dir) {
|
|
|
161891
161914
|
return [(v >> 16) & 0xff, (v >> 8) & 0xff, (v >> 0) & 0xff];
|
|
161892
161915
|
});
|
|
161893
161916
|
let ts = `namespace ${metaInfo.star.namespace} {\n`;
|
|
161894
|
-
for (let fn of nodeutil.allFiles(dir, 1)) {
|
|
161917
|
+
for (let fn of nodeutil.allFiles(dir, { maxDepth: 1 })) {
|
|
161895
161918
|
fn = fn.replace(/\\/g, "/");
|
|
161896
161919
|
let m = /(.*\/)(.*)\.png$/i.exec(fn);
|
|
161897
161920
|
if (!m)
|
|
@@ -162466,6 +162489,12 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162466
162489
|
const docsRoot = nodeutil.targetDir;
|
|
162467
162490
|
const docsTemplate = server.expandDocFileTemplate("docs.html");
|
|
162468
162491
|
pxt.log(`checking docs`);
|
|
162492
|
+
const ignoredFoldersKey = ".checkdocs-ignore";
|
|
162493
|
+
const ignoredFolders = nodeutil.allFiles("docs", { includeHiddenFiles: true })
|
|
162494
|
+
.filter(el => el.endsWith(ignoredFoldersKey))
|
|
162495
|
+
.map(el => path.dirname(path.join(el.substring(4))) + path.sep);
|
|
162496
|
+
if (ignoredFolders.length)
|
|
162497
|
+
pxt.log(`Ignoring folders [${ignoredFolders.join(", ")}]`);
|
|
162469
162498
|
const noTOCs = [];
|
|
162470
162499
|
const todo = [];
|
|
162471
162500
|
let urls = {};
|
|
@@ -162474,12 +162503,12 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162474
162503
|
// only check each snippet once.
|
|
162475
162504
|
const existingSnippets = {};
|
|
162476
162505
|
let snippets = [];
|
|
162477
|
-
const maxFileSize = checkFileSize(nodeutil.allFiles("docs", 10, true, true, ".ignorelargefiles"));
|
|
162506
|
+
const maxFileSize = checkFileSize(nodeutil.allFiles("docs", { maxDepth: 10, allowMissing: true, includeDirs: true, ignoredFileMarker: ".ignorelargefiles" }));
|
|
162478
162507
|
if (!pxt.appTarget.ignoreDocsErrors
|
|
162479
162508
|
&& maxFileSize > (pxt.appTarget.cloud.maxFileSize || (5000000)))
|
|
162480
162509
|
U.userError(`files too big in docs folder`);
|
|
162481
162510
|
// scan and fix image links
|
|
162482
|
-
nodeutil.allFiles("docs")
|
|
162511
|
+
nodeutil.allFiles("docs", { ignoredFileMarker: ignoredFoldersKey })
|
|
162483
162512
|
.filter(f => /\.md/.test(f))
|
|
162484
162513
|
.forEach(f => {
|
|
162485
162514
|
let md = fs.readFileSync(f, { encoding: "utf8" });
|
|
@@ -162534,6 +162563,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162534
162563
|
urls[url] = isResource
|
|
162535
162564
|
? nodeutil.fileExistsSync(path.join(docsRoot, "docs", url))
|
|
162536
162565
|
: nodeutil.resolveMd(docsRoot, url);
|
|
162566
|
+
const pathedUrl = path.join(url);
|
|
162567
|
+
if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
|
|
162568
|
+
return;
|
|
162537
162569
|
if (!isResource && urls[url])
|
|
162538
162570
|
todo.push(url);
|
|
162539
162571
|
}
|
|
@@ -162551,7 +162583,8 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162551
162583
|
entry.subitems.forEach(checkTOCEntry);
|
|
162552
162584
|
}
|
|
162553
162585
|
// check over TOCs
|
|
162554
|
-
nodeutil.allFiles("docs", 5
|
|
162586
|
+
nodeutil.allFiles("docs", { maxDepth: 5, ignoredFileMarker: ignoredFoldersKey })
|
|
162587
|
+
.filter(f => /SUMMARY\.md$/.test(f))
|
|
162555
162588
|
.forEach(summaryFile => {
|
|
162556
162589
|
const summaryPath = path.join(path.dirname(summaryFile), 'SUMMARY').replace(/^docs[\/\\]/, '');
|
|
162557
162590
|
pxt.log(`looking for ${summaryPath}`);
|
|
@@ -162589,7 +162622,8 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162589
162622
|
if (targetDirs) {
|
|
162590
162623
|
targetDirs.forEach(dir => {
|
|
162591
162624
|
pxt.log(`looking for markdown files in ${dir}`);
|
|
162592
|
-
nodeutil.allFiles(path.join("docs", dir), 3
|
|
162625
|
+
nodeutil.allFiles(path.join("docs", dir), { maxDepth: 3, ignoredFileMarker: ".checkdocs-ignore" })
|
|
162626
|
+
.filter(f => mdRegex.test(f))
|
|
162593
162627
|
.forEach(md => {
|
|
162594
162628
|
pushUrl(md.slice(5).replace(mdRegex, ""), true);
|
|
162595
162629
|
});
|
|
@@ -162666,6 +162700,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162666
162700
|
card.otherActions.forEach(a => { if (a.url)
|
|
162667
162701
|
urls.push(a.url); });
|
|
162668
162702
|
for (let url of urls) {
|
|
162703
|
+
const pathedUrl = path.join(url);
|
|
162704
|
+
if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
|
|
162705
|
+
return;
|
|
162669
162706
|
const tutorialMd = nodeutil.resolveMd(docsRoot, url);
|
|
162670
162707
|
if (!tutorialMd) {
|
|
162671
162708
|
pxt.log(`unable to resolve ${url}`);
|
|
@@ -162715,6 +162752,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162715
162752
|
card.otherActions.forEach(a => { if (a.url)
|
|
162716
162753
|
urls.push(a.url); });
|
|
162717
162754
|
for (let url of urls) {
|
|
162755
|
+
const pathedUrl = path.join(url);
|
|
162756
|
+
if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
|
|
162757
|
+
return;
|
|
162718
162758
|
const exMd = nodeutil.resolveMd(docsRoot, url);
|
|
162719
162759
|
if (!exMd) {
|
|
162720
162760
|
pxt.log(`unable to resolve ${url}`);
|
|
@@ -162764,7 +162804,7 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
|
|
|
162764
162804
|
async function upgradeCardsAsync() {
|
|
162765
162805
|
const docsRoot = nodeutil.targetDir;
|
|
162766
162806
|
// markdowns with cards
|
|
162767
|
-
const mds = nodeutil.allFiles(docsRoot, 10
|
|
162807
|
+
const mds = nodeutil.allFiles(docsRoot, { maxDepth: 10 })
|
|
162768
162808
|
.filter(fn => /\.md$/.test(fn))
|
|
162769
162809
|
.map(fn => ({ filename: fn, content: nodeutil.readText(fn) }))
|
|
162770
162810
|
.filter(f => /```codecard/.test(f.content));
|
|
@@ -162792,7 +162832,7 @@ function internalCacheUsedBlocksAsync() {
|
|
|
162792
162832
|
if (targetDirs) {
|
|
162793
162833
|
targetDirs.forEach(dir => {
|
|
162794
162834
|
pxt.log(`looking for tutorial markdown in ${dir}`);
|
|
162795
|
-
nodeutil.allFiles(path.join("docs", dir), 3).filter(f => mdRegex.test(f))
|
|
162835
|
+
nodeutil.allFiles(path.join("docs", dir), { maxDepth: 3 }).filter(f => mdRegex.test(f))
|
|
162796
162836
|
.forEach(md => {
|
|
162797
162837
|
mdPaths.push(md.slice(5).replace(mdRegex, ""));
|
|
162798
162838
|
});
|
|
@@ -162971,7 +163011,7 @@ function webstringsJson() {
|
|
|
162971
163011
|
}
|
|
162972
163012
|
function extractLocStringsAsync(output, dirs) {
|
|
162973
163013
|
let prereqs = [];
|
|
162974
|
-
dirs.forEach(dir => prereqs = prereqs.concat(nodeutil.allFiles(dir, 20)));
|
|
163014
|
+
dirs.forEach(dir => prereqs = prereqs.concat(nodeutil.allFiles(dir, { maxDepth: 20 })));
|
|
162975
163015
|
let errCnt = 0;
|
|
162976
163016
|
let translationStrings = {};
|
|
162977
163017
|
function processLf(filename) {
|