Skip to content

Commit 6bc3039

Browse files
committed
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
1 parent cd90fdd commit 6bc3039

File tree

1 file changed

+46
-27
lines changed

1 file changed

+46
-27
lines changed

src/theme/book.js

Lines changed: 46 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
playground_crates = [];
2-
31
$( document ).ready(function() {
42

53
// url
@@ -19,7 +17,7 @@ $( document ).ready(function() {
1917
tabReplace: ' ', // 4 spaces
2018
languages: [], // Languages used for auto-detection
2119
});
22-
20+
2321
if (window.ace) {
2422
// language-rust class needs to be removed for editable
2523
// blocks or highlightjs will capture events
@@ -33,7 +31,7 @@ $( document ).ready(function() {
3331
hljs.highlightBlock(block);
3432
});
3533
}
36-
34+
3735
// Adding the hljs class gives code blocks the color css
3836
// even if highlighting doesn't apply
3937
$('code').addClass('hljs');
@@ -130,27 +128,27 @@ $( document ).ready(function() {
130128

131129
function set_theme(theme) {
132130
let ace_theme;
133-
131+
134132
if (theme == 'coal' || theme == 'navy') {
135133
$("[href='ayu-highlight.css']").prop('disabled', true);
136134
$("[href='tomorrow-night.css']").prop('disabled', false);
137135
$("[href='highlight.css']").prop('disabled', true);
138-
136+
139137
ace_theme = "ace/theme/tomorrow_night";
140138
} else if (theme == 'ayu') {
141139
$("[href='ayu-highlight.css']").prop('disabled', false);
142140
$("[href='tomorrow-night.css']").prop('disabled', true);
143141
$("[href='highlight.css']").prop('disabled', true);
144-
142+
145143
ace_theme = "ace/theme/tomorrow_night";
146144
} else {
147145
$("[href='ayu-highlight.css']").prop('disabled', true);
148146
$("[href='tomorrow-night.css']").prop('disabled', true);
149147
$("[href='highlight.css']").prop('disabled', false);
150-
148+
151149
ace_theme = "ace/theme/dawn";
152150
}
153-
151+
154152
if (window.ace && window.editors) {
155153
window.editors.forEach(function(editor) {
156154
editor.setTheme(ace_theme);
@@ -265,9 +263,10 @@ $( document ).ready(function() {
265263
dataType: "json",
266264
contentType: "application/json",
267265
success: function(response){
268-
playground_crates = response.crates.map(function(item) {return item["id"];} );
269-
$(".playpen").each(function(block){
270-
update_play_button(this, playground_crates);
266+
// get list of crates available in the rust playground
267+
let playground_crates = response.crates.map(function(item) {return item["id"];} );
268+
$(".playpen").each(function(block) {
269+
handle_crate_list_update($(this), playground_crates);
271270
});
272271
},
273272
});
@@ -285,19 +284,47 @@ function playpen_text(playpen) {
285284
}
286285
}
287286

288-
function update_play_button(block, playground_crates) {
289-
//TODO skip if `no_run` is set
290-
var pre_block = $(block);
287+
function handle_crate_list_update(playpen_block, playground_crates) {
288+
// update the play buttons after receiving the response
289+
update_play_button(playpen_block, playground_crates);
290+
291+
// and install on change listener to dynamically update ACE editors
292+
if (window.ace) {
293+
let code_block = playpen_block.find("code").first();
294+
if (code_block.hasClass("editable")) {
295+
let editor = window.ace.edit(code_block.get(0));
296+
editor.on("change", function(e){
297+
update_play_button(playpen_block, playground_crates);
298+
});
299+
}
300+
}
301+
}
302+
303+
// updates the visibility of play button based on `no_run` class and
304+
// used crates vs ones available on http://play.rust-lang.org
305+
function update_play_button(pre_block, playground_crates) {
291306
var play_button = pre_block.find(".play-button");
292307

293-
var txt = playpen_text(pre_block);
308+
var classes = pre_block.find("code").attr("class").split(" ");
309+
// skip if code is `no_run`
310+
if (classes.indexOf("no_run") > -1) {
311+
play_button.addClass("hidden");
312+
return;
313+
}
294314

315+
// get list of `extern crate`'s from snippet
316+
var txt = playpen_text(pre_block);
295317
var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
296318
var snippet_crates = [];
297-
while (item = re.exec(txt))
319+
while (item = re.exec(txt)) {
298320
snippet_crates.push(item[1]);
321+
}
322+
323+
// check if all used crates are available on play.rust-lang.org
324+
var all_available = snippet_crates.every(function(elem) {
325+
return playground_crates.indexOf(elem) > -1;
326+
});
299327

300-
var all_available = snippet_crates.every(elem => playground_crates.indexOf(elem) > -1);
301328
if (all_available) {
302329
play_button.removeClass("hidden");
303330
} else {
@@ -341,15 +368,7 @@ function run_rust_code(code_block) {
341368
result_block = code_block.find(".result");
342369
}
343370

344-
let text;
345-
346-
let inner_code_block = code_block.find("code").first();
347-
if (window.ace && inner_code_block.hasClass("editable")) {
348-
let editor = window.ace.edit(inner_code_block.get(0));
349-
text = editor.getValue();
350-
} else {
351-
text = inner_code_block.text();
352-
}
371+
let text = playpen_text(code_block);;
353372

354373
var params = {
355374
version: "stable",

0 commit comments

Comments
 (0)