feat(code-block): added tooltip function in code block

This commit is contained in:
XPoet 2022-09-29 16:42:09 +08:00
parent 6794c38269
commit 10befe1445
11 changed files with 76 additions and 44 deletions

View File

@ -46,6 +46,11 @@ zhihu: Zhihu
twitter: Twitter twitter: Twitter
facebook: Facebook facebook: Facebook
email: Email email: Email
code_block:
copy: Copy code
copied: Copied
fold: Fold code block
folded: Folded
copyright: copyright:
author: Post author author: Post author
title: Post title title: Post title

View File

@ -46,6 +46,11 @@ zhihu: 知乎
twitter: 推特 twitter: 推特
facebook: Facebook facebook: Facebook
email: Email email: Email
code_block:
copy: 复制代码
copied: 已复制
fold: 折叠代码块
folded: 已折叠
copyright: copyright:
title: 本文标题 title: 本文标题
author: 本文作者 author: 本文作者

View File

@ -46,6 +46,11 @@ zhihu: 知乎
twitter: Twitter twitter: Twitter
facebook: Facebook facebook: Facebook
email: Email email: Email
code_block:
copy: 復製代碼
copied: 已復製
fold: 折疊代碼塊
folded: 已折疊
copyright: copyright:
author: 文章作者 author: 文章作者
title: 文章標題 title: 文章標題

View File

@ -3,7 +3,6 @@
'js/main.js', 'js/main.js',
'js/header-shrink.js', 'js/header-shrink.js',
'js/back2top.js', 'js/back2top.js',
'js/tooltip.js',
'js/dark-light-toggle.js' 'js/dark-light-toggle.js'
]) %> ]) %>

View File

@ -53,5 +53,6 @@ hexo.extend.helper.register('export_config', function () {
KEEP.hexo_config = ${JSON.stringify(hexo_config)}; KEEP.hexo_config = ${JSON.stringify(hexo_config)};
KEEP.theme_config = ${JSON.stringify(theme_config)}; KEEP.theme_config = ${JSON.stringify(theme_config)};
KEEP.language_ago = ${JSON.stringify(languageContent['ago'])}; KEEP.language_ago = ${JSON.stringify(languageContent['ago'])};
KEEP.language_code_block = ${JSON.stringify(languageContent['code_block'])};
</script>`; </script>`;
}); });

View File

@ -188,13 +188,13 @@ button {
&:hover { &:hover {
.tooltip-content { .tooltip-content {
visibility visible display inline-block
} }
} }
.tooltip-content { .tooltip-content {
position absolute position absolute
top -145% top -140%
left 50% left 50%
transform translateX(-50%) transform translateX(-50%)
font-size 0.8rem font-size 0.8rem
@ -202,9 +202,9 @@ button {
background var(--first-text-color) background var(--first-text-color)
color var(--fourth-text-color) color var(--fourth-text-color)
border-radius 0.3rem border-radius 0.3rem
visibility hidden display none
z-index $z-index-1 z-index $z-index-9
white-space nowrap white-space nowrap
transition-t("visibility", "0", "0.2", "ease") transition-t("display", "0", "0.2", "ease")
} }
} }

View File

