breaking change: 增加 macstyle 配置,取消配置 mac / mac light 主題

feat: 可更改文章標題位置
feat: 增加代碼全屏
improvement: 當代碼塊 toolbar 其它功能設為 false 時, 仍能顯示 macstyle
improvement: 優化文章標題在左邊時,不同寬度的位置顯示
improvement: 代碼優化
This commit is contained in:
Jerry
2024-04-29 13:35:18 +08:00
parent ae35499658
commit f74ede6d15
11 changed files with 189 additions and 113 deletions

View File

@@ -67,7 +67,7 @@ npm i hexo-theme-butterfly
- [x] Read Mode - [x] Read Mode
- [x] Conversion between Traditional and Simplified Chinese - [x] Conversion between Traditional and Simplified Chinese
- [X] TOC catalog is available for both computers and mobile phones - [X] TOC catalog is available for both computers and mobile phones
- [X] Built-in Syntax Highlighting Themes (darker/pale night/light/ocean/mac/mac light), also support customization - [X] Built-in Syntax Highlighting Themes (darker/pale night/light/ocean), also support customization
- [X] Code Blocks (Display code language/close or expand Code Blocks/Copy Button/word wrap) - [X] Code Blocks (Display code language/close or expand Code Blocks/Copy Button/word wrap)
- [X] Disable copy/Add a Copyright Notice to the Copied Text - [X] Disable copy/Add a Copyright Notice to the Copied Text
- [X] Search (Algolia Search/Local Search) - [X] Search (Algolia Search/Local Search)

View File

@@ -67,7 +67,7 @@ theme: butterfly
- [x] 文章閲讀模式 - [x] 文章閲讀模式
- [x] 簡體和繁體轉換 - [x] 簡體和繁體轉換
- [X] 電腦和手機都可查看TOC目錄 - [X] 電腦和手機都可查看TOC目錄
- [X] 內置多種代碼配色darker/pale night/light/ocean/mac/mac light),可自定義代碼配色 - [X] 內置多種代碼配色darker/pale night/light/ocean可自定義代碼配色
- [X] 代碼塊顯示代碼語言/關閉或展開代碼塊/代碼複製/代碼自動換行 - [X] 代碼塊顯示代碼語言/關閉或展開代碼塊/代碼複製/代碼自動換行
- [X] 可關閉文字複製/可開啟內容複製增加版權信息) - [X] 可關閉文字複製/可開啟內容複製增加版權信息)
- [X] 兩種搜索( Algolia 搜索和本地搜索) - [X] 兩種搜索( Algolia 搜索和本地搜索)

View File

@@ -22,12 +22,16 @@ menu:
# Code Blocks (代碼相關) # Code Blocks (代碼相關)
# -------------------------------------- # --------------------------------------
highlight_theme: light # darker / pale night / light / ocean / mac / mac light / false highlight_theme: light # darker / pale night / light / ocean / false
highlight_height_limit: false # unit: px
code_word_wrap: false
# highlight toolbar
highlight_theme_macStyle: false # use mac style
highlight_copy: true # copy button highlight_copy: true # copy button
highlight_lang: true # show the code language highlight_lang: true # show the code language
highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button
highlight_height_limit: false # unit: px highlight_fullpage: true # true: add button to toggle full page
code_word_wrap: false
# Social Settings (社交圖標設置) # Social Settings (社交圖標設置)
# formal: # formal:
@@ -108,6 +112,7 @@ post_meta:
tags: false # true or false 主頁是否顯示標籤 tags: false # true or false 主頁是否顯示標籤
label: true # true or false 顯示描述性文字 label: true # true or false 顯示描述性文字
post: post:
position: left # left or center 文章頁標題位置
date_type: both # created or updated or both 文章頁日期是創建日或者更新日或都顯示 date_type: both # created or updated or both 文章頁日期是創建日或者更新日或都顯示
date_format: date # date/relative 顯示日期還是相對日期 date_format: date # date/relative 顯示日期還是相對日期
categories: true # true or false 文章頁是否顯示分類 categories: true # true or false 文章頁是否顯示分類

View File

