pxt-core 7.4.11 → 7.4.15

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.
Files changed (69) hide show
  1. package/built/cli.js +117 -83
  2. package/built/nodeutil.d.ts +1 -1
  3. package/built/nodeutil.js +2 -2
  4. package/built/pxt.js +119 -84
  5. package/built/pxtblockly.js +153 -60
  6. package/built/pxtblocks.d.ts +8 -0
  7. package/built/pxtblocks.js +96 -60
  8. package/built/pxtlib.js +2 -1
  9. package/built/target.js +1 -1
  10. package/built/web/blockly.css +1 -1
  11. package/built/web/main.js +1 -1
  12. package/built/web/pxtapp.js +1 -1
  13. package/built/web/pxtasseteditor.js +1 -1
  14. package/built/web/pxtblockly.js +53 -1
  15. package/built/web/pxtblocks.js +1 -1
  16. package/built/web/pxtembed.js +53 -1
  17. package/built/web/pxtlib.js +1 -1
  18. package/built/web/pxtworker.js +1 -1
  19. package/built/web/react-common-skillmap.css +13 -0
  20. package/built/web/rtlblockly.css +1 -1
  21. package/built/web/rtlreact-common-skillmap.css +13 -0
  22. package/built/web/rtlsemantic.css +14 -2
  23. package/built/web/semantic.css +14 -2
  24. package/built/web/skillmap/css/main.b2b69d60.chunk.css +1 -0
  25. package/built/web/skillmap/js/2.fce3190c.chunk.js +2 -0
  26. package/built/web/skillmap/js/main.9d64b2d7.chunk.js +1 -0
  27. package/docfiles/tracking.html +1 -1
  28. package/localtypings/pxtarget.d.ts +1 -0
  29. package/localtypings/pxtblockly.d.ts +37 -0
  30. package/package.json +8 -4
  31. package/react-common/components/Notification.tsx +82 -0
  32. package/react-common/components/controls/Button.tsx +63 -0
  33. package/react-common/components/controls/Checkbox.tsx +47 -0
  34. package/react-common/components/controls/Input.tsx +117 -0
  35. package/react-common/components/controls/List.tsx +28 -0
  36. package/react-common/components/controls/Modal.tsx +143 -0
  37. package/react-common/components/profile/Badge.tsx +33 -0
  38. package/react-common/components/profile/BadgeInfo.tsx +74 -0
  39. package/react-common/components/profile/BadgeList.tsx +67 -0
  40. package/react-common/components/profile/Profile.tsx +42 -0
  41. package/react-common/components/profile/UserNotification.tsx +32 -0
  42. package/react-common/components/profile/UserPane.tsx +68 -0
  43. package/react-common/components/types.d.ts +29 -0
  44. package/react-common/components/util.tsx +61 -0
  45. package/react-common/styles/controls/Button.less +174 -0
  46. package/react-common/styles/controls/Checkbox.less +13 -0
  47. package/react-common/styles/controls/Icon.less +11 -0
  48. package/react-common/styles/controls/Input.less +95 -0
  49. package/react-common/styles/controls/List.less +12 -0
  50. package/react-common/styles/controls/Modal.less +105 -0
  51. package/react-common/styles/controls/Spinner.less +24 -0
  52. package/{built/web/react-common.css → react-common/styles/profile/profile.less} +13 -0
  53. package/react-common/styles/react-common-skillmap-core.less +10 -0
  54. package/react-common/styles/react-common-skillmap.less +12 -0
  55. package/react-common/styles/react-common-variables.less +47 -0
  56. package/react-common/styles/react-common.less +12 -0
  57. package/react-common/tsconfig.json +36 -0
  58. package/theme/asset-editor.less +13 -29
  59. package/theme/blockly-core.less +16 -0
  60. package/theme/common-components.less +7 -0
  61. package/theme/common.less +1 -1
  62. package/theme/highcontrast.less +4 -0
  63. package/theme/pxt.less +2 -0
  64. package/theme/tutorial-sidebar.less +64 -6
  65. package/webapp/public/blockly/plugins.js +57 -0
  66. package/webapp/public/skillmap.html +3 -3
  67. package/built/web/skillmap/css/main.96b1b3f1.chunk.css +0 -1
  68. package/built/web/skillmap/js/2.7dd06a3a.chunk.js +0 -2
  69. package/built/web/skillmap/js/main.55881627.chunk.js +0 -1
