pxt-core 7.5.4 → 7.5.5

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 (52) hide show
  1. package/built/cli.js +4 -41
  2. package/built/pxt.js +62 -80
  3. package/built/pxtblockly.js +15 -10
  4. package/built/pxtblocks.js +15 -10
  5. package/built/pxtcompiler.js +3 -0
  6. package/built/pxtlib.d.ts +5 -2
  7. package/built/pxtlib.js +55 -39
  8. package/built/target.js +1 -1
  9. package/built/web/main.js +1 -1
  10. package/built/web/pxtapp.js +1 -1
  11. package/built/web/pxtasseteditor.js +1 -1
  12. package/built/web/pxtblockly.js +2 -2
  13. package/built/web/pxtblocks.js +1 -1
  14. package/built/web/pxtcompiler.js +1 -1
  15. package/built/web/pxtembed.js +2 -2
  16. package/built/web/pxtlib.js +1 -1
  17. package/built/web/pxtworker.js +1 -1
  18. package/built/web/react-common-authcode.css +196 -4
  19. package/built/web/react-common-skillmap.css +1 -1
  20. package/built/web/rtlreact-common-skillmap.css +1 -1
  21. package/built/web/rtlsemantic.css +1 -1
  22. package/built/web/semantic.css +1 -1
  23. package/built/web/skillmap/css/{main.e0620cee.chunk.css → main.73b22966.chunk.css} +1 -1
  24. package/built/web/skillmap/js/{2.f7cdfd75.chunk.js → 2.3e47a285.chunk.js} +2 -2
  25. package/built/web/skillmap/js/main.2485091f.chunk.js +1 -0
  26. package/docfiles/apptracking.html +1 -1
  27. package/docfiles/tracking.html +1 -1
  28. package/localtypings/projectheader.d.ts +6 -0
  29. package/package.json +1 -1
  30. package/react-common/components/controls/Button.tsx +4 -1
  31. package/react-common/components/controls/EditorToggle.tsx +83 -39
  32. package/react-common/components/controls/FocusList.tsx +120 -0
  33. package/react-common/components/controls/Input.tsx +4 -4
  34. package/react-common/components/controls/Link.tsx +36 -0
  35. package/react-common/components/controls/MenuBar.tsx +5 -95
  36. package/react-common/components/controls/MenuDropdown.tsx +4 -1
  37. package/react-common/components/controls/Textarea.tsx +103 -0
  38. package/react-common/components/share/GifInfo.tsx +63 -0
  39. package/react-common/components/share/GifRecorder.tsx +97 -0
  40. package/react-common/components/share/Share.tsx +49 -0
  41. package/react-common/components/share/ShareInfo.tsx +186 -0
  42. package/react-common/components/share/SocialButton.tsx +53 -0
  43. package/react-common/styles/controls/EditorToggle.less +38 -0
  44. package/react-common/styles/controls/Modal.less +7 -5
  45. package/react-common/styles/controls/Textarea.less +81 -0
  46. package/react-common/styles/react-common-variables.less +12 -0
  47. package/react-common/styles/react-common.less +2 -0
  48. package/react-common/styles/share/share.less +116 -0
  49. package/theme/image-editor/imageEditor.less +1 -0
  50. package/webapp/public/run.html +32 -5
  51. package/webapp/public/skillmap.html +2 -2
  52. package/built/web/skillmap/js/main.f6866fc6.chunk.js +0 -1
