Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sagemath
GitHub Repository: sagemath/sage
Path: blob/develop/src/doc/common/static/jupyter-sphinx-furo.js
4111 views
1
// Change the editor theme according to the furo light/dark/auto mode
2
function changeTheme(editor, theme) {
3
if (theme === 'dark') {
4
editor.setOption('theme', 'monokai'); // the same with pygments dark style in conf.py
5
} else if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
6
editor.setOption('theme', 'monokai');
7
} else {
8
editor.setOption('theme', 'default');
9
}
10
}
11
12
// Change the editor theme of all CodeMirror cells
13
function changeThemeAll(theme) {
14
const querySet = document.querySelectorAll('.CodeMirror');
15
for (var i = 0; i < querySet.length; i++) {
16
changeTheme(querySet[i].CodeMirror, theme);
17
}
18
}
19
20
// Use the theme data of the body element set by setTheme function
21
// defined in https://github.com/pradyunsg/furo/blob/main/src/furo/assets/scripts/furo.js
22
const body = document.body;
23
const observer1 = new MutationObserver((mutationsList) => {
24
for (let mutation of mutationsList) {
25
if (mutation.type === 'attributes' && mutation.attributeName === 'data-theme') {
26
const theme = body.dataset.theme;
27
changeThemeAll(theme);
28
}
29
}
30
});
31
observer1.observe(body, { attributes: true });
32
33
34
// In the furo auto mode, we watch prefers-color-scheme and use the theme data
35
// of the body element to change the CodeMirror editor theme
36
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)');
37
38
function handlePrefersColorSchemeChange(e) {
39
const theme = body.dataset.theme;
40
if (theme === 'auto') {
41
changeThemeAll(theme);
42
}
43
}
44
45
prefersDarkMode.addEventListener('change', handlePrefersColorSchemeChange);
46
47
48
// Change the editor theme of a new CodeMirror cell
49
const callback = function(mutationsList, observer) {
50
for(const mutation of mutationsList) {
51
if (mutation.type === 'childList') {
52
const theme = body.dataset.theme;
53
for (const addedNode of mutation.addedNodes) {
54
if (addedNode.classList && addedNode.classList.contains('CodeMirror')) {
55
changeTheme(addedNode.CodeMirror, theme);
56
}}}}};
57
const observer2 = new MutationObserver(callback);
58
observer2.observe(document.getElementsByClassName("content")[0], { childList: true, subtree: true });
59
60
61
//
62
// Version selector
63
//
64
65
function fetchVersions() {
66
try {
67
let menu = document.getElementById('versions-menu');
68
69
// For the origin of the this site, see .github/workflows/doc-publish.yml
70
fetch('https://doc-release--sagemath.netlify.app/html/en/versions.txt')
71
.then(response => {
72
if (!response.ok) {
73
throw new Error('Network response was not ok ' + response.statusText);
74
}
75
return response.text();
76
})
77
.then(text => {
78
const lines = text.split('\n');
79
lines.forEach(line => {
80
if (!line.startsWith('#')) { // Ignore the comment line
81
let [ver, url] = line.split(' ');
82
if (ver && url) {
83
if (!url.startsWith('https://')) {
84
url = 'https://' + url;
85
}
86
let option = document.createElement('option');
87
option.value = url;
88
option.text = ver;
89
menu.add(option);
90
}
91
}
92
});
93
})
94
.catch(error => {
95
console.log('Failed to fetch versions.txt file.');
96
});
97
} catch (error) {
98
console.log('Failed to fetch versions.txt file.');
99
}
100
}
101
102
fetchVersions()
103
104
// Function to change the version based on versions menu selection
105
function changeVersion() {
106
let select_element = document.getElementById("versions-menu");
107
let selected_ver = select_element.options[select_element.selectedIndex].text;
108
let selected_url = select_element.value;
109
if (selected_url) {
110
if (window.location.protocol == 'file:') {
111
let pathname = window.location.pathname;
112
let cutoff_point = pathname.indexOf('/html');
113
if (cutoff_point !== -1) {
114
pathname = pathname.substring(cutoff_point);
115
window.location.href = selected_url + pathname;
116
} else {
117
window.location.href = selected_url + '/index.html';
118
}
119
} else {
120
window.location.href = selected_url + window.location.pathname;
121
}
122
}
123
}
124
125
126
// Listen to the kernel status changes
127
// https://thebe.readthedocs.io/en/stable/events.html
128
thebelab.on("status", function (evt, data) {
129
if (data.status === 'building') {
130
const elements = document.querySelectorAll('.thebelab-cell');
131
elements.forEach(element => {
132
element.style.filter = 'opacity(50%)';
133
});
134
const element = document.getElementById("thebelab-activate-button");
135
element.innerHTML = "Building";
136
element.style.right = '.4rem';
137
}
138
else if (data.status === 'built') {
139
const elements = document.querySelectorAll('.thebelab-cell');
140
elements.forEach(element => {
141
element.style.filter = 'opacity(60%)';
142
});
143
const element = document.getElementById("thebelab-activate-button");
144
element.innerHTML = "Built";
145
element.style.right = '.4rem';
146
}
147
else if (data.status === 'launching') {
148
const elements = document.querySelectorAll('.thebelab-cell');
149
elements.forEach(element => {
150
element.style.filter = 'opacity(70%)';
151
});
152
const element = document.getElementById("thebelab-activate-button");
153
element.innerHTML = "Launching";
154
element.style.right = '.4rem';
155
}
156
else if (data.status === 'failed') {
157
const elements = document.querySelectorAll('.thebelab-cell');
158
elements.forEach(element => {
159
element.style.filter = 'opacity(50%)';
160
});
161
const element = document.getElementById("thebelab-activate-button");
162
element.innerHTML = 'Failed: ' + data.message;
163
element.style.right = '.4rem';
164
element.style.width = 'auto';
165
element.style.color = 'red';
166
}
167
else if (data.status === 'ready') {
168
const elements = document.querySelectorAll('.thebelab-cell');
169
elements.forEach(element => {
170
element.style.filter = 'opacity(100%)';
171
});
172
const element = document.getElementById("thebelab-activate-button");
173
element.innerHTML = "Ready";
174
element.style.right = null;
175
// Run custom code when the kernel is ready
176
const kernel = data.kernel;
177
kernel.requestExecute({code: "%display latex"});
178
}
179
});
180
181
182
// Activate Thebe when "Sage Live" tab is clicked
183
document.querySelectorAll('input[class="tab-input"]').forEach((elem) => {
184
elem.addEventListener("click", function(event) {
185
if (elem.nextElementSibling) {
186
if (elem.nextElementSibling.nextElementSibling) {
187
if (elem.nextElementSibling.nextElementSibling.querySelector('div[class="thebelab-code"]')) {
188
initThebelab();
189
}
190
}
191
}
192
});
193
});
194
195