package/built/cli.js CHANGED
@@ -1728,94 +1728,121 @@ ${gcards.map(gcard => `[${gcard.name}](${gcard.url})`).join(',\n')}
1728
1728
  nodeutil.writeFileSync("built/target-strings.json", nodeutil.stringify(targetStringsSorted));
1729
1729
  pxt.log(`target-strings.json built`);
1730
1730
  }
1731
- function buildSemanticUIAsync(parsed) {
1732
- const forceRedbuild = parsed && parsed.flags["force"] || false;
1733
- if (!fs.existsSync(path.join("theme", "style.less")) ||
1734
- !fs.existsSync(path.join("theme", "theme.config")))
1735
- return Promise.resolve();
1736
- let dirty = !fs.existsSync("built/web/semantic.css");
1737
- if (!dirty) {
1738
- const csstime = fs.statSync("built/web/semantic.css").mtime;
1739
- dirty = nodeutil.allFiles("theme")
1740
- .map(f => fs.statSync(f))
1741
- .some(stat => stat.mtime > csstime);
1742
- }
1743
- if (!dirty && !forceRedbuild)
1744
- return Promise.resolve();
1745
- let pkg = readJson("package.json");
1731
+ async function buildSemanticUIAsync(parsed) {
1732
+ if (!fs.existsSync(path.join("theme", "style.less")) || !fs.existsSync(path.join("theme", "theme.config"))) {
1733
+ return;
1734
+ }
1735
+ const pkg = readJson("package.json");
1736
+ const isPxtCore = pkg["name"] === "pxt-core";
1746
1737
  nodeutil.mkdirP(path.join("built", "web"));
1747
1738
  const lessPath = require.resolve('less');
1748
1739
  const lessCPath = path.join(path.dirname(lessPath), '/bin/lessc');
1749
- return nodeutil.spawnAsync({
1740
+ const lessIncludePaths = [
1741
+ "node_modules/semantic-ui-less",
1742
+ "node_modules/pxt-core/theme",
1743
+ "theme/foo/bar",
1744
+ "theme",
1745
+ "node_modules/pxt-core/react-common/styles",
1746
+ "react-common/styles",
1747
+ "node_modules/@fortawesome",
1748
+ "node_modules/pxt-core/node_modules/@fortawesome" // for locally linked dev environment
1749
+ ].join(":");
1750
+ // Build semantic css
1751
+ await nodeutil.spawnAsync({
1750
1752
  cmd: "node",
1751
- args: [lessCPath, "theme/style.less", "built/web/semantic.css", "--include-path=node_modules/semantic-ui-less:node_modules/pxt-core/theme:theme/foo/bar"]
1752
- }).then(() => {
1753
- function linkFont(font, semCss) {
1754
- const fontFile = fs.readFileSync("node_modules/semantic-ui-less/themes/default/assets/fonts/" + font + ".woff");
1755
- const url = "url(data:application/font-woff;charset=utf-8;base64,"
1756
- + fontFile.toString("base64") + ") format('woff')";
1757
- const r = new RegExp(`src:.*url\\("fonts\/${font}\\.woff.*`, "g");
1758
- semCss = semCss.replace('src: url("fonts/' + font + '.eot");', "")
1759
- .replace(r, "src: " + url + ";");
1760
- return semCss;
1761
- }
1762
- let semCss = fs.readFileSync('built/web/semantic.css', "utf8");
1763
- semCss = linkFont("icons", semCss);
1764
- semCss = linkFont("outline-icons", semCss);
1765
- semCss = linkFont("brand-icons", semCss);
1766
- return semCss;
1767
- }).then((semCss) => {
1768
- // Append icons.css to semantic.css (custom pxt icons)
1769
- const iconsFile = (pkg["name"] == "pxt-core") ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
1770
- const iconsCss = fs.readFileSync(iconsFile, "utf-8");
1771
- const reactCommonFile = (pkg["name"] == "pxt-core") ? 'built/web/react-common.css' : 'node_modules/pxt-core/built/web/react-common.css';
1772
- const reactCommonCss = fs.readFileSync(reactCommonFile, "utf-8");
1773
- semCss = semCss + "\n" + iconsCss + "\n" + reactCommonCss;
1774
- nodeutil.writeFileSync('built/web/semantic.css', semCss);
1775
- }).then(() => {
1776
- // generate blockly css
1777
- if (!fs.existsSync(path.join("theme", "blockly.less")))
1778
- return Promise.resolve();
1779
- return nodeutil.spawnAsync({
1753
+ args: [
1754
+ lessCPath,
1755
+ "theme/style.less",
1756
+ "built/web/semantic.css",
1757
+ "--include-path=" + lessIncludePaths
1758
+ ]
1759
+ });
1760
+ // Inline all of our icon fonts
1761
+ let semCss = await readFileAsync('built/web/semantic.css', "utf8");
1762
+ semCss = await linkFontAsync("icons", semCss);
1763
+ semCss = await linkFontAsync("outline-icons", semCss);
1764
+ semCss = await linkFontAsync("brand-icons", semCss);
1765
+ // Append icons.css to semantic.css (custom pxt icons)
1766
+ const iconsFile = isPxtCore ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
1767
+ const iconsCss = await readFileAsync(iconsFile, "utf8");
1768
+ semCss = semCss + "\n" + iconsCss;
1769
+ nodeutil.writeFileSync('built/web/semantic.css', semCss);
1770
+ // Generate blockly css
1771
+ if (fs.existsSync(path.join("theme", "blockly.less"))) {
1772
+ await nodeutil.spawnAsync({
1780
1773
  cmd: "node",
1781
- args: [lessCPath, "theme/blockly.less", "built/web/blockly.css", "--include-path=node_modules/semantic-ui-less:node_modules/pxt-core/theme:theme/foo/bar"]
1782
- });
1783
- }).then(() => {
1784
- // run postcss with autoprefixer and rtlcss
1785
- pxt.debug("running postcss");
1786
- const postcss = require('postcss');
1787
- const browserList = [
1788
- "Chrome >= 38",
1789
- "Firefox >= 31",
1790
- "Edge >= 12",
1791
- "ie >= 11",
1792
- "Safari >= 9",
1793
- "Opera >= 21",
1794
- "iOS >= 9",
1795
- "ChromeAndroid >= 59",
1796
- "FirefoxAndroid >= 55"
1797
- ];
1798
- const cssnano = require('cssnano')({
1799
- zindex: false,
1800
- autoprefixer: { browsers: browserList, add: true }
1801
- });
1802
- const rtlcss = require('rtlcss');
1803
- const files = ['semantic.css', 'blockly.css'];
1804
- files.forEach(cssFile => {
1805
- fs.readFile(`built/web/${cssFile}`, "utf8", (err, css) => {
1806
- postcss([cssnano])
1807
- .process(css, { from: `built/web/${cssFile}`, to: `built/web/${cssFile}` }).then((result) => {
1808
- fs.writeFile(`built/web/${cssFile}`, result.css, (err2) => {
1809
- // process rtl css
1810
- postcss([rtlcss])
1811
- .process(result.css, { from: `built/web/${cssFile}`, to: `built/web/rtl${cssFile}` }).then((result2) => {
1812
- nodeutil.writeFileSync(`built/web/rtl${cssFile}`, result2.css, { encoding: "utf8" });
1813
- });
1814
- });
1815
- });
1816
- });
1774
+ args: [
1775
+ lessCPath,
1776
+ "theme/blockly.less",
1777
+ "built/web/blockly.css",
1778
+ "--include-path=" + lessIncludePaths
1779
+ ]
1817
1780
  });
1781
+ }
1782
+ // Generate react-common css for skillmap
1783
+ const skillmapFile = isPxtCore ? "react-common/styles/react-common-skillmap-core.less" :
1784
+ "node_modules/pxt-core/react-common/styles/react-common-skillmap.less";
1785
+ await nodeutil.spawnAsync({
1786
+ cmd: "node",
1787
+ args: [
1788
+ lessCPath,
1789
+ skillmapFile,
1790
+ "built/web/react-common-skillmap.css",
1791
+ "--include-path=" + lessIncludePaths
1792
+ ]
1818
1793
  });
1794
+ let fontAwesomeSource = "node_modules/@fortawesome/fontawesome-free/webfonts/";
1795
+ if (!fs.existsSync(fontAwesomeSource)) {
1796
+ fontAwesomeSource = "node_modules/pxt-core/" + fontAwesomeSource;
1797
+ }
1798
+ let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
1799
+ skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
1800
+ skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
1801
+ await writeFileAsync(`built/web/react-common-skillmap.css`, skillmapCss, "utf8");
1802
+ // Run postcss with autoprefixer and rtlcss
1803
+ pxt.debug("running postcss");
1804
+ const postcss = require('postcss');
1805
+ const browserList = [
1806
+ "Chrome >= 38",
1807
+ "Firefox >= 31",
1808
+ "Edge >= 12",
1809
+ "ie >= 11",
1810
+ "Safari >= 9",
1811
+ "Opera >= 21",
1812
+ "iOS >= 9",
1813
+ "ChromeAndroid >= 59",
1814
+ "FirefoxAndroid >= 55"
1815
+ ];
1816
+ const cssnano = require("cssnano")({
1817
+ zindex: false,
1818
+ autoprefixer: { browsers: browserList, add: true }
1819
+ });
1820
+ const rtlcss = require("rtlcss");
1821
+ const files = ["semantic.css", "blockly.css", "react-common-skillmap.css"];
1822
+ for (const cssFile of files) {
1823
+ const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
1824
+ const processed = await postcss([cssnano])
1825
+ .process(css, { from: `built/web/${cssFile}`, to: `built/web/${cssFile}` });
1826
+ await writeFileAsync(`built/web/${cssFile}`, processed.css);
1827
+ const processedRtl = await postcss([rtlcss])
1828
+ .process(processed.css, { from: `built/web/${cssFile}`, to: `built/web/rtl${cssFile}` });
1829
+ await writeFileAsync(`built/web/rtl${cssFile}`, processedRtl.css, "utf8");
1830
+ }
1831
+ if (!isPxtCore) {
1832
+ // This is just to support the local skillmap serve for development
1833
+ nodeutil.cp("built/web/react-common-skillmap.css", "node_modules/pxt-core/skillmap/public/blb");
1834
+ nodeutil.cp("built/web/semantic.css", "node_modules/pxt-core/skillmap/public/blb");
1835
+ }
1836
+ }
1837
+ async function linkFontAsync(font, semCss, sourceDir = "node_modules/semantic-ui-less/themes/default/assets/fonts/", refDir = "fonts\\/") {
1838
+ const fontFile = await readFileAsync(sourceDir + font + ".woff");
1839
+ const url = "url(data:application/font-woff;charset=utf-8;base64,"
1840
+ + fontFile.toString("base64") + ") format('woff')";
1841
+ const r = new RegExp(`src:.*url\\((?:"|')${refDir + font}\\.woff.*`, "g");
1842
+ semCss = semCss.replace('src: url("' + refDir + font + '.eot");', "")
1843
+ .replace('src: url(' + refDir + font + '.eot);', "")
1844
+ .replace(r, "src: " + url + ";");
1845
+ return semCss;
1819
1846
  }
1820
1847
  function buildWebStringsAsync() {
1821
1848
  if (pxt.appTarget.id != "core")
@@ -1826,6 +1853,7 @@ function buildWebStringsAsync() {
1826
1853
  function buildSkillMapAsync(parsed) {
1827
1854
  // local serve
1828
1855
  const skillmapRoot = "node_modules/pxt-core/skillmap";
1856
+ const reactScriptsConfigRoot = `${skillmapRoot}/node_modules/react-scripts/config`;
1829
1857
  const docsPath = parsed.flags["docs"];
1830
1858
  return rimrafAsync(`${skillmapRoot}/public/blb`, {})
1831
1859
  .then(() => rimrafAsync(`${skillmapRoot}/build/assets`, {}))
@@ -1838,9 +1866,15 @@ function buildSkillMapAsync(parsed) {
1838
1866
  nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
1839
1867
  nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
1840
1868
  nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
1841
- nodeutil.cp("node_modules/pxt-core/built/web/react-common.css", `${skillmapRoot}/public/blb`);
1869
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common-skillmap.css", `${skillmapRoot}/public/blb`);
1842
1870
  // copy 'assets' over from docs/static
1843
1871
  nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
1872
+ // copy default react-scripts webpack config into a webpack.config.base file if necessary
1873
+ if (!fs.existsSync(`${reactScriptsConfigRoot}/webpack.config.base.js`)) {
1874
+ nodeutil.cp(`${reactScriptsConfigRoot}/webpack.config.js`, reactScriptsConfigRoot, "webpack.config.base.js");
1875
+ }
1876
+ // wrap the config in our webpack.config.override for build customization
1877
+ nodeutil.cp(`${skillmapRoot}/webpack.config.override.js`, reactScriptsConfigRoot, "webpack.config.js");
1844
1878
  if (docsPath) {
1845
1879
  // copy docs over from specified path
1846
1880
  nodeutil.cpR(`docs/${docsPath}`, `${skillmapRoot}/public/docs/${docsPath}`);
@@ -6196,7 +6230,7 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
6196
6230
  help: "build required css files",
6197
6231
  flags: {
6198
6232
  force: {
6199
- description: "force re-compile of less files"
6233
+ description: "deprecated; now on by default"
6200
6234
  }
6201
6235
  }
6202
6236
  }, buildSemanticUIAsync);
@@ -42,7 +42,7 @@ export declare function getPxtTarget(): pxt.TargetBundle;
42
42
  export declare function pathToPtr(path: string): string;
43
43
  export declare function mkdirP(thePath: string): void;
44
44
  export declare function cpR(src: string, dst: string, maxDepth?: number): void;
45
- export declare function cp(srcFile: string, destDirectory: string): void;
45
+ export declare function cp(srcFile: string, destDirectory: string, destName?: string): void;
46
46
  export declare function allFiles(top: string, maxDepth?: number, allowMissing?: boolean, includeDirs?: boolean, ignoredFileMarker?: string): string[];
47
47
  export declare function existsDirSync(name: string): boolean;
48
48
  export declare function writeFileSync(p: string, data: any, options?: {
package/built/nodeutil.js CHANGED
@@ -328,9 +328,9 @@ function cpR(src, dst, maxDepth = 8) {
328
328
  }
329
329
  }
330
330
  exports.cpR = cpR;
331
- function cp(srcFile, destDirectory) {
331
+ function cp(srcFile, destDirectory, destName) {
332
332
  mkdirP(destDirectory);
333
- let dest = path.resolve(destDirectory, path.basename(srcFile));
333
+ let dest = path.resolve(destDirectory, destName || path.basename(srcFile));
334
334
  let buf = fs.readFileSync(path.resolve(srcFile));
335
335
  fs.writeFileSync(dest, buf);
336
336
  }
package/built/pxt.js CHANGED
@@ -98123,7 +98123,7 @@ var pxt;
98123
98123
  return { success: false, res: undefined };
98124
98124
  }
98125
98125
  // Apply queued patches to the remote state in isolation and develop a final diff to send to the backend
98126
- const remotePrefs = pxt.U.deepCopy(getResult.resp);
98126
+ const remotePrefs = pxt.U.deepCopy(getResult.resp) || auth.DEFAULT_USER_PREFERENCES();
98127
98127
  const patchQueue = this.patchQueue;
98128
98128
  this.patchQueue = []; // Reset the queue
98129
98129
  patchQueue.forEach(patch => {
@@ -99899,6 +99899,7 @@ var ts;
99899
99899
  "bn": { englishName: "Bengali", localizedName: "বাংলা" },
99900
99900
  "ca": { englishName: "Catalan", localizedName: "Català" },
99901
99901
  "cs": { englishName: "Czech", localizedName: "Čeština" },
99902
+ "cy": { englishName: "Welsh", localizedName: "Cymraeg" },
99902
99903
  "da": { englishName: "Danish", localizedName: "Dansk" },
99903
99904
  "de": { englishName: "German", localizedName: "Deutsch" },
99904
99905
  "el": { englishName: "Greek", localizedName: "Ελληνικά" },
@@ -157678,94 +157679,121 @@ ${gcards.map(gcard => `[${gcard.name}](${gcard.url})`).join(',\n')}
157678
157679
  nodeutil.writeFileSync("built/target-strings.json", nodeutil.stringify(targetStringsSorted));
157679
157680
  pxt.log(`target-strings.json built`);
157680
157681
  }
157681
- function buildSemanticUIAsync(parsed) {
157682
- const forceRedbuild = parsed && parsed.flags["force"] || false;
157683
- if (!fs.existsSync(path.join("theme", "style.less")) ||
157684
- !fs.existsSync(path.join("theme", "theme.config")))
157685
- return Promise.resolve();
157686
- let dirty = !fs.existsSync("built/web/semantic.css");
157687
- if (!dirty) {
157688
- const csstime = fs.statSync("built/web/semantic.css").mtime;
157689
- dirty = nodeutil.allFiles("theme")
157690
- .map(f => fs.statSync(f))
157691
- .some(stat => stat.mtime > csstime);
157692
- }
157693
- if (!dirty && !forceRedbuild)
157694
- return Promise.resolve();
157695
- let pkg = readJson("package.json");
157682
+ async function buildSemanticUIAsync(parsed) {
157683
+ if (!fs.existsSync(path.join("theme", "style.less")) || !fs.existsSync(path.join("theme", "theme.config"))) {
157684
+ return;
157685
+ }
157686
+ const pkg = readJson("package.json");
157687
+ const isPxtCore = pkg["name"] === "pxt-core";
157696
157688
  nodeutil.mkdirP(path.join("built", "web"));
157697
157689
  const lessPath = require.resolve('less');
157698
157690
  const lessCPath = path.join(path.dirname(lessPath), '/bin/lessc');
157699
- return nodeutil.spawnAsync({
157691
+ const lessIncludePaths = [
157692
+ "node_modules/semantic-ui-less",
157693
+ "node_modules/pxt-core/theme",
157694
+ "theme/foo/bar",
157695
+ "theme",
157696
+ "node_modules/pxt-core/react-common/styles",
157697
+ "react-common/styles",
157698
+ "node_modules/@fortawesome",
157699
+ "node_modules/pxt-core/node_modules/@fortawesome" // for locally linked dev environment
157700
+ ].join(":");
157701
+ // Build semantic css
157702
+ await nodeutil.spawnAsync({
157700
157703
  cmd: "node",
157701
- args: [lessCPath, "theme/style.less", "built/web/semantic.css", "--include-path=node_modules/semantic-ui-less:node_modules/pxt-core/theme:theme/foo/bar"]
157702
- }).then(() => {
157703
- function linkFont(font, semCss) {
157704
- const fontFile = fs.readFileSync("node_modules/semantic-ui-less/themes/default/assets/fonts/" + font + ".woff");
157705
- const url = "url(data:application/font-woff;charset=utf-8;base64,"
157706
- + fontFile.toString("base64") + ") format('woff')";
157707
- const r = new RegExp(`src:.*url\\("fonts\/${font}\\.woff.*`, "g");
157708
- semCss = semCss.replace('src: url("fonts/' + font + '.eot");', "")
157709
- .replace(r, "src: " + url + ";");
157710
- return semCss;
157711
- }
157712
- let semCss = fs.readFileSync('built/web/semantic.css', "utf8");
157713
- semCss = linkFont("icons", semCss);
157714
- semCss = linkFont("outline-icons", semCss);
157715
- semCss = linkFont("brand-icons", semCss);
157716
- return semCss;
157717
- }).then((semCss) => {
157718
- // Append icons.css to semantic.css (custom pxt icons)
157719
- const iconsFile = (pkg["name"] == "pxt-core") ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
157720
- const iconsCss = fs.readFileSync(iconsFile, "utf-8");
157721
- const reactCommonFile = (pkg["name"] == "pxt-core") ? 'built/web/react-common.css' : 'node_modules/pxt-core/built/web/react-common.css';
157722
- const reactCommonCss = fs.readFileSync(reactCommonFile, "utf-8");
157723
- semCss = semCss + "\n" + iconsCss + "\n" + reactCommonCss;
157724
- nodeutil.writeFileSync('built/web/semantic.css', semCss);
157725
- }).then(() => {
157726
- // generate blockly css
157727
- if (!fs.existsSync(path.join("theme", "blockly.less")))
157728
- return Promise.resolve();
157729
- return nodeutil.spawnAsync({
157704
+ args: [
157705
+ lessCPath,
157706
+ "theme/style.less",
157707
+ "built/web/semantic.css",
157708
+ "--include-path=" + lessIncludePaths
157709
+ ]
157710
+ });
157711
+ // Inline all of our icon fonts
157712
+ let semCss = await readFileAsync('built/web/semantic.css', "utf8");
157713
+ semCss = await linkFontAsync("icons", semCss);
157714
+ semCss = await linkFontAsync("outline-icons", semCss);
157715
+ semCss = await linkFontAsync("brand-icons", semCss);
157716
+ // Append icons.css to semantic.css (custom pxt icons)
157717
+ const iconsFile = isPxtCore ? 'built/web/icons.css' : 'node_modules/pxt-core/built/web/icons.css';
157718
+ const iconsCss = await readFileAsync(iconsFile, "utf8");
157719
+ semCss = semCss + "\n" + iconsCss;
157720
+ nodeutil.writeFileSync('built/web/semantic.css', semCss);
157721
+ // Generate blockly css
157722
+ if (fs.existsSync(path.join("theme", "blockly.less"))) {
157723
+ await nodeutil.spawnAsync({
157730
157724
  cmd: "node",
157731
- args: [lessCPath, "theme/blockly.less", "built/web/blockly.css", "--include-path=node_modules/semantic-ui-less:node_modules/pxt-core/theme:theme/foo/bar"]
157732
- });
157733
- }).then(() => {
157734
- // run postcss with autoprefixer and rtlcss
157735
- pxt.debug("running postcss");
157736
- const postcss = require('postcss');
157737
- const browserList = [
157738
- "Chrome >= 38",
157739
- "Firefox >= 31",
157740
- "Edge >= 12",
157741
- "ie >= 11",
157742
- "Safari >= 9",
157743
- "Opera >= 21",
157744
- "iOS >= 9",
157745
- "ChromeAndroid >= 59",
157746
- "FirefoxAndroid >= 55"
157747
- ];
157748
- const cssnano = require('cssnano')({
157749
- zindex: false,
157750
- autoprefixer: { browsers: browserList, add: true }
157751
- });
157752
- const rtlcss = require('rtlcss');
157753
- const files = ['semantic.css', 'blockly.css'];
157754
- files.forEach(cssFile => {
157755
- fs.readFile(`built/web/${cssFile}`, "utf8", (err, css) => {
157756
- postcss([cssnano])
157757
- .process(css, { from: `built/web/${cssFile}`, to: `built/web/${cssFile}` }).then((result) => {
157758
- fs.writeFile(`built/web/${cssFile}`, result.css, (err2) => {
157759
- // process rtl css
157760
- postcss([rtlcss])
157761
- .process(result.css, { from: `built/web/${cssFile}`, to: `built/web/rtl${cssFile}` }).then((result2) => {
157762
- nodeutil.writeFileSync(`built/web/rtl${cssFile}`, result2.css, { encoding: "utf8" });
157763
- });
157764
- });
157765
- });
157766
- });
157725
+ args: [
157726
+ lessCPath,
157727
+ "theme/blockly.less",
157728
+ "built/web/blockly.css",
157729
+ "--include-path=" + lessIncludePaths
157730
+ ]
157767
157731
  });
157732
+ }
157733
+ // Generate react-common css for skillmap
157734
+ const skillmapFile = isPxtCore ? "react-common/styles/react-common-skillmap-core.less" :
157735
+ "node_modules/pxt-core/react-common/styles/react-common-skillmap.less";
157736
+ await nodeutil.spawnAsync({
157737
+ cmd: "node",
157738
+ args: [
157739
+ lessCPath,
157740
+ skillmapFile,
157741
+ "built/web/react-common-skillmap.css",
157742
+ "--include-path=" + lessIncludePaths
157743
+ ]
157744
+ });
157745
+ let fontAwesomeSource = "node_modules/@fortawesome/fontawesome-free/webfonts/";
157746
+ if (!fs.existsSync(fontAwesomeSource)) {
157747
+ fontAwesomeSource = "node_modules/pxt-core/" + fontAwesomeSource;
157748
+ }
157749
+ let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
157750
+ skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
157751
+ skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
157752
+ await writeFileAsync(`built/web/react-common-skillmap.css`, skillmapCss, "utf8");
157753
+ // Run postcss with autoprefixer and rtlcss
157754
+ pxt.debug("running postcss");
157755
+ const postcss = require('postcss');
157756
+ const browserList = [
157757
+ "Chrome >= 38",
157758
+ "Firefox >= 31",
157759
+ "Edge >= 12",
157760
+ "ie >= 11",
157761
+ "Safari >= 9",
157762
+ "Opera >= 21",
157763
+ "iOS >= 9",
157764
+ "ChromeAndroid >= 59",
157765
+ "FirefoxAndroid >= 55"
157766
+ ];
157767
+ const cssnano = require("cssnano")({
157768
+ zindex: false,
157769
+ autoprefixer: { browsers: browserList, add: true }
157768
157770
  });
157771
+ const rtlcss = require("rtlcss");
157772
+ const files = ["semantic.css", "blockly.css", "react-common-skillmap.css"];
157773
+ for (const cssFile of files) {
157774
+ const css = await readFileAsync(`built/web/${cssFile}`, "utf8");
157775
+ const processed = await postcss([cssnano])
157776
+ .process(css, { from: `built/web/${cssFile}`, to: `built/web/${cssFile}` });
157777
+ await writeFileAsync(`built/web/${cssFile}`, processed.css);
157778
+ const processedRtl = await postcss([rtlcss])
157779
+ .process(processed.css, { from: `built/web/${cssFile}`, to: `built/web/rtl${cssFile}` });
157780
+ await writeFileAsync(`built/web/rtl${cssFile}`, processedRtl.css, "utf8");
157781
+ }
157782
+ if (!isPxtCore) {
157783
+ // This is just to support the local skillmap serve for development
157784
+ nodeutil.cp("built/web/react-common-skillmap.css", "node_modules/pxt-core/skillmap/public/blb");
157785
+ nodeutil.cp("built/web/semantic.css", "node_modules/pxt-core/skillmap/public/blb");
157786
+ }
157787
+ }
157788
+ async function linkFontAsync(font, semCss, sourceDir = "node_modules/semantic-ui-less/themes/default/assets/fonts/", refDir = "fonts\\/") {
157789
+ const fontFile = await readFileAsync(sourceDir + font + ".woff");
157790
+ const url = "url(data:application/font-woff;charset=utf-8;base64,"
157791
+ + fontFile.toString("base64") + ") format('woff')";
157792
+ const r = new RegExp(`src:.*url\\((?:"|')${refDir + font}\\.woff.*`, "g");
157793
+ semCss = semCss.replace('src: url("' + refDir + font + '.eot");', "")
157794
+ .replace('src: url(' + refDir + font + '.eot);', "")
157795
+ .replace(r, "src: " + url + ";");
157796
+ return semCss;
157769
157797
  }
157770
157798
  function buildWebStringsAsync() {
157771
157799
  if (pxt.appTarget.id != "core")
@@ -157776,6 +157804,7 @@ function buildWebStringsAsync() {
157776
157804
  function buildSkillMapAsync(parsed) {
157777
157805
  // local serve
157778
157806
  const skillmapRoot = "node_modules/pxt-core/skillmap";
157807
+ const reactScriptsConfigRoot = `${skillmapRoot}/node_modules/react-scripts/config`;
157779
157808
  const docsPath = parsed.flags["docs"];
157780
157809
  return rimrafAsync(`${skillmapRoot}/public/blb`, {})
157781
157810
  .then(() => rimrafAsync(`${skillmapRoot}/build/assets`, {}))
@@ -157788,9 +157817,15 @@ function buildSkillMapAsync(parsed) {
157788
157817
  nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${skillmapRoot}/public/blb`);
157789
157818
  nodeutil.cp("built/web/semantic.css", `${skillmapRoot}/public/blb`);
157790
157819
  nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${skillmapRoot}/public/blb`);
157791
- nodeutil.cp("node_modules/pxt-core/built/web/react-common.css", `${skillmapRoot}/public/blb`);
157820
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common-skillmap.css", `${skillmapRoot}/public/blb`);
157792
157821
  // copy 'assets' over from docs/static
157793
157822
  nodeutil.cpR("docs/static/skillmap/assets", `${skillmapRoot}/public/assets`);
157823
+ // copy default react-scripts webpack config into a webpack.config.base file if necessary
157824
+ if (!fs.existsSync(`${reactScriptsConfigRoot}/webpack.config.base.js`)) {
157825
+ nodeutil.cp(`${reactScriptsConfigRoot}/webpack.config.js`, reactScriptsConfigRoot, "webpack.config.base.js");
157826
+ }
157827
+ // wrap the config in our webpack.config.override for build customization
157828
+ nodeutil.cp(`${skillmapRoot}/webpack.config.override.js`, reactScriptsConfigRoot, "webpack.config.js");
157794
157829
  if (docsPath) {
157795
157830
  // copy docs over from specified path
157796
157831
  nodeutil.cpR(`docs/${docsPath}`, `${skillmapRoot}/public/docs/${docsPath}`);
@@ -162146,7 +162181,7 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
162146
162181
  help: "build required css files",
162147
162182
  flags: {
162148
162183
  force: {
162149
- description: "force re-compile of less files"
162184
+ description: "deprecated; now on by default"
162150
162185
  }
162151
162186
  }
162152
162187
  }, buildSemanticUIAsync);