Skip to content

Commit

Permalink
refactor: codeblock (HEIGE-PCloud#1225)
Browse files Browse the repository at this point in the history
* refactor: codeblock

* feat: implement wrap and toggle open animation

* chore: handle max-height calculation correctly

* chore: remove unnecessary js

* chore: remove clipboardjs

* feat: use icons

* feat: add text wrap icon

* feat: add style to icons

* refactor: switch to typescript

* chore: add global declaration

* chore: optimise image resize method

* fix: sharer wechat and mastodon icon

Close HEIGE-PCloud#1247

* Disable autoplay (HEIGE-PCloud#1249)

* Improve the `bilibili` shortcode with more options (HEIGE-PCloud#1250)

* add variables

* finished the initial dev of bilibili improvement

next is documentation

* rearrange bilibili options

* added documentation for improved bilibili shortcode

* fluent chinese

* chore: disableHTTPCache for dev env

* refactor: color scheme HEIGE-PCloud#1245 (HEIGE-PCloud#1253)

* refactor: color scheme

* refactor: colors in Tailwind Config

* fix: scss variables use error

* feat: partially adopt Prime Design for the dark theme

* feat: pick selection color

* feat: pick link color

* feat: pick codeblock, table, blockquote color

* feat: pick more colors

* refactor: remove black theme

* fix: code background color

* refactor: extract primitive colors

* refactor: use primitive colors in tailwind config

* chore: use --verbose

* chore: sync github CI build step

---------

Co-authored-by: PCloud <[email protected]>

* chore: re-enable counter

* fix: syntax highlightning

* chore: format code

* fix(style):  do not wrap line number

* feat: make line numbers fix position

* chore: bad idea, revert

* refactor: move all js logic into theme.ts

* feat: support copy icon states

* feat: implement line number toggle

* feat: move all JavaScript to theme.ts

* feat: support custom title

* feat: init all states

* feat: support maxShownLines

* fix: correct color scheme

* chore: switch icon back to svg

* feat: expand code blocks before print

* deprecate copy option

* feat: add titles to buttons

* feat: add docs

* feat: support wrap option

---------

Co-authored-by: CXwudi <[email protected]>
Co-authored-by: 恐咖兵糖 <[email protected]>
  • Loading branch information
3 people authored and Jatin794 committed Dec 19, 2024
1 parent 7484dd7 commit 98db1ec
Show file tree
Hide file tree
Showing 21 changed files with 621 additions and 318 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ Thanks to the authors of following resources included in the theme:
* [object-fit-images](https://github.com/fregante/object-fit-images)
* [Twemoji](https://github.com/twitter/twemoji)
* [lightgallery.js](https://github.com/sachinchoolur/lightgallery.js)
* [clipboard.js](https://github.com/zenorocha/clipboard.js)
* [Sharer.js](https://github.com/ellisonleao/sharer.js)
* [TypeIt](https://typeitjs.com/)
* [KaTeX](https://katex.org/)
Expand Down
1 change: 0 additions & 1 deletion README.zh-cn.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ DoIt 主题中用到了以下项目,感谢它们的作者:
* [object-fit-images](https://github.com/fregante/object-fit-images)
* [Twemoji](https://github.com/twitter/twemoji)
* [lightgallery.js](https://github.com/sachinchoolur/lightgallery.js)
* [clipboard.js](https://github.com/zenorocha/clipboard.js)
* [Sharer.js](https://github.com/ellisonleao/sharer.js)
* [TypeIt](https://typeitjs.com/)
* [KaTeX](https://katex.org/)
Expand Down
122 changes: 122 additions & 0 deletions assets/css/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,25 @@ html.dark {
--tw-contain-style: ;
}

.tw-m-0 {
margin: 0px;
}

.\!tw-my-1 {
margin-top: 0.25rem !important;
margin-bottom: 0.25rem !important;
}

.tw-mx-2 {
margin-left: 0.5rem;
margin-right: 0.5rem;
}

.tw-my-2 {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}

.tw-my-4 {
margin-top: 1rem;
margin-bottom: 1rem;
Expand All @@ -775,14 +794,34 @@ html.dark {
margin-right: 0.25rem;
}

.\!tw-block {
display: block !important;
}

.tw-block {
display: block;
}

.tw-inline-block {
display: inline-block;
}

.tw-flex {
display: flex;
}

.tw-hidden {
display: none;
}

.tw-h-10 {
height: 2.5rem;
}

.\!tw-max-h-0 {
max-height: 0px !important;
}

.tw-max-h-4 {
max-height: 1rem;
}
Expand Down Expand Up @@ -810,6 +849,32 @@ html.dark {
animation: tw-spin 1s linear infinite;
}

.tw-select-none {
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}

.tw-flex-row {
flex-direction: row;
}

.tw-justify-between {
justify-content: space-between;
}

.tw-overflow-x-auto {
overflow-x: auto;
}

.tw-overflow-y-hidden {
overflow-y: hidden;
}

.tw-text-wrap {
text-wrap: wrap;
}

.tw-rounded-full {
border-radius: 9999px;
}
Expand All @@ -823,10 +888,18 @@ html.dark {
border-color: rgb(240 240 240 / var(--tw-border-opacity));
}

.tw-bg-bgColor-secondary {
background-color: var(--bgColor-secondary);
}

.tw-bg-transparent {
background-color: transparent;
}

.tw-p-0 {
padding: 0px;
}

.tw-p-4 {
padding: 1rem;
}
Expand Down Expand Up @@ -854,10 +927,26 @@ html.dark {
transition-duration: 150ms;
}

.tw-transition-\[max-height\] {
transition-property: max-height;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}

.tw-transition-\[transform\] {
transition-property: transform;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
}

.tw-duration-300 {
transition-duration: 300ms;
}

.tw-duration-500 {
transition-duration: 500ms;
}

.tw-ease-in-out {
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
}
Expand All @@ -866,12 +955,45 @@ html.dark {
background-color: var(--bgColor-secondary);
}

.hover\:tw-text-fgColor-link:hover {
color: var(--fgColor-link);
}

.hover\:tw-shadow-md:hover {
--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);
box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
}

.tw-group.is-open .group-\[\.is-open\]\:tw-block {
display: block;
}

.tw-group.is-open .group-\[\.is-open\]\:tw-hidden {
display: none;
}

.tw-group.is-closed .group-\[\.is-closed\]\:\!tw-max-h-0 {
max-height: 0px !important;
}

.tw-group.is-open .group-\[\.is-open\]\:tw-rotate-90 {
--tw-rotate: 90deg;
transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.tw-group.is-wrap .group-\[\.is-wrap\]\:tw-text-wrap {
text-wrap: wrap;
}

.tw-group.is-wrap .group-\[\.is-wrap\]\:tw-text-fgColor-link {
color: var(--fgColor-link);
}

.tw-group.show-line-numbers .group-\[\.show-line-numbers\]\:tw-text-fgColor-link {
color: var(--fgColor-link);
}

.aria-selected\:tw-border-b-4[aria-selected="true"] {
border-bottom-width: 4px;
}
Expand Down
1 change: 0 additions & 1 deletion assets/js/shims/clipboard.js

This file was deleted.

137 changes: 63 additions & 74 deletions assets/js/theme.js → assets/js/theme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
export {};

// TODO: add more global states to the window object
declare global {
interface Window { isDark: boolean; }
}


/* eslint-disable no-new */
/* eslint-disable no-undef */
// import ClipboardJS from 'clipboard'
const Tablesort = require('tablesort')
// const autocomplete = require('autocomplete.js')

Expand Down Expand Up @@ -419,78 +426,6 @@ function initLightGallery () {
}
}

function initHighlight () {
forEach(document.querySelectorAll('.highlight > pre.chroma'), $preChroma => {
const $chroma = document.createElement('div')
$chroma.className = $preChroma.className
const $table = document.createElement('table')
$chroma.appendChild($table)
const $tbody = document.createElement('tbody')
$table.appendChild($tbody)
const $tr = document.createElement('tr')
$tbody.appendChild($tr)
const $td = document.createElement('td')
$tr.appendChild($td)
$preChroma.parentElement.replaceChild($chroma, $preChroma)
$td.appendChild($preChroma)
})
forEach(document.querySelectorAll('.highlight > .chroma'), $chroma => {
const $codeElements = $chroma.querySelectorAll('pre.chroma > code')
if ($codeElements.length) {
const $code = $codeElements[$codeElements.length - 1]
const $header = document.createElement('div')
$header.className = 'code-header ' + $code.className.toLowerCase()
const $title = document.createElement('span')
$title.classList.add('code-title')
$title.insertAdjacentHTML('afterbegin', `<svg class="arrow icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"/></svg>`)
$title.addEventListener('click', () => {
const content = $chroma.getElementsByClassName('table-wrapper')[0]
if ($chroma.classList.contains('open')) {
content.style.maxHeight = null
} else {
content.style.maxHeight = content.scrollHeight + 'px'
}
$chroma.classList.toggle('open')
}, false)
addEventListener("beforeprint", (event) => {
if ($chroma.classList.contains('open')) {
return;
}
$title.click();
});
$header.appendChild($title)
const $ellipses = document.createElement('span')
$ellipses.insertAdjacentHTML('afterbegin', '<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"/></svg>')
$ellipses.classList.add('ellipses')
$ellipses.addEventListener('click', () => {
$chroma.classList.add('open')
}, false)
$header.appendChild($ellipses)
const $copy = document.createElement('span')
const copyHTML = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M433.941 65.941l-51.882-51.882A48 48 0 0 0 348.118 0H176c-26.51 0-48 21.49-48 48v48H48c-26.51 0-48 21.49-48 48v320c0 26.51 21.49 48 48 48h224c26.51 0 48-21.49 48-48v-48h80c26.51 0 48-21.49 48-48V99.882a48 48 0 0 0-14.059-33.941zM266 464H54a6 6 0 0 1-6-6V150a6 6 0 0 1 6-6h74v224c0 26.51 21.49 48 48 48h96v42a6 6 0 0 1-6 6zm128-96H182a6 6 0 0 1-6-6V54a6 6 0 0 1 6-6h106v88c0 13.255 10.745 24 24 24h88v202a6 6 0 0 1-6 6zm6-256h-64V48h9.632c1.591 0 3.117.632 4.243 1.757l48.368 48.368a6 6 0 0 1 1.757 4.243V112z"/></svg>`;
const checkHTML = `<svg class="icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!-- Font Awesome Free 5.15.4 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) --><path d="M173.898 439.404l-166.4-166.4c-9.997-9.997-9.997-26.206 0-36.204l36.203-36.204c9.997-9.998 26.207-9.998 36.204 0L192 312.69 432.095 72.596c9.997-9.997 26.207-9.997 36.204 0l36.203 36.204c9.997 9.997 9.997 26.206 0 36.204l-294.4 294.401c-9.998 9.997-26.207 9.997-36.204-.001z"/></svg>`;
$copy.insertAdjacentHTML('afterbegin', copyHTML)
$copy.classList.add('copy')
const code = $code.innerText
if (window.config.code.maxShownLines < 0 || code.split('\n').length < window.config.code.maxShownLines + 2) $chroma.classList.add('open')
if (window.config.code.copyTitle) {
$copy.setAttribute('data-clipboard-text', code)
$copy.title = window.config.code.copyTitle
const clipboard = new ClipboardJS($copy)
clipboard.on('success', _e => {
animateCSS($code, 'animate__flash')
$copy.firstElementChild.innerHTML = checkHTML
setTimeout(() => {
$copy.firstElementChild.innerHTML = copyHTML
}, 3000)
})
$header.appendChild($copy)
}
$chroma.insertBefore($header, $chroma.firstChild)
}
})
}

function initTable () {
forEach(document.querySelectorAll('.content table'), $table => {
const $wrapper = document.createElement('div')
Expand Down Expand Up @@ -763,6 +698,60 @@ function onClickMask () {
}, false)
}

function initCodeblocks() {
document.querySelectorAll('.code-block').forEach((codeBlock) => {
// the queries are guaranteed to be successful
const titleBar = codeBlock.querySelector('div.code-block-title-bar') as HTMLDivElement;
const chroma = codeBlock.querySelector('code.chroma') as HTMLElement;
const copyCodeButton = codeBlock.querySelector('button.copy-code-button') as HTMLButtonElement;
const copyIcon = copyCodeButton.querySelector('span.copy-icon') as SVGElement;
const checkIcon = copyCodeButton.querySelector('span.check-icon') as SVGElement;
const wrapCodeButton = codeBlock.querySelector('button.wrap-code-button') as HTMLButtonElement;
const toggleLineNumbersButton = codeBlock.querySelector('button.line-number-button') as HTMLButtonElement;

chroma.style.maxHeight = chroma.scrollHeight + 10 + 'px';

// handle expanding and collapsing code blocks
titleBar.addEventListener('click', () => {
codeBlock.classList.toggle('is-open');
codeBlock.classList.toggle('is-closed');
});

// handle copying code to clipboard
copyCodeButton?.addEventListener('click', () => {
navigator.clipboard.writeText(chroma.innerText);
// toggle icons
copyIcon.style.display = 'none';
checkIcon.style.display = 'block';
setTimeout(() => {
copyIcon.style.display = 'block';
checkIcon.style.display = 'none';
}, 3000);
});

// handle wrapping lines in code blocks
wrapCodeButton?.addEventListener('click', () => {
chroma.style.maxHeight = 'fit-content';
codeBlock.classList.toggle('is-wrap');
chroma.style.maxHeight = chroma.scrollHeight + 10 + 'px';
});

toggleLineNumbersButton.addEventListener('click', () => {
codeBlock.classList.toggle('show-line-numbers');
});

addEventListener("beforeprint", (_) => {
if (codeBlock.classList.contains('is-closed')) {
titleBar.click();
}
if (!codeBlock.classList.contains('is-wrap')) {
wrapCodeButton.click();
}
});
});
}


function init () {
window.isDark = document.body.getAttribute('theme') !== 'light'
window.newScrollTop = getScrollTop()
Expand All @@ -776,9 +765,9 @@ function init () {
initSelectTheme()
initMeta()
initSearch()
initCodeblocks()
initDetails()
initLightGallery()
initHighlight()
initTable()
initTypeit()
initMapbox()
Expand Down
Loading

0 comments on commit 98db1ec

Please sign in to comment.