-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathjupyterlite_sphinx.js
210 lines (182 loc) · 6.91 KB
/
jupyterlite_sphinx.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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
window.jupyterliteShowIframe = (tryItButtonId, iframeSrc) => {
const tryItButton = document.getElementById(tryItButtonId);
const iframe = document.createElement("iframe");
const buttonRect = tryItButton.getBoundingClientRect();
const spinner = document.createElement("div");
// hardcoded spinner height and width needs to match what is in css.
const spinnerHeight = 50; // px
const spinnerWidth = 50; // px
spinner.classList.add("jupyterlite_sphinx_spinner");
spinner.style.display = "none";
// Add negative margins to center the spinner
spinner.style.marginTop = `-${spinnerHeight / 2}px`;
spinner.style.marginLeft = `-${spinnerWidth / 2}px`;
iframe.src = iframeSrc;
iframe.width = iframe.height = "100%";
iframe.classList.add("jupyterlite_sphinx_iframe");
tryItButton.style.display = "none";
spinner.style.display = "block";
tryItButton.parentNode.appendChild(spinner);
tryItButton.parentNode.appendChild(iframe);
};
window.jupyterliteConcatSearchParams = (iframeSrc, params) => {
const baseURL = window.location.origin;
const iframeUrl = new URL(iframeSrc, baseURL);
let pageParams = new URLSearchParams(window.location.search);
if (params === true) {
params = Array.from(pageParams.keys());
} else if (params === false) {
params = [];
} else if (!Array.isArray(params)) {
console.error("The search parameters are not an array");
}
params.forEach((param) => {
value = pageParams.get(param);
if (value !== null) {
iframeUrl.searchParams.append(param, value);
}
});
if (iframeUrl.searchParams.size) {
return `${iframeSrc.split("?")[0]}?${iframeUrl.searchParams.toString()}`;
} else {
return iframeSrc;
}
};
window.tryExamplesShowIframe = (
examplesContainerId,
iframeContainerId,
iframeParentContainerId,
iframeSrc,
iframeHeight,
) => {
const examplesContainer = document.getElementById(examplesContainerId);
const iframeParentContainer = document.getElementById(
iframeParentContainerId,
);
const iframeContainer = document.getElementById(iframeContainerId);
var height;
let iframe = iframeContainer.querySelector(
"iframe.jupyterlite_sphinx_iframe",
);
if (!iframe) {
// Add spinner
const spinner = document.createElement("div");
// hardcoded spinner width needs to match what is in css.
const spinnerHeight = 50; // px
const spinnerWidth = 50; // px
spinner.classList.add("jupyterlite_sphinx_spinner");
iframeContainer.appendChild(spinner);
const examples = examplesContainer.querySelector(".try_examples_content");
iframe = document.createElement("iframe");
iframe.src = iframeSrc;
iframe.style.width = "100%";
if (iframeHeight !== "None") {
height = parseInt(iframeHeight);
} else {
height = Math.max(tryExamplesGlobalMinHeight, examples.offsetHeight);
}
/* Get spinner position. It will be centered in the iframe, unless the
* iframe extends beyond the viewport, in which case it will be centered
* between the top of the iframe and the bottom of the viewport.
*/
const examplesTop = examples.getBoundingClientRect().top;
const viewportBottom = window.innerHeight;
const spinnerTop = 0.5 * Math.min(viewportBottom - examplesTop, height);
spinner.style.top = `${spinnerTop}px`;
// Add negative margins to center the spinner
spinner.style.marginTop = `-${spinnerHeight / 2}px`;
spinner.style.marginLeft = `-${spinnerWidth / 2}px`;
iframe.style.height = `${height}px`;
iframe.classList.add("jupyterlite_sphinx_iframe");
examplesContainer.classList.add("hidden");
iframeContainer.appendChild(iframe);
} else {
examplesContainer.classList.add("hidden");
}
iframeParentContainer.classList.remove("hidden");
};
window.tryExamplesHideIframe = (
examplesContainerId,
iframeParentContainerId,
) => {
const examplesContainer = document.getElementById(examplesContainerId);
const iframeParentContainer = document.getElementById(
iframeParentContainerId,
);
iframeParentContainer.classList.add("hidden");
examplesContainer.classList.remove("hidden");
};
// this will be used by the "Open in tab" button that is present next
// # to the "go back" button after an iframe is made visible.
window.openInNewTab = (examplesContainerId, iframeParentContainerId) => {
const examplesContainer = document.getElementById(examplesContainerId);
const iframeParentContainer = document.getElementById(
iframeParentContainerId,
);
window.open(
// we make some assumption that there is a single iframe and the the src is what we want to open.
// Maybe we should have tabs open JupyterLab by default.
iframeParentContainer.getElementsByTagName("iframe")[0].getAttribute("src"),
);
tryExamplesHideIframe(examplesContainerId, iframeParentContainerId);
};
/* Global variable for try_examples iframe minHeight. Defaults to 0 but can be
* modified based on configuration in try_examples.json */
var tryExamplesGlobalMinHeight = 0;
/* Global variable to check if config has been loaded. This keeps it from getting
* loaded multiple times if there are multiple try_examples directives on one page
*/
var tryExamplesConfigLoaded = false;
window.loadTryExamplesConfig = async (configFilePath) => {
if (tryExamplesConfigLoaded) {
return;
}
try {
// Add a timestamp as query parameter to ensure a cached version of the
// file is not used.
const timestamp = new Date().getTime();
const configFileUrl = `${configFilePath}?cb=${timestamp}`;
const currentPageUrl = window.location.pathname;
const response = await fetch(configFileUrl);
if (!response.ok) {
if (response.status === 404) {
// Try examples ignore file is not present.
console.log("Optional try_examples config file not found.");
return;
}
throw new Error(`Error fetching ${configFilePath}`);
}
const data = await response.json();
if (!data) {
return;
}
// Set minimum iframe height based on value in config file
if (data.global_min_height) {
tryExamplesGlobalMinHeight = parseInt(data.global_min_height);
}
// Disable interactive examples if file matches one of the ignore patterns
// by hiding try_examples_buttons.
Patterns = data.ignore_patterns;
for (let pattern of Patterns) {
let regex = new RegExp(pattern);
if (regex.test(currentPageUrl)) {
var buttons = document.getElementsByClassName("try_examples_button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].classList.add("hidden");
}
break;
}
}
} catch (error) {
console.error(error);
}
tryExamplesConfigLoaded = true;
};
window.toggleTryExamplesButtons = () => {
/* Toggle visibility of TryExamples buttons. For use in console for debug
* purposes. */
var buttons = document.getElementsByClassName("try_examples_button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].classList.toggle("hidden");
}
};