Support folding code blocks (#679)

This commit is contained in:
Mimi 2023-07-29 07:41:50 +08:00 committed by GitHub
parent a24450d9cf
commit 11e534bf28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 67 additions and 14 deletions

View File

@ -373,6 +373,10 @@ codeblock:
enable: false enable: false
# Available values: default | flat | mac # Available values: default | flat | mac
style: style:
# Fold code block
fold:
enable: false
height: 500
back2top: back2top:
enable: true enable: true

View File

@ -19,6 +19,7 @@ hexo.extend.helper.register('next_config', function() {
exturl : theme.exturl, exturl : theme.exturl,
sidebar : theme.sidebar, sidebar : theme.sidebar,
copycode : theme.codeblock.copy_button, copycode : theme.codeblock.copy_button,
fold : theme.codeblock.fold,
bookmark : theme.bookmark, bookmark : theme.bookmark,
mediumzoom: theme.mediumzoom, mediumzoom: theme.mediumzoom,
lazyload : theme.lazyload, lazyload : theme.lazyload,

View File

@ -0,0 +1,29 @@
.expand-btn {
bottom: 0;
color: var(--highlight-foreground);
cursor: pointer;
display: none;
left: 0;
right: 0;
position: absolute;
text-align: center;
}
.fold-cover {
background-image: linear-gradient(to top, var(--highlight-background) 0, rgba(0, 0, 0, 0) 100%);
bottom: 0;
display: none;
height: 50px;
left: 0;
right: 0;
position: absolute;
}
.highlight-fold {
max-height: unit(hexo-config('codeblock.fold.height'), 'px');
overflow-y: hidden !important;
.expand-btn, .fold-cover {
display: block;
}
}

View File

@ -13,6 +13,7 @@ if (hexo-config('darkmode')) {
} }
@require 'copy-code' if (hexo-config('codeblock.copy_button.enable')); @require 'copy-code' if (hexo-config('codeblock.copy_button.enable'));
@require 'fold' if (hexo-config('codeblock.fold.enable'));
// Placeholder: $code-inline $code-block // Placeholder: $code-inline $code-block
$code-inline { $code-inline {

View File

@ -46,7 +46,7 @@ NexT.boot.refresh = function() {
CONFIG.exturl && NexT.utils.registerExtURL(); CONFIG.exturl && NexT.utils.registerExtURL();
NexT.utils.wrapTableWithBox(); NexT.utils.wrapTableWithBox();
NexT.utils.registerCopyCode(); NexT.utils.registerCodeblock();
NexT.utils.registerTabsTag(); NexT.utils.registerTabsTag();
NexT.utils.registerActiveMenuItem(); NexT.utils.registerActiveMenuItem();
NexT.utils.registerLangSelect(); NexT.utils.registerLangSelect();

View File

@ -39,30 +39,48 @@ NexT.utils = {
}); });
}, },
/** registerCodeblock: function() {
* One-click copy code support.
*/
registerCopyCode: function() {
let figure = document.querySelectorAll('figure.highlight'); let figure = document.querySelectorAll('figure.highlight');
let needWrap = false; let isHljsWithWrap = true;
if (figure.length === 0) { if (figure.length === 0) {
figure = document.querySelectorAll('pre:not(.mermaid)'); figure = document.querySelectorAll('pre:not(.mermaid)');
needWrap = true; isHljsWithWrap = false;
} }
figure.forEach(element => { figure.forEach(element => {
element.querySelectorAll('.code .line span').forEach(span => { let span = element.querySelectorAll('.code .line span');
span.classList.forEach(name => { if (span.length === 0) {
span.classList.replace(name, `hljs-${name}`); // Hljs without line_number and wrap
span = element.querySelectorAll('code.highlight span');
}
span.forEach(s => {
s.classList.forEach(name => {
s.classList.replace(name, `hljs-${name}`);
}); });
}); });
if (!CONFIG.copycode.enable) return; const height = parseInt(window.getComputedStyle(element).height.replace('px', ''), 10);
let target = element; const needFold = CONFIG.fold.enable && (height > CONFIG.fold.height);
if (needWrap) { if (!needFold && !CONFIG.copycode.enable) return;
let target;
if (isHljsWithWrap && CONFIG.copycode.style === 'mac') {
target = element;
} else {
// https://github.com/next-theme/hexo-theme-next/issues/98
// https://github.com/next-theme/hexo-theme-next/pull/508
const container = element.querySelector('.table-container') || element;
const box = document.createElement('div'); const box = document.createElement('div');
box.className = 'code-container'; box.className = 'code-container';
element.wrap(box); container.wrap(box);
target = box; target = box;
} }
if (needFold) {
target.classList.add('highlight-fold');
target.insertAdjacentHTML('beforeend', '<div class="fold-cover"></div><div class="expand-btn"><i class="fa fa-angle-down fa-fw"></i></div>');
target.querySelector('.expand-btn').addEventListener('click', () => {
target.classList.remove('highlight-fold');
});
}
if (!CONFIG.copycode.enable) return;
// One-click copy code support.
target.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>'); target.insertAdjacentHTML('beforeend', '<div class="copy-btn"><i class="fa fa-copy fa-fw"></i></div>');
const button = target.querySelector('.copy-btn'); const button = target.querySelector('.copy-btn');
button.addEventListener('click', () => { button.addEventListener('click', () => {