@@ -0,0 +1,186 @@
1
+ import * as React from "react";
2
+ import { Button } from "../controls/Button";
3
+ import { EditorToggle } from "../controls/EditorToggle";
4
+ import { Input } from "../controls/Input";
5
+ import { Textarea } from "../controls/Textarea";
6
+
7
+ import { ShareData } from "./Share";
8
+ import { GifInfo } from "./GifInfo";
9
+ import { SocialButton } from "./SocialButton";
10
+
11
+ export interface ShareInfoProps {
12
+ projectName: string;
13
+ description?: string;
14
+ screenshotUri?: string;
15
+
16
+ screenshotAsync?: () => Promise<string>;
17
+ gifRecordAsync?: () => Promise<void>;
18
+ gifRenderAsync?: () => Promise<string | void>;
19
+ gifAddFrame?: (dataUri: ImageData, delay?: number) => boolean;
20
+ publishAsync: (name: string, screenshotUri?: string) => Promise<ShareData>;
21
+ registerSimulatorMsgHandler?: (handler: (msg: any) => void) => void;
22
+ unregisterSimulatorMsgHandler?: () => void;
23
+ }
24
+
25
+ export const ShareInfo = (props: ShareInfoProps) => {
26
+ const { projectName, description, screenshotUri, screenshotAsync, gifRecordAsync, gifRenderAsync, gifAddFrame,
27
+ publishAsync, registerSimulatorMsgHandler, unregisterSimulatorMsgHandler } = props;
28
+ const [ name, setName ] = React.useState(projectName);
29
+ const [ thumbnailUri, setThumbnailUri ] = React.useState(screenshotUri);
30
+ const [ shareState, setShareState ] = React.useState<"share" | "gifrecord" | "publish">("share");
31
+ const [ shareData, setShareData ] = React.useState<ShareData>();
32
+ const [ embedState, setEmbedState ] = React.useState<"none" | "code" | "editor" | "simulator">("none");
33
+ const [ showQRCode, setShowQRCode ] = React.useState(false);
34
+
35
+ const showSimulator = !!screenshotAsync || !!gifRecordAsync;
36
+
37
+ React.useEffect(() => {
38
+ setThumbnailUri(screenshotUri)
39
+ }, [screenshotUri])
40
+
41
+ const exitGifRecord = () => {
42
+ setShareState("share");
43
+ }
44
+
45
+ const applyGifChange = (uri: string) => {
46
+ setThumbnailUri(uri);
47
+ exitGifRecord();
48
+ }
49
+
50
+ const handlePublishClick = async () => {
51
+ let publishedShareData = await publishAsync(name, thumbnailUri);
52
+ setShareData(publishedShareData);
53
+ if (!publishedShareData?.error) setShareState("publish");
54
+ }
55
+
56
+ const handleCopyClick = () => {
57
+ navigator.clipboard.writeText(shareData.url);
58
+ }
59
+
60
+ const handleEmbedClick = () => {
61
+ if (embedState === "none") {
62
+ setShowQRCode(false);
63
+ setEmbedState("code");
64
+ } else {
65
+ setEmbedState("none");
66
+ }
67
+ }
68
+
69
+ const handleQRCodeClick = () => {
70
+ pxt.tickEvent('share.qrtoggle');
71
+ if (!showQRCode) {
72
+ setEmbedState("none");
73
+ setShowQRCode(true);
74
+ } else {
75
+ setShowQRCode(false);
76
+ }
77
+ }
78
+
79
+
80
+ const embedOptions = [{
81
+ name: "code",
82
+ label: lf("Code"),
83
+ title: lf("Code"),
84
+ focusable: true,
85
+ onClick: () => setEmbedState("code")
86
+ },
87
+ {
88
+ name: "editor",
89
+ label: lf("Editor"),
90
+ title: lf("Editor"),
91
+ focusable: true,
92
+ onClick: () => setEmbedState("editor")
93
+ },
94
+ {
95
+ name: "simulator",
96
+ label: lf("Simulator"),
97
+ title: lf("Simulator"),
98
+ focusable: true,
99
+ onClick: () => setEmbedState("simulator")
100
+ }];
101
+
102
+ return <>
103
+ <div className="project-share-info">
104
+ {(shareState === "share" || shareState === "publish") && <>
105
+ {showSimulator && <h2>{lf("About your project")}</h2>}
106
+ <Input label={lf("Project Name")}
107
+ initialValue={name}
108
+ placeholder={lf("Name your project")}
109
+ readOnly={shareState === "publish"}
110
+ onChange={setName} />
111
+ <Textarea label={lf("Description")}
112
+ initialValue={description}
113
+ placeholder={lf("Tell others about your game")}
114
+ readOnly={shareState === "publish"}
115
+ rows={5} />
116
+ {shareState === "share" && <>
117
+ {showSimulator && <div className="project-share-thumbnail">
118
+ {thumbnailUri
119
+ ? <img src={thumbnailUri} />
120
+ : <div className="project-thumbnail-placeholder" />
121
+ }
122
+ <Button title={lf("Update project thumbnail")}
123
+ label={lf("Update project thumbnail")}
124
+ onClick={() => setShareState("gifrecord")} />
125
+ </div>}
126
+ <div>{lf("By publishing you agree that you are allowed to share this game.")}</div>
127
+ {shareData?.error && <div className="project-share-error">
128
+ {(shareData.error.statusCode === 413
129
+ && pxt.appTarget?.cloud?.cloudProviders?.github)
130
+ ? lf("Oops! Your project is too big. You can create a GitHub repository to share it.")
131
+ : lf("Oops! There was an error. Please ensure you are connected to the Internet and try again.")}
132
+ </div>}
133
+ <Button className="primary"
134
+ title={lf("Publish to share")}
135
+ label={lf("Publish to share")}
136
+ onClick={handlePublishClick} />
137
+ </>}
138
+ {shareState === "publish" && <div className="project-share-actions">
139
+ <Button className="teal"
140
+ title={lf("Copy link")}
141
+ label={lf("Copy link")}
142
+ leftIcon="fas fa-link"
143
+ onClick={handleCopyClick} />
144
+ <Button className="share-button"
145
+ title={lf("Show QR code")}
146
+ leftIcon="fas fa-qrcode"
147
+ onClick={handleQRCodeClick} />
148
+ <Button className="share-button"
149
+ title={lf("Show embed code")}
150
+ leftIcon="fas fa-code"
151
+ onClick={handleEmbedClick} />
152
+ <SocialButton className="share-button"
153
+ url={shareData?.url}
154
+ type='facebook'
155
+ heading={lf("Share on Facebook")} />
156
+ <SocialButton className="share-button"
157
+ url={shareData?.url}
158
+ type='twitter'
159
+ heading={lf("Share on Twitter")} />
160
+ </div>}
161
+ {embedState !== "none" && <div className="project-embed">
162
+ <EditorToggle id="project-embed-toggle"
163
+ className="slim tablet-compact"
164
+ items={embedOptions}
165
+ selected={embedOptions.findIndex(i => i.name === embedState)} />
166
+ <Textarea readOnly={true}
167
+ rows={5}
168
+ initialValue={shareData?.embed[embedState]} />
169
+ </div>}
170
+ {showQRCode && <div className="project-qrcode">
171
+ <img src={shareData?.qr} />
172
+ </div>}
173
+ </>}
174
+ {shareState === "gifrecord" && <GifInfo
175
+ initialUri={thumbnailUri}
176
+ onApply={applyGifChange}
177
+ onCancel={exitGifRecord}
178
+ screenshotAsync={screenshotAsync}
179
+ gifRecordAsync={gifRecordAsync}
180
+ gifRenderAsync={gifRenderAsync}
181
+ gifAddFrame={gifAddFrame}
182
+ registerSimulatorMsgHandler={registerSimulatorMsgHandler}
183
+ unregisterSimulatorMsgHandler={unregisterSimulatorMsgHandler} />}
184
+ </div>
185
+ </>
186
+ }
@@ -0,0 +1,53 @@
1
+ import * as React from "react";
2
+ import { Button } from "../controls/Button";
3
+
4
+ interface SocialButtonProps {
5
+ className?: string;
6
+ url?: string;
7
+ type?: "facebook" | "twitter" | "discourse";
8
+ heading?: string;
9
+ }
10
+
11
+ export const SocialButton = (props: SocialButtonProps) => {
12
+ const { className, url, type, heading } = props;
13
+
14
+ const handleClick = () => {
15
+ const socialOptions = pxt.appTarget.appTheme.socialOptions;
16
+ let socialUrl = '';
17
+ switch (type) {
18
+ case "facebook": {
19
+ socialUrl = `https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(url)}`;
20
+ break;
21
+ }
22
+ case "twitter": {
23
+ let twitterText = lf("Check out what I made!");
24
+ if (socialOptions.twitterHandle && socialOptions.orgTwitterHandle) {
25
+ twitterText = lf("Check out what I made with @{0} and @{1}!", socialOptions.twitterHandle, socialOptions.orgTwitterHandle);
26
+ } else if (socialOptions.twitterHandle) {
27
+ twitterText = lf("Check out what I made with @{0}!", socialOptions.twitterHandle);
28
+ } else if (socialOptions.orgTwitterHandle) {
29
+ twitterText = lf("Check out what I made with @{0}!", socialOptions.orgTwitterHandle);
30
+ }
31
+ socialUrl = `https://twitter.com/intent/tweet?url=${encodeURIComponent(url)}` +
32
+ `&text=${encodeURIComponent(twitterText)}` +
33
+ (socialOptions.hashtags ? `&hashtags=${encodeURIComponent(socialOptions.hashtags)}` : '') +
34
+ (socialOptions.related ? `&related=${encodeURIComponent(socialOptions.related)}` : '');
35
+ break;
36
+ }
37
+ case "discourse": {
38
+ // https://meta.discourse.org/t/compose-a-new-pre-filled-topic-via-url/28074
39
+ socialUrl = `${socialOptions.discourse || "https://forum.makecode.com/"}new-topic?title=${encodeURIComponent(url)}`;
40
+ if (socialOptions.discourseCategory)
41
+ socialUrl += `&category=${encodeURIComponent(socialOptions.discourseCategory)}`;
42
+ break;
43
+ }
44
+ }
45
+ pxt.BrowserUtils.popupWindow(socialUrl, heading, 600, 600);
46
+ }
47
+
48
+ return <Button className={className}
49
+ ariaLabel={type}
50
+ title={type}
51
+ leftIcon={`icon ${type}`}
52
+ onClick={handleClick} />
53
+ }
@@ -1,3 +1,7 @@
1
+ .common-editor-toggle-outer {
2
+ position: relative;
3
+ }
4
+
1
5
  .common-editor-toggle {
2
6
  position: relative;
3
7
  border-radius: 0.2rem;
@@ -126,6 +130,40 @@
126
130
  }
