(function () { "use strict"; const PLAYPEN_URL = "https://playground.ponylang.org"; // For convenience of development var PREFIX = location.href.indexOf("/web.html") != -1 ? PLAYPEN_URL + "/" : "/"; var samples = 2; function optionalLocalStorageGetItem(key) { try { return localStorage.getItem(key); } catch(e) { return null; } } function optionalLocalStorageSetItem(key, value) { try { window.localStorage.setItem(key, value); } catch(e) { // ignore } } function build_themes(themelist) { // Load all ace themes, sorted by their proper name. var themes = themelist.themes; themes.sort(function (a, b) { if (a.caption < b.caption) { return -1; } else if (a.caption > b.caption) { return 1; } return 0; }); var themeopt, themefrag = document.createDocumentFragment(); for (var i=0; i < themes.length; i++) { themeopt = document.createElement("option"); themeopt.setAttribute("val", themes[i].theme); themeopt.textContent = themes[i].caption; themefrag.appendChild(themeopt); } document.getElementById("themes").appendChild(themefrag); } function send(path, data, callback, button, message, result) { button.disabled = true; set_result(result, "
Connection failure" + "
Are you connected to the Internet?"); } else { set_result(result, "
Something went wrong" + "
The HTTP request produced a response with status code " + request.status + "."); } } }; request.timeout = 10000; request.ontimeout = function() { set_result(result, "
Connection timed out" + "
Are you connected to the Internet?");
};
request.send(JSON.stringify(data));
}
var PYGMENTS_TO_ACE_MAPPINGS = {
'asm': {
'c': 'ace_comment', // Comment,
'na': 'ace_support ace_function ace_directive', // Name.Attribute,
'no': 'ace_constant', // Name.Constant,
'nl': 'ace_entity ace_name ace_function', // Name.Label,
'nv': 'ace_variable ace_parameter ace_register', // Name.Variable,
'mh': 'ace_constant ace_character ace_hexadecimal', // Number.Hex,
'mi': 'ace_constant ace_character ace_decimal', // Number.Integer,
'p': 'ace_punctuation', // Punctuation,
's': 'ace_string', // String,
'sc': 'ace_string', // String.Char,
'': '', // Text,
},
'llvm-ir': {
'c': 'ace_comment', // Comment
'k': 'ace_keyword', // Keyword
'kt': 'ace_storage ace_type', // Keyword.Type
'nl': 'ace_identifier', // Name.Label
'nv': 'ace_variable', // Name.Variable
'nv-Anonymous': 'ace_support ace_variable', // Name.Variable.Anonymous
'vg': 'ace_variable ace_other', // Name.Variable.Global
'm': 'ace_constant ace_numeric', // Number
'p': 'ace_punctuation', // Punctuation
's': 'ace_string', // String
'': '', // Text
}
};
function rehighlight(pygmentized, language) {
var mappings = PYGMENTS_TO_ACE_MAPPINGS[language];
return pygmentized.replace(/([^<]*)<\/span>/g, function() {
var classes = mappings[arguments[1]];
if (classes) {
return '' + arguments[2] + '';
} else {
return arguments[2];
}
});
}
function redrawResult(result) {
// Sadly the fun letter-spacing animation can leave artefacts,
// so we want to manually trigger a redraw. It doesn’t matter
// whether it’s relative or static for now, so we’ll flip that.
result.parentNode.style.visibility = "hidden";
var _ = result.parentNode.offsetHeight; // This empty assignment is intentional
result.parentNode.style.visibility = "";
}
function evaluate(result, code, button) {
send("evaluate.json", {
code: code,
separate_output: true,
color: true,
branch: branch
}, function(object) {
var samp, pre;
set_result(result);
if (object.rustc) {
samp = document.createElement("samp");
samp.innerHTML = formatCompilerOutput(object.rustc);
pre = document.createElement("pre");
pre.className = "rustc-output " + (("program" in object) ? "rustc-warnings" : "rustc-errors");
pre.appendChild(samp);
result.appendChild(pre);
}
var div = document.createElement("p");
div.className = "message";
if (object["program"]) {
samp = document.createElement("samp");
samp.className = "output";
samp.innerHTML = formatCompilerOutput(object.program);
pre = document.createElement("pre");
pre.appendChild(samp);
result.appendChild(pre);
div.textContent = "Program ended.";
} else {
div.textContent = "Compilation failed.";
}
if (div) {
result.appendChild(div);
}
}, button, "Running…", result);
}
function compile(emit, result, code, button) {
send("compile.json", {
emit: emit,
code: code,
color: true,
highlight: true,
branch: branch
}, function(object) {
if ("error" in object) {
set_result(result, " Failed to fetch Gist" +
" Are you connected to the Internet?");
}
);
}
function getQueryParameters() {
var a = window.location.search.substr(1).split('&');
if (a === "") return {};
var b = {};
for (var i = 0; i < a.length; i++) {
var p = a[i].split('=');
if (p.length != 2) continue;
b[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
}
return b;
}
function clear_result(result) {
result.innerHTML = "";
result.parentNode.setAttribute("data-empty", "");
set_result.editor.resize();
}
function set_result(result, contents) {
result.parentNode.removeAttribute("data-empty");
if (contents === undefined) {
result.textContent = "";
} else if (typeof contents == "string") {
result.innerHTML = contents;
} else {
result.textContent = "";
result.appendChild(contents);
}
set_result.editor.resize();
}
function set_keyboard(editor, mode) {
if (mode == "Emacs") {
editor.setKeyboardHandler("ace/keyboard/emacs");
} else if (mode == "Vim") {
editor.setKeyboardHandler("ace/keyboard/vim");
if (!set_keyboard.vim_set_up) {
ace.config.loadModule("ace/keyboard/vim", function(m) {
var Vim = ace.require("ace/keyboard/vim").CodeMirror.Vim;
Vim.defineEx("write", "w", function(cm, input) {
cm.ace.execCommand("evaluate");
});
});
}
set_keyboard.vim_set_up = true;
} else {
editor.setKeyboardHandler(null);
}
}
function set_theme(editor, themelist, theme) {
var themes = document.getElementById("themes");
var themepath = null,
i = 0,
themelen = themelist.themes.length,
selected = themes.options[themes.selectedIndex];
if (selected.textContent === theme) {
themepath = selected.getAttribute("val");
} else {
for (i; i < themelen; i++) {
if (themelist.themes[i].caption == theme) {
themes.selectedIndex = i;
themepath = themelist.themes[i].theme;
break;
}
}
}
if (themepath !== null) {
editor.setTheme(themepath);
optionalLocalStorageSetItem("theme", theme);
}
}
function getRadioValue(name) {
var nodes = document.getElementsByName(name);
for (var i = 0; i < nodes.length; i++) {
var node = nodes[i];
if (node.checked) {
return node.value;
}
}
}
var evaluateButton;
var asmButton;
var irButton;
var formatButton;
var gistButton;
var configureEditorButton;
var result;
var clearResultButton;
var keyboard;
var themes;
var editor;
var session;
var themelist;
var theme;
var mode;
var query;
function doEvaluate() {
var code = session.getValue();
evaluate(result, session.getValue(), evaluateButton);
}
var COLOR_CODES = ['black', 'red', 'green', 'yellow', 'blue', 'magenta', 'cyan', 'white'];
// A simple function to decode ANSI escape codes into HTML.
// This is very basic, with lots of very obvious omissions and holes;
// it’s designed purely to cope with rustc output.
//
// TERM=xterm rustc uses these:
//
// - bug/fatal/error = red
// - warning = yellow
// - note = green
// - help = cyan
// - error code = magenta
// - bold
function ansi2html(text) {
return text.replace(/&/g, '&')
.replace(//g, '>')
.replace(/\x1b\[1m\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function(original, colorCode, text) {
return '' + text + '';
}).replace(/\x1b\[3([0-7])m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function(original, colorCode, text) {
return '' + text + '';
}).replace(/\x1b\[1m([^\x1b]*)(?:\x1b\(B)?\x1b\[0?m/g, function(original, text) {
return "" + text + "";
}).replace(/(?:\x1b\(B)?\x1b\[0?m/g, '');
}
//This affects how mouse acts on the program output.
//Screenshots here: https://github.com/rust-lang/rust-playpen/pull/192#issue-145465630
//If mouse hovers on eg. "");
result.firstChild.firstChild.innerHTML = formatCompilerOutput(object.error);
} else {
set_result(result, "
");
}
}, button, "Compiling…", result);
}
function shareGist(result, code, button) {
send("gist.json", {
code: code,
base_url: PLAYPEN_URL,
branch: branch,
}, function(response) {
var gist_id = response.gist_id;
var gist_url = response.gist_url;
var play_url = PLAYPEN_URL + "/?gist=" + encodeURIComponent(gist_id);
if (branch != "release") {
play_url += "&branch=" + branch;
}
set_result(
result,
"" +
""
);
}, button, "Creating Gist…", result);
}
function httpRequest(method, url, data, expect, on_success, on_fail) {
var req = new XMLHttpRequest();
req.open(method, url, true);
req.onreadystatechange = function() {
if (req.readyState == XMLHttpRequest.DONE) {
if (req.status == expect) {
if (on_success) {
on_success(req.responseText);
}
} else {
if (on_fail) {
on_fail(req.status, req.responseText);
}
}
}
};
if (method === "GET") {
req.send();
} else if (method === "POST") {
req.send(data);
}
}
function fetchGist(session, result, gist_id, do_evaluate, evaluateButton) {
session.setValue("// Loading Gist: https://gist.github.com/" + gist_id + " ...");
httpRequest("GET", "https://api.github.com/gists/" + gist_id, null, 200,
function(response) {
response = JSON.parse(response);
if (response) {
var files = response.files;
for (var name in files) {
if (files.hasOwnProperty(name)) {
session.setValue(files[name].content);
if (do_evaluate) {
doEvaluate();
}
break;
}
}
}
},
function(status, response) {
set_result(result, "" + rehighlight(object.result, emit) + "