Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 31e06fc

Browse files
committed
Drop jQuery in copybutton.js
1 parent 36c7743 commit 31e06fc

File tree

2 files changed

+79
-55
lines changed

2 files changed

+79
-55
lines changed
Lines changed: 59 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,68 @@
1-
$(document).ready(function() {
1+
2+
const loadCopyButton = () => {
23
/* Add a [>>>] button on the top-right corner of code samples to hide
34
* the >>> and ... prompts and the output and thus make the code
45
* copyable. */
5-
var div = $('.highlight-python .highlight,' +
6-
'.highlight-python3 .highlight,' +
7-
'.highlight-pycon .highlight,' +
8-
'.highlight-pycon3 .highlight,' +
9-
'.highlight-default .highlight');
10-
var pre = div.find('pre');
6+
const hide_text = 'Hide the prompts and output'
7+
const show_text = 'Show the prompts and output'
118

12-
// get the styles from the current theme
13-
pre.parent().parent().css('position', 'relative');
14-
var hide_text = 'Hide the prompts and output';
15-
var show_text = 'Show the prompts and output';
16-
var border_width = pre.css('border-top-width');
17-
var border_style = pre.css('border-top-style');
18-
var border_color = pre.css('border-top-color');
19-
var button_styles = {
20-
'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
21-
'border-color': border_color, 'border-style': border_style,
22-
'border-width': border_width, 'color': border_color, 'text-size': '75%',
23-
'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
24-
'border-radius': '0 3px 0 0'
9+
const button = document.createElement("span")
10+
button.classList.add("copybutton")
11+
button.innerText = ">>>"
12+
button.title = hide_text
13+
button.dataset.hidden = false
14+
const buttonClick = event => {
15+
// define the behavior of the button when it's clicked
16+
event.preventDefault()
17+
const buttonEl = event.currentTarget
18+
const codeEl = buttonEl.nextElementSibling
19+
if (buttonEl.dataset.hidden === 'false') {
20+
// hide the code output
21+
codeEl.querySelectorAll('.go, .gp, .gt').forEach(el => el.hidden = true)
22+
codeEl.querySelectorAll('.gt').forEach(el => {
23+
while ((el = el.nextSibling) && el.nodeType !== Node.DOCUMENT_NODE) {
24+
if (el.nodeType === Node.ELEMENT_NODE && el.matches(".gp, .go")) break;
25+
if (el.nodeType === Node.TEXT_NODE && el.textContent.trim()) {
26+
const wrapper = document.createElement('span');
27+
el.after(wrapper);
28+
wrapper.appendChild(el);
29+
el = wrapper
30+
}
31+
el.hidden = true
32+
}
33+
})
34+
buttonEl.title = show_text
35+
buttonEl.dataset.hidden = "true"
36+
} else {
37+
// show the code output
38+
codeEl.childNodes.forEach(el => el.hidden = false)
39+
buttonEl.title = hide_text
40+
buttonEl.dataset.hidden = "false"
41+
}
2542
}
2643

44+
const highlightedElements = document.querySelectorAll(
45+
'.highlight-python .highlight,' +
46+
'.highlight-python3 .highlight,' +
47+
'.highlight-pycon .highlight,' +
48+
'.highlight-pycon3 .highlight,' +
49+
'.highlight-default .highlight')
50+
2751
// create and add the button to all the code blocks that contain >>>
28-
div.each(function(index) {
29-
var jthis = $(this);
30-
if (jthis.find('.gp').length > 0) {
31-
var button = $('<span class="copybutton">&gt;&gt;&gt;</span>');
32-
button.css(button_styles)
33-
button.attr('title', hide_text);
34-
button.data('hidden', 'false');
35-
jthis.prepend(button);
36-
}
37-
// tracebacks (.gt) contain bare text elements that need to be
38-
// wrapped in a span to work with .nextUntil() (see later)
39-
jthis.find('pre:has(.gt)').contents().filter(function() {
40-
return ((this.nodeType == 3) && (this.data.trim().length > 0));
41-
}).wrap('<span>');
42-
});
52+
highlightedElements.forEach(el => {
53+
el.style.position = "relative"
4354

44-
// define the behavior of the button when it's clicked
45-
$('.copybutton').click(function(e){
46-
e.preventDefault();
47-
var button = $(this);
48-
if (button.data('hidden') === 'false') {
49-
// hide the code output
50-
button.parent().find('.go, .gp, .gt').hide();
51-
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
52-
button.css('text-decoration', 'line-through');
53-
button.attr('title', show_text);
54-
button.data('hidden', 'true');
55-
} else {
56-
// show the code output
57-
button.parent().find('.go, .gp, .gt').show();
58-
button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
59-
button.css('text-decoration', 'none');
60-
button.attr('title', hide_text);
61-
button.data('hidden', 'false');
55+
// if we find a console prompt (.gp), prepend the (deeply cloned) button
56+
const clonedButton = button.cloneNode(true)
57+
clonedButton.onclick = buttonClick // onclick isn't cloned :(
58+
if (el.querySelector(".gp") !== null) {
59+
el.prepend(clonedButton)
6260
}
63-
});
64-
});
61+
})
62+
}
63+
64+
if (document.readyState !== "loading") {
65+
loadCopyButton()
66+
} else {
67+
document.addEventListener("DOMContentLoaded", loadCopyButton)
68+
}

python_docs_theme/static/pydoctheme.css

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,26 @@ div.genindex-jumpbox a {
308308
text-align: center;
309309
}
310310

311+
.copybutton {
312+
cursor: pointer;
313+
position: absolute;
314+
top: 0;
315+
right: 0;
316+
text-size: 75%;
317+
font-family: monospace;
318+
padding-left: 0.2em;
319+
padding-right: 0.2em;
320+
border-radius: 0 3px 0 0;
321+
color: #ac9; /* follows div.body pre */
322+
border-color: #ac9; /* follows div.body pre */
323+
border-style: solid; /* follows div.body pre */
324+
border-width: 1px; /* follows div.body pre */
325+
}
326+
327+
.copybutton[data-hidden='true'] {
328+
text-decoration: line-through;
329+
}
330+
311331
@media (max-width: 1023px) {
312332
/* Body layout */
313333
div.body {

0 commit comments

Comments
 (0)