127
131
  }
128
132
 
133
+ /*****************************************************
134
+ * Accessibility Menu *
135
+ ****************************************************/
136
+
137
+ .common-toggle-accessibility {
138
+ position: absolute;
139
+ z-index: 2;
140
+ width: 0px;
141
+ height: 0px;
142
+ left: 0;
143
+ background: white;
144
+
145
+ .common-button {
146
+ width: 0px;
147
+ height: 0px;
148
+ min-height: 0px;
149
+
150
+ overflow: hidden;
151
+ padding: 0;
152
+ position: absolute;
153
+ top: 0;
154
+ left: 0;
155
+ }
156
+ .common-button:focus {
157
+ width: 100%;
158
+ height: 100%;
159
+ }
160
+ }
161
+
162
+ .common-toggle-accessibility:focus-within {
163
+ width: 100%;
164
+ height: 100%;
165
+ }
166
+
129
167
 
130
168
  /*****************************************************
131
169
  * Tablet View *
@@ -1,3 +1,5 @@
1
+
2
+
1
3
  .common-modal-container {
2
4
  position: fixed;
3
5
  display: flex;
@@ -7,12 +9,12 @@
7
9
  left: 0;
8
10
  right: 0;
9
11
  bottom: 0;
10
- background-color: var(--modal-overlay-color);
12
+ background-color: @modalOverlayColor;
11
13
  z-index: @modalDimmerZIndex;
12
14
  }
13
15
 
14
16
  .common-modal-container.fullscreen {
15
- z-index: var(--fullscreen-modal-zindex)
17
+ z-index: @modalFullscreenZIndex;
16
18
  }
17
19
 
18
20
  .common-modal {
@@ -44,7 +46,7 @@
44
46
  }
45
47
 
46
48
  .common-modal-body {
47
- background-color: @modalBodyBackgroundColor;
49
+ background-color: @pageBackground;
48
50
  min-height: 4rem;
49
51
  padding: 1.25rem 1.5rem;
50
52
  }
@@ -77,7 +79,7 @@
77
79
  }
78
80
 
79
81
  .fullscreen > .common-modal > .common-modal-header {
80
- background-color: var(--primary-color);
82
+ background-color: @primaryColor;
81
83
  color: white;
82
84
  margin-bottom: 0;
83
85
 
@@ -99,7 +101,7 @@
99
101
 
100
102
  .fullscreen > .common-modal > .common-modal-body {
101
103
  flex-grow: 1;
102
- background-color: var(--body-background-color);
104
+ background-color: @homeScreenBackground;
103
105
  padding: 1rem;
104
106
  max-height: unset;
105
107
  }
@@ -0,0 +1,81 @@
1
+ /****************************************************
2
+ * Textarea *
3
+ ****************************************************/
4
+
5
+ .common-textarea-group {
6
+ position: relative;
7
+ display: flex;
8
+ align-items: stretch;
9
+ border-radius: 2px;
10
+ border: 1px solid @textareaBorderColor;
11
+ background: @textareaBackgroundColor;
12
+ }
13
+
14
+ .common-textarea-group:focus::after,
15
+ .common-textarea-group:focus-within::after {
16
+ content: "";
17
+ position: absolute;
18
+ inset: -1px;
19
+ border: 2px solid @textareaBorderColorFocus;
20
+ border-radius: 2px;
21
+ pointer-events: none;
22
+ }
23
+
24
+ .common-textarea {
25
+ width: 100%;
26
+ min-width: 0;
27
+ padding: 0.5rem;
28
+ color: @textareaTextColor;
29
+ border: none;
30
+ outline: 0;
31
+ background: none transparent;
32
+ text-overflow: ellipsis;
33
+ resize: none;
34
+
35
+ &.resize-both { resize: both; }
36
+ &.resize-horizontal { resize: horizontal; }
37
+ &.resize-vertical { resize: vertical; }
38
+ }
39
+
40
+
41
+ /****************************************************
42
+ * Textarea Label *
43
+ ****************************************************/
44
+
45
+ .common-textarea-label {
46
+ display: block;
47
+ font-size: 14px;
48
+ font-weight: 600;
49
+ padding: 0.3rem 0;
50
+ overflow-wrap: break-word;
51
+ }
52
+
53
+ /****************************************************
54
+ * Disabled Textarea *
55
+ ****************************************************/
56
+
57
+ .common-textarea-wrapper.disabled {
58
+ .common-textarea-group {
59
+ cursor: default;
60
+ border: 1px solid @textareaBackgroundColorDisabled;
61
+ background: @textareaBackgroundColorDisabled;
62
+ }
63
+ }
64
+
65
+ /****************************************************
66
+ * High Contrast *
67
+ ****************************************************/
68
+
69
+ .high-contrast {
70
+ .common-textarea {
71
+ color: @highContrastTextColor;
72
+ border-color: @highContrastTextColor;
73
+ background-color: @highContrastBackgroundColor;
74
+ }
75
+
76
+ .common-textarea-group:focus::after,
77
+ .common-textarea-group:focus-within::after {
78
+ border-color: @highContrastHighlightColor;
79
+ }
80
+
81
+ }
@@ -45,7 +45,9 @@
45
45
  @modalHeaderBackgroundColor: @modalBodyBackgroundColor;
