pxt-core 9.1.6 → 9.1.7

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/README.md CHANGED
@@ -93,6 +93,13 @@ If you are working on the CLI exclusively,
93
93
  gulp watchCli
94
94
  ```
95
95
 
96
+ If you don't need to build the suite of associated webapps (skillmap, multiplayer, etc.), you can skip them and speed up your build a bit:
97
+
98
+ ```
99
+ gulp --no-webapps
100
+ ```
101
+
102
+
96
103
  ### Icons
97
104
 
98
105
  There are a number of custom icons (to use in addition
package/built/cli.js CHANGED
@@ -307,7 +307,8 @@ function pxtFileList(pref) {
307
307
  .concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
308
308
  .concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
309
309
  .concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }))
310
- .concat(nodeutil.allFiles(pref + "built/web/multiplayer", { maxDepth: 4 }));
310
+ .concat(nodeutil.allFiles(pref + "built/web/multiplayer", { maxDepth: 4 }))
311
+ .concat(nodeutil.allFiles(pref + "built/web/kiosk", { maxDepth: 4 }));
311
312
  }
312
313
  function semverCmp(a, b) {
313
314
  let parse = (s) => {
@@ -390,7 +391,8 @@ function ciAsync() {
390
391
  .then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
391
392
  .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
392
393
  .then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"))
393
- .then(() => crowdin.execCrowdinAsync("upload", "built/multiplayer-strings.json"));
394
+ .then(() => crowdin.execCrowdinAsync("upload", "built/multiplayer-strings.json"))
395
+ .then(() => crowdin.execCrowdinAsync("upload", "built/kiosk-strings.json"));
394
396
  if (uploadApiStrings)
395
397
  p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
396
398
  if (uploadDocs || uploadApiStrings)
@@ -919,6 +921,7 @@ function uploadCoreAsync(opts) {
919
921
  "skillmapUrl": opts.localDir + "skillmap.html",
920
922
  "authcodeUrl": opts.localDir + "authcode.html",
921
923
  "multiplayerUrl": opts.localDir + "multiplayer.html",
924
+ "kioskUrl": opts.localDir + "kiosk.html",
922
925
  "isStatic": true,
923
926
  };
924
927
  const targetImageLocalPaths = targetImagePaths.map(k => `${opts.localDir}${path.join('./docs', k)}`);
@@ -968,6 +971,7 @@ function uploadCoreAsync(opts) {
968
971
  "skillmap.html",
969
972
  "authcode.html",
970
973
  "multiplayer.html",
974
+ "kiosk.html",
971
975
  ];
972
976
  // expandHtml is manually called on these files before upload
973
977
  // runs <!-- @include --> substitutions, fills in locale, etc
@@ -976,6 +980,7 @@ function uploadCoreAsync(opts) {
976
980
  "skillmap.html",
977
981
  "authcode.html",
978
982
  "multiplayer.html",
983
+ "kiosk.html",
979
984
  ];
980
985
  nodeutil.mkdirP("built/uploadrepl");
981
986
  function encodeURLs(urls) {
@@ -1780,7 +1785,7 @@ async function buildSemanticUIAsync(parsed) {
1780
1785
  appCss = await linkFontAsync("fa-regular-400", appCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
1781
1786
  await writeFileAsync(`built/web/react-common-${app}.css`, appCss, "utf8");
1782
1787
  }
1783
- // Generate react-common css for skillmap, authcode, and multiplayer
1788
+ // Generate react-common css for skillmap, authcode, and multiplayer (but not kiosk yet)
1784
1789
  await Promise.all([
1785
1790
  generateReactCommonCss("skillmap"),
1786
1791
  generateReactCommonCss("authcode"),
@@ -1805,7 +1810,13 @@ async function buildSemanticUIAsync(parsed) {
1805
1810
  autoprefixer: { browsers: browserList, add: true }
1806
1811
  });
1807
1812
  const rtlcss = require("rtlcss");
1808
- const files = ["semantic.css", "blockly.css", "react-common-skillmap.css", "react-common-authcode.css", "react-common-multiplayer.css"];
1813
+ const files = [
1814
+ "semantic.css",
1815
+ "blockly.css",
1816
+ "react-common-skillmap.css",
1817
+ "react-common-authcode.css",
1818
+ "react-common-multiplayer.css"
1819
+ ];
1809
1820
  for (const cssFile of files) {
1810
1821
  const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
1811
1822
  const processed = await postcss([cssnano])
package/built/pxt.js CHANGED
@@ -102467,11 +102467,11 @@ var pxt;
102467
102467
  }
102468
102468
  BrowserUtils.isSkillmapEditor = isSkillmapEditor;
102469
102469
  function isTabletSize() {
102470
- return (window === null || window === void 0 ? void 0 : window.innerWidth) < pxt.BREAKPOINT_TABLET;
102470
+ return (window === null || window === void 0 ? void 0 : window.innerWidth) <= pxt.BREAKPOINT_TABLET;
102471
102471
  }
102472
102472
  BrowserUtils.isTabletSize = isTabletSize;
102473
102473
  function isComputerSize() {
102474
- return (window === null || window === void 0 ? void 0 : window.innerWidth) >= pxt.BREAKPOINT_TABLET;
102474
+ return (window === null || window === void 0 ? void 0 : window.innerWidth) > pxt.BREAKPOINT_TABLET;
102475
102475
  }
102476
102476
  BrowserUtils.isComputerSize = isComputerSize;
102477
102477
  function noSharedLocalStorage() {
@@ -122704,7 +122704,7 @@ var pxt;
122704
122704
  const domainCheck = `(?:(?:https:\/\/)?(?:${domains.join('|')})\/)`;
122705
122705
  const versionRefCheck = "(?:v[0-9]+\/)";
122706
122706
  const oembedCheck = "api\/oembed\\?url=.*%2F([^&#]*)&.*";
122707
- const sharePageCheck = "([a-z0-9\\-_]+)(?:[#?&].*)?";
122707
+ const sharePageCheck = "\/?([a-z0-9\\-_]+)(?:[#?&].*)?";
122708
122708
  const scriptIdCheck = `^${domainCheck}?${versionRefCheck}?(?:(?:${oembedCheck})|(?:${sharePageCheck}))$`;
122709
122709
  const m = new RegExp(scriptIdCheck, 'i').exec(uri.trim());
122710
122710
  const scriptid = (m === null || m === void 0 ? void 0 : m[1] /** oembed res **/) || (m === null || m === void 0 ? void 0 : m[2]) /** share page res **/;
@@ -160959,7 +160959,8 @@ function pxtFileList(pref) {
160959
160959
  .concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
160960
160960
  .concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
160961
160961
  .concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }))
160962
- .concat(nodeutil.allFiles(pref + "built/web/multiplayer", { maxDepth: 4 }));
160962
+ .concat(nodeutil.allFiles(pref + "built/web/multiplayer", { maxDepth: 4 }))
160963
+ .concat(nodeutil.allFiles(pref + "built/web/kiosk", { maxDepth: 4 }));
160963
160964
  }
160964
160965
  function semverCmp(a, b) {
160965
160966
  let parse = (s) => {
@@ -161042,7 +161043,8 @@ function ciAsync() {
161042
161043
  .then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
161043
161044
  .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
161044
161045
  .then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"))
161045
- .then(() => crowdin.execCrowdinAsync("upload", "built/multiplayer-strings.json"));
161046
+ .then(() => crowdin.execCrowdinAsync("upload", "built/multiplayer-strings.json"))
161047
+ .then(() => crowdin.execCrowdinAsync("upload", "built/kiosk-strings.json"));
161046
161048
  if (uploadApiStrings)
161047
161049
  p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
161048
161050
  if (uploadDocs || uploadApiStrings)
@@ -161571,6 +161573,7 @@ function uploadCoreAsync(opts) {
161571
161573
  "skillmapUrl": opts.localDir + "skillmap.html",
161572
161574
  "authcodeUrl": opts.localDir + "authcode.html",
161573
161575
  "multiplayerUrl": opts.localDir + "multiplayer.html",
161576
+ "kioskUrl": opts.localDir + "kiosk.html",
161574
161577
  "isStatic": true,
161575
161578
  };
161576
161579
  const targetImageLocalPaths = targetImagePaths.map(k => `${opts.localDir}${path.join('./docs', k)}`);
@@ -161620,6 +161623,7 @@ function uploadCoreAsync(opts) {
161620
161623
  "skillmap.html",
161621
161624
  "authcode.html",
161622
161625
  "multiplayer.html",
161626
+ "kiosk.html",
161623
161627
  ];
161624
161628
  // expandHtml is manually called on these files before upload
161625
161629
  // runs <!-- @include --> substitutions, fills in locale, etc
@@ -161628,6 +161632,7 @@ function uploadCoreAsync(opts) {
161628
161632
  "skillmap.html",
161629
161633
  "authcode.html",
161630
161634
  "multiplayer.html",
161635
+ "kiosk.html",
161631
161636
  ];
161632
161637
  nodeutil.mkdirP("built/uploadrepl");
161633
161638
  function encodeURLs(urls) {
@@ -162432,7 +162437,7 @@ async function buildSemanticUIAsync(parsed) {
162432
162437
  appCss = await linkFontAsync("fa-regular-400", appCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
162433
162438
  await writeFileAsync(`built/web/react-common-${app}.css`, appCss, "utf8");
162434
162439
  }
162435
- // Generate react-common css for skillmap, authcode, and multiplayer
162440
+ // Generate react-common css for skillmap, authcode, and multiplayer (but not kiosk yet)
162436
162441
  await Promise.all([
162437
162442
  generateReactCommonCss("skillmap"),
162438
162443
  generateReactCommonCss("authcode"),
@@ -162457,7 +162462,13 @@ async function buildSemanticUIAsync(parsed) {
162457
162462
  autoprefixer: { browsers: browserList, add: true }
162458
162463
  });
162459
162464
  const rtlcss = require("rtlcss");
162460
- const files = ["semantic.css", "blockly.css", "react-common-skillmap.css", "react-common-authcode.css", "react-common-multiplayer.css"];
162465
+ const files = [
162466
+ "semantic.css",
162467
+ "blockly.css",
162468
+ "react-common-skillmap.css",
162469
+ "react-common-authcode.css",
162470
+ "react-common-multiplayer.css"
162471
+ ];
162461
162472
  for (const cssFile of files) {
162462
162473
  const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
162463
162474
  const processed = await postcss([cssnano])
package/built/pxtlib.d.ts CHANGED
@@ -556,6 +556,7 @@ declare namespace pxt {
556
556
  skillmapUrl?: string;
557
557
  authcodeUrl?: string;
558
558
  multiplayerUrl?: string;
559
+ kioskUrl?: string;
559
560
  isStatic?: boolean;
560
561
  verprefix?: string;
561
562
  }
package/built/pxtlib.js CHANGED
@@ -4781,11 +4781,11 @@ var pxt;
4781
4781
  }
4782
4782
  BrowserUtils.isSkillmapEditor = isSkillmapEditor;
4783
4783
  function isTabletSize() {
4784
- return (window === null || window === void 0 ? void 0 : window.innerWidth) < pxt.BREAKPOINT_TABLET;
4784
+ return (window === null || window === void 0 ? void 0 : window.innerWidth) <= pxt.BREAKPOINT_TABLET;
4785
4785
  }
4786
4786
  BrowserUtils.isTabletSize = isTabletSize;
4787
4787
  function isComputerSize() {
4788
- return (window === null || window === void 0 ? void 0 : window.innerWidth) >= pxt.BREAKPOINT_TABLET;
4788
+ return (window === null || window === void 0 ? void 0 : window.innerWidth) > pxt.BREAKPOINT_TABLET;
4789
4789
  }
4790
4790
  BrowserUtils.isComputerSize = isComputerSize;
4791
4791
  function noSharedLocalStorage() {
@@ -25018,7 +25018,7 @@ var pxt;
25018
25018
  const domainCheck = `(?:(?:https:\/\/)?(?:${domains.join('|')})\/)`;
25019
25019
  const versionRefCheck = "(?:v[0-9]+\/)";
25020
25020
  const oembedCheck = "api\/oembed\\?url=.*%2F([^&#]*)&.*";
25021
- const sharePageCheck = "([a-z0-9\\-_]+)(?:[#?&].*)?";
25021
+ const sharePageCheck = "\/?([a-z0-9\\-_]+)(?:[#?&].*)?";
25022
25022
  const scriptIdCheck = `^${domainCheck}?${versionRefCheck}?(?:(?:${oembedCheck})|(?:${sharePageCheck}))$`;
25023
25023
  const m = new RegExp(scriptIdCheck, 'i').exec(uri.trim());
25024
25024
  const scriptid = (m === null || m === void 0 ? void 0 : m[1] /** oembed res **/) || (m === null || m === void 0 ? void 0 : m[2]) /** share page res **/;
package/built/server.js CHANGED
@@ -22,6 +22,10 @@ let docsDir = "";
22
22
  let packagedDir = "";
23
23
  let localHexCacheDir = path.join("built", "hexcache");
24
24
  let serveOptions;
25
+ const webappNames = [
26
+ "kiosk"
27
+ // TODO: Add other webapp names here: "multiplayer", "skillmap", "authcode"
28
+ ];
25
29
  function setupDocfilesdirs() {
26
30
  docfilesdirs = [
27
31
  "docfiles",
@@ -775,7 +779,7 @@ function certificateTestAsync() {
775
779
  }
776
780
  // use http://localhost:3232/45912-50568-62072-42379 for testing
777
781
  function scriptPageTestAsync(id) {
778
- return Cloud.privateGetAsync(id)
782
+ return Cloud.privateGetAsync(pxt.Cloud.parseScriptId(id))
779
783
  .then((info) => {
780
784
  // if running against old cloud, infer 'thumb' field
781
785
  // can be removed after new cloud deployment
@@ -931,7 +935,8 @@ function serveAsync(options) {
931
935
  error(404, "File missing: " + filename);
932
936
  }
933
937
  };
934
- let pathname = decodeURI(url.parse(req.url).pathname);
938
+ let uri = url.parse(req.url);
939
+ let pathname = decodeURI(uri.pathname);
935
940
  const opts = querystring.parse(url.parse(req.url).query);
936
941
  const htmlParams = {};
937
942
  if (opts["lang"] || opts["forcelang"])
@@ -950,6 +955,43 @@ function serveAsync(options) {
950
955
  if (elts.some(s => s[0] == ".")) {
951
956
  return error(400, "Bad path :-(\n");
952
957
  }
958
+ // Strip leading version number
959
+ if (elts.length && /^v\d+/.test(elts[0])) {
960
+ elts.shift();
961
+ }
962
+ // Rebuild pathname without leading version number
963
+ pathname = "/" + elts.join("/");
964
+ const expandWebappHtml = (appname, html) => {
965
+ // Expand templates
966
+ html = expandHtml(html);
967
+ // Rewrite application resource references
968
+ html = html.replace(/src="(\/static\/js\/[^"]*)"/, (m, f) => `src="/${appname}${f}"`);
969
+ html = html.replace(/src="(\/static\/css\/[^"]*)"/, (m, f) => `src="/${appname}${f}"`);
970
+ return html;
971
+ };
972
+ const serveWebappFile = (webappName, webappPath) => {
973
+ const webappUri = url.parse(`http://localhost:3000/${webappPath}${uri.search || ""}`);
974
+ http.get(webappUri, r => {
975
+ let body = "";
976
+ r.on("data", (chunk) => {
977
+ body += chunk;
978
+ });
979
+ r.on("end", () => {
980
+ if (!webappPath || webappPath === "index.html") {
981
+ body = expandWebappHtml(webappName, body);
982
+ }
983
+ res.writeHead(200);
984
+ res.write(body);
985
+ res.end();
986
+ });
987
+ });
988
+ };
989
+ const webappIdx = webappNames.findIndex(s => new RegExp(`^-{0,3}${s}$`).test(elts[0] || ''));
990
+ if (webappIdx >= 0) {
991
+ const webappName = webappNames[webappIdx];
992
+ const webappPath = pathname.split("/").slice(2).join('/'); // remove /<webappName>/ from path
993
+ return serveWebappFile(webappName, webappPath);
994
+ }
953
995
  if (elts[0] == "api") {
954
996
  if (elts[1] == "streams") {
955
997
  let trg = Cloud.apiRoot + req.url.slice(5);
@@ -1063,9 +1105,10 @@ function serveAsync(options) {
1063
1105
  sendFile(path.join(publicDir, 'codeembed.html'));
1064
1106
  return;
1065
1107
  }
1066
- if (/^\/(\d\d\d\d[\d-]+)$/.test(pathname)) {
1067
- scriptPageTestAsync(pathname.slice(1))
1068
- .then(sendHtml);
1108
+ if (!!pxt.Cloud.parseScriptId(pathname)) {
1109
+ scriptPageTestAsync(pathname)
1110
+ .then(sendHtml)
1111
+ .catch(() => error(404, "Script not found"));
1069
1112
  return;
1070
1113
  }
1071
1114
  if (/^\/(pkg|package)\/.*$/.test(pathname)) {