128 lines
4.2 KiB
JavaScript
128 lines
4.2 KiB
JavaScript
/**
|
|
* Initialize variables
|
|
*/
|
|
// for tracking notebook url
|
|
let notebookLocation = window.location.href;
|
|
|
|
// for tracking the scrollbar position
|
|
let scrollPercentage = 0;
|
|
let lastWidth = window.innerWidth;
|
|
|
|
/**
|
|
* Helper: Standard Debounce Function
|
|
*/
|
|
function debounce(func, wait) {
|
|
let timeout;
|
|
return function(...args) {
|
|
clearTimeout(timeout);
|
|
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
};
|
|
}
|
|
|
|
function windowScrolled(_event) {
|
|
const maxScroll = document.documentElement.scrollHeight - window.innerHeight;
|
|
if (maxScroll > 0) {
|
|
scrollPercentage = window.scrollY / maxScroll;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* windowResized is called when the browser window is resized.
|
|
* It adjusts the scroll position to maintain approximately the same visible portion of the page.
|
|
*/
|
|
const windowResized = debounce(() => {
|
|
// console.log('window resized...')
|
|
const currentWidth = window.innerWidth;
|
|
|
|
// Only adjust if the width actually changed
|
|
if (currentWidth !== lastWidth) {
|
|
lastWidth = currentWidth;
|
|
|
|
const newMaxScroll = document.documentElement.scrollHeight - window.innerHeight;
|
|
const newScrollTop = scrollPercentage * newMaxScroll;
|
|
|
|
window.scrollTo({
|
|
top: newScrollTop,
|
|
behavior: 'smooth' // Or 'auto'
|
|
});
|
|
}
|
|
}, 200); // 200ms delay after the last resize event
|
|
|
|
/**
|
|
* clickCallback handles clicks on links to prevent default browser navigation.
|
|
* It checks if the clicked link points to the current page or a different one.
|
|
* For same page links, it updates window.location.href to navigate.
|
|
* For external links, it opens the URL in a new tab/window.
|
|
*/
|
|
function clickCallback(event) {
|
|
// console.log(`Notebook location ${notebookLocation}`);
|
|
if (event.target.tagName !== 'A') return;
|
|
event.preventDefault();
|
|
const link = event.target.href;
|
|
|
|
if (link.startsWith(notebookLocation)) {
|
|
// console.log("same page");
|
|
window.location.href = link;
|
|
} else {
|
|
// console.log("different page");
|
|
window.open(link, '_blank');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a copy button to code cells to allow copying cell contents.
|
|
* Searches for code cells with selectors and inserts a copy button.
|
|
*/
|
|
function addCopyThisButton() {
|
|
// Add a 'copy this' button to every code cell
|
|
// The bottons are added just before the code cells with the classes specified in 'selectors'
|
|
let selectors = [".hl-ipython2", ".hl-ipython3"];
|
|
let html = "<button title='Copy this code' class='copy-code-btn' style='position: absolute; top: 5px; right: 5px;"
|
|
html += "color: lightseagreen; font-weight: bold;'><i class='fa fa-clipboard' aria-hidden='true'></i></button>";
|
|
let cells;
|
|
for (let selector of selectors) {
|
|
cells = [];
|
|
cells = document.querySelectorAll(selector);
|
|
cells.forEach(cell => cell.insertAdjacentHTML("beforebegin", html));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* domLoaded is called when the DOM has loaded.
|
|
* It sets up event listeners and calls addCopyThisButton to add copy buttons.
|
|
*/
|
|
function domLoaded() {
|
|
addCopyThisButton();
|
|
notebookLocation = window.location.href;
|
|
|
|
// Add event listeners
|
|
window.addEventListener('scroll', windowScrolled);
|
|
window.addEventListener('resize', windowResized);
|
|
if (document.addEventListener) document.addEventListener('click', clickCallback, false);
|
|
else document.attachEvent('onclick', clickCallback);
|
|
|
|
// add the logic for copying the content of the code cells to the clipboard
|
|
// courtesy of https://clipboardjs.com/
|
|
let clipboard = new ClipboardJS('.copy-code-btn', {
|
|
target: function(trigger) {
|
|
return trigger.nextElementSibling;
|
|
}
|
|
});
|
|
|
|
// what do do after the item has been copied to the clipboard
|
|
clipboard.on('success', function(e) {
|
|
let trigger = e.trigger;
|
|
e.clearSelection();
|
|
const btnTextBackup = trigger.innerHTML;
|
|
trigger.disabled = true;
|
|
trigger.innerText = 'Copied!';
|
|
setTimeout(() => {
|
|
trigger.innerHTML = btnTextBackup;
|
|
trigger.disabled = false;
|
|
}, 2000);
|
|
});
|
|
}
|
|
|
|
// what to do when the DOM has loaded
|
|
document.addEventListener("DOMContentLoaded", domLoaded);
|