46
46
  @modalFooterBackgroundColor: #f9fafb;
47
47
  @modalSeparatorBorder: 1px solid rgba(34, 36, 38, .15);
48
+ @modalOverlayColor: rgba(0, 0, 0, 0.5);
48
49
  @modalDimmerZIndex: 1000;
50
+ @modalFullscreenZIndex: @modalDimmerZIndex;
49
51
 
50
52
 
51
53
  /****************************************************
@@ -74,6 +76,16 @@
74
76
  @inputButtonColor: rgb(0, 120, 212);
75
77
  @inputButtonColorHover: rgb(16, 110, 190);
76
78
 
79
+ /****************************************************
80
+ * Textarea *
81
+ ****************************************************/
82
+
83
+ @textareaTextColor: @commonTextColor;
84
+ @textareaBorderColor: @commonBorderColor;
85
+ @textareaBorderColorFocus: rgb(0, 120, 212);
86
+ @textareaBackgroundColor: #ffffff;
87
+ @textareaBackgroundColorDisabled: @commonBackgroundDisabledColor;
88
+
77
89
  /****************************************************
78
90
  * EditorToggle *
79
91
  ****************************************************/
@@ -1,4 +1,5 @@
1
1
  @import "profile/profile.less";
2
+ @import "share/share.less";
2
3
  @import "controls/Button.less";
