Both static and ACE editable snippets have optional play button

- list of available crates is dynamically loaded from play.rust-lang.org
- play button is enabled only if crates used in snippet are available on playground
- ACE editor's play button is dynamically updated on each text change
- `no_run` is honored by always disabling the play button
- minor cleanups
This commit is contained in:
Michal Budzynski 2017-08-08 00:36:38 +02:00 committed by Michał Budzyński
parent cd90fdd407
commit 6bc3039b4f
1 changed files with 46 additions and 27 deletions

View File

@ -1,5 +1,3 @@
playground_crates = [];
$( document ).ready(function() { $( document ).ready(function() {
// url // url
@ -19,7 +17,7 @@ $( document ).ready(function() {
tabReplace: ' ', // 4 spaces tabReplace: ' ', // 4 spaces
languages: [], // Languages used for auto-detection languages: [], // Languages used for auto-detection
}); });
if (window.ace) { if (window.ace) {
// language-rust class needs to be removed for editable // language-rust class needs to be removed for editable
// blocks or highlightjs will capture events // blocks or highlightjs will capture events
@ -33,7 +31,7 @@ $( document ).ready(function() {
hljs.highlightBlock(block); hljs.highlightBlock(block);
}); });
} }
// Adding the hljs class gives code blocks the color css // Adding the hljs class gives code blocks the color css
// even if highlighting doesn't apply // even if highlighting doesn't apply
$('code').addClass('hljs'); $('code').addClass('hljs');
@ -130,27 +128,27 @@ $( document ).ready(function() {
function set_theme(theme) { function set_theme(theme) {
let ace_theme; let ace_theme;
if (theme == 'coal' || theme == 'navy') { if (theme == 'coal' || theme == 'navy') {
$("[href='ayu-highlight.css']").prop('disabled', true); $("[href='ayu-highlight.css']").prop('disabled', true);
$("[href='tomorrow-night.css']").prop('disabled', false); $("[href='tomorrow-night.css']").prop('disabled', false);
$("[href='highlight.css']").prop('disabled', true); $("[href='highlight.css']").prop('disabled', true);
ace_theme = "ace/theme/tomorrow_night"; ace_theme = "ace/theme/tomorrow_night";
} else if (theme == 'ayu') { } else if (theme == 'ayu') {
$("[href='ayu-highlight.css']").prop('disabled', false); $("[href='ayu-highlight.css']").prop('disabled', false);
$("[href='tomorrow-night.css']").prop('disabled', true); $("[href='tomorrow-night.css']").prop('disabled', true);
$("[href='highlight.css']").prop('disabled', true); $("[href='highlight.css']").prop('disabled', true);
ace_theme = "ace/theme/tomorrow_night"; ace_theme = "ace/theme/tomorrow_night";
} else { } else {
$("[href='ayu-highlight.css']").prop('disabled', true); $("[href='ayu-highlight.css']").prop('disabled', true);
$("[href='tomorrow-night.css']").prop('disabled', true); $("[href='tomorrow-night.css']").prop('disabled', true);
$("[href='highlight.css']").prop('disabled', false); $("[href='highlight.css']").prop('disabled', false);
ace_theme = "ace/theme/dawn"; ace_theme = "ace/theme/dawn";
} }
if (window.ace && window.editors) { if (window.ace && window.editors) {
window.editors.forEach(function(editor) { window.editors.forEach(function(editor) {
editor.setTheme(ace_theme); editor.setTheme(ace_theme);
@ -265,9 +263,10 @@ $( document ).ready(function() {
dataType: "json", dataType: "json",
contentType: "application/json", contentType: "application/json",
success: function(response){ success: function(response){
playground_crates = response.crates.map(function(item) {return item["id"];} ); // get list of crates available in the rust playground
$(".playpen").each(function(block){ let playground_crates = response.crates.map(function(item) {return item["id"];} );
update_play_button(this, playground_crates); $(".playpen").each(function(block) {
handle_crate_list_update($(this), playground_crates);
}); });
}, },
}); });
@ -285,19 +284,47 @@ function playpen_text(playpen) {
} }
} }
function update_play_button(block, playground_crates) { function handle_crate_list_update(playpen_block, playground_crates) {
//TODO skip if `no_run` is set // update the play buttons after receiving the response
var pre_block = $(block); update_play_button(playpen_block, playground_crates);
// and install on change listener to dynamically update ACE editors
if (window.ace) {
let code_block = playpen_block.find("code").first();
if (code_block.hasClass("editable")) {
let editor = window.ace.edit(code_block.get(0));
editor.on("change", function(e){
update_play_button(playpen_block, playground_crates);
});
}
}
}
// updates the visibility of play button based on `no_run` class and
// used crates vs ones available on http://play.rust-lang.org
function update_play_button(pre_block, playground_crates) {
var play_button = pre_block.find(".play-button"); var play_button = pre_block.find(".play-button");
var txt = playpen_text(pre_block); var classes = pre_block.find("code").attr("class").split(" ");
// skip if code is `no_run`
if (classes.indexOf("no_run") > -1) {
play_button.addClass("hidden");
return;
}
// get list of `extern crate`'s from snippet
var txt = playpen_text(pre_block);
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
var snippet_crates = []; var snippet_crates = [];
while (item = re.exec(txt)) while (item = re.exec(txt)) {
snippet_crates.push(item[1]); snippet_crates.push(item[1]);
}
// check if all used crates are available on play.rust-lang.org
var all_available = snippet_crates.every(function(elem) {
return playground_crates.indexOf(elem) > -1;
});
var all_available = snippet_crates.every(elem => playground_crates.indexOf(elem) > -1);
if (all_available) { if (all_available) {
play_button.removeClass("hidden"); play_button.removeClass("hidden");
} else { } else {
@ -341,15 +368,7 @@ function run_rust_code(code_block) {
result_block = code_block.find(".result"); result_block = code_block.find(".result");
} }
let text; let text = playpen_text(code_block);;
let inner_code_block = code_block.find("code").first();
if (window.ace && inner_code_block.hasClass("editable")) {
let editor = window.ace.edit(inner_code_block.get(0));
text = editor.getValue();
} else {
text = inner_code_block.text();
}
var params = { var params = {
version: "stable", version: "stable",