pxt-core
Version:
Microsoft MakeCode provides Blocks / JavaScript / Python tools and editors
309 lines (290 loc) • 12.6 kB
HTML
<html lang="en" data-manifest="" data-framework="typescript">
<head>
<meta charset="utf-8">
<title>simulator</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<style>
/* fix for iOS; see https://github.com/PierBover/ios-iframe-fix */
#wrap {
position: fixed;
top: 0;
right:0;
bottom:0;
left: 0;
overflow-y: hidden;
-webkit-overflow-scrolling: touch;
}
html {
width: 100%;
height: 100%;
overflow: hidden;
}
body {
height: 100%;
}
div.simframe {
border: none;
margin: 0 0 0.5rem 0;
position: relative;
background: transparent;
width: 100%;
display: inline-block;
}
div.simframe > iframe {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
footer {
position: absolute;
bottom: 0;
right: 0;
left: 0;
z-index: 1;
font-size: 0.75rem;
font-family: "Lucida Console", Monaco, monospace;
color: #333;
padding: 0.5em;
margin: 0;
background: #fff;
}
footer img {
max-height: 1rem;
vertical-align: middle;
margin-left: 0.5rem;
}
footer a,
footer a:visited {
text-decoration: none;
cursor: pointer;
border: none;
color: #333;
}
a.center {
font-size: 3em;
font-family: monospace;
}
</style>
<style id="injected-style">
</style>
</head>
<body>
<div id="wrap">
<div id='loading' style='font-size: 25px; font-family:monospace; margin: 20% auto; width: 200px;'>
loading...
</div>
<div id="simulators" className="simulator">
</div>
<footer id="footer" style="display:none;">
</footer>
</div>
<script>
// This line gets patched up by the cloud
var pxtConfig = null;
</script>
<!-- @include apptrackingweb.html -->
<!-- @include apptracking.html -->
<script type="text/javascript" src="/embed.js"></script>
<script type="text/javascript">
(function () {
var loading = document.getElementById('loading');
var id = /id(?:[:=])([^&?]+)/i.exec(window.location.href);
var localToken = /local_token(?:[:=])([^&?]+)/i.exec(window.location.href);
var hex = !!/hex(?:[:=])1/i.exec(window.location.href);
var footer = !/nofooter(?:[:=])1/i.exec(window.location.href);
var debugSim = !!/debugSim(?:[:=])1/i.exec(window.location.href);
var sims = document.getElementById('simulators');
var highContrast = !!/hc(?:[:=])1/i.exec(window.location.href);
var light = !!/light(?:[:=])1/i.exec(window.location.href);
var fullScreen = !!/fullscreen(?:[:=])1/i.exec(window.location.href);
var autofocus = !!/autofocus(?:[:=])1/i.exec(window.location.href);
var deps = /deps(?:[:=])([^&?]+)/i.exec(window.location.href);
var prebuiltSimJs = /prebuilt(?:[:=])1/i.test(window.location.href);
var single = !!/single(?:[:=])1/i.test(window.location.href);
var hideSimButtons = !!/hideSimButtons(?:[:=])1/i.test(window.location.href);
var server = !!/server(?:[:=])1/i.test(window.location.href);
var mpRole = /[\&\?]mp=(server|client)/i.exec(window.location.href)?.[1]?.toLowerCase();
var codeFromSrc = /code(?:[:=])([^&?]+)/i.exec(window.location.href);
var additionalSimParams = /simParams(?:[:=])([^&?]+)/i.exec(window.location.href)?.[1];
var sendBuilt = !!/sendBuilt(?:[:=])1/i.test(window.location.href);
var loadingColor = /[\&\?]loadingColor=(#[0-9A-Fa-f]{3}|#[0-9A-Fa-f]{6}|[A-Za-z]+)\b/i.exec(window.location.href)?.[1];
var codeFromData = undefined;
var assetJsonFromData = undefined;
try {
codeFromData = window.frameElement ? window.frameElement.getAttribute('data-code') : undefined;
assetJsonFromData = window.frameElement ? window.frameElement.getAttribute('data-assets') : undefined;
} catch (e) {
/**
* Internet Explorer 11 and Microsoft Edge throw an exception when checking
* if the frame element exists when the iframe is on a different origin
*/
}
var code = codeFromData || (codeFromSrc ? codeFromSrc[1] : undefined);
if (loading && loadingColor) {
loading.style.color = loadingColor;
}
if (additionalSimParams) {
additionalSimParams = decodeURIComponent(additionalSimParams);
if (!/^[a-z0-9=\-:&]+$/i.test(additionalSimParams)) {
additionalSimParams = undefined;
}
}
if (!id && !code && !debugSim && !server) {
console.error("missing id or code");
loading.textContent = 'Oops, wrong arguments...';
return;
}
if (fullScreen) {
document.getElementById("injected-style").textContent =
"#simulators {\n"
+ " height: 100%;\n"
+ "}\n"
+ "div.simframe {\n"
+ " height: calc(100% - 1rem);\n"
+ " padding-bottom: 0 !important;\n"
+ "}\n";
}
function initAppCache() {
if (!window.applicationCache)
return;
if (window.applicationCache.status === window.applicationCache.UPDATEREADY)
window.location.reload();
window.applicationCache.addEventListener('updateready', function () {
if (window.applicationCache.status === window.applicationCache.UPDATEREADY)
window.location.reload();
});
}
initAppCache();
window.addEventListener('message', msg => {
var data = msg.data;
if (typeof window !== 'undefined' && window.parent !== window && data) {
if (data.type == "messagepacket") {
// propagate message packets to parent frames
window.parent.postMessage(msg.data, "*");
}
else if (data.type == "simulator" && data.command == "setstate") {
// propagate message packets to parent frames
window.parent.postMessage(msg.data, "*");
}
else if (mpRole && data.type === "multiplayer") {
// propagate message packets to parent frames
window.parent.postMessage(msg.data, "*");
}
else if (server && data.type === "builtjs") {
var options = {
id: id ? id[1] : undefined,
code: code ? decodeURIComponent(code) : undefined,
assets: assetJsonFromData ? decodeURIComponent(assetJsonFromData) : undefined,
highContrast: highContrast,
light: light,
fullScreen: fullScreen,
dependencies: deps ? decodeURIComponent(deps[1]).split(",") : undefined,
builtJsInfo: data,
single: single,
hideSimButtons: hideSimButtons,
autofocus: autofocus,
additionalQueryParameters: additionalSimParams
};
pxt.runner.simulateAsync(sims, options).then(function() {
$(loading).remove();
})
}
else if (server && data.type === "simulateproject") {
var files = typeof data.project === "string" ? JSON.parse(data.project) : data.project;
ksRunnerReady(() => {
const deps = JSON.parse(files["pxt.json"]).dependencies
prebuiltCodePromise.then(builtSimJs => {
var options = {
code: files["main.ts"],
assets: JSON.stringify(files),
dependencies: Object.keys(deps).map(v => v + "=" + deps[v]),
highContrast: highContrast,
light: light,
fullScreen: fullScreen,
builtJsInfo: builtSimJs,
single: single,
hideSimButtons: hideSimButtons,
autofocus: autofocus,
additionalQueryParameters: additionalSimParams
};
console.log('simulating project')
pxt.runner.simulateAsync(sims, options).then(function() {
console.log('simulator started for project...')
$(loading).remove();
})
});
})
}
}
});
var prebuiltCodePromise = Promise.resolve(undefined);
if (prebuiltSimJs) {
var versionsuff = /localhost:/.test(window.location.href) ? "" : "@versionsuff@";
var builtSimJsUrl = "/static/builtjs/" + id[1] + versionsuff + ".json"
// kick off fetch immediately, no need to wait for ksrunnerready
prebuiltCodePromise = fetch(builtSimJsUrl)
.then(resp => resp.json())
.catch(e => {
// TODO: send tick that something broke :(
console.error("Failed to get prebuilt code")
});
}
ksRunnerReady(function() {
var theme = pxt.appTarget.appTheme;
document.title = theme.title;
if (footer) pxt.runner.initFooter(document.getElementById('footer'), id);
if (server) return;
if (hex) {
console.log('compiling script to hex')
pxt.runner.generateHexFileAsync(options).then(function(hex) {
$(loading).remove();
var name = pxt.appTarget.id + '-' + ts.pxt.BINARY_HEX;
var uri = pxt.BrowserUtils.browserDownloadBinText(hex, name, { maintainObjectURL: true });
var a = document.createElement("a");
a.href = uri;
a.download = name;
a.appendChild(document.createTextNode("Right click to save to another location."))
sims.appendChild(a);
})
}
else if (!debugSim) {
prebuiltCodePromise.then(builtSimJs => {
var options = {
id: id ? id[1] : undefined,
code: code ? decodeURIComponent(code) : undefined,
assets: assetJsonFromData ? decodeURIComponent(assetJsonFromData) : undefined,
highContrast: highContrast,
light: light,
fullScreen: fullScreen,
dependencies: deps ? decodeURIComponent(deps[1]).split(",") : undefined,
builtJsInfo: builtSimJs,
single: single,
hideSimButtons: hideSimButtons,
autofocus: autofocus,
additionalQueryParameters: additionalSimParams
};
console.log('simulating script')
pxt.runner.simulateAsync(sims, options).then(function(value) {
if (sendBuilt) {
window.parent.postMessage(value, "*");
}
console.log('simulator started...')
$(loading).remove();
})
});
}
else {
$(loading).remove();
if (localToken) {
pxt.Cloud.localToken = localToken[1];
}
pxt.runner.startDebuggerAsync(sims);
}
})
})()
</script>
</body>
</html>