3
4
  @import "controls/Checkbox.less";
4
5
  @import "controls/EditorToggle.less";
@@ -7,6 +8,7 @@
7
8
  @import "controls/MenuDropdown.less";
8
9
  @import "controls/Modal.less";
9
10
  @import "controls/Spinner.less";
11
+ @import "controls/Textarea.less";
10
12
  @import "./react-common-variables.less";
11
13
 
12
14
  @import "fontawesome-free/less/solid.less";
@@ -0,0 +1,116 @@
1
+ .sharedialog.fullscreen.common-modal-container > .common-modal > .common-modal-body {
2
+ padding: 0;
3
+ }
4
+
5
+ .project-share {
6
+ display: flex;
7
+ height: 100%;
8
+ }
9
+
10
+ .project-share-simulator {
11
+ flex: 1;
12
+ height: 100%;
13
+ background-color: @simulatorBackground;
14
+
15
+ #shareLoanedSimulator {
16
+ position: relative;
17
+ top: 50%;
18
+ transform: translateY(-50%);
19
+ }
20
+
21
+ .simframe {
22
+ padding-bottom: 56.25%!important;
23
+ }
24
+ }
25
+
26
+ .project-share-info {
27
+ display: flex;
28
+ flex-direction: column;
29
+ justify-content: center;
30
+ flex: 1;
31
+
32
+ > div {
33
+ margin-bottom: 1rem;
34
+ flex-shrink: 0;
35
+ }
36
+ }
37
+
38
+ .project-share-thumbnail {
39
+ display: flex;
40
+ flex-direction: column;
41
+
42
+ .project-thumbnail-placeholder,
43
+ img {
44
+ margin: 0.3rem 0;
45
+ width: 15rem;
46
+ height: 11.25rem;
47
+ background-color: rgba(0, 0, 0, 0.05);
48
+ }
49
+ }
50
+
51
+ .fullscreen {
52
+ .project-share > div {
53
+ padding: 2rem;
54
+ }
55
+
56
+ .project-share-info {
57
+ flex: unset;
58
+ width: 28rem;
59
+ }
60
+ }
61
+
62
+ /////////////////////////////////////////
63
+ // Embed //
64
+ /////////////////////////////////////////
65
+
66
+ .project-share-actions {
67
+ display: flex;
68
+
69
+ .share-button {
70
+ width: 3rem;
71
+ padding: 1rem 0.75rem;
72
+
73
+ i {
74
+ margin: 0;
75
+ }
76
+ }
77
+ }
78
+
79
+
80
+ /////////////////////////////////////////
81
+ // Gif Recorder //
82
+ /////////////////////////////////////////
83
+
84
+ .gif-recorder {
85
+ position: absolute;
86
+ display: flex;
87
+ flex-direction: column;
88
+ align-items: center;
89
+
90
+ bottom: 0;
91
+ left: calc(~'(100vw - 25rem)/2');
92
+ padding: 1rem;
93
+ transform: translateX(-50%);
94
+ background: @white;
95
+ border: @teal;
96
+ border-radius: 0.2rem;
97
+ font-family: @segoeUIFont;
98
+ }
99
+
100
+ .gif-recorder-label,
101
+ .thumbnail-label {
102
+ margin-bottom: 0.5rem;
103
+ font-family: @segoeUIFont;
104
+ }
105
+
106
+ .gif-recorder-actions {
107
+ display: flex;
108
+ }
109
+
110
+ .thumbnail-image,
111
+ .thumbnail-placeholder {
112
+ display: flex;
113
+ background-color: rgba(0, 0, 0, 0.05);
114
+ width: 24.5rem;
115
+ height: 18.375rem;
116
+ }
@@ -108,6 +108,7 @@
108
108
  display: flex;