@@ -85,7 +85,9 @@
plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs', plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs',
highlightCopy: theme.highlight_copy, highlightCopy: theme.highlight_copy,
highlightLang: theme.highlight_lang, highlightLang: theme.highlight_lang,
highlightHeightLimit: theme.highlight_height_limit highlightHeightLimit: theme.highlight_height_limit,
highlightFullpage: theme.highlight_fullpage,
highlightMacStyle: theme.highlight_theme_macStyle
}) })
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "hexo-theme-butterfly", "name": "hexo-theme-butterfly",
"version": "4.14.0-b2", "version": "4.14.0-b3",
"description": "A Simple and Card UI Design theme for Hexo", "description": "A Simple and Card UI Design theme for Hexo",
"main": "package.json", "main": "package.json",
"scripts": { "scripts": {

View File

@@ -7,9 +7,11 @@ hexo.extend.filter.register('before_generate', () => {
}, },
menu: null, menu: null,
highlight_theme: 'light', highlight_theme: 'light',
highlight_theme_macStyle: false,
highlight_copy: true, highlight_copy: true,
highlight_lang: true, highlight_lang: true,
highlight_shrink: false, highlight_shrink: false,
highlight_fullpage: true,
highlight_height_limit: false, highlight_height_limit: false,
code_word_wrap: false, code_word_wrap: false,
social: null, social: null,
@@ -51,6 +53,7 @@ hexo.extend.filter.register('before_generate', () => {
label: true label: true
}, },
post: { post: {
position: 'left',
date_type: 'both', date_type: 'both',
date_format: 'date', date_format: 'date',
categories: true, categories: true,

View File

@@ -1,4 +1,5 @@
$highlight_theme = hexo-config('highlight_theme') $highlight_theme = hexo-config('highlight_theme')
$highlight_macstyle = hexo-config('highlight_theme_macStyle')
wordWrap = $highlight_enable && !$highlight_line_number && hexo-config('code_word_wrap') wordWrap = $highlight_enable && !$highlight_line_number && hexo-config('code_word_wrap')
@require 'theme' @require 'theme'
@@ -95,36 +96,38 @@ $code-block
opacity: 0 opacity: 0
.highlight-tools .highlight-tools
position: relative
display: flex display: flex
align-items: center align-items: center
overflow: hidden padding: 0 8px
min-height: 24px min-height: 24px
height: 2.15em height: 2.15em
background: var(--hltools-bg) background: var(--hltools-bg)
color: var(--hltools-color) color: var(--hltools-color)
font-size: $code-font-size font-size: $code-font-size
& > *
margin: 0 3px
i
cursor: pointer
transition: all .3s
&:hover
color: $theme-color
&.closed &.closed
& ~ * & ~ *
display: none display: none
.expand .expand
transition: all .3s transform: rotate(-90deg)
transform: rotate(-90deg) !important
.expand if !$highlight_macstyle
position: absolute & > .macStyle
padding: .57em .7em margin: 0
cursor: pointer
transition: transform .3s
& + .code-lang
left: 1.7em
.code-lang .code-lang
position: absolute flex: 1
left: 14px
text-transform: uppercase text-transform: uppercase
font-weight: bold font-weight: bold
font-size: 1.15em font-size: 1.15em
@@ -132,19 +135,19 @@ $code-block
-webkit-user-select: none -webkit-user-select: none
.copy-notice .copy-notice
position: absolute padding-right: 2px
right: 2.4em
opacity: 0 opacity: 0
transition: opacity .4s transition: opacity .4s
.copy-button if hexo-config('highlight_lang')
position: absolute .code-lang
right: 14px flex: 1
cursor: pointer else if (!$highlight_macstyle && hexo-config('highlight_shrink') != 'none')
transition: color .2s & > div:nth-child(2)
flex: 1
&:hover else
color: $theme-color .macStyle
flex: 1
.gutter .gutter
user-select: none user-select: none
@@ -156,7 +159,8 @@ $code-block
td td
border: none border: none
if $highlight_theme == 'mac' || ($highlight_theme == 'mac light') if $highlight_macstyle
#article-container
figure.highlight figure.highlight
margin: 0 0 24px margin: 0 0 24px
border-radius: 7px border-radius: 7px
@@ -164,33 +168,39 @@ $code-block
-webkit-transform: translateZ(0) -webkit-transform: translateZ(0)
.highlight-tools .highlight-tools
&:after padding: 0 10px
position: absolute
left: 14px
width: 12px
height: 12px
border-radius: 50%
background: #fc625d
box-shadow: 20px 0 #fdbc40, 40px 0 #35cd4b
content: ' '
.expand .macStyle
right: 0 display: flex
& > *
margin-right: 8px
width: 12px
height: 12px
border-radius: 50%
& > :last-child
margin-right: 5px
.mac-close
background: #fc625d
.mac-minimize
background: #fdbc40
.mac-maximize
background: #35cd4b
if hexo-config('highlight_shrink') != 'none'
& > div:nth-child(2)
order: 8
&.closed &.closed
transition: all .3s .expand
transform: rotate(90deg) !important transform: rotate(90deg)
& ~ .copy-notice if hexo-config('highlight_height_limit')
right: 3.45em #article-container
& ~ .copy-button
right: 2.1em
.code-lang
left: 75px
if hexo-config('highlight_height_limit')
.code-expand-btn .code-expand-btn
position: absolute position: absolute
bottom: 0 bottom: 0
@@ -220,12 +230,50 @@ $code-block
overflow: hidden overflow: hidden
height: unit(hexo-config('highlight_height_limit'), px) height: unit(hexo-config('highlight_height_limit'), px)
@keyframes code-expand-key @keyframes code-expand-key
0% 0%
opacity: .6 opacity: .6
50% 50%
opacity: .1 opacity: .1
100% 100%
opacity: .6 opacity: .6
if hexo-config('highlight_fullpage')
#article-container
figure.highlight.code-fullpage
position: fixed
top: 0
right: 0
bottom: 0
left: 0
z-index: 9999
margin: 0
border-radius: 0
animation: code-fullpage .3s
.code-expand-btn,
.expand
display: none
.highlight-tools
& ~ pre,
& ~ table
display: block
overflow: auto
height: calc(100vh - 2.15em)
margin-bottom: 0
@keyframes code-fullpage
0%,
100%
transform: translateX(0)
20%,
60%
transform: translateX(-5px)
40%,
80%
transform: translateX(5px)

View File

@@ -1,4 +1,4 @@
if $highlight_theme == 'light' || ($highlight_theme == 'mac light') if $highlight_theme == 'light'
// prism-base16-ateliersulphurpool.light // prism-base16-ateliersulphurpool.light
pre[class*='language-'] pre[class*='language-']
.token.function .token.function
@@ -82,7 +82,7 @@ if $highlight_theme == 'light' || ($highlight_theme == 'mac light')
outline: .4em solid #c94922 outline: .4em solid #c94922
outline-offset: .4em outline-offset: .4em
if $highlight_theme == 'darker' || ($highlight_theme == 'mac') if $highlight_theme == 'darker'
// prism-atom-dark // prism-atom-dark
pre[class*='language-'] pre[class*='language-']
.token.comment, .token.comment,

View File

@@ -1,4 +1,4 @@
if $highlight_theme == 'darker' || ($highlight_theme == 'mac') if $highlight_theme == 'darker'
$highlight-background = #212121 $highlight-background = #212121
$highlight-selection = #61616150 $highlight-selection = #61616150
$highlight-foreground = #EEFFFF $highlight-foreground = #EEFFFF
@@ -29,6 +29,7 @@ if $highlight_theme == 'pale night'
$highlight-background = #292D3E $highlight-background = #292D3E
$highlight-selection = #717CB450 $highlight-selection = #717CB450
$highlight-foreground = #A6ACCD $highlight-foreground = #A6ACCD
$highlight-mac-border = rgba($highlight-background, .4)
$highlight-gutter = { $highlight-gutter = {
color: alpha($highlight-foreground, .5), color: alpha($highlight-foreground, .5),
bg-color: $highlight-background bg-color: $highlight-background
@@ -55,6 +56,7 @@ if $highlight_theme == 'ocean'
$highlight-background = #0F111A $highlight-background = #0F111A
$highlight-selection = #717CB450 $highlight-selection = #717CB450
$highlight-foreground = #8F93A2 $highlight-foreground = #8F93A2
$highlight-mac-border = rgba($highlight-background, .4)
$highlight-gutter = { $highlight-gutter = {
color: alpha($highlight-foreground, .5), color: alpha($highlight-foreground, .5),
bg-color: $highlight-background bg-color: $highlight-background
@@ -77,7 +79,7 @@ if $highlight_theme == 'ocean'
$highlight-deletion = #BF42BF $highlight-deletion = #BF42BF
$highlight-addition = #105EDE $highlight-addition = #105EDE
if $highlight_theme == 'light' || ($highlight_theme == 'mac light') if $highlight_theme == 'light'
$highlight-background = #F6F8FA $highlight-background = #F6F8FA
$highlight-selection = #80CBC440 $highlight-selection = #80CBC440
$highlight-foreground = #90A4AE $highlight-foreground = #90A4AE

View File

@@ -99,13 +99,29 @@
#post-info #post-info
position: absolute position: absolute
bottom: 30px
padding: 0 8%
width: 100% width: 100%
+maxWidth768() if hexo-config('post_meta.post.position') == 'center'
bottom: 22px top: calc(50% + 30px)
padding: 0 22px padding: 0 8%
text-align: center
transform: translateY(-50%)
+maxWidth768()
padding: 0 15px
else
bottom: 30px
& > *
margin: 0 auto
padding: 0 15px
max-width: 1200px
@media screen and (min-width: 768px) and (max-width: 1300px)
padding: 0 30px
+minWidth2000()
max-width: 70%
&.not-top-img &.not-top-img
margin-bottom: 10px margin-bottom: 10px

View File

@@ -63,26 +63,27 @@ document.addEventListener('DOMContentLoaded', function () {
const highLight = GLOBAL_CONFIG.highlight const highLight = GLOBAL_CONFIG.highlight
if (!highLight) return if (!highLight) return
const { highlightCopy, highlightLang, highlightHeightLimit, plugin } = highLight const { highlightCopy, highlightLang, highlightHeightLimit, highlightFullpage, highlightMacStyle, plugin } = highLight
const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink
const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined || highlightFullpage || highlightMacStyle
const $figureHighlight = plugin === 'highlight.js' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]') const $figureHighlight = plugin === 'highlight.js' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return
const isPrismjs = plugin === 'prismjs' const isPrismjs = plugin === 'prismjs'
const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' const highlightShrinkClass = isHighlightShrink === true ? 'closed' : ''
const highlightShrinkEle = isHighlightShrink !== undefined ? '<i class="fas fa-angle-down expand"></i>' : '' const highlightShrinkEle = isHighlightShrink !== undefined ? '<div><i class="fas fa-angle-down expand"></i></div>' : ''
const highlightCopyEle = highlightCopy ? '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' : '' const highlightCopyEle = highlightCopy ? '<div class="copy-notice"></div><i class="fas fa-paste copy-button"></i>' : ''
const highlightMacStyleEle = '<div class="macStyle"><div class="mac-close"></div><div class="mac-minimize"></div><div class="mac-maximize"></div></div>'
const highlightFullpageEle = highlightFullpage ? '<i class="fa-solid fa-up-right-and-down-left-from-center fullpage-button"></i>' : ''
const alertInfo = (ele, text) => { const alertInfo = (ele, text) => {
if (GLOBAL_CONFIG.Snackbar !== undefined) { if (GLOBAL_CONFIG.Snackbar !== undefined) {
btf.snackbarShow(text) btf.snackbarShow(text)
} else { } else {
const prevEle = ele.previousElementSibling ele.textContent = text
prevEle.textContent = text ele.style.opacity = 1
prevEle.style.opacity = 1 setTimeout(() => { ele.style.opacity = 0 }, 800)
setTimeout(() => { prevEle.style.opacity = 0 }, 800)
} }
} }
@@ -96,16 +97,16 @@ document.addEventListener('DOMContentLoaded', function () {
} }
// click events // click events
const highlightCopyFn = ele => { const highlightCopyFn = (ele, clickEle) => {
const $buttonParent = ele.parentNode const $buttonParent = ele.parentNode
$buttonParent.classList.add('copy-true') $buttonParent.classList.add('copy-true')
const selection = window.getSelection() const selection = window.getSelection()
const range = document.createRange() const range = document.createRange()
const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre' const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre'
range.selectNodeContents($buttonParent.querySelectorAll(`${preCodeSelector}`)[0]) range.selectNodeContents($buttonParent.querySelector(`${preCodeSelector}`))
selection.removeAllRanges() selection.removeAllRanges()
selection.addRange(range) selection.addRange(range)
copy(ele.lastChild) copy(clickEle.previousElementSibling)
selection.removeAllRanges() selection.removeAllRanges()
$buttonParent.classList.remove('copy-true') $buttonParent.classList.remove('copy-true')
} }
@@ -114,23 +115,33 @@ document.addEventListener('DOMContentLoaded', function () {
ele.classList.toggle('closed') ele.classList.toggle('closed')
} }
const codeFullpage = (item, clickEle) => {
const wrapEle = item.closest('figure.highlight')
const isFullpage = wrapEle.classList.toggle('code-fullpage')
document.body.style.overflow = isFullpage ? 'hidden' : ''
clickEle.classList.toggle('fa-down-left-and-up-right-to-center', isFullpage)
clickEle.classList.toggle('fa-up-right-and-down-left-from-center', !isFullpage)
}
const highlightToolsFn = function (e) { const highlightToolsFn = function (e) {
const $target = e.target.classList const $target = e.target.classList
if ($target.contains('expand')) highlightShrinkFn(this) if ($target.contains('expand')) highlightShrinkFn(this)
else if ($target.contains('copy-button')) highlightCopyFn(this) else if ($target.contains('copy-button')) highlightCopyFn(this, e.target)
else if ($target.contains('fullpage-button')) codeFullpage(this, e.target)
} }
const expandCode = function () { const expandCode = function () {
this.classList.toggle('expand-done') this.classList.toggle('expand-done')
} }
const createEle = (lang, item, service) => { const createEle = (lang, item) => {
const fragment = document.createDocumentFragment() const fragment = document.createDocumentFragment()
if (isShowTool) { if (isShowTool) {
const hlTools = document.createElement('div') const hlTools = document.createElement('div')
hlTools.className = `highlight-tools ${highlightShrinkClass}` hlTools.className = `highlight-tools ${highlightShrinkClass}`
hlTools.innerHTML = highlightShrinkEle + lang + highlightCopyEle hlTools.innerHTML = highlightMacStyleEle + highlightShrinkEle + lang + highlightCopyEle + highlightFullpageEle
btf.addEventListenerPjax(hlTools, 'click', highlightToolsFn) btf.addEventListenerPjax(hlTools, 'click', highlightToolsFn)
fragment.appendChild(hlTools) fragment.appendChild(hlTools)
} }
@@ -143,37 +154,26 @@ document.addEventListener('DOMContentLoaded', function () {
fragment.appendChild(ele) fragment.appendChild(ele)
} }
if (service === 'hl') { isPrismjs ? item.parentNode.insertBefore(fragment, item) : item.insertBefore(fragment, item.firstChild)
item.insertBefore(fragment, item.firstChild)
} else {
item.parentNode.insertBefore(fragment, item)
}
} }
if (isPrismjs) { $figureHighlight.forEach(item => {
$figureHighlight.forEach(item => { let langName = ''
if (highlightLang) { if (isPrismjs) btf.wrap(item, 'figure', { class: 'highlight' })
const langName = item.getAttribute('data-language') || 'Code'
const highlightLangEle = `<div class="code-lang">${langName}</div>` if (!highlightLang) {
btf.wrap(item, 'figure', { class: 'highlight' }) createEle('', item)
createEle(highlightLangEle, item) return
} else { }
btf.wrap(item, 'figure', { class: 'highlight' })
createEle('', item) if (isPrismjs) {
} langName = item.getAttribute('data-language') || 'Code'
}) } else {
} else { langName = item.getAttribute('class').split(' ')[1]
$figureHighlight.forEach(item => { if (langName === 'plain' || langName === undefined) langName = 'Code'
if (highlightLang) { }
let langName = item.getAttribute('class').split(' ')[1] createEle(`<div class="code-lang">${langName}</div>`, item)
if (langName === 'plain' || langName === undefined) langName = 'Code' })
const highlightLangEle = `<div class="code-lang">${langName}</div>`
createEle(highlightLangEle, item, 'hl')
} else {
createEle('', item, 'hl')
}
})
}
} }
/** /**