pxt-core
Version:
Microsoft MakeCode provides Blocks / JavaScript / Python tools and editors
269 lines (253 loc) • 11 kB
HTML
<html lang="en" data-manifest="" data-framework="typescript">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width,height=device-height,user-scalable=no,initial-scale=1.0,maximum-scale=1.0,minimum-scale=1.0" />
<style>
@import "/blb/semantic.css";
body {
display: flex;
flex-direction: column;
}
#logs {
width: 100%;
height: 10rem;
border: 0;
font-size: 0.6rem;
}
#logs img {
max-width:18rem;
}
#iframe {
border: 0;
flex-grow: 1;
}
.ui.buttons {
flex-wrap: wrap;
}
</style>
<script>
var projects = [
{
"text": {
"main.blocks": "<xml xmlns=\"http://www.w3.org/1999/xhtml\">\n <block type=\"pxt-on-start\" id=\",{,HjW]u:lVGcDRS_Cu|\" x=\"-247\" y=\"113\"></block>\n</xml>",
"main.ts": "\n",
"README.md": " ",
"pxt.json": "{\n \"name\": \"Untitled\",\n \"dependencies\": {\n \"core\": \"*\"\n },\n \"description\": \"\",\n \"files\": [\n \"main.blocks\",\n \"main.ts\",\n \"README.md\"\n ]\n}"
}
}];
var header = {
target: "microbit",
targetVersion: "7.0.15",
name: "controller-test-project",
meta: {},
editor: "blocksprj",
pubId: "",
pubCurrent: false,
_rev: null,
id: "762e2fa2-2129-4122-a651-bff7fd72cc95",
recentUse: Date.now(),
modificationTime: Date.now(),
cloudUserId: null,
cloudCurrent: false,
cloudVersion: null,
cloudLastSyncTime: 0,
isDeleted: false,
};
var filters = {
"namespaces": {
"events": 0,
"math": 2
},
"blocks": {
"dash_move_forward": 0,
"dash_turn": 2
},
"fns": {
"move": 0,
"turn": 2
}
}
var lastSaved;
var filter = false;
function toggleFilters() {
filter = !filter;
var logs = document.getElementById("logs");
logs.innerText += "filter: " + filter + "\n";
}
var languageRestrictions = [
"python-only",
"javascript-only",
"blocks-only",
"no-blocks",
"no-python",
"no-javascript",
""
];
var languageRestrictionIndex = 0;
var pendingMsgs = {};
var fullScreen = false;
function sendMessage(action) {
console.log('send ' + action)
var logs = document.getElementById("logs");
logs.innerText += "> " + action + "\n";
var editor = document.getElementById("iframe").contentWindow;
var msg = {
type: "pxteditor",
id: Math.random().toString(),
action: action
};
if(action == 'importproject') {
var prj = JSON.parse(JSON.stringify(projects[0]));
msg.project = prj;
msg.filters = filter ? JSON.parse(JSON.stringify(filters)) : {};
msg.response = true;
} else if (action == 'renderblocks') {
msg.response = true;
msg.ts = 'while(true){ }'
} else if (action == 'toggletrace') {
msg.intervalSpeed = 1000;
}
else if (action == 'settracestate') {
msg.enabled = true;
} else if (action == 'setsimulatorfullscreen') {
msg.enabled = fullScreen = !fullScreen;
}
else if (action == 'setlanguagerestriction') {
msg.restriction = languageRestrictions[languageRestrictionIndex];
languageRestrictionIndex = (languageRestrictionIndex + 1) % languageRestrictions.length;
}
else if (action == 'importexternalproject') {
const text = { ...projects[0].text }
const config = JSON.parse(text["pxt.json"]);
config.name = header.name;
text["pxt.json"] = JSON.stringify(config);
msg.project = {
header,
text
};
msg.response = true;
}
else if (action == 'info') {
msg.response = true;
}
if (msg.response)
pendingMsgs[msg.id] = msg;
editor.postMessage(msg, "*")
}
function receiveMessage(ev) {
var editor = document.getElementById("iframe")?.contentWindow;
// Prevents messages from other sources being logged to the console.
if (!editor || editor !== ev.source) {
return;
}
var msg = ev.data;
console.log('received...')
console.log(msg)
var logs = document.getElementById("logs");
if (msg.action === "simevent") {
logs.innerText += "< " + msg.type + " " + msg.action + " (" + msg.subtype + ")\n";
}
else {
logs.innerText += "< " + msg.type +(msg.action ? " " + msg.action : "" ) + "\n";
}
if(msg.resp)
console.log(JSON.stringify(msg.resp, null, 2))
if (msg.type == "pxthost") {
if (msg.action == "workspacesync") {
// no project
msg.projects = projects;
if (filter) msg.editor = {
"filters": JSON.parse(JSON.stringify(filters)),
"searchBar": false
}
editor.postMessage(msg, "*")
return;
} else if (msg.action == "workspacesave") {
console.log(JSON.stringify(msg.project, null, 2))
lastSaved = msg.project;
}
else if (msg.action == "importexternalproject") {
console.log(msg.resp);
}
}
if (msg.type == "pxteditor") {
var req = pendingMsgs[msg.id];
if (!req) return;
if (req.action == "renderblocks") {
var img = document.createElement("img");
img.src = msg.resp;
logs.appendChild(img)
}
}
if (msg.download) {
const blob = new Blob([msg.download], {type: "application/octet-stream"});
const a = document.createElement("a");
a.href = URL.createObjectURL(blob);
a.download = `${msg.name}.hex`;
a.click();
URL.revokeObjectURL(a.href);
}
delete pendingMsgs[msg.id];
}
window.addEventListener("message", receiveMessage, false);
function importHexFile() {
var f = document.getElementById("hexfile").files[0];
var reader = new FileReader();
reader.onload = (ev) => {
var editor = document.getElementById("iframe").contentWindow;
var s = reader.result;
editor.postMessage({
type: "importfile",
filename: f.name,
parts: [s]
}, "*")
}
reader.readAsText(f);
}
function toggleControllerMode() {
const iframe = document.querySelector("#iframe");
const src = new URL(iframe.src);
let controller = src.searchParams.get("controller");
src.searchParams.set("controller", controller === "1" ? "2" : "1");
iframe.src = src.toString();
}
</script>
</head>
<body>
<div id="buttons" class="ui buttons">
<button class="ui button" onclick="toggleControllerMode()">toggle mode</button>
<button class="ui button" onclick="sendMessage('switchblocks')">switch to blocks</button>
<button class="ui button" onclick="sendMessage('switchjavascript')">switch to javascript</button>
<button class="ui button" onclick="sendMessage('setlanguagerestriction')">restrict language</button>
<button class="ui button" onclick="sendMessage('startsimulator')">start sim</button>
<button class="ui button" onclick="sendMessage('restartsimulator')">reset sim</button>
<button class="ui button" onclick="sendMessage('stopsimulator')">stop sim</button>
<button class="ui button" onclick="sendMessage('newproject')">newproject</button>
<button class="ui button" onclick="sendMessage('importproject')">importproject</button>
<button class="ui button" onclick="sendMessage('compile')">compile</button>
<button class="ui button" onclick="toggleFilters()">filter</button>
<button class="ui button" onclick="sendMessage('toggletrace')">toggle trace</button>
<button class="ui button" onclick="sendMessage('settracestate')">trace on</button>
<button class="ui button" onclick="sendMessage('undo')">undo</button>
<button class="ui button" onclick="sendMessage('redo')">redo</button>
<button class="ui button" onclick="sendMessage('renderblocks')">renderblocks</button>
<button class="ui button" onclick="sendMessage('closeflyout')">close flyout</button>
<button class="ui button" onclick="sendMessage('setsimulatorfullscreen')">set sim full screen</button>
<button class="ui button" onclick="sendMessage('showthemepicker')">show theme picker</button>
<button class="ui button" onclick="sendMessage('togglehighcontrast')">toggle high contrast</button>
<button class="ui button" onclick="sendMessage('togglegreenscreen')">toggle green screen</button>
<button class="ui button" onclick="sendMessage('togglekeyboardcontrols')">toggle keyboard controls</button>
<button class="ui button" onclick="sendMessage('print')">print</button>
<button class="ui button" onclick="sendMessage('pair')">pair</button>
<button class="ui button" onclick="sendMessage('info')">info</button>
<button class="ui button" onclick="sendMessage('importexternalproject')">importexternalproject</button>
<br/>
<input id="hexfile" class="ui input" type="file" />
<button class="ui button" onclick="importHexFile()">import hex</button>
</div>
<pre id="logs" class="ui"></pre>
<iframe id="iframe" src="index.html?dbg=1&controller=1"></iframe>
</body>
</html>