109
109
  justify-content: center;
110
110
  align-items: center;
111
+ position: relative;
111
112
  }
112
113
 
113
114
  .image-editor-header-right {
@@ -114,6 +114,7 @@
114
114
  var deps = /deps(?:[:=])([^&?]+)/i.exec(window.location.href);
115
115
  var prebuiltSimJs = /prebuilt(?:[:=])1/i.test(window.location.href);
116
116
  var single = !!/single(?:[:=])1/i.test(window.location.href);
117
+ var server = !!/server(?:[:=])1/i.test(window.location.href);
117
118
 
118
119
  var codeFromSrc = /code(?:[:=])([^&?]+)/i.exec(window.location.href);
119
120
  var codeFromData = undefined;
@@ -129,7 +130,7 @@
129
130
  }
130
131
  var code = codeFromData || (codeFromSrc ? codeFromSrc[1] : undefined);
131
132
 
132
- if (!id && !code && !debugSim) {
133
+ if (!id && !code && !debugSim && !server) {
133
134
  console.error("missing id or code");
134
135
  loading.textContent = 'Oops, wrong arguments...';
135
136
  return;
@@ -159,10 +160,35 @@
159
160
  initAppCache();
160
161
 
161
162
  window.addEventListener('message', msg => {
162
- if (typeof window !== 'undefined' && window.parent !== window
163
- && msg.data && msg.data.type == "messagepacket") {
164
- // propagate message packets to parent frames
165
- window.parent.postMessage(msg.data, "*");
163
+ var data = msg.data;
164
+ if (typeof window !== 'undefined' && window.parent !== window && data) {
165
+ if (data.type == "messagepacket") {
166
+ // propagate message packets to parent frames
167
+ window.parent.postMessage(msg.data, "*");
168
+ }
169
+ else if (server && data.type === "simulateproject") {
170
+ var files = typeof data.project === "string" ? JSON.parse(data.project) : data.project;
171
+ ksRunnerReady(() => {
172
+ const deps = JSON.parse(files["pxt.json"]).dependencies
173
+ prebuiltCodePromise.then(builtSimJs => {
174
+ var options = {
175
+ code: files["main.ts"],
176
+ assets: JSON.stringify(files),
177
+ dependencies: Object.keys(deps).map(v => v + "=" + deps[v]),
178
+ highContrast: highContrast,
179
+ light: light,
180
+ fullScreen: fullScreen,
181
+ builtJsInfo: builtSimJs,
182
+ single: single
183
+ };
184
+ console.log('simulating project')
185
+ pxt.runner.simulateAsync(sims, options).then(function() {
186
+ console.log('simulator started for project...')
187
+ $(loading).remove();
188
+ })
189
+ });
190
+ })
191
+ }
166
192
  }
167
193
  });
168
194
 
@@ -183,6 +209,7 @@
183
209
  var theme = pxt.appTarget.appTheme;
184
210
  document.title = theme.title;
185
211
  if (footer) pxt.runner.initFooter(document.getElementById('footer'), id);
212
+ if (server) return;
186
213
  if (hex) {
187
214
  console.log('compiling script to hex')
188
215
  pxt.runner.generateHexFileAsync(options).then(function(hex) {
@@ -7,7 +7,7 @@
7
7
  <link rel="stylesheet" data-rtl="/blb/rtlsemantic.css" href="/blb/semantic.css">
8
8
  <link rel="stylesheet" href="/blb/icons.css">
9
9
  <link rel="stylesheet" href="/blb/react-common-skillmap.css">
10
- <link href="/blb/skillmap/css/main.e0620cee.chunk.css" rel="stylesheet"></head>
10
+ <link href="/blb/skillmap/css/main.73b22966.chunk.css" rel="stylesheet"></head>
11
11
  <body>
12
12
  <noscript>You need to enable JavaScript to run this app.</noscript>
13
13
 
@@ -28,5 +28,5 @@
28
28
  <!-- end usabilla live embed code -->
29
29
 
30
30
  <!-- @include thin-footer.html -->
31
- <script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this.webpackJsonpskillsmap=this.webpackJsonpskillsmap||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/blb/skillmap/js/2.f7cdfd75.chunk.js"></script><script src="/blb/skillmap/js/main.f6866fc6.chunk.js"></script></body>
31
+ <script>!function(e){function r(r){for(var n,l,i=r[0],a=r[1],p=r[2],c=0,s=[];c<i.length;c++)l=i[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in a)Object.prototype.hasOwnProperty.call(a,n)&&(e[n]=a[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,p||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var a=t[i];0!==o[a]&&(n=!1)}n&&(u.splice(r--,1),e=l(l.s=t[0]))}return e}var n={},o={1:0},u=[];function l(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,l),t.l=!0,t.exports}l.m=e,l.c=n,l.d=function(e,r,t){l.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,r){if(1&r&&(e=l(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(l.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)l.d(t,n,function(r){return e[r]}.bind(null,n));return t},l.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(r,"a",r),r},l.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},l.p="/";var i=this.webpackJsonpskillsmap=this.webpackJsonpskillsmap||[],a=i.push.bind(i);i.push=r,i=i.slice();for(var p=0;p<i.length;p++)r(i[p]);var f=a;t()}([])</script><script src="/blb/skillmap/js/2.3e47a285.chunk.js"></script><script src="/blb/skillmap/js/main.2485091f.chunk.js"></script></body>
32
32
  </html>