-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathsphinx-thebe.js
126 lines (111 loc) · 3.89 KB
/
sphinx-thebe.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/**
* Add attributes to Thebe blocks to initialize thebe properly
*/
var configureThebe = () => {
// Load thebe config in case we want to update it as some point
console.log("[sphinx-thebe]: Loading thebe config...");
thebe_config = $('script[type="text/x-thebe-config"]')[0];
// If we already detect a Thebe cell, don't re-run
if (document.querySelectorAll("div.thebe-cell").length > 0) {
return;
}
// Update thebe buttons with loading message
$(".thebe-launch-button").each((ii, button) => {
button.innerHTML = `
<div class="spinner">
<div class="rect1"></div>
<div class="rect2"></div>
<div class="rect3"></div>
<div class="rect4"></div>
</div>
<span class="loading-text"></span>`;
});
// Set thebe event hooks
var thebeStatus;
thebelab.on("status", function (evt, data) {
console.log("Status changed:", data.status, data.message);
$(".thebe-launch-button ")
.removeClass("thebe-status-" + thebeStatus)
.addClass("thebe-status-" + data.status)
.find(".loading-text")
.html(
"<span class='launch_msg'>Launching from mybinder.org: </span><span class='status'>" +
data.status +
"</span>"
);
// Now update our thebe status
thebeStatus = data.status;
// Find any cells with an initialization tag and ask thebe to run them when ready
if (data.status === "ready") {
var thebeInitCells = document.querySelectorAll(
".thebe-init, .tag_thebe-init"
);
thebeInitCells.forEach((cell) => {
console.log("Initializing Thebe with cell: " + cell.id);
cell.querySelector(".thebelab-run-button").click();
});
}
});
};
/**
* Update the page DOM to use Thebe elements
*/
var modifyDOMForThebe = () => {
// Find all code cells, replace with Thebe interactive code cells
const codeCells = document.querySelectorAll(thebe_selector);
codeCells.forEach((codeCell, index) => {
const codeCellId = (index) => `codecell${index}`;
codeCell.id = codeCellId(index);
codeCellText = codeCell.querySelector(thebe_selector_input);
codeCellOutput = codeCell.querySelector(thebe_selector_output);
// Clean up the language to make it work w/ CodeMirror and add it to the cell
dataLanguage = detectLanguage(kernelName);
// Re-arrange the cell and add metadata
if (codeCellText) {
codeCellText.setAttribute("data-language", dataLanguage);
codeCellText.setAttribute("data-executable", "true");
// If we had an output, insert it just after the `pre` cell
if (codeCellOutput) {
$(codeCellOutput).attr("data-output", "");
$(codeCellOutput).insertAfter(codeCellText);
}
}
// Remove sphinx-copybutton blocks, which are common in Sphinx
codeCell.querySelectorAll("button.copybtn").forEach((el) => {
el.remove();
});
});
};
var initThebe = () => {
// Load thebe dynamically if it's not already loaded
if (typeof thebelab === "undefined") {
console.log("[sphinx-thebe]: Loading thebe from CDN...");
$(".thebe-launch-button ").text("Loading thebe from CDN...");
const script = document.createElement("script");
script.src = `${THEBE_JS_URL}`;
document.head.appendChild(script);
// Runs once the script has finished loading
script.addEventListener("load", () => {
console.log("[sphinx-thebe]: Finished loading thebe from CDN...");
configureThebe();
modifyDOMForThebe();
thebelab.bootstrap();
});
} else {
console.log(
"[sphinx-thebe]: thebe already loaded, not loading from CDN..."
);
configureThebe();
modifyDOMForThebe();
thebelab.bootstrap();
}
};
// Helper function to munge the language name
var detectLanguage = (language) => {
if (language.indexOf("python") > -1) {
language = "python";
} else if (language === "ir") {
language = "r";
}
return language;
};