mirror of
https://github.com/cotes2020/jekyll-theme-chirpy.git
synced 2025-12-20 22:53:17 +00:00
perf: replace jQuery with Vanilla JS (#1681)
Also replaced `magnific-popup` with `GLightbox`
This commit is contained in:
@@ -7,102 +7,103 @@
|
||||
*/
|
||||
|
||||
const clipboardSelector = '.code-header>button';
|
||||
|
||||
const ICON_DEFAULT = 'far fa-clipboard';
|
||||
const ICON_SUCCESS = 'fas fa-check';
|
||||
|
||||
const ATTR_TIMEOUT = 'timeout';
|
||||
const ATTR_TITLE_SUCCEED = 'data-title-succeed';
|
||||
const ATTR_TITLE_ORIGIN = 'data-bs-original-title';
|
||||
const TIMEOUT = 2000; // in milliseconds
|
||||
|
||||
function isLocked(node) {
|
||||
if ($(node)[0].hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = $(node).attr(ATTR_TIMEOUT);
|
||||
if (node.hasAttribute(ATTR_TIMEOUT)) {
|
||||
let timeout = node.getAttribute(ATTR_TIMEOUT);
|
||||
if (Number(timeout) > Date.now()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function lock(node) {
|
||||
$(node).attr(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
node.setAttribute(ATTR_TIMEOUT, Date.now() + TIMEOUT);
|
||||
}
|
||||
|
||||
function unlock(node) {
|
||||
$(node).removeAttr(ATTR_TIMEOUT);
|
||||
node.removeAttribute(ATTR_TIMEOUT);
|
||||
}
|
||||
|
||||
function getIcon(btn) {
|
||||
let iconNode = $(btn).children();
|
||||
return iconNode.attr('class');
|
||||
}
|
||||
|
||||
const ICON_DEFAULT = getIcon(clipboardSelector);
|
||||
|
||||
function showTooltip(btn) {
|
||||
const succeedTitle = $(btn).attr(ATTR_TITLE_SUCCEED);
|
||||
$(btn).attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
const succeedTitle = btn.getAttribute(ATTR_TITLE_SUCCEED);
|
||||
btn.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||
bootstrap.Tooltip.getInstance(btn).show();
|
||||
}
|
||||
|
||||
function hideTooltip(btn) {
|
||||
$(btn).tooltip('hide').removeAttr(ATTR_TITLE_ORIGIN);
|
||||
bootstrap.Tooltip.getInstance(btn).hide();
|
||||
btn.removeAttribute(ATTR_TITLE_ORIGIN);
|
||||
}
|
||||
|
||||
function setSuccessIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_SUCCESS);
|
||||
const icon = btn.children[0];
|
||||
icon.setAttribute('class', ICON_SUCCESS);
|
||||
}
|
||||
|
||||
function resumeIcon(btn) {
|
||||
let btnNode = $(btn);
|
||||
let iconNode = btnNode.children();
|
||||
iconNode.attr('class', ICON_DEFAULT);
|
||||
const icon = btn.children[0];
|
||||
icon.setAttribute('class', ICON_DEFAULT);
|
||||
}
|
||||
|
||||
export function initClipboard() {
|
||||
// Initial the clipboard.js object
|
||||
if ($(clipboardSelector).length) {
|
||||
const clipboard = new ClipboardJS(clipboardSelector, {
|
||||
target(trigger) {
|
||||
let codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
const clipboardList = document.querySelectorAll(clipboardSelector);
|
||||
|
||||
const clipboardList = document.querySelectorAll(clipboardSelector);
|
||||
[...clipboardList].map(
|
||||
(elem) =>
|
||||
new bootstrap.Tooltip(elem, {
|
||||
placement: 'left'
|
||||
})
|
||||
);
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
e.clearSelection();
|
||||
|
||||
const trigger = e.trigger;
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
if (clipboardList.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Initial the clipboard.js object
|
||||
const clipboard = new ClipboardJS(clipboardSelector, {
|
||||
target: (trigger) => {
|
||||
const codeBlock = trigger.parentNode.nextElementSibling;
|
||||
return codeBlock.querySelector('code .rouge-code');
|
||||
}
|
||||
});
|
||||
|
||||
[...clipboardList].map(
|
||||
(elem) =>
|
||||
new bootstrap.Tooltip(elem, {
|
||||
placement: 'left'
|
||||
})
|
||||
);
|
||||
|
||||
clipboard.on('success', (e) => {
|
||||
const trigger = e.trigger;
|
||||
|
||||
e.clearSelection();
|
||||
|
||||
if (isLocked(trigger)) {
|
||||
return;
|
||||
}
|
||||
|
||||
setSuccessIcon(trigger);
|
||||
showTooltip(trigger);
|
||||
lock(trigger);
|
||||
|
||||
setTimeout(() => {
|
||||
hideTooltip(trigger);
|
||||
resumeIcon(trigger);
|
||||
unlock(trigger);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
|
||||
/* --- Post link sharing --- */
|
||||
|
||||
const btnCopyLink = $('#copy-link');
|
||||
const btnCopyLink = document.getElementById('copy-link');
|
||||
|
||||
btnCopyLink.on('click', (e) => {
|
||||
let target = $(e.target);
|
||||
btnCopyLink.addEventListener('click', (e) => {
|
||||
const target = e.target;
|
||||
|
||||
if (isLocked(target)) {
|
||||
return;
|
||||
@@ -110,21 +111,23 @@ export function initClipboard() {
|
||||
|
||||
// Copy URL to clipboard
|
||||
navigator.clipboard.writeText(window.location.href).then(() => {
|
||||
const defaultTitle = target.attr(ATTR_TITLE_ORIGIN);
|
||||
const succeedTitle = target.attr(ATTR_TITLE_SUCCEED);
|
||||
const defaultTitle = target.getAttribute(ATTR_TITLE_ORIGIN);
|
||||
const succeedTitle = target.getAttribute(ATTR_TITLE_SUCCEED);
|
||||
|
||||
// Switch tooltip title
|
||||
target.attr(ATTR_TITLE_ORIGIN, succeedTitle).tooltip('show');
|
||||
target.setAttribute(ATTR_TITLE_ORIGIN, succeedTitle);
|
||||
bootstrap.Tooltip.getInstance(target).show();
|
||||
|
||||
lock(target);
|
||||
|
||||
setTimeout(() => {
|
||||
target.attr(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||
target.setAttribute(ATTR_TITLE_ORIGIN, defaultTitle);
|
||||
unlock(target);
|
||||
}, TIMEOUT);
|
||||
});
|
||||
});
|
||||
|
||||
btnCopyLink.on('mouseleave', function (e) {
|
||||
const target = $(e.target);
|
||||
target.tooltip('hide');
|
||||
btnCopyLink.addEventListener('mouseleave', (e) => {
|
||||
bootstrap.Tooltip.getInstance(e.target).hide();
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user