mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-12 22:17:06 +08:00
Merge branch 'dev'
This commit is contained in:
@@ -319,6 +319,7 @@ aside:
|
|||||||
# If set 0 will show all
|
# If set 0 will show all
|
||||||
limit: 40
|
limit: 40
|
||||||
color: false
|
color: false
|
||||||
|
custom_colors:
|
||||||
# Order of tags, random/name/length
|
# Order of tags, random/name/length
|
||||||
orderby: random
|
orderby: random
|
||||||
# Sort of order. 1, asc for ascending; -1, desc for descending
|
# Sort of order. 1, asc for ascending; -1, desc for descending
|
||||||
@@ -939,6 +940,10 @@ mermaid:
|
|||||||
theme:
|
theme:
|
||||||
light: default
|
light: default
|
||||||
dark: dark
|
dark: dark
|
||||||
|
# Enable "Open in New Tab" button to view diagram in a separate window
|
||||||
|
open_in_new_tab: true
|
||||||
|
# Enable zoom and pan interactions on diagrams
|
||||||
|
zoom_pan: true
|
||||||
|
|
||||||
# chartjs
|
# chartjs
|
||||||
# see https://www.chartjs.org/docs/latest/
|
# see https://www.chartjs.org/docs/latest/
|
||||||
|
|||||||
@@ -72,20 +72,16 @@
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let highlight = 'undefined'
|
let highlightProvider = config.syntax_highlighter || (config.highlight.enable ? 'highlight.js' : config.prismjs.enable ? 'prismjs' : null)
|
||||||
let syntaxHighlighter = config.syntax_highlighter
|
const { copy, language, height_limit, fullpage, macStyle, shrink } = theme.code_blocks
|
||||||
let highlightEnable = syntaxHighlighter ? ['highlight.js', 'prismjs'].includes(syntaxHighlighter) : (config.highlight.enable || config.prismjs.enable)
|
let highlight = JSON.stringify({
|
||||||
if (highlightEnable) {
|
plugin: highlightProvider,
|
||||||
const { copy, language, height_limit, fullpage, macStyle } = theme.code_blocks
|
highlightCopy: copy,
|
||||||
highlight = JSON.stringify({
|
highlightLang: language,
|
||||||
plugin: syntaxHighlighter ? syntaxHighlighter : config.highlight.enable ? 'highlight.js' : 'prismjs',
|
highlightHeightLimit: height_limit,
|
||||||
highlightCopy: copy,
|
highlightFullpage: fullpage,
|
||||||
highlightLang: language,
|
highlightMacStyle: macStyle
|
||||||
highlightHeightLimit: height_limit,
|
})
|
||||||
highlightFullpage: fullpage,
|
|
||||||
highlightMacStyle: macStyle
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
script.
|
script.
|
||||||
const GLOBAL_CONFIG = {
|
const GLOBAL_CONFIG = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
mixin indexPostUI()
|
mixin indexPostUI()
|
||||||
- const indexLayout = theme.index_layout
|
- const indexLayout = theme.index_layout
|
||||||
- const masonryLayoutClass = (indexLayout === 6 || indexLayout === 7) ? 'masonry' : ''
|
- const masonryLayoutClass = [6, 7].includes(indexLayout) ? 'masonry' : ''
|
||||||
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
|
#recent-posts.recent-posts.nc(class=masonryLayoutClass)
|
||||||
.recent-post-items
|
.recent-post-items
|
||||||
each article, index in page.posts.data
|
each article, index in page.posts.data
|
||||||
@@ -8,17 +8,17 @@ mixin indexPostUI()
|
|||||||
- const link = article.link || article.path
|
- const link = article.link || article.path
|
||||||
- const title = article.title || _p('no_title')
|
- const title = article.title || _p('no_title')
|
||||||
- const leftOrRight = indexLayout === 3 ? (index % 2 === 0 ? 'left' : 'right') : (indexLayout === 2 ? 'right' : '')
|
- const leftOrRight = indexLayout === 3 ? (index % 2 === 0 ? 'left' : 'right') : (indexLayout === 2 ? 'right' : '')
|
||||||
- const post_cover = article.cover
|
- const postCover = article.cover
|
||||||
- const no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
|
- const noCover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
|
||||||
|
|
||||||
if post_cover && theme.cover.index_enable
|
if postCover && theme.cover.index_enable
|
||||||
.post_cover(class=leftOrRight)
|
.post_cover(class=leftOrRight)
|
||||||
a(href=url_for(link) title=title)
|
a(href=url_for(link) title=title)
|
||||||
if article.cover_type === 'img'
|
if article.cover_type === 'img'
|
||||||
img.post-bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
img.post-bg(src=url_for(postCover) onerror=`this.onerror=null;this.src='${url_for(theme.error_img.post_page)}'` alt=title)
|
||||||
else
|
else
|
||||||
div.post-bg(style=`background: ${post_cover}`)
|
div.post-bg(style=`background: ${postCover}`)
|
||||||
.recent-post-info(class=no_cover)
|
.recent-post-info(class=noCover)
|
||||||
a.article-title(href=url_for(link) title=title)
|
a.article-title(href=url_for(link) title=title)
|
||||||
if globalPageType === 'home' && (article.top || article.sticky > 0)
|
if globalPageType === 'home' && (article.top || article.sticky > 0)
|
||||||
i.fas.fa-thumbtack.sticky
|
i.fas.fa-thumbtack.sticky
|
||||||
@@ -35,13 +35,13 @@ mixin indexPostUI()
|
|||||||
span.article-meta-label=_p('post.updated')
|
span.article-meta-label=_p('post.updated')
|
||||||
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))= date(article.updated, config.date_format)
|
time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))= date(article.updated, config.date_format)
|
||||||
else
|
else
|
||||||
- const data_type_updated = theme.post_meta.page.date_type === 'updated'
|
- const isUpdatedType = theme.post_meta.page.date_type === 'updated'
|
||||||
- const date_type = data_type_updated ? 'updated' : 'date'
|
- const dateType = isUpdatedType ? 'updated' : 'date'
|
||||||
- const date_icon = data_type_updated ? 'fas fa-history' : 'far fa-calendar-alt'
|
- const dateIcon = isUpdatedType ? 'fas fa-history' : 'far fa-calendar-alt'
|
||||||
- const date_title = data_type_updated ? _p('post.updated') : _p('post.created')
|
- const dateTitle = isUpdatedType ? _p('post.updated') : _p('post.created')
|
||||||
i(class=date_icon)
|
i(class=dateIcon)
|
||||||
span.article-meta-label= date_title
|
span.article-meta-label= dateTitle
|
||||||
time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))= date(article[date_type], config.date_format)
|
time(datetime=date_xml(article[dateType]) title=dateTitle + ' ' + full_date(article[dateType]))= date(article[dateType], config.date_format)
|
||||||
if theme.post_meta.page.categories && article.categories.data.length > 0
|
if theme.post_meta.page.categories && article.categories.data.length > 0
|
||||||
span.article-meta
|
span.article-meta
|
||||||
span.article-meta-separator |
|
span.article-meta-separator |
|
||||||
@@ -69,7 +69,10 @@ mixin indexPostUI()
|
|||||||
span.article-meta-label= ' ' + _p('card_post_count')
|
span.article-meta-label= ' ' + _p('card_post_count')
|
||||||
|
|
||||||
if theme.comments.card_post_count && theme.comments.use
|
if theme.comments.card_post_count && theme.comments.use
|
||||||
case theme.comments.use[0]
|
- const commentSystem = theme.comments.use[0]
|
||||||
|
- const commentLink = url_for(link) + '#post-comment'
|
||||||
|
|
||||||
|
case commentSystem
|
||||||
when 'Disqus'
|
when 'Disqus'
|
||||||
when 'Disqusjs'
|
when 'Disqusjs'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
@@ -77,30 +80,30 @@ mixin indexPostUI()
|
|||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Valine'
|
when 'Valine'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=url_for(link) + '#post-comment')
|
a(href=commentLink)
|
||||||
span.valine-comment-count(data-xid=url_for(link))
|
span.valine-comment-count(data-xid=url_for(link))
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Waline'
|
when 'Waline'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=url_for(link) + '#post-comment')
|
a(href=commentLink)
|
||||||
span.waline-comment-count(data-path=url_for(link))
|
span.waline-comment-count(data-path=url_for(link))
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Twikoo'
|
when 'Twikoo'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a.twikoo-count(href=url_for(link) + '#post-comment')
|
a.twikoo-count(href=commentLink)
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Facebook Comments'
|
when 'Facebook Comments'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=url_for(link) + '#post-comment')
|
a(href=commentLink)
|
||||||
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
|
span.fb-comments-count(data-href=urlNoIndex(article.permalink))
|
||||||
when 'Remark42'
|
when 'Remark42'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=url_for(link) + '#post-comment')
|
a(href=commentLink)
|
||||||
span.remark42__counter(data-url=urlNoIndex(article.permalink))
|
span.remark42__counter(data-url=urlNoIndex(article.permalink))
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
when 'Artalk'
|
when 'Artalk'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=url_for(link) + '#post-comment')
|
a(href=commentLink)
|
||||||
span.artalk-count(data-page-key=url_for(link))
|
span.artalk-count(data-page-key=url_for(link))
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
|
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
.tag-cloud-list.text-center
|
.tag-cloud-list.text-center
|
||||||
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em'})
|
!=cloudTags({source: site.tags, orderby: page.orderby || 'random', order: page.order || 1, minfontsize: 1.2, maxfontsize: 1.5, limit: 0, unit: 'em', custom_colors: page.custom_colors})
|
||||||
|
|||||||
2
layout/includes/third-party/abcjs/abcjs.pug
vendored
2
layout/includes/third-party/abcjs/abcjs.pug
vendored
@@ -24,7 +24,7 @@ script.
|
|||||||
const options = { ...params, responsive: "resize" }
|
const options = { ...params, responsive: "resize" }
|
||||||
|
|
||||||
// Render the music score using ABCJS.renderAbc
|
// Render the music score using ABCJS.renderAbc
|
||||||
ABCJS.renderAbc(ele, ele.innerHTML, options)
|
ABCJS.renderAbc(ele, ele.textContent, options)
|
||||||
}
|
}
|
||||||
}, 100)
|
}, 100)
|
||||||
}
|
}
|
||||||
|
|||||||
268
layout/includes/third-party/math/mermaid.pug
vendored
268
layout/includes/third-party/math/mermaid.pug
vendored
@@ -1,11 +1,275 @@
|
|||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
|
const parseViewBox = viewBox => {
|
||||||
|
if (!viewBox) return null
|
||||||
|
const parts = viewBox.trim().split(/[\s,]+/).map(n => Number(n))
|
||||||
|
if (parts.length !== 4 || parts.some(n => Number.isNaN(n))) return null
|
||||||
|
return parts
|
||||||
|
}
|
||||||
|
|
||||||
|
const getSvgViewBox = svg => {
|
||||||
|
const attr = parseViewBox(svg.getAttribute('viewBox'))
|
||||||
|
if (attr) return attr
|
||||||
|
|
||||||
|
// Fallback: use bbox to build a viewBox
|
||||||
|
try {
|
||||||
|
const bbox = svg.getBBox()
|
||||||
|
if (bbox && bbox.width && bbox.height) return [bbox.x, bbox.y, bbox.width, bbox.height]
|
||||||
|
} catch (e) {
|
||||||
|
// getBBox may fail on some edge cases; ignore
|
||||||
|
}
|
||||||
|
|
||||||
|
const w = Number(svg.getAttribute('width')) || 0
|
||||||
|
const h = Number(svg.getAttribute('height')) || 0
|
||||||
|
if (w > 0 && h > 0) return [0, 0, w, h]
|
||||||
|
return [0, 0, 100, 100]
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSvgViewBox = (svg, vb) => {
|
||||||
|
svg.setAttribute('viewBox', `${vb[0]} ${vb[1]} ${vb[2]} ${vb[3]}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const clamp = (v, min, max) => Math.max(min, Math.min(max, v))
|
||||||
|
|
||||||
|
const openSvgInNewTab = ({ source, initViewBox }) => {
|
||||||
|
const getClonedSvg = () => {
|
||||||
|
if (typeof source === 'string') {
|
||||||
|
const template = document.createElement('template')
|
||||||
|
template.innerHTML = source.trim()
|
||||||
|
const svg = template.content.querySelector('svg')
|
||||||
|
return svg ? svg.cloneNode(true) : null
|
||||||
|
}
|
||||||
|
if (source && typeof source.cloneNode === 'function') {
|
||||||
|
return source.cloneNode(true)
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const clone = getClonedSvg()
|
||||||
|
if (!clone) return
|
||||||
|
if (initViewBox && initViewBox.length === 4) {
|
||||||
|
clone.setAttribute('viewBox', initViewBox.join(' '))
|
||||||
|
}
|
||||||
|
if (!clone.getAttribute('xmlns')) clone.setAttribute('xmlns', 'http://www.w3.org/2000/svg')
|
||||||
|
if (!clone.getAttribute('xmlns:xlink') && clone.outerHTML.includes('xlink:')) {
|
||||||
|
clone.setAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink')
|
||||||
|
}
|
||||||
|
// inject background to match current theme
|
||||||
|
const isDark = document.documentElement.getAttribute('data-theme') === 'dark'
|
||||||
|
const bg = getComputedStyle(document.body).backgroundColor || (isDark ? '#1e1e1e' : '#ffffff')
|
||||||
|
if (!clone.style.background) clone.style.background = bg
|
||||||
|
|
||||||
|
const serializer = new XMLSerializer()
|
||||||
|
const svgSource = serializer.serializeToString(clone)
|
||||||
|
const htmlSource = `<!doctype html><html><head><meta charset="utf-8" />
|
||||||
|
<style>
|
||||||
|
html, body { width: 100%; height: 100%; margin: 0; display: flex; align-items: center; justify-content: center; background: ${bg}; }
|
||||||
|
svg { max-width: 100%; max-height: 100%; height: auto; width: auto; }
|
||||||
|
</style>
|
||||||
|
</head><body>${svgSource}</body></html>`
|
||||||
|
const blob = new Blob([htmlSource], { type: 'text/html;charset=utf-8' })
|
||||||
|
const url = URL.createObjectURL(blob)
|
||||||
|
window.open(url, '_blank', 'noopener')
|
||||||
|
setTimeout(() => URL.revokeObjectURL(url), 30000)
|
||||||
|
}
|
||||||
|
|
||||||
|
const attachMermaidViewerButton = wrap => {
|
||||||
|
let btn = wrap.querySelector('.mermaid-open-btn')
|
||||||
|
if (!btn) {
|
||||||
|
btn = document.createElement('button')
|
||||||
|
btn.type = 'button'
|
||||||
|
btn.className = 'mermaid-open-btn'
|
||||||
|
wrap.appendChild(btn)
|
||||||
|
}
|
||||||
|
|
||||||
|
btn.innerHTML = '<i class="fa fa-search fa-fw" aria-hidden="true"></i>'
|
||||||
|
|
||||||
|
if (!btn.__mermaidViewerBound) {
|
||||||
|
btn.addEventListener('click', e => {
|
||||||
|
e.preventDefault()
|
||||||
|
e.stopPropagation()
|
||||||
|
const svg = wrap.__mermaidOriginalSvg || wrap.querySelector('svg')
|
||||||
|
if (!svg) return
|
||||||
|
const initViewBox = wrap.__mermaidInitViewBox
|
||||||
|
if (typeof svg === 'string') {
|
||||||
|
openSvgInNewTab({ source: svg, initViewBox })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
openSvgInNewTab({ source: svg, initViewBox })
|
||||||
|
})
|
||||||
|
btn.__mermaidViewerBound = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zoom around a point (px, py) in the SVG viewport (in viewBox coordinates)
|
||||||
|
const zoomAtPoint = (vb, factor, px, py) => {
|
||||||
|
const w = vb[2] * factor
|
||||||
|
const h = vb[3] * factor
|
||||||
|
const nx = px - (px - vb[0]) * factor
|
||||||
|
const ny = py - (py - vb[1]) * factor
|
||||||
|
return [nx, ny, w, h]
|
||||||
|
}
|
||||||
|
|
||||||
|
const initMermaidGestures = wrap => {
|
||||||
|
const svg = wrap.querySelector('svg')
|
||||||
|
if (!svg) return
|
||||||
|
|
||||||
|
// Ensure viewBox exists so gestures always work
|
||||||
|
const initVb = getSvgViewBox(svg)
|
||||||
|
wrap.__mermaidInitViewBox = initVb
|
||||||
|
wrap.__mermaidCurViewBox = initVb.slice()
|
||||||
|
setSvgViewBox(svg, initVb)
|
||||||
|
|
||||||
|
// Avoid binding multiple times on themeChange/pjax
|
||||||
|
if (wrap.__mermaidGestureBound) return
|
||||||
|
wrap.__mermaidGestureBound = true
|
||||||
|
|
||||||
|
// Helper: map client (viewport) coordinate -> viewBox coordinate
|
||||||
|
const clientToViewBox = (clientX, clientY) => {
|
||||||
|
const rect = svg.getBoundingClientRect()
|
||||||
|
const vb = wrap.__mermaidCurViewBox || getSvgViewBox(svg)
|
||||||
|
const x = vb[0] + (clientX - rect.left) * (vb[2] / rect.width)
|
||||||
|
const y = vb[1] + (clientY - rect.top) * (vb[3] / rect.height)
|
||||||
|
return { x, y, rect, vb }
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
pointers: new Map(),
|
||||||
|
startVb: null,
|
||||||
|
startDist: 0,
|
||||||
|
startCenter: null
|
||||||
|
}
|
||||||
|
|
||||||
|
const clampVb = vb => {
|
||||||
|
const init = wrap.__mermaidInitViewBox || vb
|
||||||
|
const minW = init[2] * 0.1
|
||||||
|
const maxW = init[2] * 10
|
||||||
|
const minH = init[3] * 0.1
|
||||||
|
const maxH = init[3] * 10
|
||||||
|
vb[2] = clamp(vb[2], minW, maxW)
|
||||||
|
vb[3] = clamp(vb[3], minH, maxH)
|
||||||
|
return vb
|
||||||
|
}
|
||||||
|
|
||||||
|
const setCurVb = vb => {
|
||||||
|
vb = clampVb(vb)
|
||||||
|
wrap.__mermaidCurViewBox = vb
|
||||||
|
setSvgViewBox(svg, vb)
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPointerDown = e => {
|
||||||
|
// Allow only primary button for mouse
|
||||||
|
if (e.pointerType === 'mouse' && e.button !== 0) return
|
||||||
|
svg.setPointerCapture(e.pointerId)
|
||||||
|
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
|
||||||
|
|
||||||
|
if (state.pointers.size === 1) {
|
||||||
|
state.startVb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
|
||||||
|
} else if (state.pointers.size === 2) {
|
||||||
|
const pts = [...state.pointers.values()]
|
||||||
|
const dx = pts[0].x - pts[1].x
|
||||||
|
const dy = pts[0].y - pts[1].y
|
||||||
|
state.startDist = Math.hypot(dx, dy)
|
||||||
|
state.startVb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
|
||||||
|
state.startCenter = { x: (pts[0].x + pts[1].x) / 2, y: (pts[0].y + pts[1].y) / 2 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPointerMove = e => {
|
||||||
|
if (!state.pointers.has(e.pointerId)) return
|
||||||
|
state.pointers.set(e.pointerId, { x: e.clientX, y: e.clientY })
|
||||||
|
|
||||||
|
// Pan with 1 pointer
|
||||||
|
if (state.pointers.size === 1 && state.startVb) {
|
||||||
|
const p = [...state.pointers.values()][0]
|
||||||
|
const prev = { x: e.clientX - e.movementX, y: e.clientY - e.movementY }
|
||||||
|
// movementX/Y unreliable on touch, compute from stored last position
|
||||||
|
const last = wrap.__mermaidLastSinglePointer || p
|
||||||
|
const dxClient = p.x - last.x
|
||||||
|
const dyClient = p.y - last.y
|
||||||
|
wrap.__mermaidLastSinglePointer = p
|
||||||
|
|
||||||
|
const { rect } = clientToViewBox(p.x, p.y)
|
||||||
|
const vb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
|
||||||
|
const dx = dxClient * (vb[2] / rect.width)
|
||||||
|
const dy = dyClient * (vb[3] / rect.height)
|
||||||
|
setCurVb([vb[0] - dx, vb[1] - dy, vb[2], vb[3]])
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pinch zoom with 2 pointers
|
||||||
|
if (state.pointers.size === 2 && state.startVb && state.startDist > 0) {
|
||||||
|
const pts = [...state.pointers.values()]
|
||||||
|
const dx = pts[0].x - pts[1].x
|
||||||
|
const dy = pts[0].y - pts[1].y
|
||||||
|
const dist = Math.hypot(dx, dy)
|
||||||
|
if (!dist) return
|
||||||
|
const factor = state.startDist / dist // dist bigger => zoom in (viewBox smaller)
|
||||||
|
|
||||||
|
const cx = (pts[0].x + pts[1].x) / 2
|
||||||
|
const cy = (pts[0].y + pts[1].y) / 2
|
||||||
|
const centerClient = { x: cx, y: cy }
|
||||||
|
|
||||||
|
const pxy = clientToViewBox(centerClient.x, centerClient.y)
|
||||||
|
const cpx = pxy.x
|
||||||
|
const cpy = pxy.y
|
||||||
|
|
||||||
|
const vb = zoomAtPoint(state.startVb, factor, cpx, cpy)
|
||||||
|
setCurVb(vb)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const onPointerUpOrCancel = e => {
|
||||||
|
state.pointers.delete(e.pointerId)
|
||||||
|
if (state.pointers.size === 0) {
|
||||||
|
state.startVb = null
|
||||||
|
state.startDist = 0
|
||||||
|
state.startCenter = null
|
||||||
|
wrap.__mermaidLastSinglePointer = null
|
||||||
|
} else if (state.pointers.size === 1) {
|
||||||
|
// reset single pointer baseline to avoid jump
|
||||||
|
wrap.__mermaidLastSinglePointer = [...state.pointers.values()][0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wheel zoom (mouse/trackpad)
|
||||||
|
const onWheel = e => {
|
||||||
|
// ctrlKey on mac trackpad pinch; we treat both as zoom
|
||||||
|
e.preventDefault()
|
||||||
|
const delta = e.deltaY
|
||||||
|
const zoomFactor = delta > 0 ? 1.1 : 0.9
|
||||||
|
const { x, y } = clientToViewBox(e.clientX, e.clientY)
|
||||||
|
const vb = (wrap.__mermaidCurViewBox || getSvgViewBox(svg)).slice()
|
||||||
|
setCurVb(zoomAtPoint(vb, zoomFactor, x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDblClick = () => {
|
||||||
|
const init = wrap.__mermaidInitViewBox
|
||||||
|
if (!init) return
|
||||||
|
wrap.__mermaidCurViewBox = init.slice()
|
||||||
|
setSvgViewBox(svg, init)
|
||||||
|
}
|
||||||
|
|
||||||
|
svg.addEventListener('pointerdown', onPointerDown)
|
||||||
|
svg.addEventListener('pointermove', onPointerMove)
|
||||||
|
svg.addEventListener('pointerup', onPointerUpOrCancel)
|
||||||
|
svg.addEventListener('pointercancel', onPointerUpOrCancel)
|
||||||
|
svg.addEventListener('wheel', onWheel, { passive: false })
|
||||||
|
svg.addEventListener('dblclick', onDblClick)
|
||||||
|
}
|
||||||
|
|
||||||
const runMermaid = ele => {
|
const runMermaid = ele => {
|
||||||
window.loadMermaid = true
|
window.loadMermaid = true
|
||||||
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{theme.mermaid.theme.dark}' : '!{theme.mermaid.theme.light}'
|
const theme = document.documentElement.getAttribute('data-theme') === 'dark' ? '!{theme.mermaid.theme.dark}' : '!{theme.mermaid.theme.light}'
|
||||||
|
|
||||||
ele.forEach((item, index) => {
|
ele.forEach((item, index) => {
|
||||||
const mermaidSrc = item.firstElementChild
|
const mermaidSrc = item.firstElementChild
|
||||||
|
|
||||||
|
// Clear old render (themeChange/pjax will rerun)
|
||||||
|
const oldSvg = item.querySelector('svg')
|
||||||
|
if (oldSvg) oldSvg.remove()
|
||||||
|
item.__mermaidGestureBound = false
|
||||||
|
|
||||||
const config = mermaidSrc.dataset.config ? JSON.parse(mermaidSrc.dataset.config) : {}
|
const config = mermaidSrc.dataset.config ? JSON.parse(mermaidSrc.dataset.config) : {}
|
||||||
if (!config.theme) {
|
if (!config.theme) {
|
||||||
config.theme = theme
|
config.theme = theme
|
||||||
@@ -17,8 +281,12 @@ script.
|
|||||||
const renderFn = mermaid.render(mermaidID, mermaidDefinition)
|
const renderFn = mermaid.render(mermaidID, mermaidDefinition)
|
||||||
const renderMermaid = svg => {
|
const renderMermaid = svg => {
|
||||||
mermaidSrc.insertAdjacentHTML('afterend', svg)
|
mermaidSrc.insertAdjacentHTML('afterend', svg)
|
||||||
|
if (!{theme.mermaid.zoom_pan}) initMermaidGestures(item)
|
||||||
|
item.__mermaidOriginalSvg = svg
|
||||||
|
if (!{theme.mermaid.open_in_new_tab}) attachMermaidViewerButton(item)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// mermaid v9 and v10 compatibility
|
// mermaid v9 and v10 compatibility
|
||||||
typeof renderFn === 'string' ? renderMermaid(renderFn) : renderFn.then(({ svg }) => renderMermaid(svg))
|
typeof renderFn === 'string' ? renderMermaid(renderFn) : renderFn.then(({ svg }) => renderMermaid(svg))
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ if theme.aside.card_tags.enable
|
|||||||
i.fas.fa-tags
|
i.fas.fa-tags
|
||||||
span= _p('aside.card_tags')
|
span= _p('aside.card_tags')
|
||||||
|
|
||||||
- let { limit, orderby, order } = theme.aside.card_tags
|
- let { limit, orderby, order, custom_colors } = theme.aside.card_tags
|
||||||
- limit = limit === 0 ? 0 : limit || 40
|
- limit = limit === 0 ? 0 : limit || 40
|
||||||
|
|
||||||
if theme.aside.card_tags.color
|
if theme.aside.card_tags.color
|
||||||
.card-tag-cloud!= cloudTags({source: site.tags, orderby: orderby, order: order, minfontsize: 1.15, maxfontsize: 1.45, limit: limit, unit: 'em', page: 'index'})
|
.card-tag-cloud!= cloudTags({source: site.tags, orderby: orderby, order: order, minfontsize: 1.15, maxfontsize: 1.45, limit: limit, unit: 'em', page: 'index', custom_colors: custom_colors})
|
||||||
else
|
else
|
||||||
.card-tag-cloud!= tagcloud({orderby: orderby, order: order, min_font: 1.1, max_font: 1.5, amount: limit , color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'})
|
.card-tag-cloud!= tagcloud({orderby: orderby, order: order, min_font: 1.1, max_font: 1.5, amount: limit, color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'})
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hexo-theme-butterfly",
|
"name": "hexo-theme-butterfly",
|
||||||
"version": "5.5.3",
|
"version": "5.5.4",
|
||||||
"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": {
|
||||||
|
|||||||
22
plugins.yml
22
plugins.yml
@@ -1,7 +1,7 @@
|
|||||||
abcjs_basic_js:
|
abcjs_basic_js:
|
||||||
name: abcjs
|
name: abcjs
|
||||||
file: dist/abcjs-basic-min.js
|
file: dist/abcjs-basic-min.js
|
||||||
version: 6.5.2
|
version: 6.6.0
|
||||||
activate_power_mode:
|
activate_power_mode:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/activate-power-mode.min.js
|
file: dist/activate-power-mode.min.js
|
||||||
@@ -9,7 +9,7 @@ activate_power_mode:
|
|||||||
algolia_search:
|
algolia_search:
|
||||||
name: algoliasearch
|
name: algoliasearch
|
||||||
file: dist/lite/builds/browser.umd.js
|
file: dist/lite/builds/browser.umd.js
|
||||||
version: 5.46.0
|
version: 5.47.0
|
||||||
aplayer_css:
|
aplayer_css:
|
||||||
name: aplayer
|
name: aplayer
|
||||||
file: dist/APlayer.min.css
|
file: dist/APlayer.min.css
|
||||||
@@ -66,26 +66,26 @@ docsearch_css:
|
|||||||
name: '@docsearch/css'
|
name: '@docsearch/css'
|
||||||
other_name: docsearch-css
|
other_name: docsearch-css
|
||||||
file: dist/style.css
|
file: dist/style.css
|
||||||
version: 4.3.2
|
version: 4.5.3
|
||||||
docsearch_js:
|
docsearch_js:
|
||||||
name: '@docsearch/js'
|
name: '@docsearch/js'
|
||||||
other_name: docsearch-js
|
other_name: docsearch-js
|
||||||
file: dist/umd/index.js
|
file: dist/umd/index.js
|
||||||
version: 4.3.2
|
version: 4.5.3
|
||||||
egjs_infinitegrid:
|
egjs_infinitegrid:
|
||||||
name: '@egjs/infinitegrid'
|
name: '@egjs/infinitegrid'
|
||||||
other_name: egjs-infinitegrid
|
other_name: egjs-infinitegrid
|
||||||
file: dist/infinitegrid.min.js
|
file: dist/infinitegrid.min.js
|
||||||
version: 4.12.0
|
version: 4.13.0
|
||||||
fancybox:
|
fancybox:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.umd.js
|
file: dist/fancybox/fancybox.umd.js
|
||||||
version: 6.1.7
|
version: 6.1.9
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
fancybox_css:
|
fancybox_css:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.css
|
file: dist/fancybox/fancybox.css
|
||||||
version: 6.1.7
|
version: 6.1.9
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
fireworks:
|
fireworks:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
@@ -112,12 +112,12 @@ katex:
|
|||||||
name: katex
|
name: katex
|
||||||
file: dist/katex.min.css
|
file: dist/katex.min.css
|
||||||
other_name: KaTeX
|
other_name: KaTeX
|
||||||
version: 0.16.27
|
version: 0.16.28
|
||||||
katex_copytex:
|
katex_copytex:
|
||||||
name: katex
|
name: katex
|
||||||
file: dist/contrib/copy-tex.min.js
|
file: dist/contrib/copy-tex.min.js
|
||||||
other_name: KaTeX
|
other_name: KaTeX
|
||||||
version: 0.16.27
|
version: 0.16.28
|
||||||
lazyload:
|
lazyload:
|
||||||
name: vanilla-lazyload
|
name: vanilla-lazyload
|
||||||
file: dist/lazyload.iife.min.js
|
file: dist/lazyload.iife.min.js
|
||||||
@@ -125,7 +125,7 @@ lazyload:
|
|||||||
mathjax:
|
mathjax:
|
||||||
name: mathjax
|
name: mathjax
|
||||||
file: tex-mml-chtml.js
|
file: tex-mml-chtml.js
|
||||||
version: 4.0.0
|
version: 4.1.0
|
||||||
medium_zoom:
|
medium_zoom:
|
||||||
name: medium-zoom
|
name: medium-zoom
|
||||||
file: dist/medium-zoom.min.js
|
file: dist/medium-zoom.min.js
|
||||||
@@ -190,7 +190,7 @@ twikoo:
|
|||||||
typed:
|
typed:
|
||||||
name: typed.js
|
name: typed.js
|
||||||
file: dist/typed.umd.js
|
file: dist/typed.umd.js
|
||||||
version: 2.1.0
|
version: 3.0.0
|
||||||
valine:
|
valine:
|
||||||
name: valine
|
name: valine
|
||||||
file: dist/Valine.min.js
|
file: dist/Valine.min.js
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ module.exports = {
|
|||||||
enable: true,
|
enable: true,
|
||||||
limit: 40,
|
limit: 40,
|
||||||
color: false,
|
color: false,
|
||||||
|
custom_colors: null,
|
||||||
orderby: 'random',
|
orderby: 'random',
|
||||||
order: 1,
|
order: 1,
|
||||||
sort_order: null
|
sort_order: null
|
||||||
@@ -522,7 +523,9 @@ module.exports = {
|
|||||||
theme: {
|
theme: {
|
||||||
light: 'default',
|
light: 'default',
|
||||||
dark: 'dark'
|
dark: 'dark'
|
||||||
}
|
},
|
||||||
|
open_in_new_tab: true,
|
||||||
|
zoom_pan: true
|
||||||
},
|
},
|
||||||
chartjs: {
|
chartjs: {
|
||||||
enable: false,
|
enable: false,
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ hexo.extend.helper.register('postDesc', data => {
|
|||||||
|
|
||||||
hexo.extend.helper.register('cloudTags', function (options = {}) {
|
hexo.extend.helper.register('cloudTags', function (options = {}) {
|
||||||
const env = this
|
const env = this
|
||||||
let { source, minfontsize, maxfontsize, limit, unit = 'px', orderby, order, page = 'tags' } = options
|
let { source, minfontsize, maxfontsize, limit, unit = 'px', orderby, order, page = 'tags', custom_colors } = options
|
||||||
|
|
||||||
if (limit > 0) {
|
if (limit > 0) {
|
||||||
source = source.limit(limit)
|
source = source.limit(limit)
|
||||||
@@ -36,15 +36,48 @@ hexo.extend.helper.register('cloudTags', function (options = {}) {
|
|||||||
return `rgb(${Math.max(r, 50)}, ${Math.max(g, 50)}, ${Math.max(b, 50)})`
|
return `rgb(${Math.max(r, 50)}, ${Math.max(g, 50)}, ${Math.max(b, 50)})`
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateStyle = (size, unit, page) => {
|
const normalizeColors = input => {
|
||||||
const colorStyle = page === 'tags' ? `background-color: ${getRandomColor()};` : `color: ${getRandomColor()};`
|
if (!input) return null
|
||||||
|
if (typeof input === 'string') {
|
||||||
|
const color = input.trim()
|
||||||
|
return color ? [color] : null
|
||||||
|
}
|
||||||
|
if (Array.isArray(input)) {
|
||||||
|
const result = []
|
||||||
|
for (let i = 0; i < input.length; i++) {
|
||||||
|
const value = input[i]
|
||||||
|
if (value === null || value === undefined) continue
|
||||||
|
const color = String(value).trim()
|
||||||
|
if (!color) continue
|
||||||
|
result.push(color)
|
||||||
|
}
|
||||||
|
return result.length ? result : null
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const userColors = normalizeColors(custom_colors)
|
||||||
|
|
||||||
|
const resolveColorClass = (idx) => `tag-color-${idx % userColors.length}`
|
||||||
|
|
||||||
|
const generateStyle = (size, unit, page, color) => {
|
||||||
|
const colorStyle = page === 'tags' ? `background-color: ${color};` : `color: ${color};`
|
||||||
return `font-size: ${parseFloat(size.toFixed(2))}${unit}; ${colorStyle}`
|
return `font-size: ${parseFloat(size.toFixed(2))}${unit}; ${colorStyle}`
|
||||||
}
|
}
|
||||||
|
|
||||||
return source.sort(orderby, order).map(tag => {
|
return source.sort(orderby, order).map((tag, idx) => {
|
||||||
const ratio = length ? sizeMap.get(tag.length) / length : 0
|
const ratio = length ? sizeMap.get(tag.length) / length : 0
|
||||||
const size = minfontsize + ((maxfontsize - minfontsize) * ratio)
|
const size = minfontsize + ((maxfontsize - minfontsize) * ratio)
|
||||||
const style = generateStyle(size, unit, page)
|
|
||||||
|
if (userColors && userColors.length) {
|
||||||
|
const colorClass = resolveColorClass(idx)
|
||||||
|
const color = userColors[idx % userColors.length]
|
||||||
|
const style = generateStyle(size, unit, page, color)
|
||||||
|
return `<a href="${env.url_for(tag.path)}" class="tag-cloud-item ${colorClass}" style="${style}">${tag.name}</a>`
|
||||||
|
}
|
||||||
|
|
||||||
|
const color = getRandomColor()
|
||||||
|
const style = generateStyle(size, unit, page, color)
|
||||||
return `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}</a>`
|
return `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}</a>`
|
||||||
}).join('')
|
}).join('')
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -24,6 +24,14 @@ wordWrap = $highlight_enable && !$highlight_line_number && hexo-config('code_blo
|
|||||||
--hlscrollbar-bg: lighten(#121212, 5)
|
--hlscrollbar-bg: lighten(#121212, 5)
|
||||||
--hlexpand-bg: linear-gradient(180deg, rgba(lighten(#121212, 2), .6), rgba(lighten(#121212, 2), .9))
|
--hlexpand-bg: linear-gradient(180deg, rgba(lighten(#121212, 2), .6), rgba(lighten(#121212, 2), .9))
|
||||||
|
|
||||||
|
$scrollbar-style
|
||||||
|
// scrollbar - firefox
|
||||||
|
@-moz-document url-prefix()
|
||||||
|
scrollbar-color: var(--hlscrollbar-bg) transparent
|
||||||
|
|
||||||
|
&::-webkit-scrollbar-thumb
|
||||||
|
background: var(--hlscrollbar-bg)
|
||||||
|
|
||||||
if $highlight_enable
|
if $highlight_enable
|
||||||
@require 'highlight/index'
|
@require 'highlight/index'
|
||||||
|
|
||||||
@@ -88,6 +96,11 @@ $code-block
|
|||||||
&:hover
|
&:hover
|
||||||
border-bottom-color: var(--hl-color)
|
border-bottom-color: var(--hl-color)
|
||||||
|
|
||||||
|
&.default
|
||||||
|
pre
|
||||||
|
padding: 10px 20px
|
||||||
|
@extend $scrollbar-style
|
||||||
|
|
||||||
&.copy-true
|
&.copy-true
|
||||||
user-select: all
|
user-select: all
|
||||||
-webkit-user-select: all
|
-webkit-user-select: all
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
figure.highlight
|
figure.highlight
|
||||||
table
|
table
|
||||||
// scrollbar - firefox
|
@extend $scrollbar-style
|
||||||
@-moz-document url-prefix()
|
|
||||||
scrollbar-color: var(--hlscrollbar-bg) transparent
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb
|
|
||||||
background: var(--hlscrollbar-bg)
|
|
||||||
|
|
||||||
pre .deletion
|
pre .deletion
|
||||||
color: $highlight-deletion
|
color: $highlight-deletion
|
||||||
|
|||||||
@@ -6,12 +6,7 @@ if $highlight_theme != false
|
|||||||
|
|
||||||
.container
|
.container
|
||||||
pre[class*='language-']
|
pre[class*='language-']
|
||||||
// scrollbar - firefox
|
@extend $scrollbar-style
|
||||||
@-moz-document url-prefix()
|
|
||||||
scrollbar-color: var(--hlscrollbar-bg) transparent
|
|
||||||
|
|
||||||
&::-webkit-scrollbar-thumb
|
|
||||||
background: var(--hlscrollbar-bg)
|
|
||||||
|
|
||||||
&:not(.line-numbers)
|
&:not(.line-numbers)
|
||||||
padding: 10px 20px
|
padding: 10px 20px
|
||||||
|
|||||||
@@ -37,6 +37,8 @@
|
|||||||
margin: 0
|
margin: 0
|
||||||
color: var(--white)
|
color: var(--white)
|
||||||
font-size: 1.85em
|
font-size: 1.85em
|
||||||
|
@extend .limit-more-line
|
||||||
|
-webkit-line-clamp: 3
|
||||||
|
|
||||||
+minWidth768()
|
+minWidth768()
|
||||||
font-size: 2.85em
|
font-size: 2.85em
|
||||||
|
|||||||
@@ -37,13 +37,13 @@
|
|||||||
display: none
|
display: none
|
||||||
padding: 0 0 15px
|
padding: 0 0 15px
|
||||||
width: 100%
|
width: 100%
|
||||||
addBorderRadius()
|
|
||||||
|
|
||||||
.reward-all
|
.reward-all
|
||||||
display: inline-block
|
display: inline-block
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: 20px 10px
|
padding: 20px 10px
|
||||||
background: var(--reward-pop)
|
background: var(--reward-pop)
|
||||||
|
addBorderRadius()
|
||||||
|
|
||||||
&:before
|
&:before
|
||||||
position: absolute
|
position: absolute
|
||||||
|
|||||||
@@ -65,12 +65,55 @@ if hexo-config('waline.bg')
|
|||||||
|
|
||||||
if hexo-config('mermaid.enable')
|
if hexo-config('mermaid.enable')
|
||||||
.mermaid-wrap
|
.mermaid-wrap
|
||||||
|
position: relative
|
||||||
margin: 0 0 20px
|
margin: 0 0 20px
|
||||||
|
background: var(--card-bg)
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
|
if hexo-config('mermaid.open_in_new_tab')
|
||||||
|
.mermaid-open-btn
|
||||||
|
position: absolute
|
||||||
|
top: 8px
|
||||||
|
right: 8px
|
||||||
|
z-index: 2
|
||||||
|
display: flex
|
||||||
|
justify-content: center
|
||||||
|
align-items: center
|
||||||
|
padding: 0
|
||||||
|
width: 34px
|
||||||
|
height: 25px
|
||||||
|
border: none
|
||||||
|
border-radius: 20%
|
||||||
|
background: #D3D3D3
|
||||||
|
box-shadow: 0 4px 10px rgba(0, 0, 0, .15)
|
||||||
|
color: #fff
|
||||||
|
font-size: 0
|
||||||
|
line-height: 1
|
||||||
|
cursor: pointer
|
||||||
|
transition: background .2s ease, transform .2s ease
|
||||||
|
|
||||||
|
i
|
||||||
|
font-size: 16px
|
||||||
|
line-height: 1
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
&:focus-visible
|
||||||
|
outline: none
|
||||||
|
background: #C0C0C0
|
||||||
|
transform: translateY(-1px)
|
||||||
|
|
||||||
& > svg
|
& > svg
|
||||||
|
max-width: 100%
|
||||||
height: 100%
|
height: 100%
|
||||||
|
|
||||||
|
if hexo-config('mermaid.zoom_pan')
|
||||||
|
cursor: grab
|
||||||
|
user-select: none
|
||||||
|
touch-action: none
|
||||||
|
|
||||||
|
&:active
|
||||||
|
cursor: grabbing
|
||||||
|
|
||||||
if hexo-config('mermaid.code_write')
|
if hexo-config('mermaid.code_write')
|
||||||
pre > code.mermaid
|
pre > code.mermaid
|
||||||
display: none
|
display: none
|
||||||
|
|||||||
@@ -61,11 +61,14 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const { highlightCopy, highlightLang, highlightHeightLimit, highlightFullpage, highlightMacStyle, 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 || highlightFullpage || highlightMacStyle
|
const isShowTool = highlightCopy || highlightLang || isHighlightShrink !== undefined || highlightFullpage || highlightMacStyle
|
||||||
const $figureHighlight = plugin === 'highlight.js' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]')
|
const isNotHighlightJs = plugin !== 'highlight.js'
|
||||||
|
const isPrismjs = plugin === 'prismjs'
|
||||||
|
const $figureHighlight = isNotHighlightJs
|
||||||
|
? Array.from(document.querySelectorAll('code[class*="language-"]')).map(code => code.parentElement)
|
||||||
|
: document.querySelectorAll('figure.highlight')
|
||||||
|
|
||||||
if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return
|
if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return
|
||||||
|
|
||||||
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 ? '<i class="fas fa-angle-down expand"></i>' : ''
|
||||||
const highlightCopyEle = highlightCopy ? '<i class="fas fa-paste copy-button"></i>' : ''
|
const highlightCopyEle = highlightCopy ? '<i class="fas fa-paste copy-button"></i>' : ''
|
||||||
@@ -133,7 +136,7 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
const highlightCopyFn = (ele, clickEle) => {
|
const highlightCopyFn = (ele, clickEle) => {
|
||||||
const $buttonParent = ele.parentNode
|
const $buttonParent = ele.parentNode
|
||||||
$buttonParent.classList.add('copy-true')
|
$buttonParent.classList.add('copy-true')
|
||||||
const preCodeSelector = isPrismjs ? 'pre code' : 'table .code pre'
|
const preCodeSelector = isNotHighlightJs ? 'pre code' : 'table .code pre'
|
||||||
const codeElement = $buttonParent.querySelector(preCodeSelector)
|
const codeElement = $buttonParent.querySelector(preCodeSelector)
|
||||||
if (!codeElement) return
|
if (!codeElement) return
|
||||||
copy(codeElement.innerText, clickEle)
|
copy(codeElement.innerText, clickEle)
|
||||||
@@ -213,20 +216,23 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||||||
fragment.appendChild(ele)
|
fragment.appendChild(ele)
|
||||||
}
|
}
|
||||||
|
|
||||||
isPrismjs ? item.parentNode.insertBefore(fragment, item) : item.insertBefore(fragment, item.firstChild)
|
isNotHighlightJs ? item.parentNode.insertBefore(fragment, item) : item.insertBefore(fragment, item.firstChild)
|
||||||
}
|
}
|
||||||
|
|
||||||
$figureHighlight.forEach(item => {
|
$figureHighlight.forEach(item => {
|
||||||
let langName = ''
|
let langName = ''
|
||||||
if (isPrismjs) btf.wrap(item, 'figure', { class: 'highlight' })
|
if (isNotHighlightJs) {
|
||||||
|
const newClassName = isPrismjs ? 'prismjs' : 'default'
|
||||||
|
btf.wrap(item, 'figure', { class: `highlight ${newClassName}` })
|
||||||
|
}
|
||||||
|
|
||||||
if (!highlightLang) {
|
if (!highlightLang) {
|
||||||
createEle('', item)
|
createEle('', item)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isPrismjs) {
|
if (isNotHighlightJs) {
|
||||||
langName = item.getAttribute('data-language') || 'Code'
|
langName = isPrismjs ? item.getAttribute('data-language') || 'Code' : item.querySelector('code').getAttribute('class').replace('language-', '')
|
||||||
} else {
|
} else {
|
||||||
langName = item.getAttribute('class').split(' ')[1]
|
langName = item.getAttribute('class').split(' ')[1]
|
||||||
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
||||||
|
|||||||
Reference in New Issue
Block a user