-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathinteract-update.html
142 lines (128 loc) · 4.72 KB
/
interact-update.html
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
{% if site.use_jupyterhub_button or site.use_binder_button %}
<script>
/**
* To auto-embed hub URLs in interact links if given in a RESTful fashion
*/
function getJsonFromUrl(url) {
var query = url.split('?');
if (query.length < 2) {
// No queries so just return false
return false;
}
query = query[1];
// Collect REST params into a dictionary
var result = {};
query.split("&").forEach(function(part) {
var item = part.split("=");
result[item[0]] = decodeURIComponent(item[1]);
});
return result;
}
function dict2param(dict) {
params = Object.keys(dict).map(function(k) {
return encodeURIComponent(k) + '=' + encodeURIComponent(dict[k])
});
return params.join('&')
}
// Parse a Binder URL, converting it to the string needed for JupyterHub
function binder2Jupyterhub(url) {
newUrl = {};
parts = url.split('v2/gh/')[1];
// Grab the base repo information
repoinfo = parts.split('?')[0];
var [org, repo, ref] = repoinfo.split('/');
newUrl['repo'] = ['https://github.com', org, repo].join('/');
newUrl['branch'] = ref
// Grab extra parameters passed
params = getJsonFromUrl(url);
if (params['filepath'] !== undefined) {
newUrl['subPath'] = params['filepath']
}
return dict2param(newUrl);
}
// Filter out potentially unsafe characters to prevent xss
function safeUrl(url)
{
return String(encodeURIComponent(url))
.replace(/&/g, '&')
.replace(/"/g, '"')
.replace(/'/g, ''')
.replace(/</g, '<')
.replace(/>/g, '>');
}
function addParamToInternalLinks(hub) {
var links = document.querySelectorAll("a").forEach(function(link) {
var href = link.href;
// If the link is an internal link...
if (href.search("{{ site.url }}") !== -1 || href.startsWith('/') || href.search("127.0.0.1:") !== -1) {
// Assume we're an internal link, add the hub param to it
var params = getJsonFromUrl(href);
if (params !== false) {
// We have REST params, so append a new one
params['jupyterhub'] = hub;
} else {
// Create the REST params
params = {'jupyterhub': hub};
}
// Update the link
var newHref = href.split('?')[0] + '?' + dict2param(params);
link.setAttribute('href', decodeURIComponent(newHref));
}
});
return false;
}
// Update interact links
function updateInteractLink() {
// hack to make this work since it expects a ? in the URL
rest = getJsonFromUrl("?" + location.search.substr(1));
jupyterHubUrl = rest['jupyterhub'];
var hubType = null;
var hubUrl = null;
if (jupyterHubUrl !== undefined) {
hubType = 'jupyterhub';
hubUrl = jupyterHubUrl;
}
if (hubType !== null) {
// Sanitize the hubUrl
hubUrl = safeUrl(hubUrl);
// Add HTTP text if omitted
if (hubUrl.indexOf('http') < 0) {hubUrl = 'http://' + hubUrl;}
var interactButtons = document.querySelectorAll("button.interact-button")
var lastButton = interactButtons[interactButtons.length-1];
var link = lastButton.parentElement;
// If we've already run this, skip the link updating
if (link.nextElementSibling !== null) {
return;
}
// Update the link and add context div
var href = link.getAttribute('href');
if (lastButton.id === 'interact-button-binder') {
// If binder links exist, we need to re-work them for jupyterhub
if (hubUrl.indexOf('http%3A%2F%2Flocalhost') > -1) {
// If localhost, assume we're working from a local Jupyter server and remove `/hub`
first = [hubUrl, 'git-sync'].join('/')
} else {
first = [hubUrl, 'hub', 'user-redirect', 'git-sync'].join('/')
}
href = first + '?' + binder2Jupyterhub(href);
} else {
// If interact button isn't binderhub, assume it's jupyterhub
// If JupyterHub links, we only need to replace the hub url
href = href.replace("{{ site.jupyterhub_url }}", hubUrl);
if (hubUrl.indexOf('http%3A%2F%2Flocalhost') > -1) {
// Assume we're working from a local Jupyter server and remove `/hub`
href = href.replace("/hub/user-redirect", "");
}
}
link.setAttribute('href', decodeURIComponent(href));
// Add text after interact link saying where we're launching
hubUrlNoHttp = decodeURIComponent(hubUrl).replace('http://', '').replace('https://', '');
link.insertAdjacentHTML('afterend', '<div class="interact-context">on ' + hubUrlNoHttp + '</div>');
// Update internal links so we retain the hub url
addParamToInternalLinks(hubUrl);
}
}
runWhenDOMLoaded(updateInteractLink)
document.addEventListener('turbolinks:load', updateInteractLink)
</script>
{% endif %}