@ -9,7 +9,6 @@ disable-user-select() {
position relative position relative
box-sizing border-box box-sizing border-box
margin 1.4rem 0 margin 1.4rem 0
overflow hidden
.code-tools-box { .code-tools-box {
box-sizing border-box box-sizing border-box
@ -49,7 +48,7 @@ disable-user-select() {
.fold { .fold {
font-weight bold font-weight bold
padding 0.1rem 0.4rem 0.1rem 0.2rem padding 0 0.4rem 0 0.2rem
} }
} }
@ -106,7 +105,7 @@ disable-user-select() {
.fold { .fold {
order 2 order 2
padding 0.1rem 0.1rem 0.1rem 0.6rem padding 0 0.1rem 0 0.6rem
i { i {
color #ccc color #ccc
} }
@ -115,9 +114,9 @@ disable-user-select() {
.copy { .copy {
position absolute position absolute
bottom 0 bottom 0.3rem
right 0 right 0.5rem
padding 0.4rem 0.5rem padding 0 0.1rem
font-weight bold font-weight bold
opacity 0 opacity 0
transition-t("opacity", "0", "0.2", "ease-in-out") transition-t("opacity", "0", "0.2", "ease-in-out")

View File

@ -11,8 +11,8 @@ KEEP.initCodeBlockTools = () => {
const { style: codeBlockStyle } = KEEP.theme_config?.code_block_tools; const { style: codeBlockStyle } = KEEP.theme_config?.code_block_tools;
const isMac = (codeBlockStyle || codeCopyStyle || 'default') === 'mac'; const isMac = (codeBlockStyle || codeCopyStyle || 'default') === 'mac';
const foldedIconClassName = isMac ? 'fas fa-chevron-left' : 'fas fa-chevron-right'; const foldedIconClassName = isMac ? 'fas fa-chevron-left' : 'fas fa-chevron-right';
const { copy: copyLang, copied: copiedLang, fold: foldLang, folded: foldedLang } = KEEP.language_code_block;
const foldDom = `<span class="tool fold"><i class="fas fa-chevron-down"></i></span>` const foldDom = `<span class="tool fold tooltip" data-content="${foldLang}"><i class="fas fa-chevron-down"></i></span>`
document.querySelectorAll('figure.highlight').forEach(element => { document.querySelectorAll('figure.highlight').forEach(element => {
let codeLang = element.classList.length ? element.classList[1].toUpperCase() : ''; let codeLang = element.classList.length ? element.classList[1].toUpperCase() : '';
@ -21,13 +21,14 @@ KEEP.initCodeBlockTools = () => {
highlightContainer.classList.add('highlight-container'); highlightContainer.classList.add('highlight-container');
element.wrap(highlightContainer); element.wrap(highlightContainer);
const codeLangDom = `${codeLang ? '<span class="code-lang">' + codeLang + '</span>' : ''}` const codeLangDom = `${codeLang ? '<span class="code-lang">' + codeLang + '</span>' : ''}`
highlightContainer.insertAdjacentHTML( highlightContainer.insertAdjacentHTML(
'afterbegin', 'afterbegin',
`<div class="code-tools-box"> `<div class="code-tools-box">
${isMac ? foldDom + codeLangDom : '<span>' + foldDom + codeLangDom + '</span>'} ${isMac ? foldDom + codeLangDom : '<span>' + foldDom + codeLangDom + '</span>'}
<span class="tool copy"><i class="fas fa-copy"></i></span> <span class="tool copy tooltip" data-content="${copyLang}"><i class="fas fa-copy"></i></span>
</div>` </div>`
); );
const codeToolsBox = element.parentNode.querySelector('.code-tools-box'); const codeToolsBox = element.parentNode.querySelector('.code-tools-box');
@ -50,7 +51,17 @@ KEEP.initCodeBlockTools = () => {
tta.setSelectionRange(0, code.length); tta.setSelectionRange(0, code.length);
tta.readOnly = false; tta.readOnly = false;
const result = document.execCommand('copy'); const result = document.execCommand('copy');
target.querySelector('i').className = result ? 'fas fa-check' : 'fas fa-times';
const copyIconDom = target.querySelector('i');
const copyTooltipDom = codeToolsBox.querySelector('.copy .tooltip-content');
if (result) {
copyIconDom.className = 'fas fa-check';
copyTooltipDom && (copyTooltipDom.innerHTML = copiedLang);
} else {
copyIconDom.className = 'fas fa-times';
}
tta.blur(); tta.blur();
target.blur(); target.blur();
if (selected) { if (selected) {
@ -63,6 +74,8 @@ KEEP.initCodeBlockTools = () => {
copyDom.addEventListener('mouseleave', event => { copyDom.addEventListener('mouseleave', event => {
setTimeout(() => { setTimeout(() => {
event.target.querySelector('i').className = 'fas fa-copy'; event.target.querySelector('i').className = 'fas fa-copy';
const copyTooltipDom = codeToolsBox.querySelector('.copy .tooltip-content');
copyTooltipDom && (copyTooltipDom.innerHTML = copyLang);
}, 500); }, 500);
}); });
@ -70,15 +83,18 @@ KEEP.initCodeBlockTools = () => {
targetFoldDom.addEventListener('click', event => { targetFoldDom.addEventListener('click', event => {
const target = event.currentTarget; const target = event.currentTarget;
const icon = target.querySelector('i'); const icon = target.querySelector('i');
isFold = !isFold const foldTooltipDom = codeToolsBox.querySelector('.fold .tooltip-content');
isFold = !isFold;
if (isFold) { if (isFold) {
icon.className = foldedIconClassName icon.className = foldedIconClassName;
element.classList.add('folded'); element.classList.add('folded');
codeToolsBox.classList.add('folded'); codeToolsBox.classList.add('folded');
foldTooltipDom && (foldTooltipDom.innerHTML = foldedLang)
} else { } else {
icon.className = 'fas fa-chevron-down'; icon.className = 'fas fa-chevron-down';
element.classList.remove('folded'); element.classList.remove('folded');
codeToolsBox.classList.remove('folded'); codeToolsBox.classList.remove('folded');
foldTooltipDom && (foldTooltipDom.innerHTML = foldLang)
} }
}); });
}); });

View File

@ -49,7 +49,6 @@ window.addEventListener('DOMContentLoaded', () => {
KEEP.initHeaderShrink(); KEEP.initHeaderShrink();
KEEP.initModeToggle(); KEEP.initModeToggle();
KEEP.initBack2Top(); KEEP.initBack2Top();
KEEP.initTooltip();
if (KEEP.theme_config.local_search?.enable === true) { if (KEEP.theme_config.local_search?.enable === true) {
KEEP.initLocalSearch(); KEEP.initLocalSearch();

View File

@ -1,16 +0,0 @@
/* global KEEP */
KEEP.initTooltip = () => {
KEEP.utils.insertTooltipContent = () => {
document.querySelectorAll('.tooltip').forEach(element => {
const { content } = element.dataset
if (content) {
element.insertAdjacentHTML(
'afterbegin',
`<span class="tooltip-content">${content}</span>`
);
}
})
}
KEEP.utils.insertTooltipContent();
}

View File

@ -264,8 +264,7 @@ KEEP.initUtils = () => {
}, },
getHowLongAgo(timestamp) { getHowLongAgo(timestamp) {
const l = KEEP.language_ago; const lang = KEEP.language_ago;
const __Y = Math.floor(timestamp / (60 * 60 * 24 * 30) / 12); const __Y = Math.floor(timestamp / (60 * 60 * 24 * 30) / 12);
const __M = Math.floor(timestamp / (60 * 60 * 24 * 30)); const __M = Math.floor(timestamp / (60 * 60 * 24 * 30));
const __W = Math.floor(timestamp / (60 * 60 * 24) / 7); const __W = Math.floor(timestamp / (60 * 60 * 24) / 7);
@ -275,25 +274,25 @@ KEEP.initUtils = () => {
const __s = Math.floor(timestamp % 60); const __s = Math.floor(timestamp % 60);
if (__Y > 0) { if (__Y > 0) {
return this.setHowLongAgoLanguage(__Y, l.year); return this.setHowLongAgoLanguage(__Y, lang.year);
} else if (__M > 0) { } else if (__M > 0) {
return this.setHowLongAgoLanguage(__M, l.month); return this.setHowLongAgoLanguage(__M, lang.month);
} else if (__W > 0) { } else if (__W > 0) {
return this.setHowLongAgoLanguage(__W, l.week); return this.setHowLongAgoLanguage(__W, lang.week);
} else if (__d > 0) { } else if (__d > 0) {
return this.setHowLongAgoLanguage(__d, l.day); return this.setHowLongAgoLanguage(__d, lang.day);
} else if (__h > 0) { } else if (__h > 0) {
return this.setHowLongAgoLanguage(__h, l.hour); return this.setHowLongAgoLanguage(__h, lang.hour);
} else if (__m > 0) { } else if (__m > 0) {
return this.setHowLongAgoLanguage(__m, l.minute); return this.setHowLongAgoLanguage(__m, lang.minute);
} else if (__s > 0) { } else if (__s > 0) {
return this.setHowLongAgoLanguage(__s, l.second); return this.setHowLongAgoLanguage(__s, lang.second);
} }
}, },
@ -349,6 +348,24 @@ KEEP.initUtils = () => {
}, 200); }, 200);
}, },
// insert tooltip content dom
insertTooltipContent() {
const init = () => {
document.querySelectorAll('.tooltip').forEach(element => {
const { content } = element.dataset;
if (content) {
element.insertAdjacentHTML(
'afterbegin',
`<span class="tooltip-content">${content}</span>`
);
}
});
}
setTimeout(() => {
init();
}, 1000);
}
} }
// init data // init data
@ -381,4 +398,6 @@ KEEP.initUtils = () => {
// set how long age in home article block // set how long age in home article block
KEEP.utils.setHowLongAgoInHome(); KEEP.utils.setHowLongAgoInHome();
// insert tooltip content dom
KEEP.utils.insertTooltipContent();
} }