mirror of
https://github.com/jerryc127/hexo-theme-butterfly.git
synced 2026-04-10 21:17:07 +08:00
breaking change: 重構 gallery 標籤外掛
improvement: 首頁社交圖標左右邊距調整 feat: 文章版權增加圖標 improvement: 重構 main.js 代碼 improvement: 優化 pjax 下的性能 fix: 修復子目錄下,pjax 跳轉 404 錯誤 feat: getScript 增加 attribute 配置 improvement: 優化手機端 toc 打開和關閉特效 improvement: 文章進入特效改為 transform, 優化 stylus improvement: 目錄側邊欄出現滾動條時,元素不會被擠壓 feat: 文章左右對齊 improvement: 處理 waline 的 url 後面多 / 導致跨域的問題 fix: 修復夜間模式下,小屏幕的toc 滾動條顏色不明顯的 bug fix: 修復設置字體超過17px時,toc 裏面的邊框異常的 bug improvement: 優化語言文件部分用詞 improvement: disqus 和 disqusjs 的評論數獲取不到時,顯示為 0 improvement: disqusjs 的評論數改為 api 獲取 improvement: 代碼優化 improvement: 更新 plugins.yml
This commit is contained in:
@@ -977,8 +977,7 @@ CDN:
|
|||||||
# click_heart:
|
# click_heart:
|
||||||
# ClickShowText:
|
# ClickShowText:
|
||||||
# fontawesome:
|
# fontawesome:
|
||||||
# flickr_justified_gallery_js:
|
# egjs_infinitegrid:
|
||||||
# flickr_justified_gallery_css:
|
|
||||||
# aplayer_css:
|
# aplayer_css:
|
||||||
# aplayer_js:
|
# aplayer_js:
|
||||||
# meting_js:
|
# meting_js:
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ footer:
|
|||||||
theme: Theme
|
theme: Theme
|
||||||
|
|
||||||
copy:
|
copy:
|
||||||
success: Copy successfully
|
success: Copy Successful
|
||||||
error: Copy error
|
error: Copy Error
|
||||||
noSupport: The browser does not support
|
noSupport: Browser Not Supported
|
||||||
|
|
||||||
page:
|
page:
|
||||||
articles: Articles
|
articles: Articles
|
||||||
@@ -15,15 +15,15 @@ page:
|
|||||||
|
|
||||||
card_post_count: comments
|
card_post_count: comments
|
||||||
|
|
||||||
no_title: No title
|
no_title: Untitled
|
||||||
|
|
||||||
post:
|
post:
|
||||||
created: Created
|
created: Created
|
||||||
updated: Updated
|
updated: Updated
|
||||||
wordcount: Word count
|
wordcount: Word Count
|
||||||
min2read: Reading time
|
min2read: Reading Time
|
||||||
min2read_unit: min
|
min2read_unit: mins
|
||||||
page_pv: Post View
|
page_pv: Post Views
|
||||||
comments: Comments
|
comments: Comments
|
||||||
copyright:
|
copyright:
|
||||||
author: Author
|
author: Author
|
||||||
@@ -47,8 +47,8 @@ search:
|
|||||||
hits_stats: '${hits} results found'
|
hits_stats: '${hits} results found'
|
||||||
|
|
||||||
pagination:
|
pagination:
|
||||||
prev: Previous Post
|
prev: Previous
|
||||||
next: Next Post
|
next: Next
|
||||||
|
|
||||||
comment: Comment
|
comment: Comment
|
||||||
|
|
||||||
@@ -65,33 +65,33 @@ aside:
|
|||||||
headline: Info
|
headline: Info
|
||||||
article_name: Article
|
article_name: Article
|
||||||
runtime:
|
runtime:
|
||||||
name: Run time
|
name: Runtime
|
||||||
unit: days
|
unit: days
|
||||||
last_push_date:
|
last_push_date:
|
||||||
name: Last Push
|
name: Last Update
|
||||||
site_wordcount: Total Count
|
site_wordcount: Total Count
|
||||||
site_uv_name: UV
|
site_uv_name: UV
|
||||||
site_pv_name: PV
|
site_pv_name: PV
|
||||||
more_button: More
|
more_button: View More
|
||||||
card_newest_comments:
|
card_newest_comments:
|
||||||
headline: Newest Comments
|
headline: Latest Comments
|
||||||
loading_text: loading...
|
loading_text: loading...
|
||||||
error: Unable to get the data, please make sure the settings are correct.
|
error: Unable to retrieve comments, please check the configuration
|
||||||
zero: No Comment
|
zero: No comments
|
||||||
image: image
|
image: image
|
||||||
link: link
|
link: link
|
||||||
code: code
|
code: code
|
||||||
card_toc: Catalog
|
card_toc: Contents
|
||||||
card_post_series: Series
|
card_post_series: Series
|
||||||
|
|
||||||
date_suffix:
|
date_suffix:
|
||||||
just: Just
|
just: Just now
|
||||||
min: minutes ago
|
min: minutes ago
|
||||||
hour: hours ago
|
hour: hours ago
|
||||||
day: days ago
|
day: days ago
|
||||||
month: months ago
|
month: months ago
|
||||||
|
|
||||||
donate: Donate
|
donate: Sponsor
|
||||||
share: Share
|
share: Share
|
||||||
|
|
||||||
rightside:
|
rightside:
|
||||||
@@ -102,7 +102,7 @@ rightside:
|
|||||||
toc: Table Of Contents
|
toc: Table Of Contents
|
||||||
scroll_to_comment: Scroll To Comments
|
scroll_to_comment: Scroll To Comments
|
||||||
setting: Setting
|
setting: Setting
|
||||||
aside: Toggle between single-column and double-column
|
aside: Toggle between Single-column and Double-column
|
||||||
chat: Chat
|
chat: Chat
|
||||||
|
|
||||||
copy_copyright:
|
copy_copyright:
|
||||||
@@ -112,12 +112,12 @@ copy_copyright:
|
|||||||
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
|
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
|
||||||
|
|
||||||
Snackbar:
|
Snackbar:
|
||||||
chs_to_cht: Traditional Chinese Activated Manually
|
chs_to_cht: You have switched to Traditional Chinese
|
||||||
cht_to_chs: Simplified Chinese Activated Manually
|
cht_to_chs: You have switched to Simplified Chinese
|
||||||
day_to_night: Dark Mode Activated Manually
|
day_to_night: You have switched to Dark Mode
|
||||||
night_to_day: Light Mode Activated Manually
|
night_to_day: You have switched to Light Mode
|
||||||
|
|
||||||
loading: Loading...
|
loading: Loading...
|
||||||
load_more: Load More
|
load_more: Load More
|
||||||
|
|
||||||
error404: Page not found
|
error404: Page Not Found
|
||||||
|
|||||||
@@ -3,9 +3,9 @@ footer:
|
|||||||
theme: Theme
|
theme: Theme
|
||||||
|
|
||||||
copy:
|
copy:
|
||||||
success: Copy successfully
|
success: Copy Successful
|
||||||
error: Copy error
|
error: Copy Error
|
||||||
noSupport: The browser does not support
|
noSupport: Browser Not Supported
|
||||||
|
|
||||||
page:
|
page:
|
||||||
articles: Articles
|
articles: Articles
|
||||||
@@ -15,15 +15,15 @@ page:
|
|||||||
|
|
||||||
card_post_count: comments
|
card_post_count: comments
|
||||||
|
|
||||||
no_title: No title
|
no_title: Untitled
|
||||||
|
|
||||||
post:
|
post:
|
||||||
created: Created
|
created: Created
|
||||||
updated: Updated
|
updated: Updated
|
||||||
wordcount: Word count
|
wordcount: Word Count
|
||||||
min2read: Reading time
|
min2read: Reading Time
|
||||||
min2read_unit: min
|
min2read_unit: mins
|
||||||
page_pv: Post View
|
page_pv: Post Views
|
||||||
comments: Comments
|
comments: Comments
|
||||||
copyright:
|
copyright:
|
||||||
author: Author
|
author: Author
|
||||||
@@ -47,8 +47,8 @@ search:
|
|||||||
hits_stats: '${hits} results found'
|
hits_stats: '${hits} results found'
|
||||||
|
|
||||||
pagination:
|
pagination:
|
||||||
prev: Previous Post
|
prev: Previous
|
||||||
next: Next Post
|
next: Next
|
||||||
|
|
||||||
comment: Comment
|
comment: Comment
|
||||||
|
|
||||||
@@ -65,44 +65,44 @@ aside:
|
|||||||
headline: Info
|
headline: Info
|
||||||
article_name: Article
|
article_name: Article
|
||||||
runtime:
|
runtime:
|
||||||
name: Run time
|
name: Runtime
|
||||||
unit: days
|
unit: days
|
||||||
last_push_date:
|
last_push_date:
|
||||||
name: Last Push
|
name: Last Update
|
||||||
site_wordcount: Total Count
|
site_wordcount: Total Count
|
||||||
site_uv_name: UV
|
site_uv_name: UV
|
||||||
site_pv_name: PV
|
site_pv_name: PV
|
||||||
more_button: More
|
more_button: View More
|
||||||
card_newest_comments:
|
card_newest_comments:
|
||||||
headline: Newest Comments
|
headline: Latest Comments
|
||||||
loading_text: loading...
|
loading_text: loading...
|
||||||
error: Unable to get the data, please make sure the settings are correct.
|
error: Unable to retrieve comments, please check the configuration
|
||||||
zero: No Comment
|
zero: No comments
|
||||||
image: image
|
image: image
|
||||||
link: link
|
link: link
|
||||||
code: code
|
code: code
|
||||||
card_toc: Catalog
|
card_toc: Contents
|
||||||
card_post_series: Series
|
card_post_series: Series
|
||||||
|
|
||||||
date_suffix:
|
date_suffix:
|
||||||
just: Just
|
just: Just now
|
||||||
min: minutes ago
|
min: minutes ago
|
||||||
hour: hours ago
|
hour: hours ago
|
||||||
day: days ago
|
day: days ago
|
||||||
month: months ago
|
month: months ago
|
||||||
|
|
||||||
donate: Donate
|
donate: Sponsor
|
||||||
share: Share
|
share: Share
|
||||||
|
|
||||||
rightside:
|
rightside:
|
||||||
readmode_title: Read Mode
|
readmode_title: Read Mode
|
||||||
translate_title: Switch Between Traditional Chinese And Simplified Chinese
|
translate_title: Toggle Between Traditional Chinese And Simplified Chinese
|
||||||
night_mode_title: Switch Between Light And Dark Mode
|
night_mode_title: Toggle Between Light And Dark Mode
|
||||||
back_to_top: Back To Top
|
back_to_top: Back To Top
|
||||||
toc: Table Of Contents
|
toc: Table Of Contents
|
||||||
scroll_to_comment: Scroll To Comments
|
scroll_to_comment: Scroll To Comments
|
||||||
setting: Setting
|
setting: Setting
|
||||||
aside: Toggle between single-column and double-column
|
aside: Toggle between Single-column and Double-column
|
||||||
chat: Chat
|
chat: Chat
|
||||||
|
|
||||||
copy_copyright:
|
copy_copyright:
|
||||||
@@ -112,12 +112,12 @@ copy_copyright:
|
|||||||
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
|
info: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
|
||||||
|
|
||||||
Snackbar:
|
Snackbar:
|
||||||
chs_to_cht: Traditional Chinese Activated Manually
|
chs_to_cht: You have switched to Traditional Chinese
|
||||||
cht_to_chs: Simplified Chinese Activated Manually
|
cht_to_chs: You have switched to Simplified Chinese
|
||||||
day_to_night: Dark Mode Activated Manually
|
day_to_night: You have switched to Dark Mode
|
||||||
night_to_day: Light Mode Activated Manually
|
night_to_day: You have switched to Light Mode
|
||||||
|
|
||||||
loading: Loading...
|
loading: Loading...
|
||||||
load_more: Load More
|
load_more: Load More
|
||||||
|
|
||||||
error404: Page not found
|
error404: Page Not Found
|
||||||
@@ -92,7 +92,7 @@ date_suffix:
|
|||||||
day: 天前
|
day: 天前
|
||||||
month: 个月前
|
month: 个月前
|
||||||
|
|
||||||
donate: 打赏
|
donate: 赞助
|
||||||
share: 分享
|
share: 分享
|
||||||
|
|
||||||
rightside:
|
rightside:
|
||||||
@@ -113,8 +113,8 @@ copy_copyright:
|
|||||||
info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
info: 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
|
||||||
|
|
||||||
Snackbar:
|
Snackbar:
|
||||||
chs_to_cht: 你已切换为繁体
|
chs_to_cht: 你已切换为繁体中文
|
||||||
cht_to_chs: 你已切换为简体
|
cht_to_chs: 你已切换为简体中文
|
||||||
day_to_night: 你已切换为深色模式
|
day_to_night: 你已切换为深色模式
|
||||||
night_to_day: 你已切换为浅色模式
|
night_to_day: 你已切换为浅色模式
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ page:
|
|||||||
|
|
||||||
card_post_count: 條評論
|
card_post_count: 條評論
|
||||||
|
|
||||||
no_title: 無題
|
no_title: 無標題
|
||||||
|
|
||||||
post:
|
post:
|
||||||
created: 發表於
|
created: 發表於
|
||||||
@@ -83,7 +83,7 @@ aside:
|
|||||||
link: 連結
|
link: 連結
|
||||||
code: 程式碼
|
code: 程式碼
|
||||||
card_toc: 目錄
|
card_toc: 目錄
|
||||||
card_post_series: 系列文章
|
card_post_series: 文章系列
|
||||||
|
|
||||||
date_suffix:
|
date_suffix:
|
||||||
just: 剛剛
|
just: 剛剛
|
||||||
@@ -92,14 +92,14 @@ date_suffix:
|
|||||||
day: 天前
|
day: 天前
|
||||||
month: 個月前
|
month: 個月前
|
||||||
|
|
||||||
donate: 打賞
|
donate: 贊助
|
||||||
share: 分享
|
share: 分享
|
||||||
|
|
||||||
rightside:
|
rightside:
|
||||||
readmode_title: 閱讀模式
|
readmode_title: 閱讀模式
|
||||||
translate_title: 簡繁轉換
|
translate_title: 簡繁轉換
|
||||||
night_mode_title: 淺色和深色模式轉換
|
night_mode_title: 淺色和深色模式轉換
|
||||||
back_to_top: 回到頂部
|
back_to_top: 返回頂部
|
||||||
toc: 目錄
|
toc: 目錄
|
||||||
scroll_to_comment: 直達評論
|
scroll_to_comment: 直達評論
|
||||||
setting: 設定
|
setting: 設定
|
||||||
@@ -110,11 +110,11 @@ copy_copyright:
|
|||||||
author: 作者
|
author: 作者
|
||||||
link: 連結
|
link: 連結
|
||||||
source: 來源
|
source: 來源
|
||||||
info: 著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。
|
info: 著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。
|
||||||
|
|
||||||
Snackbar:
|
Snackbar:
|
||||||
chs_to_cht: 你已切換為繁體
|
chs_to_cht: 你已切換為繁體中文
|
||||||
cht_to_chs: 你已切換為簡體
|
cht_to_chs: 你已切換為簡體中文
|
||||||
day_to_night: 你已切換為深色模式
|
day_to_night: 你已切換為深色模式
|
||||||
night_to_day: 你已切換為淺色模式
|
night_to_day: 你已切換為淺色模式
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ extends includes/layout.pug
|
|||||||
block content
|
block content
|
||||||
include ./includes/mixins/article-sort.pug
|
include ./includes/mixins/article-sort.pug
|
||||||
#archive
|
#archive
|
||||||
- const archiveLength = findArchiveLength(fragment_cache)
|
.article-sort-title= `${_p('page.articles')} - ${getArchiveLength()}`
|
||||||
.article-sort-title= _p('page.articles') + ' - ' + archiveLength
|
|
||||||
+articleSort(page.posts)
|
+articleSort(page.posts)
|
||||||
include includes/pagination.pug
|
include includes/pagination.pug
|
||||||
@@ -4,9 +4,9 @@
|
|||||||
- var nowYear = now.getFullYear()
|
- var nowYear = now.getFullYear()
|
||||||
if theme.footer.owner.since != false
|
if theme.footer.owner.since != false
|
||||||
if theme.footer.owner.since != nowYear
|
if theme.footer.owner.since != nowYear
|
||||||
.copyright!= `©${theme.footer.owner.since} - ${nowYear} By ${config.author}`
|
.copyright!= `©${theme.footer.owner.since} - ${nowYear} By ${config.author}`
|
||||||
else
|
else
|
||||||
.copyright!= `©${nowYear} By ${config.author}`
|
.copyright!= `©${nowYear} By ${config.author}`
|
||||||
if theme.footer.copyright
|
if theme.footer.copyright
|
||||||
.framework-info
|
.framework-info
|
||||||
span= _p('footer.framework') + ' '
|
span= _p('footer.framework') + ' '
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ if theme.fancybox
|
|||||||
!=partial('includes/head/analytics', {}, {cache: true})
|
!=partial('includes/head/analytics', {}, {cache: true})
|
||||||
|
|
||||||
//- font
|
//- font
|
||||||
if theme.blog_title_font && theme.blog_title_font.font_link
|
if theme.blog_title_font && theme.blog_title_font.font_link
|
||||||
link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'")
|
link(rel='stylesheet' href=url_for(theme.blog_title_font.font_link) media="print" onload="this.media='all'")
|
||||||
|
|
||||||
//- global config
|
//- global config
|
||||||
|
|||||||
@@ -115,11 +115,9 @@ script.
|
|||||||
copyright: !{copyright},
|
copyright: !{copyright},
|
||||||
lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}',
|
lightbox: '!{ theme.medium_zoom ? "mediumZoom" : (theme.fancybox ? "fancybox" : "null" )}',
|
||||||
Snackbar: !{Snackbar},
|
Snackbar: !{Snackbar},
|
||||||
source: {
|
infinitegrid: {
|
||||||
justifiedGallery: {
|
js: '!{url_for(theme.asset.egjs_infinitegrid)}',
|
||||||
js: '!{url_for(theme.asset.flickr_justified_gallery_js)}',
|
buttonText: '!{_p("load_more")}'
|
||||||
css: '!{url_for(theme.asset.flickr_justified_gallery_css)}'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
isPhotoFigcaption: !{theme.photofigcaption},
|
isPhotoFigcaption: !{theme.photofigcaption},
|
||||||
islazyload: !{theme.lazyload.enable},
|
islazyload: !{theme.lazyload.enable},
|
||||||
|
|||||||
@@ -3,10 +3,6 @@ noscript.
|
|||||||
#nav {
|
#nav {
|
||||||
opacity: 1
|
opacity: 1
|
||||||
}
|
}
|
||||||
.justified-gallery img {
|
|
||||||
opacity: 1
|
|
||||||
}
|
|
||||||
|
|
||||||
#recent-posts time,
|
#recent-posts time,
|
||||||
#post-meta time {
|
#post-meta time {
|
||||||
display: inline !important
|
display: inline !important
|
||||||
|
|||||||
@@ -102,14 +102,12 @@
|
|||||||
case whichCount
|
case whichCount
|
||||||
when 'Disqus'
|
when 'Disqus'
|
||||||
+countBlock
|
+countBlock
|
||||||
span.disqus-comment-count
|
a.disqus-comment-count(href=full_url_for(page.path) + '#post-comment')
|
||||||
a(href=full_url_for(page.path) + '#disqus_thread')
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
when 'Disqusjs'
|
when 'Disqusjs'
|
||||||
+countBlock
|
+countBlock
|
||||||
a(href=full_url_for(page.path) + '#disqusjs')
|
a.disqusjs-comment-count(href=full_url_for(page.path) + '#post-comment')
|
||||||
span.disqus-comment-count(data-disqus-url=full_url_for(page.path))
|
i.fa-solid.fa-spinner.fa-spin
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
when 'Valine'
|
when 'Valine'
|
||||||
+countBlock
|
+countBlock
|
||||||
a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl")
|
a(href=url_for(page.path) + '#post-comment' itemprop="discussionUrl")
|
||||||
|
|||||||
@@ -71,14 +71,10 @@ mixin postUI(posts)
|
|||||||
if theme.comments.card_post_count && theme.comments.use
|
if theme.comments.card_post_count && theme.comments.use
|
||||||
case theme.comments.use[0]
|
case theme.comments.use[0]
|
||||||
when 'Disqus'
|
when 'Disqus'
|
||||||
+countBlockInIndex
|
|
||||||
a(href=full_url_for(link) + '#disqus_thread')
|
|
||||||
i.fa-solid.fa-spinner.fa-spin
|
|
||||||
when 'Disqusjs'
|
when 'Disqusjs'
|
||||||
+countBlockInIndex
|
+countBlockInIndex
|
||||||
a(href=full_url_for(link) + '#disqusjs')
|
a.disqus-count(href=full_url_for(link) + '#post-comment')
|
||||||
span.disqus-comment-count(data-disqus-url=full_url_for(link))
|
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=url_for(link) + '#post-comment')
|
||||||
|
|||||||
@@ -5,13 +5,19 @@ if theme.post_copyright.enable && page.copyright !== false
|
|||||||
- let info = page.copyright_info || _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title)
|
- let info = page.copyright_info || _p('post.copyright.copyright_content', theme.post_copyright.license_url, theme.post_copyright.license, config.url, config.title)
|
||||||
.post-copyright
|
.post-copyright
|
||||||
.post-copyright__author
|
.post-copyright__author
|
||||||
span.post-copyright-meta= _p('post.copyright.author') + ": "
|
span.post-copyright-meta
|
||||||
|
i.fas.fa-circle-user.fa-fw
|
||||||
|
= _p('post.copyright.author') + ": "
|
||||||
span.post-copyright-info
|
span.post-copyright-info
|
||||||
a(href=authorHref)=author
|
a(href=authorHref)=author
|
||||||
.post-copyright__type
|
.post-copyright__type
|
||||||
span.post-copyright-meta= _p('post.copyright.link') + ": "
|
span.post-copyright-meta
|
||||||
|
i.fas.fa-square-arrow-up-right.fa-fw
|
||||||
|
= _p('post.copyright.link') + ": "
|
||||||
span.post-copyright-info
|
span.post-copyright-info
|
||||||
a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url
|
a(href=url_for(url))= theme.post_copyright.decode ? decodeURI(url) : url
|
||||||
.post-copyright__notice
|
.post-copyright__notice
|
||||||
span.post-copyright-meta= _p('post.copyright.copyright_notice') + ": "
|
span.post-copyright-meta
|
||||||
|
i.fas.fa-circle-exclamation.fa-fw
|
||||||
|
= _p('post.copyright.copyright_notice') + ": "
|
||||||
span.post-copyright-info!= info
|
span.post-copyright-info!= info
|
||||||
|
|||||||
@@ -42,15 +42,15 @@ mixin rightsideItem(array)
|
|||||||
#rightside-config-show
|
#rightside-config-show
|
||||||
if enable
|
if enable
|
||||||
if hide
|
if hide
|
||||||
button#rightside_config(type="button" title=_p("rightside.setting"))
|
button#rightside-config(type="button" title=_p("rightside.setting"))
|
||||||
i.fas.fa-cog.fa-spin
|
i.fas.fa-cog.fa-spin
|
||||||
else
|
else
|
||||||
if is_post()
|
if is_post()
|
||||||
if (readmode || translate.enable || (darkmode.enable && darkmode.button))
|
if (readmode || translate.enable || (darkmode.enable && darkmode.button))
|
||||||
button#rightside_config(type="button" title=_p("rightside.setting"))
|
button#rightside-config(type="button" title=_p("rightside.setting"))
|
||||||
i.fas.fa-cog.fa-spin
|
i.fas.fa-cog.fa-spin
|
||||||
else if translate.enable || (darkmode.enable && darkmode.button)
|
else if translate.enable || (darkmode.enable && darkmode.button)
|
||||||
button#rightside_config(type="button" title=_p("rightside.setting"))
|
button#rightside-config(type="button" title=_p("rightside.setting"))
|
||||||
i.fas.fa-cog.fa-spin
|
i.fas.fa-cog.fa-spin
|
||||||
|
|
||||||
if showArray
|
if showArray
|
||||||
|
|||||||
12
layout/includes/third-party/abcjs/abcjs.pug
vendored
12
layout/includes/third-party/abcjs/abcjs.pug
vendored
@@ -1,15 +1,15 @@
|
|||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
function abcjsInit() {
|
const abcjsInit = () => {
|
||||||
function abcjsFn() {
|
const abcjsFn = () => {
|
||||||
for (let abcContainer of document.getElementsByClassName("abc-music-sheet")) {
|
document.querySelectorAll(".abc-music-sheet").forEach(ele => {
|
||||||
ABCJS.renderAbc(abcContainer, abcContainer.innerHTML, {responsive: 'resize'})
|
ABCJS.renderAbc(ele, ele.innerHTML, {responsive: 'resize'})
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
typeof ABCJS === 'object' ? abcjsFn()
|
typeof ABCJS === 'object' ? abcjsFn()
|
||||||
: getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
|
: getScript('!{url_for(theme.asset.abcjs_basic_js)}').then(abcjsFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
window.pjax ? abcjsInit() : document.addEventListener('DOMContentLoaded', abcjsInit)
|
window.pjax ? abcjsInit() : window.addEventListener('load', abcjsInit)
|
||||||
})()
|
})()
|
||||||
@@ -1,16 +1,25 @@
|
|||||||
|
- const { shortname, apikey } = theme.disqus
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
const getCount = () => {
|
const getCount = async () => {
|
||||||
if (window.DISQUSWIDGETS === undefined) {
|
try {
|
||||||
var d = document, s = d.createElement('script');
|
const eleGroup = document.querySelectorAll('#recent-posts .disqus-count')
|
||||||
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js';
|
const cleanedLinks = Array.from(eleGroup).map(i => `thread:link=${i.href.replace(/#post-comment$/, '')}`);
|
||||||
s.id = 'dsq-count-scr';
|
|
||||||
(d.head || d.body).appendChild(s);
|
const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&${cleanedLinks.join('&')}`,{
|
||||||
} else {
|
method: 'GET'
|
||||||
DISQUSWIDGETS.getCount({reset: true});
|
})
|
||||||
|
const result = await res.json()
|
||||||
|
|
||||||
|
eleGroup.forEach(i => {
|
||||||
|
const cleanedLink = i.href.replace(/#post-comment$/, '')
|
||||||
|
const urlData = result.response.find(data => data.link === cleanedLink) || { posts: 0 }
|
||||||
|
i.textContent = urlData.posts
|
||||||
|
})
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.pjax ? getCount() : window.addEventListener('load', getCount)
|
window.pjax ? getCount() : window.addEventListener('load', getCount)
|
||||||
|
|
||||||
})()
|
})()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
|
||||||
script.
|
script.
|
||||||
(() => {
|
(() => {
|
||||||
async function loadWaline () {
|
async function loadWaline () {
|
||||||
@@ -5,7 +6,7 @@ script.
|
|||||||
const eleGroup = document.querySelectorAll('#recent-posts .waline-comment-count')
|
const eleGroup = document.querySelectorAll('#recent-posts .waline-comment-count')
|
||||||
const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-path'))
|
const keyArray = Array.from(eleGroup).map(i => i.getAttribute('data-path'))
|
||||||
|
|
||||||
const res = await fetch(`!{theme.waline.serverURL}/api/comment?type=count&url=${keyArray}`, { method: 'GET' })
|
const res = await fetch(`!{serverURL}/api/comment?type=count&url=${keyArray}`, { method: 'GET' })
|
||||||
const result = await res.json()
|
const result = await res.json()
|
||||||
|
|
||||||
result.data.forEach((count, index) => {
|
result.data.forEach((count, index) => {
|
||||||
|
|||||||
50
layout/includes/third-party/comments/artalk.pug
vendored
50
layout/includes/third-party/comments/artalk.pug
vendored
@@ -1,8 +1,9 @@
|
|||||||
- const { server, site, option } = theme.artalk
|
- const { server, site, option } = theme.artalk
|
||||||
|
- const { use, lazyload } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadArtalk () {
|
(() => {
|
||||||
function initArtalk () {
|
const initArtalk = () => {
|
||||||
window.artalkItem = new Artalk(Object.assign({
|
window.artalkItem = new Artalk(Object.assign({
|
||||||
el: '#artalk-wrap',
|
el: '#artalk-wrap',
|
||||||
server: '!{server}',
|
server: '!{server}',
|
||||||
@@ -23,28 +24,29 @@ script.
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof window.artalkItem === 'object') initArtalk()
|
const loadArtalk = async () => {
|
||||||
else {
|
if (typeof window.artalkItem === 'object') initArtalk()
|
||||||
getCSS('!{theme.asset.artalk_css}').then(()=>{
|
else {
|
||||||
getScript('!{theme.asset.artalk_js}').then(initArtalk)
|
await getCSS('!{theme.asset.artalk_css}')
|
||||||
})
|
await getScript('!{theme.asset.artalk_js}')
|
||||||
|
initArtalk()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function artalkChangeMode (theme) {
|
const artalkChangeMode = theme => {
|
||||||
const artalkWrap = document.getElementById('artalk-wrap')
|
const artalkWrap = document.getElementById('artalk-wrap')
|
||||||
if (!(artalkWrap && artalkWrap.children.length)) return
|
if (!(artalkWrap && artalkWrap.children.length)) return
|
||||||
const isDark = theme === 'dark'
|
const isDark = theme === 'dark'
|
||||||
window.artalkItem.setDarkMode(isDark)
|
window.artalkItem.setDarkMode(isDark)
|
||||||
}
|
|
||||||
|
|
||||||
btf.addModeChange('artalk', artalkChangeMode)
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Artalk' || !!{theme.comments.lazyload}) {
|
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
|
|
||||||
else loadArtalk()
|
|
||||||
} else {
|
|
||||||
function loadOtherComment () {
|
|
||||||
loadArtalk()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
btf.addGlobalFn('themeChange', artalkChangeMode, 'artalk')
|
||||||
|
|
||||||
|
if ('!{use[0]}' === 'Artalk' || !!{lazyload}) {
|
||||||
|
if (!{lazyload}) btf.loadComment(document.getElementById('artalk-wrap'), loadArtalk)
|
||||||
|
else loadArtalk()
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadArtalk
|
||||||
|
}
|
||||||
|
})()
|
||||||
66
layout/includes/third-party/comments/disqus.pug
vendored
66
layout/includes/third-party/comments/disqus.pug
vendored
@@ -1,7 +1,9 @@
|
|||||||
- let disqusPageTitle = page.title.replace(/'/ig,"\\'")
|
- const disqusPageTitle = page.title.replace(/'/ig,"\\'")
|
||||||
|
- const { shortname, apikey } = theme.disqus
|
||||||
|
- const { use, lazyload, count } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadDisqus () {
|
(() => {
|
||||||
const disqus_config = function () {
|
const disqus_config = function () {
|
||||||
this.page.url = '!{ page.permalink }'
|
this.page.url = '!{ page.permalink }'
|
||||||
this.page.identifier = '!{ url_for(page.path) }'
|
this.page.identifier = '!{ url_for(page.path) }'
|
||||||
@@ -9,41 +11,49 @@ script.
|
|||||||
}
|
}
|
||||||
|
|
||||||
const disqusReset = () => {
|
const disqusReset = () => {
|
||||||
DISQUS.reset({
|
window.DISQUS && window.DISQUS.reset({
|
||||||
reload: true,
|
reload: true,
|
||||||
config: disqus_config
|
config: disqus_config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addModeChange('disqus', disqusReset)
|
btf.addGlobalFn('themeChange', disqusReset, 'disqus')
|
||||||
|
|
||||||
if (window.DISQUS) disqusReset()
|
const loadDisqus = () =>{
|
||||||
else {
|
if (window.DISQUS) disqusReset()
|
||||||
(function() {
|
else {
|
||||||
var d = document, s = d.createElement('script');
|
const script = document.createElement('script')
|
||||||
s.src = 'https://!{theme.disqus.shortname}.disqus.com/embed.js';
|
script.src = 'https://!{shortname}.disqus.com/embed.js'
|
||||||
s.setAttribute('data-timestamp', +new Date());
|
script.setAttribute('data-timestamp', +new Date())
|
||||||
(d.head || d.body).appendChild(s);
|
document.head.appendChild(script)
|
||||||
})();
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Disqus' || !!{theme.comments.lazyload}) {
|
const getCount = async() => {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
|
try {
|
||||||
else loadDisqus()
|
const eleGroup = document.querySelector('#post-meta .disqus-comment-count')
|
||||||
} else {
|
if (!eleGroup) return
|
||||||
function loadOtherComment () {
|
const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
|
||||||
loadDisqus()
|
|
||||||
|
const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{shortname}&api_key=!{apikey}&thread:link=${cleanedLinks}`,{
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
const result = await res.json()
|
||||||
|
|
||||||
|
const count = result.response.length ? result.response[0].posts : 0
|
||||||
|
eleGroup.textContent = count
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if is_post() && !theme.comments.lazyload && theme.comments.count && theme.comments.use[0] === 'Disqus'
|
if ('!{use[0]}' === 'Disqus' || !!{lazyload}) {
|
||||||
script.
|
if (!{lazyload}) btf.loadComment(document.getElementById('disqus_thread'), loadDisqus)
|
||||||
if (window.DISQUSWIDGETS === undefined) {
|
else {
|
||||||
var d = document, s = d.createElement('script');
|
loadDisqus()
|
||||||
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js';
|
!{ count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
|
||||||
s.id = 'dsq-count-scr';
|
}
|
||||||
(d.head || d.body).appendChild(s);
|
|
||||||
} else {
|
} else {
|
||||||
DISQUSWIDGETS.getCount({reset: true});
|
window.loadOtherComment = loadDisqus
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
- let disqusjsPageTitle = page.title.replace(/'/ig,"\\'")
|
- let disqusjsPageTitle = page.title.replace(/'/ig,"\\'")
|
||||||
|
- const { shortname:dqShortname, apikey:dqApikey, option:dqOption } = theme.disqusjs
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadDisqusjs () {
|
(() => {
|
||||||
function initDisqusjs () {
|
const initDisqusjs = () => {
|
||||||
window.disqusjs = null
|
window.disqusjs = null
|
||||||
disqusjs = new DisqusJS(Object.assign({
|
disqusjs = new DisqusJS(Object.assign({
|
||||||
shortname: '!{theme.disqusjs.shortname}',
|
shortname: '!{dqShortname}',
|
||||||
identifier: '!{ url_for(page.path) }',
|
identifier: '!{ url_for(page.path) }',
|
||||||
url: '!{ page.permalink }',
|
url: '!{ page.permalink }',
|
||||||
title: '!{ disqusjsPageTitle }',
|
title: '!{ disqusjsPageTitle }',
|
||||||
apikey: '!{theme.disqusjs.apikey}',
|
apikey: '!{dqApikey}',
|
||||||
},!{JSON.stringify(theme.disqusjs.option)}))
|
},!{JSON.stringify(dqOption)}))
|
||||||
|
|
||||||
disqusjs.render(document.getElementById('disqusjs'))
|
disqusjs.render(document.getElementById('disqusjs-wrap'))
|
||||||
}
|
}
|
||||||
|
|
||||||
const themeChange = () => {
|
const themeChange = () => {
|
||||||
@@ -22,36 +23,42 @@ script.
|
|||||||
initDisqusjs()
|
initDisqusjs()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btf.addGlobalFn('themeChange', themeChange, 'disqusjs')
|
||||||
|
|
||||||
btf.addModeChange('disqusjs', themeChange)
|
const loadDisqusjs = async() => {
|
||||||
|
if (window.disqusJsLoad) initDisqusjs()
|
||||||
if (window.disqusJsLoad) initDisqusjs()
|
else {
|
||||||
else {
|
await getCSS('!{url_for(theme.asset.disqusjs_css)}')
|
||||||
getCSS('!{url_for(theme.asset.disqusjs_css)}')
|
await getScript('!{url_for(theme.asset.disqusjs)}')
|
||||||
getScript('!{url_for(theme.asset.disqusjs)}').then(initDisqusjs)
|
initDisqusjs()
|
||||||
window.disqusJsLoad = true
|
window.disqusJsLoad = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
|
const getCount = async() => {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs'), loadDisqusjs)
|
try {
|
||||||
else loadDisqusjs()
|
const eleGroup = document.querySelector('#post-meta .disqusjs-comment-count')
|
||||||
}
|
if (!eleGroup) return
|
||||||
else {
|
const cleanedLinks = eleGroup.href.replace(/#post-comment$/, '')
|
||||||
function loadOtherComment () {
|
|
||||||
loadDisqusjs()
|
const res = await fetch(`https://disqus.com/api/3.0/threads/set.json?forum=!{dqShortname}&api_key=!{dqApikey}&thread:link=${cleanedLinks}`,{
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
const result = await res.json()
|
||||||
|
const count = result.response.length ? result.response[0].posts : 0
|
||||||
|
eleGroup.textContent = count
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if ('!{theme.comments.use[0]}' === 'Disqusjs' || !!{theme.comments.lazyload}) {
|
||||||
if is_post() && !theme.comments.lazyload && theme.comments.count && theme.comments.use[0] === 'Disqusjs'
|
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('disqusjs-wrap'), loadDisqusjs)
|
||||||
script.
|
else {
|
||||||
if (window.DISQUSWIDGETS === undefined) {
|
loadDisqusjs()
|
||||||
var d = document, s = d.createElement('script');
|
!{ theme.comments.count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : '' }
|
||||||
s.src = 'https://!{theme.disqus.shortname}.disqus.com/count.js';
|
}
|
||||||
s.id = 'dsq-count-scr';
|
|
||||||
(d.head || d.body).appendChild(s);
|
|
||||||
} else {
|
} else {
|
||||||
DISQUSWIDGETS.getCount({reset: true});
|
window.loadOtherComment = loadDisqusjs
|
||||||
}
|
}
|
||||||
|
})()
|
||||||
@@ -2,45 +2,45 @@
|
|||||||
- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
|
- const fbSDK = theme.messenger.enable ? `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk/xfbml.customerchat.js#xfbml=1&version=${fbSDKVer}` : `https://connect.facebook.net/${theme.facebook_comments.lang}/sdk.js#xfbml=1&version=${fbSDKVer}`
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadFBComment () {
|
(()=>{
|
||||||
document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
|
const loadFBComment = () => {
|
||||||
|
document.getElementById('fb-root') ? '' : document.body.insertAdjacentHTML('afterend', '<div id="fb-root"></div>')
|
||||||
|
|
||||||
const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
const themeNow = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
|
||||||
const $fbComment = document.getElementsByClassName('fb-comments')[0]
|
const $fbComment = document.getElementsByClassName('fb-comments')[0]
|
||||||
$fbComment.setAttribute('data-colorscheme',themeNow)
|
$fbComment.setAttribute('data-colorscheme',themeNow)
|
||||||
$fbComment.setAttribute('data-href', '!{urlNoIndex(page.permalink)}')
|
$fbComment.setAttribute('data-href', '!{urlNoIndex(page.permalink)}')
|
||||||
|
|
||||||
if (typeof FB === 'object') {
|
if (typeof FB === 'object') {
|
||||||
FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
|
FB.XFBML.parse(document.getElementsByClassName('post-meta-commentcount')[0])
|
||||||
FB.XFBML.parse(document.getElementById('post-comment'))
|
FB.XFBML.parse(document.getElementById('post-comment'))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let ele = document.createElement('script')
|
||||||
|
ele.setAttribute('src','!{fbSDK}')
|
||||||
|
ele.setAttribute('async', 'true')
|
||||||
|
ele.setAttribute('defer', 'true')
|
||||||
|
ele.setAttribute('crossorigin', 'anonymous')
|
||||||
|
ele.setAttribute('id', 'facebook-jssdk')
|
||||||
|
document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
let ele = document.createElement('script')
|
const fbModeChange = theme => {
|
||||||
ele.setAttribute('src','!{fbSDK}')
|
const $fbComment = document.getElementsByClassName('fb-comments')[0]
|
||||||
ele.setAttribute('async', 'true')
|
if ($fbComment && typeof FB === 'object') {
|
||||||
ele.setAttribute('defer', 'true')
|
$fbComment.setAttribute('data-colorscheme',theme)
|
||||||
ele.setAttribute('crossorigin', 'anonymous')
|
FB.XFBML.parse(document.getElementById('post-comment'))
|
||||||
ele.setAttribute('id', 'facebook-jssdk')
|
}
|
||||||
document.getElementById('fb-root').insertAdjacentElement('afterbegin',ele)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function fbModeChange (theme) {
|
btf.addGlobalFn('themeChange', fbModeChange, 'facebook_comments')
|
||||||
const $fbComment = document.getElementsByClassName('fb-comments')[0]
|
|
||||||
if ($fbComment && typeof FB === 'object') {
|
if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) {
|
||||||
$fbComment.setAttribute('data-colorscheme',theme)
|
if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment)
|
||||||
FB.XFBML.parse(document.getElementById('post-comment'))
|
else loadFBComment()
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadFBComment
|
||||||
}
|
}
|
||||||
}
|
})()
|
||||||
|
|
||||||
btf.addModeChange('facebook_comments', fbModeChange)
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Facebook Comments' || !!{theme.comments.lazyload}) {
|
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.querySelector('#post-comment .fb-comments'), loadFBComment)
|
|
||||||
else loadFBComment()
|
|
||||||
} else {
|
|
||||||
function loadOtherComment () {
|
|
||||||
loadFBComment()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
89
layout/includes/third-party/comments/giscus.pug
vendored
89
layout/includes/third-party/comments/giscus.pug
vendored
@@ -1,53 +1,54 @@
|
|||||||
- const { repo, repo_id, category_id, theme:themes, option } = theme.giscus
|
- const { repo, repo_id, category_id, theme:themes, option } = theme.giscus
|
||||||
- const giscusUrl = theme.asset.giscus || 'https://giscus.app/client.js'
|
- const giscusUrl = theme.asset.giscus || 'https://giscus.app/client.js'
|
||||||
- const giscusOriginUrl = new URL(giscusUrl).origin
|
- const giscusOriginUrl = new URL(giscusUrl).origin
|
||||||
|
- const { use, lazyload } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function getGiscusTheme (theme) {
|
(()=>{
|
||||||
return theme === 'dark' ? '!{themes.dark}' : '!{themes.light}'
|
const getGiscusTheme = theme => {
|
||||||
}
|
return theme === 'dark' ? '!{themes.dark}' : '!{themes.light}'
|
||||||
|
|
||||||
function loadGiscus () {
|
|
||||||
const config = Object.assign({
|
|
||||||
src: '!{giscusUrl}',
|
|
||||||
'data-repo': '!{repo}',
|
|
||||||
'data-repo-id': '!{repo_id}',
|
|
||||||
'data-category-id': '!{category_id}',
|
|
||||||
'data-mapping': 'pathname',
|
|
||||||
'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
|
|
||||||
'data-reactions-enabled': '1',
|
|
||||||
crossorigin: 'anonymous',
|
|
||||||
async: true
|
|
||||||
},!{JSON.stringify(option)})
|
|
||||||
|
|
||||||
let ele = document.createElement('script')
|
|
||||||
for (let key in config) {
|
|
||||||
ele.setAttribute(key, config[key])
|
|
||||||
}
|
|
||||||
document.getElementById('giscus-wrap').insertAdjacentElement('afterbegin',ele)
|
|
||||||
}
|
|
||||||
|
|
||||||
function changeGiscusTheme (theme) {
|
|
||||||
function sendMessage(message) {
|
|
||||||
const iframe = document.querySelector('iframe.giscus-frame')
|
|
||||||
if (!iframe) return
|
|
||||||
iframe.contentWindow.postMessage({ giscus: message }, '!{giscusOriginUrl}')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage({
|
const loadGiscus = () => {
|
||||||
setConfig: {
|
const config = Object.assign({
|
||||||
theme: getGiscusTheme(theme)
|
src: '!{giscusUrl}',
|
||||||
|
'data-repo': '!{repo}',
|
||||||
|
'data-repo-id': '!{repo_id}',
|
||||||
|
'data-category-id': '!{category_id}',
|
||||||
|
'data-mapping': 'pathname',
|
||||||
|
'data-theme': getGiscusTheme(document.documentElement.getAttribute('data-theme')),
|
||||||
|
'data-reactions-enabled': '1',
|
||||||
|
crossorigin: 'anonymous',
|
||||||
|
async: true
|
||||||
|
},!{JSON.stringify(option)})
|
||||||
|
|
||||||
|
const ele = document.createElement('script')
|
||||||
|
for (let key in config) {
|
||||||
|
ele.setAttribute(key, config[key])
|
||||||
}
|
}
|
||||||
});
|
document.getElementById('giscus-wrap').appendChild(ele)
|
||||||
}
|
|
||||||
|
|
||||||
btf.addModeChange('giscus', changeGiscusTheme)
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Giscus' || !!{theme.comments.lazyload}) {
|
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
|
|
||||||
else loadGiscus()
|
|
||||||
} else {
|
|
||||||
function loadOtherComment () {
|
|
||||||
loadGiscus()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
const changeGiscusTheme = theme => {
|
||||||
|
const sendMessage = message => {
|
||||||
|
const iframe = document.querySelector('iframe.giscus-frame')
|
||||||
|
if (!iframe) return
|
||||||
|
iframe.contentWindow.postMessage({ giscus: message }, '!{giscusOriginUrl}')
|
||||||
|
}
|
||||||
|
|
||||||
|
sendMessage({
|
||||||
|
setConfig: {
|
||||||
|
theme: getGiscusTheme(theme)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
btf.addGlobalFn('themeChange', changeGiscusTheme, 'giscus')
|
||||||
|
|
||||||
|
if ('!{use[0]}' === 'Giscus' || !!{lazyload}) {
|
||||||
|
if (!{lazyload}) btf.loadComment(document.getElementById('giscus-wrap'), loadGiscus)
|
||||||
|
else loadGiscus()
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment= loadGiscus
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|||||||
55
layout/includes/third-party/comments/gitalk.pug
vendored
55
layout/includes/third-party/comments/gitalk.pug
vendored
@@ -1,41 +1,44 @@
|
|||||||
|
- const { client_id, client_secret, repo, owner, admin, option } = theme.gitalk
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadGitalk () {
|
(() => {
|
||||||
function initGitalk () {
|
const initGitalk = () => {
|
||||||
var gitalk = new Gitalk(Object.assign({
|
const gitalk = new Gitalk(Object.assign({
|
||||||
clientID: '!{theme.gitalk.client_id}',
|
clientID: '!{client_id}',
|
||||||
clientSecret: '!{theme.gitalk.client_secret}',
|
clientSecret: '!{client_secret}',
|
||||||
repo: '!{theme.gitalk.repo}',
|
repo: '!{repo}',
|
||||||
owner: '!{theme.gitalk.owner}',
|
owner: '!{owner}',
|
||||||
admin: ['!{theme.gitalk.admin}'],
|
admin: ['!{admin}'],
|
||||||
id: '!{md5(page.path)}',
|
id: '!{md5(page.path)}',
|
||||||
updateCountCallback: commentCount
|
updateCountCallback: commentCount
|
||||||
},!{JSON.stringify(theme.gitalk.option)}))
|
},!{JSON.stringify(option)}))
|
||||||
|
|
||||||
gitalk.render('gitalk-container')
|
gitalk.render('gitalk-container')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Gitalk === 'function') initGitalk()
|
const loadGitalk = async() => {
|
||||||
else {
|
if (typeof Gitalk === 'function') initGitalk()
|
||||||
getCSS('!{url_for(theme.asset.gitalk_css)}')
|
else {
|
||||||
getScript('!{url_for(theme.asset.gitalk)}').then(initGitalk)
|
await getCSS('!{url_for(theme.asset.gitalk_css)}')
|
||||||
|
await getScript('!{url_for(theme.asset.gitalk)}')
|
||||||
|
initGitalk()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function commentCount(n){
|
const commentCount = n => {
|
||||||
let isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
|
const isCommentCount = document.querySelector('#post-meta .gitalk-comment-count')
|
||||||
if (isCommentCount) {
|
if (isCommentCount) {
|
||||||
isCommentCount.textContent= n
|
isCommentCount.textContent= n
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Gitalk' || !!{theme.comments.lazyload}) {
|
if ('!{theme.comments.use[0]}' === 'Gitalk' || !!{theme.comments.lazyload}) {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
|
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('gitalk-container'), loadGitalk)
|
||||||
else loadGitalk()
|
else loadGitalk()
|
||||||
} else {
|
} else {
|
||||||
function loadOtherComment () {
|
window.loadOtherComment = loadGitalk
|
||||||
loadGitalk()
|
|
||||||
}
|
}
|
||||||
}
|
})()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ hr.custom-hr
|
|||||||
span= ' ' + _p('comment')
|
span= ' ' + _p('comment')
|
||||||
|
|
||||||
if theme.comments.use.length > 1
|
if theme.comments.use.length > 1
|
||||||
#comment-switch
|
.comment-switch
|
||||||
span.first-comment=defaultComment
|
span.first-comment=defaultComment
|
||||||
span.switch-btn
|
span#switch-btn
|
||||||
span.second-comment=theme.comments.use[1]
|
span.second-comment=theme.comments.use[1]
|
||||||
|
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ hr.custom-hr
|
|||||||
when 'Valine'
|
when 'Valine'
|
||||||
#vcomment.vcomment
|
#vcomment.vcomment
|
||||||
when 'Disqusjs'
|
when 'Disqusjs'
|
||||||
#disqusjs
|
#disqusjs-wrap
|
||||||
when 'Livere'
|
when 'Livere'
|
||||||
#lv-container(data-id="city" data-uid=theme.livere.uid)
|
#lv-container(data-id="city" data-uid=theme.livere.uid)
|
||||||
when 'Gitalk'
|
when 'Gitalk'
|
||||||
|
|||||||
47
layout/includes/third-party/comments/livere.pug
vendored
47
layout/includes/third-party/comments/livere.pug
vendored
@@ -1,26 +1,25 @@
|
|||||||
script.
|
- const { use, lazyload } = theme.comments
|
||||||
function loadLivere () {
|
|
||||||
if (typeof LivereTower === 'object') {
|
|
||||||
window.LivereTower.init()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
(function(d, s) {
|
|
||||||
var j, e = d.getElementsByTagName(s)[0];
|
|
||||||
if (typeof LivereTower === 'function') { return; }
|
|
||||||
j = d.createElement(s);
|
|
||||||
j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
|
|
||||||
j.async = true;
|
|
||||||
e.parentNode.insertBefore(j, e);
|
|
||||||
})(document, 'script');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Livere' || !!{theme.comments.lazyload}) {
|
script.
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
|
(()=>{
|
||||||
else loadLivere()
|
const loadLivere = () => {
|
||||||
}
|
if (typeof LivereTower === 'object') window.LivereTower.init()
|
||||||
else {
|
else {
|
||||||
function loadOtherComment () {
|
(function(d, s) {
|
||||||
loadLivere()
|
var j, e = d.getElementsByTagName(s)[0];
|
||||||
|
if (typeof LivereTower === 'function') { return; }
|
||||||
|
j = d.createElement(s);
|
||||||
|
j.src = 'https://cdn-city.livere.com/js/embed.dist.js';
|
||||||
|
j.async = true;
|
||||||
|
e.parentNode.insertBefore(j, e);
|
||||||
|
})(document, 'script');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if ('!{use[0]}' === 'Livere' || !!{lazyload}) {
|
||||||
|
if (!{lazyload}) btf.loadComment(document.getElementById('lv-container'), loadLivere)
|
||||||
|
else loadLivere()
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadLivere
|
||||||
|
}
|
||||||
|
})()
|
||||||
@@ -56,7 +56,7 @@ script.
|
|||||||
window.REMARK42.changeTheme(theme)
|
window.REMARK42.changeTheme(theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addModeChange('remark42', remarkChangeMode)
|
btf.addGlobalFn('themeChange', remarkChangeMode, 'remark42')
|
||||||
|
|
||||||
if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) {
|
if ('!{theme.comments.use[0]}' === 'Remark42' || !!{theme.comments.lazyload}) {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42)
|
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('remark42'), loadRemark42)
|
||||||
|
|||||||
37
layout/includes/third-party/comments/twikoo.pug
vendored
37
layout/includes/third-party/comments/twikoo.pug
vendored
@@ -2,18 +2,23 @@
|
|||||||
- const { use, lazyload, count } = theme.comments
|
- const { use, lazyload, count } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
(()=>{
|
(() => {
|
||||||
const init = () => {
|
const init = () => {
|
||||||
twikoo.init(Object.assign({
|
twikoo.init(Object.assign({
|
||||||
el: '#twikoo-wrap',
|
el: '#twikoo-wrap',
|
||||||
envId: '!{envId}',
|
envId: '!{envId}',
|
||||||
region: '!{region}',
|
region: '!{region}',
|
||||||
onCommentLoaded: function () {
|
onCommentLoaded: () => {
|
||||||
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
|
btf.loadLightbox(document.querySelectorAll('#twikoo .tk-content img:not(.tk-owo-emotion)'))
|
||||||
}
|
}
|
||||||
}, !{JSON.stringify(option)}))
|
}, !{JSON.stringify(option)}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const loadTwikoo = () => {
|
||||||
|
if (typeof twikoo === 'object') setTimeout(init,0)
|
||||||
|
else getScript('!{url_for(theme.asset.twikoo)}').then(init)
|
||||||
|
}
|
||||||
|
|
||||||
const getCount = () => {
|
const getCount = () => {
|
||||||
const countELement = document.getElementById('twikoo-count')
|
const countELement = document.getElementById('twikoo-count')
|
||||||
if(!countELement) return
|
if(!countELement) return
|
||||||
@@ -22,32 +27,20 @@ script.
|
|||||||
region: '!{region}',
|
region: '!{region}',
|
||||||
urls: [window.location.pathname],
|
urls: [window.location.pathname],
|
||||||
includeReply: false
|
includeReply: false
|
||||||
}).then(function (res) {
|
}).then(res => {
|
||||||
countELement.textContent = res[0].count
|
countELement.textContent = res[0].count
|
||||||
}).catch(function (err) {
|
}).catch(err => {
|
||||||
console.error(err);
|
console.error(err)
|
||||||
});
|
})
|
||||||
}
|
|
||||||
|
|
||||||
const runFn = () => {
|
|
||||||
init()
|
|
||||||
!{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
|
|
||||||
}
|
|
||||||
|
|
||||||
const loadTwikoo = () => {
|
|
||||||
if (typeof twikoo === 'object') {
|
|
||||||
setTimeout(runFn,0)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
getScript('!{url_for(theme.asset.twikoo)}').then(runFn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Twikoo' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
|
if (!{lazyload}) btf.loadComment(document.getElementById('twikoo-wrap'), loadTwikoo)
|
||||||
else loadTwikoo()
|
else {
|
||||||
} else {
|
|
||||||
window.loadOtherComment = () => {
|
|
||||||
loadTwikoo()
|
loadTwikoo()
|
||||||
|
!{count ? 'GLOBAL_CONFIG_SITE.isPost && getCount()' : ''}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadTwikoo
|
||||||
}
|
}
|
||||||
})()
|
})()
|
||||||
@@ -1,36 +1,39 @@
|
|||||||
|
- const { use, lazyload } = theme.comments
|
||||||
|
- const { repo, issue_term, light_theme, dark_theme } = theme.utterances
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadUtterances () {
|
(() => {
|
||||||
let ele = document.createElement('script')
|
const loadUtterances = () => {
|
||||||
ele.setAttribute('id', 'utterances_comment')
|
let ele = document.createElement('script')
|
||||||
ele.setAttribute('src', 'https://utteranc.es/client.js')
|
ele.id = 'utterances_comment'
|
||||||
ele.setAttribute('repo', '!{theme.utterances.repo}')
|
ele.src = 'https://utteranc.es/client.js'
|
||||||
ele.setAttribute('issue-term', '!{theme.utterances.issue_term}')
|
ele.setAttribute('repo', '!{repo}')
|
||||||
let nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}'
|
ele.setAttribute('issue-term', '!{issue_term}')
|
||||||
ele.setAttribute('theme', nowTheme)
|
const nowTheme = document.documentElement.getAttribute('data-theme') === 'dark' ? '#{dark_theme}' : '#{light_theme}'
|
||||||
ele.setAttribute('crossorigin', 'anonymous')
|
ele.setAttribute('theme', nowTheme)
|
||||||
ele.setAttribute('async', 'true')
|
ele.crossOrigin = 'anonymous'
|
||||||
document.getElementById('utterances-wrap').insertAdjacentElement('afterbegin',ele)
|
ele.async = true
|
||||||
}
|
document.getElementById('utterances-wrap').appendChild(ele)
|
||||||
|
|
||||||
function utterancesTheme (theme) {
|
|
||||||
const iframe = document.querySelector('.utterances-frame')
|
|
||||||
if (iframe) {
|
|
||||||
const theme = theme === 'dark' ? '#{theme.utterances.dark_theme}' : '#{theme.utterances.light_theme}'
|
|
||||||
const message = {
|
|
||||||
type: 'set-theme',
|
|
||||||
theme: theme
|
|
||||||
};
|
|
||||||
iframe.contentWindow.postMessage(message, 'https://utteranc.es');
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
btf.addModeChange('utterances', utterancesTheme)
|
const utterancesTheme = theme => {
|
||||||
|
const iframe = document.querySelector('.utterances-frame')
|
||||||
if ('!{theme.comments.use[0]}' === 'Utterances' || !!{theme.comments.lazyload}) {
|
if (iframe) {
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
|
const theme = theme === 'dark' ? '#{dark_theme}' : '#{light_theme}'
|
||||||
else loadUtterances()
|
const message = {
|
||||||
} else {
|
type: 'set-theme',
|
||||||
function loadOtherComment () {
|
theme: theme
|
||||||
loadUtterances()
|
};
|
||||||
|
iframe.contentWindow.postMessage(message, 'https://utteranc.es');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
btf.addGlobalFn('themeChange', utterancesTheme, 'utterances')
|
||||||
|
|
||||||
|
if ('!{use[0]}' === 'Utterances' || !!{lazyload}) {
|
||||||
|
if (!{lazyload}) btf.loadComment(document.getElementById('utterances-wrap'), loadUtterances)
|
||||||
|
else loadUtterances()
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadUtterances
|
||||||
|
}
|
||||||
|
})()
|
||||||
43
layout/includes/third-party/comments/valine.pug
vendored
43
layout/includes/third-party/comments/valine.pug
vendored
@@ -1,33 +1,38 @@
|
|||||||
|
- const { use, lazyload } = theme.comments
|
||||||
|
- const { appId, appKey, avatar, serverURLs, visitor, option } = theme.valine
|
||||||
|
|
||||||
- let emojiMaps = '""'
|
- let emojiMaps = '""'
|
||||||
if site.data.valine
|
if site.data.valine
|
||||||
- emojiMaps = JSON.stringify(site.data.valine)
|
- emojiMaps = JSON.stringify(site.data.valine)
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadValine () {
|
(() => {
|
||||||
function initValine () {
|
const initValine = () => {
|
||||||
const valine = new Valine(Object.assign({
|
const valine = new Valine(Object.assign({
|
||||||
el: '#vcomment',
|
el: '#vcomment',
|
||||||
appId: '#{theme.valine.appId}',
|
appId: '#{appId}',
|
||||||
appKey: '#{theme.valine.appKey}',
|
appKey: '#{appKey}',
|
||||||
avatar: '#{theme.valine.avatar}',
|
avatar: '#{avatar}',
|
||||||
serverURLs: '#{theme.valine.serverURLs}',
|
serverURLs: '#{serverURLs}',
|
||||||
emojiMaps: !{emojiMaps},
|
emojiMaps: !{emojiMaps},
|
||||||
path: window.location.pathname,
|
path: window.location.pathname,
|
||||||
visitor: #{theme.valine.visitor}
|
visitor: #{visitor}
|
||||||
}, !{JSON.stringify(theme.valine.option)}))
|
}, !{JSON.stringify(option)}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Valine === 'function') initValine()
|
const loadValine = async () => {
|
||||||
else getScript('!{url_for(theme.asset.valine)}').then(initValine)
|
if (typeof Valine === 'function') initValine()
|
||||||
}
|
else {
|
||||||
|
await getScript('!{url_for(theme.asset.valine)}')
|
||||||
if ('!{theme.comments.use[0]}' === 'Valine' || !!{theme.comments.lazyload}) {
|
initValine()
|
||||||
if (!{theme.comments.lazyload}) btf.loadComment(document.getElementById('vcomment'),loadValine)
|
}
|
||||||
else setTimeout(loadValine, 0)
|
|
||||||
} else {
|
|
||||||
function loadOtherComment () {
|
|
||||||
loadValine()
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if ('!{use[0]}' === 'Valine' || !!{lazyload}) {
|
||||||
|
if (!{lazyload}) btf.loadComment(document.getElementById('vcomment'),loadValine)
|
||||||
|
else setTimeout(loadValine, 0)
|
||||||
|
} else {
|
||||||
|
window.loadOtherComment = loadValine
|
||||||
|
}
|
||||||
|
})()
|
||||||
|
|
||||||
|
|||||||
31
layout/includes/third-party/comments/waline.pug
vendored
31
layout/includes/third-party/comments/waline.pug
vendored
@@ -2,8 +2,8 @@
|
|||||||
- const { lazyload, count, use } = theme.comments
|
- const { lazyload, count, use } = theme.comments
|
||||||
|
|
||||||
script.
|
script.
|
||||||
function loadWaline () {
|
(() => {
|
||||||
function initWaline () {
|
const initWaline = () => {
|
||||||
const waline = Waline.init(Object.assign({
|
const waline = Waline.init(Object.assign({
|
||||||
el: '#waline-wrap',
|
el: '#waline-wrap',
|
||||||
serverURL: '!{serverURL}',
|
serverURL: '!{serverURL}',
|
||||||
@@ -14,21 +14,20 @@ script.
|
|||||||
}, !{JSON.stringify(option)}))
|
}, !{JSON.stringify(option)}))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof Waline === 'object') initWaline()
|
const loadWaline = async () => {
|
||||||
else {
|
if (typeof Waline === 'object') initWaline()
|
||||||
getCSS('!{url_for(theme.asset.waline_css)}').then(() => {
|
else {
|
||||||
getScript('!{url_for(theme.asset.waline_js)}').then(initWaline)
|
await getCSS('!{url_for(theme.asset.waline_css)}')
|
||||||
})
|
await getScript('!{url_for(theme.asset.waline_js)}')
|
||||||
|
initWaline()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ('!{use[0]}' === 'Waline' || !!{lazyload}) {
|
if ('!{use[0]}' === 'Waline' || !!{lazyload}) {
|
||||||
if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
|
if (!{lazyload}) btf.loadComment(document.getElementById('waline-wrap'),loadWaline)
|
||||||
else setTimeout(loadWaline, 0)
|
else setTimeout(loadWaline, 0)
|
||||||
} else {
|
} else {
|
||||||
function loadOtherComment () {
|
window.loadOtherComment = loadWaline
|
||||||
loadWaline()
|
|
||||||
}
|
}
|
||||||
}
|
})()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
2
layout/includes/third-party/math/mermaid.pug
vendored
2
layout/includes/third-party/math/mermaid.pug
vendored
@@ -32,7 +32,7 @@ script.
|
|||||||
window.loadMermaid ? runMermaid() : getScript('!{url_for(theme.asset.mermaid)}').then(runMermaid)
|
window.loadMermaid ? runMermaid() : getScript('!{url_for(theme.asset.mermaid)}').then(runMermaid)
|
||||||
}
|
}
|
||||||
|
|
||||||
btf.addModeChange('mermaid', runMermaid)
|
btf.addGlobalFn('themeChange', runMermaid, 'mermaid')
|
||||||
|
|
||||||
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
|
window.pjax ? loadMermaid() : document.addEventListener('DOMContentLoaded', loadMermaid)
|
||||||
})()
|
})()
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
- const serverURL = theme.waline.serverURL.replace(/\/$/, '')
|
||||||
|
|
||||||
script.
|
script.
|
||||||
window.addEventListener('load', () => {
|
window.addEventListener('load', () => {
|
||||||
const changeContent = content => {
|
const changeContent = content => {
|
||||||
@@ -43,7 +45,7 @@ script.
|
|||||||
|
|
||||||
const getComment = async () => {
|
const getComment = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await fetch('!{theme.waline.serverURL}/api/comment?type=recent&count=!{theme.newest_comments.limit}', { method: 'GET' })
|
const res = await fetch('!{serverURL}/api/comment?type=recent&count=!{theme.newest_comments.limit}', { method: 'GET' })
|
||||||
const result = await res.json()
|
const result = await res.json()
|
||||||
const walineArray = result.data.map(e => {
|
const walineArray = result.data.map(e => {
|
||||||
return {
|
return {
|
||||||
|
|||||||
12
layout/includes/third-party/pjax.pug
vendored
12
layout/includes/third-party/pjax.pug
vendored
@@ -26,11 +26,11 @@ script.
|
|||||||
|
|
||||||
document.addEventListener('pjax:send', function () {
|
document.addEventListener('pjax:send', function () {
|
||||||
|
|
||||||
// removeEventListener scroll
|
// removeEventListener
|
||||||
window.tocScrollFn && window.removeEventListener('scroll', window.tocScrollFn)
|
btf.removeGlobalFnEvent('pjax')
|
||||||
window.scrollCollect && window.removeEventListener('scroll', scrollCollect)
|
btf.removeGlobalFnEvent('themeChange')
|
||||||
|
|
||||||
document.getElementById('rightside').style.cssText = "opacity: ''; transform: ''"
|
document.getElementById('rightside').classList.remove('rightside-show')
|
||||||
|
|
||||||
if (window.aplayers) {
|
if (window.aplayers) {
|
||||||
for (let i = 0; i < window.aplayers.length; i++) {
|
for (let i = 0; i < window.aplayers.length; i++) {
|
||||||
@@ -76,8 +76,8 @@ script.
|
|||||||
typeof Prism === 'object' && Prism.highlightAll()
|
typeof Prism === 'object' && Prism.highlightAll()
|
||||||
})
|
})
|
||||||
|
|
||||||
document.addEventListener('pjax:error', (e) => {
|
document.addEventListener('pjax:error', e => {
|
||||||
if (e.request.status === 404) {
|
if (e.request.status === 404) {
|
||||||
pjax.loadUrl('/404.html')
|
pjax.loadUrl('!{url_for("/404.html")}')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -13,11 +13,12 @@
|
|||||||
container: '#docsearch',
|
container: '#docsearch',
|
||||||
}, !{JSON.stringify(option)}))
|
}, !{JSON.stringify(option)}))
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
document.querySelector('.DocSearch-Button').click()
|
||||||
|
}
|
||||||
|
|
||||||
const searchClickFn = () => {
|
const searchClickFn = () => {
|
||||||
document.querySelector('#search-button > .search').addEventListener('click', () => {
|
btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', handleClick)
|
||||||
document.querySelector('.DocSearch-Button').click()
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
searchClickFn()
|
searchClickFn()
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hexo-theme-butterfly",
|
"name": "hexo-theme-butterfly",
|
||||||
"version": "4.9.0",
|
"version": "4.10.0-b1",
|
||||||
"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": {
|
||||||
|
|||||||
23
plugins.yml
23
plugins.yml
@@ -5,7 +5,7 @@ algolia_search:
|
|||||||
instantsearch:
|
instantsearch:
|
||||||
name: instantsearch.js
|
name: instantsearch.js
|
||||||
file: dist/instantsearch.production.min.js
|
file: dist/instantsearch.production.min.js
|
||||||
version: 4.56.3
|
version: 4.56.5
|
||||||
pjax:
|
pjax:
|
||||||
name: pjax
|
name: pjax
|
||||||
file: pjax.min.js
|
file: pjax.min.js
|
||||||
@@ -73,7 +73,7 @@ katex_copytex:
|
|||||||
mermaid:
|
mermaid:
|
||||||
name: mermaid
|
name: mermaid
|
||||||
file: dist/mermaid.min.js
|
file: dist/mermaid.min.js
|
||||||
version: 10.2.3
|
version: 10.2.4
|
||||||
canvas_ribbon:
|
canvas_ribbon:
|
||||||
name: butterfly-extsrc
|
name: butterfly-extsrc
|
||||||
file: dist/canvas-ribbon.min.js
|
file: dist/canvas-ribbon.min.js
|
||||||
@@ -105,7 +105,7 @@ ClickShowText:
|
|||||||
lazyload:
|
lazyload:
|
||||||
name: vanilla-lazyload
|
name: vanilla-lazyload
|
||||||
file: dist/lazyload.iife.min.js
|
file: dist/lazyload.iife.min.js
|
||||||
version: 17.8.3
|
version: 17.8.4
|
||||||
instantpage:
|
instantpage:
|
||||||
name: instant.page
|
name: instant.page
|
||||||
file: instantpage.js
|
file: instantpage.js
|
||||||
@@ -121,12 +121,12 @@ pangu:
|
|||||||
fancybox_css:
|
fancybox_css:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.css
|
file: dist/fancybox/fancybox.css
|
||||||
version: 5.0.19
|
version: 5.0.20
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
fancybox:
|
fancybox:
|
||||||
name: '@fancyapps/ui'
|
name: '@fancyapps/ui'
|
||||||
file: dist/fancybox/fancybox.umd.js
|
file: dist/fancybox/fancybox.umd.js
|
||||||
version: 5.0.19
|
version: 5.0.20
|
||||||
other_name: fancyapps-ui
|
other_name: fancyapps-ui
|
||||||
medium_zoom:
|
medium_zoom:
|
||||||
name: medium-zoom
|
name: medium-zoom
|
||||||
@@ -145,14 +145,11 @@ fontawesome:
|
|||||||
file: css/all.min.css
|
file: css/all.min.css
|
||||||
other_name: font-awesome
|
other_name: font-awesome
|
||||||
version: 6.4.0
|
version: 6.4.0
|
||||||
flickr_justified_gallery_js:
|
egjs_infinitegrid:
|
||||||
name: flickr-justified-gallery
|
name: '@egjs/infinitegrid'
|
||||||
file: dist/fjGallery.min.js
|
other_name: egjs-infinitegrid
|
||||||
version: 2.1.2
|
file: dist/infinitegrid.min.js
|
||||||
flickr_justified_gallery_css:
|
version: 4.10.0
|
||||||
name: flickr-justified-gallery
|
|
||||||
file: dist/fjGallery.css
|
|
||||||
version: 2.1.2
|
|
||||||
aplayer_css:
|
aplayer_css:
|
||||||
name: aplayer
|
name: aplayer
|
||||||
file: dist/APlayer.min.css
|
file: dist/APlayer.min.css
|
||||||
|
|||||||
@@ -1,15 +1,16 @@
|
|||||||
/**
|
/**
|
||||||
* stylus
|
* Stylus renderer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
hexo.extend.filter.register('stylus:renderer', function (style) {
|
hexo.extend.filter.register('stylus:renderer', style => {
|
||||||
const { highlight, prismjs } = hexo.config
|
const { enable: highlightEnable, line_number: highlightLineNumber } = hexo.config.highlight
|
||||||
style
|
const { enable: prismjsEnable, line_number: prismjsLineNumber } = hexo.config.prismjs
|
||||||
.define('$highlight_enable', highlight && highlight.enable)
|
|
||||||
.define('$highlight_line_number', highlight && highlight.line_number)
|
style.define('$highlight_enable', highlightEnable)
|
||||||
.define('$prismjs_enable', prismjs && prismjs.enable)
|
.define('$highlight_line_number', highlightLineNumber)
|
||||||
.define('$prismjs_line_number', prismjs && prismjs.line_number)
|
.define('$prismjs_enable', prismjsEnable)
|
||||||
// .import(this.source_dir.replace(/\\/g, '/') + '_data/css/*')
|
.define('$prismjs_line_number', prismjsLineNumber)
|
||||||
|
// .import(`${this.source_dir.replace(/\\/g, '/')}_data/css/*`)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -8,22 +8,20 @@
|
|||||||
|
|
||||||
const urlFor = require('hexo-util').url_for.bind(hexo)
|
const urlFor = require('hexo-util').url_for.bind(hexo)
|
||||||
|
|
||||||
function lazyload (htmlContent) {
|
const lazyload = htmlContent => {
|
||||||
const bg = hexo.theme.config.lazyload.placeholder ? urlFor(hexo.theme.config.lazyload.placeholder) : 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
|
const bg = hexo.theme.config.lazyload.placeholder ? urlFor(hexo.theme.config.lazyload.placeholder) : 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
|
||||||
return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)
|
return htmlContent.replace(/(<img.*? src=)/ig, `$1 "${bg}" data-lazy-src=`)
|
||||||
}
|
}
|
||||||
|
|
||||||
hexo.extend.filter.register('after_render:html', function (data) {
|
hexo.extend.filter.register('after_render:html', data => {
|
||||||
const config = hexo.theme.config.lazyload
|
const { enable, field } = hexo.theme.config.lazyload
|
||||||
if (!config.enable) return
|
if (!enable || field !== 'site') return
|
||||||
if (config.field !== 'site') return
|
return lazyload(data)
|
||||||
return lazyload.call(this, data)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
hexo.extend.filter.register('after_post_render', data => {
|
hexo.extend.filter.register('after_post_render', data => {
|
||||||
const config = hexo.theme.config.lazyload
|
const { enable, field } = hexo.theme.config.lazyload
|
||||||
if (!config.enable) return
|
if (!enable || field !== 'post') return
|
||||||
if (config.field !== 'post') return
|
data.content = lazyload(data.content)
|
||||||
data.content = lazyload.call(this, data.content)
|
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,40 +5,35 @@
|
|||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
hexo.extend.filter.register('before_post_render', function (data) {
|
hexo.extend.filter.register('before_post_render', data => {
|
||||||
const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
|
const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
|
||||||
let randomCover
|
let { cover: coverVal, top_img: topImg } = data
|
||||||
let coverVal = data.cover
|
|
||||||
|
|
||||||
// Add path to top_img and cover if post_asset_folder is enabled
|
// Add path to top_img and cover if post_asset_folder is enabled
|
||||||
if (hexo.config.post_asset_folder) {
|
if (hexo.config.post_asset_folder) {
|
||||||
const topImg = data.top_img
|
if (topImg && topImg.indexOf('/') === -1 && imgTestReg.test(topImg)) data.top_img = `${data.path}${topImg}`
|
||||||
if (topImg && topImg.indexOf('/') === -1 && imgTestReg.test(topImg)) data.top_img = data.path + topImg
|
if (coverVal && coverVal.indexOf('/') === -1 && imgTestReg.test(coverVal)) data.cover = `${data.path}${coverVal}`
|
||||||
if (coverVal && coverVal.indexOf('/') === -1 && imgTestReg.test(coverVal)) data.cover = data.path + coverVal
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const randomCoverFn = () => {
|
const randomCoverFn = () => {
|
||||||
const theme = hexo.theme.config
|
const { cover: { default_cover: defaultCover } } = hexo.theme.config
|
||||||
if (!(theme.cover && theme.cover.default_cover)) return false
|
if (!defaultCover) return false
|
||||||
if (!Array.isArray(theme.cover.default_cover)) return theme.cover.default_cover
|
if (!Array.isArray(defaultCover)) return defaultCover
|
||||||
const num = Math.floor(Math.random() * theme.cover.default_cover.length)
|
const num = Math.floor(Math.random() * defaultCover.length)
|
||||||
return theme.cover.default_cover[num]
|
return defaultCover[num]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverVal === false) return data
|
if (coverVal === false) return data
|
||||||
|
|
||||||
// If cover is not set, use random cover
|
// If cover is not set, use random cover
|
||||||
if (!coverVal) {
|
if (!coverVal) {
|
||||||
randomCover = randomCoverFn()
|
const randomCover = randomCoverFn()
|
||||||
data.cover = randomCover
|
data.cover = randomCover
|
||||||
coverVal = randomCover // update coverVal
|
coverVal = randomCover // update coverVal
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coverVal) {
|
if (coverVal && (coverVal.indexOf('//') !== -1 || imgTestReg.test(coverVal))) {
|
||||||
if (coverVal.indexOf('//') !== -1 || imgTestReg.test(coverVal)) {
|
data.cover_type = 'img'
|
||||||
data.cover_type = 'img'
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
|
|||||||
if (parent) { query.parent = parent } else { query.parent = { $exists: false } }
|
if (parent) { query.parent = parent } else { query.parent = { $exists: false } }
|
||||||
return categories.find(query).sort(orderby, order).filter((cat) => cat.length)
|
return categories.find(query).sort(orderby, order).filter((cat) => cat.length)
|
||||||
}
|
}
|
||||||
|
let expandBtn = ''
|
||||||
|
|
||||||
const hierarchicalList = (t, level, parent, topparent = true) => {
|
const hierarchicalList = (t, level, parent, topparent = true) => {
|
||||||
let result = ''
|
let result = ''
|
||||||
@@ -59,6 +60,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isExpand && isTopParent && child) {
|
if (isExpand && isTopParent && child) {
|
||||||
|
expandBtn = ' expandBtn'
|
||||||
result += `<i class="fas fa-caret-left ${expandClass}"></i>`
|
result += `<i class="fas fa-caret-left ${expandClass}"></i>`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +93,7 @@ hexo.extend.helper.register('aside_categories', function (categories, options) {
|
|||||||
<span>${this._p('aside.card_categories')}</span>
|
<span>${this._p('aside.card_categories')}</span>
|
||||||
${moreButton()}
|
${moreButton()}
|
||||||
</div>
|
</div>
|
||||||
<ul class="card-category-list" id="aside-cat-list">
|
<ul class="card-category-list${expandBtn}" id="aside-cat-list">
|
||||||
${list[0]}
|
${list[0]}
|
||||||
</ul>`
|
</ul>`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,36 +1,36 @@
|
|||||||
hexo.extend.helper.register('findArchiveLength', function (func) {
|
hexo.extend.helper.register('getArchiveLength', function () {
|
||||||
const allPostsLength = this.site.posts.length
|
const { archive_generator: archiveGenerator } = hexo.config
|
||||||
if (hexo.config.archive_generator && hexo.config.archive_generator.enable === false) return allPostsLength
|
if (archiveGenerator && archiveGenerator.enable === false) return this.site.posts.length
|
||||||
const { yearly, monthly, daily } = hexo.config.archive_generator
|
const { yearly, monthly, daily } = archiveGenerator
|
||||||
const { year, month, day } = this.page
|
const { year, month, day } = this.page
|
||||||
if (yearly === false || !year) return allPostsLength
|
if (yearly === false || !year) return this.site.posts.length
|
||||||
|
|
||||||
const posts = this.site.posts.sort('date')
|
const posts = this.site.posts.sort('date')
|
||||||
|
|
||||||
const compareFunc = (type, y1, m1, d1, y2, m2, d2) => {
|
const compareFunc = (type, y1, m1, d1, y2, m2, d2) => {
|
||||||
if (type === 'year') {
|
switch (type) {
|
||||||
return y1 === y2
|
case 'year':
|
||||||
} else if (type === 'month') {
|
return y1 === y2
|
||||||
return y1 === y2 && m1 === m2
|
case 'month':
|
||||||
} else if (type === 'day') {
|
return y1 === y2 && m1 === m2
|
||||||
return y1 === y2 && m1 === m2 && d1 === d2
|
case 'day':
|
||||||
|
return y1 === y2 && m1 === m2 && d1 === d2
|
||||||
|
default:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateDateObj = (type) => {
|
const generateDateObj = (type) => {
|
||||||
const dateObj = []
|
return posts.reduce((dateObj, post) => {
|
||||||
let length = 0
|
|
||||||
|
|
||||||
posts.forEach(post => {
|
|
||||||
const date = post.date.clone()
|
const date = post.date.clone()
|
||||||
const year = date.year()
|
const year = date.year()
|
||||||
const month = date.month() + 1
|
const month = date.month() + 1
|
||||||
const day = date.date()
|
const day = date.date()
|
||||||
const lastData = dateObj[length - 1]
|
const lastData = dateObj[dateObj.length - 1]
|
||||||
|
|
||||||
if (!lastData || !compareFunc(type, lastData.year, lastData.month, lastData.day, year, month, day)) {
|
if (!lastData || !compareFunc(type, lastData.year, lastData.month, lastData.day, year, month, day)) {
|
||||||
const name = type === 'year' ? year : type === 'month' ? `${year}-${month}` : `${year}-${month}-${day}`
|
const name = type === 'year' ? year : type === 'month' ? `${year}-${month}` : `${year}-${month}-${day}`
|
||||||
length = dateObj.push({
|
dateObj.push({
|
||||||
name,
|
name,
|
||||||
year,
|
year,
|
||||||
month,
|
month,
|
||||||
@@ -40,19 +40,19 @@ hexo.extend.helper.register('findArchiveLength', function (func) {
|
|||||||
} else {
|
} else {
|
||||||
lastData.count++
|
lastData.count++
|
||||||
}
|
}
|
||||||
})
|
|
||||||
|
|
||||||
return dateObj
|
return dateObj
|
||||||
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = func('createArchiveObj', () => {
|
const data = this.fragment_cache('createArchiveObj', () => {
|
||||||
const yearObj = yearly ? generateDateObj('year') : []
|
const dateObjs = []
|
||||||
const monthObj = monthly ? generateDateObj('month') : []
|
if (yearly) dateObjs.push(...generateDateObj('year'))
|
||||||
const dayObj = daily ? generateDateObj('day') : []
|
if (monthly) dateObjs.push(...generateDateObj('month'))
|
||||||
const fullObj = [...yearObj, ...monthObj, ...dayObj]
|
if (daily) dateObjs.push(...generateDateObj('day'))
|
||||||
return fullObj
|
return dateObjs
|
||||||
})
|
})
|
||||||
|
|
||||||
const name = month ? day ? `${year}-${month}-${day}` : `${year}-${month}` : year
|
const name = month ? (day ? `${year}-${month}-${day}` : `${year}-${month}`) : year
|
||||||
return data.find(item => item.name === name).count
|
return data.find(item => item.name === name).count
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -7,87 +7,99 @@
|
|||||||
|
|
||||||
hexo.extend.helper.register('inject_head_js', function () {
|
hexo.extend.helper.register('inject_head_js', function () {
|
||||||
const { darkmode, aside } = this.theme
|
const { darkmode, aside } = this.theme
|
||||||
const start = darkmode.start ? darkmode.start : 6
|
const start = darkmode.start || 6
|
||||||
const end = darkmode.end ? darkmode.end : 18
|
const end = darkmode.end || 18
|
||||||
const { theme_color } = hexo.theme.config
|
const { theme_color } = hexo.theme.config
|
||||||
const themeColorLight = (theme_color && theme_color.enable && theme_color.meta_theme_color_light) || '#ffffff'
|
const themeColorLight = (theme_color && theme_color.enable && theme_color.meta_theme_color_light) || '#ffffff'
|
||||||
const themeColorDark = (theme_color && theme_color.enable && theme_color.meta_theme_color_dark) || '#0d0d0d'
|
const themeColorDark = (theme_color && theme_color.enable && theme_color.meta_theme_color_dark) || '#0d0d0d'
|
||||||
|
|
||||||
const localStore = `
|
const createLocalStore = () => {
|
||||||
win.saveToLocal = {
|
return `
|
||||||
set: function setWithExpiry(key, value, ttl) {
|
win.saveToLocal = {
|
||||||
if (ttl === 0) return
|
set: (key, value, ttl) => {
|
||||||
const now = new Date()
|
if (ttl === 0) return
|
||||||
const expiryDay = ttl * 86400000
|
const now = Date.now()
|
||||||
const item = {
|
const expiry = now + ttl * 86400000
|
||||||
value: value,
|
const item = {
|
||||||
expiry: now.getTime() + expiryDay,
|
value,
|
||||||
}
|
expiry
|
||||||
localStorage.setItem(key, JSON.stringify(item))
|
}
|
||||||
},
|
localStorage.setItem(key, JSON.stringify(item))
|
||||||
|
},
|
||||||
|
|
||||||
get: function getWithExpiry(key) {
|
get: key => {
|
||||||
const itemStr = localStorage.getItem(key)
|
const itemStr = localStorage.getItem(key)
|
||||||
|
|
||||||
if (!itemStr) {
|
if (!itemStr) {
|
||||||
return undefined
|
return undefined
|
||||||
}
|
}
|
||||||
const item = JSON.parse(itemStr)
|
const item = JSON.parse(itemStr)
|
||||||
const now = new Date()
|
const now = Date.now()
|
||||||
|
|
||||||
if (now.getTime() > item.expiry) {
|
if (now > item.expiry) {
|
||||||
localStorage.removeItem(key)
|
localStorage.removeItem(key)
|
||||||
return undefined
|
return undefined
|
||||||
|
}
|
||||||
|
return item.value
|
||||||
}
|
}
|
||||||
return item.value
|
|
||||||
}
|
}
|
||||||
}
|
`
|
||||||
`
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/16839698/jquery-getscript-alternative-in-native-javascript
|
// https://stackoverflow.com/questions/16839698/jquery-getscript-alternative-in-native-javascript
|
||||||
const getScript = `
|
const createGetScript = () => {
|
||||||
win.getScript = url => new Promise((resolve, reject) => {
|
return `
|
||||||
const script = document.createElement('script')
|
win.getScript = (url, attr = {}) => new Promise((resolve, reject) => {
|
||||||
script.src = url
|
const script = document.createElement('script')
|
||||||
script.async = true
|
script.src = url
|
||||||
script.onerror = reject
|
script.async = true
|
||||||
script.onload = script.onreadystatechange = function() {
|
script.onerror = reject
|
||||||
const loadState = this.readyState
|
script.onload = script.onreadystatechange = function() {
|
||||||
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
const loadState = this.readyState
|
||||||
script.onload = script.onreadystatechange = null
|
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
||||||
resolve()
|
script.onload = script.onreadystatechange = null
|
||||||
}
|
resolve()
|
||||||
document.head.appendChild(script)
|
}
|
||||||
})
|
|
||||||
`
|
|
||||||
|
|
||||||
const getCSS = `
|
Object.keys(attr).forEach(key => {
|
||||||
win.getCSS = (url,id = false) => new Promise((resolve, reject) => {
|
script.setAttribute(key, attr[key])
|
||||||
const link = document.createElement('link')
|
})
|
||||||
link.rel = 'stylesheet'
|
|
||||||
link.href = url
|
|
||||||
if (id) link.id = id
|
|
||||||
link.onerror = reject
|
|
||||||
link.onload = link.onreadystatechange = function() {
|
|
||||||
const loadState = this.readyState
|
|
||||||
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
|
||||||
link.onload = link.onreadystatechange = null
|
|
||||||
resolve()
|
|
||||||
}
|
|
||||||
document.head.appendChild(link)
|
|
||||||
})
|
|
||||||
`
|
|
||||||
|
|
||||||
let darkmodeJs = ''
|
document.head.appendChild(script)
|
||||||
if (darkmode.enable) {
|
})
|
||||||
darkmodeJs = `
|
`
|
||||||
win.activateDarkMode = function () {
|
}
|
||||||
|
|
||||||
|
const createGetCSS = () => {
|
||||||
|
return `
|
||||||
|
win.getCSS = (url, id = false) => new Promise((resolve, reject) => {
|
||||||
|
const link = document.createElement('link')
|
||||||
|
link.rel = 'stylesheet'
|
||||||
|
link.href = url
|
||||||
|
if (id) link.id = id
|
||||||
|
link.onerror = reject
|
||||||
|
link.onload = link.onreadystatechange = function() {
|
||||||
|
const loadState = this.readyState
|
||||||
|
if (loadState && loadState !== 'loaded' && loadState !== 'complete') return
|
||||||
|
link.onload = link.onreadystatechange = null
|
||||||
|
resolve()
|
||||||
|
}
|
||||||
|
document.head.appendChild(link)
|
||||||
|
})
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
const createDarkmodeJs = () => {
|
||||||
|
if (!darkmode.enable) return ''
|
||||||
|
|
||||||
|
let darkmodeJs = `
|
||||||
|
win.activateDarkMode = () => {
|
||||||
document.documentElement.setAttribute('data-theme', 'dark')
|
document.documentElement.setAttribute('data-theme', 'dark')
|
||||||
if (document.querySelector('meta[name="theme-color"]') !== null) {
|
if (document.querySelector('meta[name="theme-color"]') !== null) {
|
||||||
document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorDark}')
|
document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorDark}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
win.activateLightMode = function () {
|
win.activateLightMode = () => {
|
||||||
document.documentElement.setAttribute('data-theme', 'light')
|
document.documentElement.setAttribute('data-theme', 'light')
|
||||||
if (document.querySelector('meta[name="theme-color"]') !== null) {
|
if (document.querySelector('meta[name="theme-color"]') !== null) {
|
||||||
document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorLight}')
|
document.querySelector('meta[name="theme-color"]').setAttribute('content', '${themeColorLight}')
|
||||||
@@ -114,7 +126,7 @@ hexo.extend.helper.register('inject_head_js', function () {
|
|||||||
const isNight = hour <= ${start} || hour >= ${end}
|
const isNight = hour <= ${start} || hour >= ${end}
|
||||||
isNight ? activateDarkMode() : activateLightMode()
|
isNight ? activateDarkMode() : activateLightMode()
|
||||||
}
|
}
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addListener(function (e) {
|
window.matchMedia('(prefers-color-scheme: dark)').addListener(e => {
|
||||||
if (saveToLocal.get('theme') === undefined) {
|
if (saveToLocal.get('theme') === undefined) {
|
||||||
e.matches ? activateDarkMode() : activateLightMode()
|
e.matches ? activateDarkMode() : activateLightMode()
|
||||||
}
|
}
|
||||||
@@ -133,15 +145,18 @@ hexo.extend.helper.register('inject_head_js', function () {
|
|||||||
`
|
`
|
||||||
} else {
|
} else {
|
||||||
darkmodeJs += `
|
darkmodeJs += `
|
||||||
if (t === 'dark') activateDarkMode()
|
if (t === 'dark') activateDarkMode()
|
||||||
else if (t === 'light') activateLightMode()
|
else if (t === 'light') activateLightMode()
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return darkmodeJs
|
||||||
}
|
}
|
||||||
|
|
||||||
let asideStatus = ''
|
const createAsideStatus = () => {
|
||||||
if (aside.enable && aside.button) {
|
if (!aside.enable || !aside.button) return ''
|
||||||
asideStatus = `
|
|
||||||
|
return `
|
||||||
const asideStatus = saveToLocal.get('aside-status')
|
const asideStatus = saveToLocal.get('aside-status')
|
||||||
if (asideStatus !== undefined) {
|
if (asideStatus !== undefined) {
|
||||||
if (asideStatus === 'hide') {
|
if (asideStatus === 'hide') {
|
||||||
@@ -153,14 +168,16 @@ hexo.extend.helper.register('inject_head_js', function () {
|
|||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
const detectApple = `
|
const createDetectApple = () => {
|
||||||
const detectApple = () => {
|
return `
|
||||||
if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
|
const detectApple = () => {
|
||||||
document.documentElement.classList.add('apple')
|
if(/iPad|iPhone|iPod|Macintosh/.test(navigator.userAgent)){
|
||||||
|
document.documentElement.classList.add('apple')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
detectApple()
|
||||||
detectApple()
|
|
||||||
`
|
`
|
||||||
|
}
|
||||||
|
|
||||||
return `<script>(win=>{${localStore + getScript + getCSS + darkmodeJs + asideStatus + detectApple}})(window)</script>`
|
return `<script>(win=>{${createLocalStore() + createGetScript() + createGetCSS() + createDarkmodeJs() + createAsideStatus() + createDetectApple()}})(window)</script>`
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,3 @@
|
|||||||
/**
|
|
||||||
* Butterfly
|
|
||||||
* @example
|
|
||||||
* page_description()
|
|
||||||
* cloudTags(source, minfontsize, maxfontsize, limit)
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const { stripHTML, escapeHTML, prettyUrls } = require('hexo-util')
|
const { stripHTML, escapeHTML, prettyUrls } = require('hexo-util')
|
||||||
@@ -60,12 +53,8 @@ hexo.extend.helper.register('md5', function (path) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
hexo.extend.helper.register('injectHtml', function (data) {
|
hexo.extend.helper.register('injectHtml', function (data) {
|
||||||
let result = ''
|
|
||||||
if (!data) return ''
|
if (!data) return ''
|
||||||
for (let i = 0; i < data.length; i++) {
|
return data.join('')
|
||||||
result += data[i]
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
})
|
})
|
||||||
|
|
||||||
hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
|
hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
|
||||||
@@ -95,8 +84,5 @@ hexo.extend.helper.register('findArchivesTitle', function (page, menu, date) {
|
|||||||
|
|
||||||
hexo.extend.helper.register('isImgOrUrl', function (path) {
|
hexo.extend.helper.register('isImgOrUrl', function (path) {
|
||||||
const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
|
const imgTestReg = /\.(png|jpe?g|gif|svg|webp)(\?.*)?$/i
|
||||||
if (path.indexOf('//') !== -1 || imgTestReg.test(path)) {
|
return path.indexOf('//') !== -1 || imgTestReg.test(path)
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,9 @@
|
|||||||
* Butterfly
|
* Butterfly
|
||||||
* galleryGroup and gallery
|
* galleryGroup and gallery
|
||||||
* {% galleryGroup [name] [descr] [url] [img] %}
|
* {% galleryGroup [name] [descr] [url] [img] %}
|
||||||
* {% gallery [lazyload],[rowHeight],[limit] %}
|
*
|
||||||
* {% gallery url,[url],[lazyload],[rowHeight],[limit] %}
|
* {% gallery [button],%}
|
||||||
|
* {% gallery url,[url],[button]%}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
@@ -11,14 +12,15 @@
|
|||||||
const urlFor = require('hexo-util').url_for.bind(hexo)
|
const urlFor = require('hexo-util').url_for.bind(hexo)
|
||||||
|
|
||||||
const gallery = (args, content) => {
|
const gallery = (args, content) => {
|
||||||
const { data, languages } = hexo.theme.i18n
|
|
||||||
args = args.join(' ').split(',')
|
args = args.join(' ').split(',')
|
||||||
let rowHeight, limit, lazyload, type, dataStr
|
let button = false
|
||||||
|
let type = 'data'
|
||||||
|
let dataStr = ''
|
||||||
|
|
||||||
if (args[0] === 'url') {
|
if (args[0] === 'url') {
|
||||||
[type, dataStr, lazyload, rowHeight = 220, limit = 10] = args // url,[link],[lazyload],[rowHeight],[limit]
|
[type, dataStr, button] = args // url,[link],[lazyload]
|
||||||
} else {
|
} else {
|
||||||
[lazyload, rowHeight = 220, limit = 10] = args // [lazyload],[rowHeight],[limit]
|
[button] = args // [lazyload]
|
||||||
const regex = /!\[(.*?)\]\(([^\s]*)\s*(?:["'](.*?)["']?)?\s*\)/g
|
const regex = /!\[(.*?)\]\(([^\s]*)\s*(?:["'](.*?)["']?)?\s*\)/g
|
||||||
let m
|
let m
|
||||||
const arr = []
|
const arr = []
|
||||||
@@ -36,14 +38,10 @@ const gallery = (args, content) => {
|
|||||||
dataStr = JSON.stringify(arr)
|
dataStr = JSON.stringify(arr)
|
||||||
}
|
}
|
||||||
|
|
||||||
type = type ? ' url' : ' data'
|
return `<div class="gallery-container" data-type="${type}" data-button="${button}">
|
||||||
const lazyloadClass = lazyload === 'true' ? 'lazyload' : ''
|
<div class="gallery-data">${dataStr}</div>
|
||||||
|
<div class="gallery-items">
|
||||||
return `<div class="gallery">
|
</div>
|
||||||
<div class="fj-gallery ${lazyloadClass + type}" data-rowHeight="${rowHeight}" data-limit="${limit}">
|
|
||||||
<span class="gallery-data">${dataStr}</span>
|
|
||||||
</div>
|
|
||||||
<button class="gallery-load-more"><span>${data[languages[0]].load_more}</span><i class="fa-solid fa-arrow-down"></i></button>
|
|
||||||
</div>`
|
</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +50,7 @@ const galleryGroup = args => {
|
|||||||
const imgUrl = urlFor(img)
|
const imgUrl = urlFor(img)
|
||||||
const urlLink = urlFor(url)
|
const urlLink = urlFor(url)
|
||||||
|
|
||||||
return `
|
return `<figure class="gallery-group">
|
||||||
<figure class="gallery-group">
|
|
||||||
<img class="gallery-group-img no-lightbox" src='${imgUrl}' alt="Group Image Gallery">
|
<img class="gallery-group-img no-lightbox" src='${imgUrl}' alt="Group Image Gallery">
|
||||||
<figcaption>
|
<figcaption>
|
||||||
<div class="gallery-group-name">${name}</div>
|
<div class="gallery-group-name">${name}</div>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ const postTabs = (args, content) => {
|
|||||||
let tabId = 0
|
let tabId = 0
|
||||||
let tabNav = ''
|
let tabNav = ''
|
||||||
let tabContent = ''
|
let tabContent = ''
|
||||||
|
let noDefault = true
|
||||||
|
|
||||||
!tabName && hexo.log.warn('Tabs block must have unique name!')
|
!tabName && hexo.log.warn('Tabs block must have unique name!')
|
||||||
|
|
||||||
@@ -41,17 +42,21 @@ const postTabs = (args, content) => {
|
|||||||
const icon = tabIcon.trim()
|
const icon = tabIcon.trim()
|
||||||
tabIcon.length > 0 && (tabIcon = `<i class="${icon}"${isOnlyicon}></i>`)
|
tabIcon.length > 0 && (tabIcon = `<i class="${icon}"${isOnlyicon}></i>`)
|
||||||
|
|
||||||
const toTop = '<button type="button" class="tab-to-top" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button>'
|
let isActive = ''
|
||||||
|
if ((tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1)) {
|
||||||
const isActive = (tabActive > 0 && tabActive === tabId) || (tabActive === 0 && tabId === 1) ? ' active' : ''
|
isActive = ' active'
|
||||||
tabNav += `<li class="tab${isActive}"><button type="button" data-href="#${tabHref}">${tabIcon + tabCaption.trim()}</button></li>`
|
noDefault = false
|
||||||
tabContent += `<div class="tab-item-content${isActive}" id="${tabHref}">${postContent + toTop}</div>`
|
}
|
||||||
|
tabNav += `<button type="button" class="tab ${isActive}" data-href="${tabHref}">${tabIcon + tabCaption.trim()}</button>`
|
||||||
|
tabContent += `<div class="tab-item-content${isActive}" id="${tabHref}">${postContent}</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
tabNav = `<ul class="nav-tabs">${tabNav}</ul>`
|
const toTop = '<div class="tab-to-top"><button type="button" aria-label="scroll to top"><i class="fas fa-arrow-up"></i></button></div>'
|
||||||
|
|
||||||
|
tabNav = `<ul class="nav-tabs${noDefault ? ' no-default' : ''}">${tabNav}</ul>`
|
||||||
tabContent = `<div class="tab-contents">${tabContent}</div>`
|
tabContent = `<div class="tab-contents">${tabContent}</div>`
|
||||||
|
|
||||||
return `<div class="tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent}</div>`
|
return `<div class="tabs" id="${tabName.toLowerCase().split(' ').join('-')}">${tabNav + tabContent + toTop}</div>`
|
||||||
}
|
}
|
||||||
|
|
||||||
hexo.extend.tag.register('tabs', postTabs, { ends: true })
|
hexo.extend.tag.register('tabs', postTabs, { ends: true })
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ if hexo-config('enter_transitions')
|
|||||||
&.open
|
&.open
|
||||||
for i in 1 2 3 4
|
for i in 1 2 3 4
|
||||||
> :nth-child({i})
|
> :nth-child({i})
|
||||||
animation: sidebarItem (i / 5)s
|
animation: sidebarItem (i / 5s)
|
||||||
|
|
||||||
.scroll-down-effects
|
.scroll-down-effects
|
||||||
animation: scroll-down-effect 1.5s infinite
|
animation: scroll-down-effect 1.5s infinite
|
||||||
@@ -169,16 +169,16 @@ if hexo-config('avatar.effect') == true
|
|||||||
|
|
||||||
@keyframes scroll-down-effect
|
@keyframes scroll-down-effect
|
||||||
0%
|
0%
|
||||||
top: 0
|
|
||||||
opacity: .4
|
opacity: .4
|
||||||
|
transform: translate(0, 0)
|
||||||
|
|
||||||
50%
|
50%
|
||||||
top: -16px
|
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
transform: translate(0, -16px)
|
||||||
|
|
||||||
100%
|
100%
|
||||||
top: 0
|
|
||||||
opacity: .4
|
opacity: .4
|
||||||
|
transform: translate(0, 0)
|
||||||
|
|
||||||
@keyframes header-effect
|
@keyframes header-effect
|
||||||
0%
|
0%
|
||||||
@@ -198,12 +198,12 @@ if hexo-config('avatar.effect') == true
|
|||||||
|
|
||||||
@keyframes bottom-top
|
@keyframes bottom-top
|
||||||
0%
|
0%
|
||||||
margin-top: 50px
|
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
transform: translateY(50px)
|
||||||
|
|
||||||
100%
|
100%
|
||||||
margin-top: 0
|
|
||||||
opacity: 1
|
opacity: 1
|
||||||
|
transform: translateY(0)
|
||||||
|
|
||||||
@keyframes titleScale
|
@keyframes titleScale
|
||||||
0%
|
0%
|
||||||
|
|||||||
@@ -13,6 +13,16 @@ wordWrap = $highlight_enable && !$highlight_line_number && hexo-config('code_wor
|
|||||||
--hlscrollbar-bg: $highlight-scrollbar
|
--hlscrollbar-bg: $highlight-scrollbar
|
||||||
--hlexpand-bg: linear-gradient(180deg, rgba($highlight-background, .6), rgba($highlight-background, .9))
|
--hlexpand-bg: linear-gradient(180deg, rgba($highlight-background, .6), rgba($highlight-background, .9))
|
||||||
|
|
||||||
|
[data-theme='dark']
|
||||||
|
--hl-color: alpha(#FFFFFF, .7)
|
||||||
|
--hl-bg: lighten(#121212, 2)
|
||||||
|
--hltools-bg: lighten(#121212, 3)
|
||||||
|
--hltools-color: #90a4ae
|
||||||
|
--hlnumber-bg: lighten(#121212, 2)
|
||||||
|
--hlnumber-color: alpha(#FFFFFF, .4)
|
||||||
|
--hlscrollbar-bg: lighten(#121212, 5)
|
||||||
|
--hlexpand-bg: linear-gradient(180deg, rgba(lighten(#121212, 2), .6), rgba(lighten(#121212, 2), .9))
|
||||||
|
|
||||||
if $highlight_enable
|
if $highlight_enable
|
||||||
@require 'highlight/index'
|
@require 'highlight/index'
|
||||||
|
|
||||||
@@ -94,8 +104,13 @@ $code-block
|
|||||||
color: var(--hltools-color)
|
color: var(--hltools-color)
|
||||||
font-size: $code-font-size
|
font-size: $code-font-size
|
||||||
|
|
||||||
&.closed ~ *
|
&.closed
|
||||||
display: none
|
& ~ *
|
||||||
|
display: none
|
||||||
|
|
||||||
|
.expand
|
||||||
|
transition: all .3s
|
||||||
|
transform: rotate(-90deg) !important
|
||||||
|
|
||||||
.expand
|
.expand
|
||||||
position: absolute
|
position: absolute
|
||||||
@@ -106,10 +121,6 @@ $code-block
|
|||||||
& + .code-lang
|
& + .code-lang
|
||||||
left: 1.7em
|
left: 1.7em
|
||||||
|
|
||||||
&.closed
|
|
||||||
transition: all .3s
|
|
||||||
transform: rotate(-90deg) !important
|
|
||||||
|
|
||||||
.code-lang
|
.code-lang
|
||||||
position: absolute
|
position: absolute
|
||||||
left: 14px
|
left: 14px
|
||||||
|
|||||||
@@ -179,6 +179,13 @@
|
|||||||
|
|
||||||
> .parent
|
> .parent
|
||||||
> a
|
> a
|
||||||
|
&.expand
|
||||||
|
i
|
||||||
|
transform: rotate(-90deg)
|
||||||
|
|
||||||
|
& + .child
|
||||||
|
display: block
|
||||||
|
|
||||||
.card-category-list
|
.card-category-list
|
||||||
&-name
|
&-name
|
||||||
width: 70% !important
|
width: 70% !important
|
||||||
@@ -187,15 +194,12 @@
|
|||||||
width: calc(100% - 70% - 20px)
|
width: calc(100% - 70% - 20px)
|
||||||
text-align: right
|
text-align: right
|
||||||
|
|
||||||
i
|
i
|
||||||
float: right
|
float: right
|
||||||
margin-right: -.5em
|
margin-right: -.5em
|
||||||
padding: .5em
|
padding: .5em
|
||||||
transition: transform .3s
|
transition: transform .3s
|
||||||
transform: rotate(0)
|
transform: rotate(0)
|
||||||
|
|
||||||
&.expand
|
|
||||||
transform: rotate(-90deg)
|
|
||||||
|
|
||||||
if hexo-config('aside.card_categories.expand') == false
|
if hexo-config('aside.card_categories.expand') == false
|
||||||
> .child
|
> .child
|
||||||
@@ -220,16 +224,19 @@
|
|||||||
|
|
||||||
+maxWidth900()
|
+maxWidth900()
|
||||||
position: fixed
|
position: fixed
|
||||||
right: -100%
|
right: 55px
|
||||||
bottom: 30px
|
bottom: 30px
|
||||||
z-index: 100
|
z-index: 100
|
||||||
max-width: $toc-mobile-maxWidth
|
max-width: $toc-mobile-maxWidth
|
||||||
max-height: calc(100% - 60px)
|
max-height: calc(100% - 60px)
|
||||||
width: $toc-mobile-width
|
width: $toc-mobile-width
|
||||||
opacity: 0
|
transition: transform .3s
|
||||||
transition: initial
|
transform: scale(0)
|
||||||
transform-origin: right bottom
|
transform-origin: right bottom
|
||||||
|
|
||||||
|
&.open
|
||||||
|
transform: scale(1)
|
||||||
|
|
||||||
.toc-percentage
|
.toc-percentage
|
||||||
float: right
|
float: right
|
||||||
margin-top: -9px
|
margin-top: -9px
|
||||||
@@ -242,6 +249,7 @@
|
|||||||
overflow-y: overlay
|
overflow-y: overlay
|
||||||
margin: 0 -24px
|
margin: 0 -24px
|
||||||
max-height: calc(100vh - 120px)
|
max-height: calc(100vh - 120px)
|
||||||
|
width: calc(100% + 48px)
|
||||||
|
|
||||||
+maxWidth900()
|
+maxWidth900()
|
||||||
max-height: calc(100vh - 140px)
|
max-height: calc(100vh - 140px)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
font-weight: 700
|
font-weight: 700
|
||||||
font-size: 1.43em
|
font-size: 1.43em
|
||||||
|
|
||||||
#comment-switch
|
.comment-switch
|
||||||
display: inline-block
|
display: inline-block
|
||||||
|
|
||||||
if hexo-config('comments.text')
|
if hexo-config('comments.text')
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
.second-comment
|
.second-comment
|
||||||
color: $comments-switch-second-text
|
color: $comments-switch-second-text
|
||||||
|
|
||||||
.switch-btn
|
#switch-btn
|
||||||
position: relative
|
position: relative
|
||||||
display: inline-block
|
display: inline-block
|
||||||
margin: -4px 8px 0
|
margin: -4px 8px 0
|
||||||
@@ -53,12 +53,24 @@
|
|||||||
content: ''
|
content: ''
|
||||||
transition: .4s
|
transition: .4s
|
||||||
|
|
||||||
&.move
|
|
||||||
background-color: $comments-switch-second-text
|
|
||||||
|
|
||||||
&:before
|
|
||||||
transform: translateX(20px)
|
|
||||||
|
|
||||||
.comment-wrap
|
.comment-wrap
|
||||||
> div:nth-child(2)
|
> div
|
||||||
display: none
|
animation: tabshow .5s
|
||||||
|
|
||||||
|
&:nth-child(2)
|
||||||
|
display: none
|
||||||
|
|
||||||
|
&.move
|
||||||
|
#switch-btn
|
||||||
|
background-color: $comments-switch-second-text
|
||||||
|
|
||||||
|
&:before
|
||||||
|
transform: translateX(20px)
|
||||||
|
|
||||||
|
.comment-wrap
|
||||||
|
> div
|
||||||
|
&:first-child
|
||||||
|
display: none
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
display: block
|
||||||
@@ -51,7 +51,6 @@
|
|||||||
#site_social_icons
|
#site_social_icons
|
||||||
display: none
|
display: none
|
||||||
margin: 0 auto
|
margin: 0 auto
|
||||||
width: 300px
|
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
@@ -65,7 +64,7 @@
|
|||||||
|
|
||||||
#scroll-down
|
#scroll-down
|
||||||
position: absolute
|
position: absolute
|
||||||
bottom: 0
|
bottom: 10px
|
||||||
width: 100%
|
width: 100%
|
||||||
cursor: pointer
|
cursor: pointer
|
||||||
|
|
||||||
@@ -73,7 +72,7 @@
|
|||||||
position: relative
|
position: relative
|
||||||
width: 100%
|
width: 100%
|
||||||
color: var(--light-grey)
|
color: var(--light-grey)
|
||||||
font-size: 30px
|
font-size: 20px
|
||||||
|
|
||||||
// page
|
// page
|
||||||
&.not-home-page
|
&.not-home-page
|
||||||
|
|||||||
@@ -72,6 +72,7 @@ beautify()
|
|||||||
#article-container
|
#article-container
|
||||||
word-wrap: break-word
|
word-wrap: break-word
|
||||||
overflow-wrap: break-word
|
overflow-wrap: break-word
|
||||||
|
text-align: justify
|
||||||
|
|
||||||
a
|
a
|
||||||
color: $theme-link-color
|
color: $theme-link-color
|
||||||
@@ -226,6 +227,9 @@ beautify()
|
|||||||
color: $light-blue
|
color: $light-blue
|
||||||
font-weight: bold
|
font-weight: bold
|
||||||
|
|
||||||
|
i
|
||||||
|
margin-right: 3px
|
||||||
|
|
||||||
&-info
|
&-info
|
||||||
padding-left: 6px
|
padding-left: 6px
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,10 @@
|
|||||||
opacity: 0
|
opacity: 0
|
||||||
transition: all .5s
|
transition: all .5s
|
||||||
|
|
||||||
|
&.rightside-show
|
||||||
|
opacity: .8
|
||||||
|
transform: translate(-58px, 0)
|
||||||
|
|
||||||
#rightside-config-hide
|
#rightside-config-hide
|
||||||
height: 0
|
height: 0
|
||||||
opacity: 0
|
opacity: 0
|
||||||
|
|||||||
@@ -13,7 +13,8 @@
|
|||||||
right: -($sidebar-width)
|
right: -($sidebar-width)
|
||||||
z-index: 103
|
z-index: 103
|
||||||
overflow-x: hidden
|
overflow-x: hidden
|
||||||
overflow-y: auto
|
overflow-y: scroll
|
||||||
|
padding-left: 5px
|
||||||
width: $sidebar-width
|
width: $sidebar-width
|
||||||
height: 100%
|
height: 100%
|
||||||
background: var(--sidebar-bg)
|
background: var(--sidebar-bg)
|
||||||
@@ -32,7 +33,7 @@
|
|||||||
margin: 20px auto
|
margin: 20px auto
|
||||||
|
|
||||||
.menus_items
|
.menus_items
|
||||||
padding: 0 10px 40px
|
padding: 0 5px
|
||||||
|
|
||||||
.site-page
|
.site-page
|
||||||
@extend .limit-one-line
|
@extend .limit-one-line
|
||||||
@@ -53,7 +54,7 @@
|
|||||||
& > i:last-child
|
& > i:last-child
|
||||||
position: absolute
|
position: absolute
|
||||||
top: .78em
|
top: .78em
|
||||||
right: 18px
|
right: 13px
|
||||||
transition: transform .3s
|
transition: transform .3s
|
||||||
|
|
||||||
&.hide
|
&.hide
|
||||||
@@ -65,4 +66,5 @@
|
|||||||
|
|
||||||
.menus_item_child
|
.menus_item_child
|
||||||
margin: 0
|
margin: 0
|
||||||
|
padding-left: 25px
|
||||||
list-style: none
|
list-style: none
|
||||||
@@ -28,15 +28,7 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
|||||||
--blockquote-bg: lighten(#121212, 10)
|
--blockquote-bg: lighten(#121212, 10)
|
||||||
--reward-pop: lighten(#121212, 10)
|
--reward-pop: lighten(#121212, 10)
|
||||||
--toc-link-color: alpha(#FFFFFF, .6)
|
--toc-link-color: alpha(#FFFFFF, .6)
|
||||||
--hl-color: alpha(#FFFFFF, .7)
|
--scrollbar-color: lighten(#121212, 25)
|
||||||
--hl-bg: lighten(#121212, 2)
|
|
||||||
--hltools-bg: lighten(#121212, 3)
|
|
||||||
--hltools-color: #90a4ae
|
|
||||||
--hlnumber-bg: lighten(#121212, 2)
|
|
||||||
--hlnumber-color: alpha(#FFFFFF, .4)
|
|
||||||
--hlscrollbar-bg: lighten(#121212, 5)
|
|
||||||
--hlexpand-bg: linear-gradient(180deg, rgba(lighten(#121212, 2), .6), rgba(lighten(#121212, 2), .9))
|
|
||||||
--scrollbar-color: lighten(#121212, 5)
|
|
||||||
--timeline-bg: lighten(#121212, 5)
|
--timeline-bg: lighten(#121212, 5)
|
||||||
--zoom-bg: #121212
|
--zoom-bg: #121212
|
||||||
--mark-bg: alpha($dark-black, .6)
|
--mark-bg: alpha($dark-black, .6)
|
||||||
@@ -78,11 +70,11 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark'
|
|||||||
box-shadow: 0 5px 6px -5px rgba(133, 133, 133, 0)
|
box-shadow: 0 5px 6px -5px rgba(133, 133, 133, 0)
|
||||||
|
|
||||||
#post-comment
|
#post-comment
|
||||||
#comment-switch
|
.comment-switch
|
||||||
if hexo-config('comments.text')
|
if hexo-config('comments.text')
|
||||||
background: #2c2c2c !important
|
background: #2c2c2c !important
|
||||||
|
|
||||||
.switch-btn
|
#switch-btn
|
||||||
filter: brightness(.8)
|
filter: brightness(.8)
|
||||||
|
|
||||||
// note
|
// note
|
||||||
|
|||||||
@@ -145,18 +145,7 @@ if hexo-config('readmode')
|
|||||||
background: transparent
|
background: transparent
|
||||||
|
|
||||||
> .tab
|
> .tab
|
||||||
border-bottom: 0
|
border-top: none !important
|
||||||
|
|
||||||
button
|
|
||||||
border-top: none !important
|
|
||||||
background: transparent
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
background: none !important
|
|
||||||
|
|
||||||
&.active
|
|
||||||
button
|
|
||||||
text-decoration: underline
|
|
||||||
|
|
||||||
> .tab-contents .tab-item-content.active
|
> .tab-contents .tab-item-content.active
|
||||||
animation: none
|
animation: none
|
||||||
|
|||||||
@@ -94,25 +94,20 @@
|
|||||||
overflow: auto
|
overflow: auto
|
||||||
padding: 0 0 16px
|
padding: 0 0 16px
|
||||||
|
|
||||||
.gallery
|
.gallery-container
|
||||||
margin: 0 0 16px
|
margin: 0 0 16px
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
.fj-gallery
|
img
|
||||||
opacity: 0
|
display: initial
|
||||||
|
margin: 0
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
|
||||||
.img-alt
|
.gallery-data
|
||||||
display: none
|
display: none
|
||||||
|
|
||||||
&.lazyload
|
|
||||||
+ button
|
|
||||||
display: inline-block
|
|
||||||
|
|
||||||
.gallery-data
|
|
||||||
display: none
|
|
||||||
|
|
||||||
button
|
button
|
||||||
display: none
|
|
||||||
margin-top: 25px
|
margin-top: 25px
|
||||||
padding: 10px
|
padding: 10px
|
||||||
width: 9em
|
width: 9em
|
||||||
@@ -123,17 +118,88 @@
|
|||||||
font-size: 1.1em
|
font-size: 1.1em
|
||||||
transition: all .3s
|
transition: all .3s
|
||||||
|
|
||||||
& > *
|
|
||||||
transition: all .4s
|
|
||||||
|
|
||||||
i
|
|
||||||
width: 0
|
|
||||||
opacity: 0
|
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
background: var(--btn-hover-color)
|
background: var(--btn-hover-color)
|
||||||
|
|
||||||
i
|
.loading-container
|
||||||
margin-left: 2px
|
display: inline-block
|
||||||
width: 20px
|
overflow: hidden
|
||||||
opacity: 1
|
width: 154px
|
||||||
|
height: 154px
|
||||||
|
|
||||||
|
.loading-item
|
||||||
|
position: relative
|
||||||
|
width: 100%
|
||||||
|
height: 100%
|
||||||
|
backface-visibility: hidden
|
||||||
|
transform: translateZ(0) scale(1)
|
||||||
|
transform-origin: 0 0
|
||||||
|
|
||||||
|
div
|
||||||
|
position: absolute
|
||||||
|
width: 30.8px
|
||||||
|
height: 30.8px
|
||||||
|
border-radius: 50%
|
||||||
|
background: #e15b64
|
||||||
|
transform: translate(61.6px, 61.6px) scale(1)
|
||||||
|
animation: loading-ball 1.92s infinite cubic-bezier(0, .5, .5, 1)
|
||||||
|
|
||||||
|
&:nth-child(1)
|
||||||
|
background: #f47e60
|
||||||
|
transform: translate(113.96px, 61.6px) scale(1)
|
||||||
|
animation: loading-ball-r .48s infinite cubic-bezier(0, .5, .5, 1), loading-ball-c 1.92s infinite step-start
|
||||||
|
|
||||||
|
&:nth-child(2)
|
||||||
|
background: #e15b64
|
||||||
|
animation-delay: -.48s
|
||||||
|
|
||||||
|
&:nth-child(3)
|
||||||
|
background: #f47e60
|
||||||
|
animation-delay: -.96s
|
||||||
|
|
||||||
|
&:nth-child(4)
|
||||||
|
background: #f8b26a
|
||||||
|
animation-delay: -1.44s
|
||||||
|
|
||||||
|
&:nth-child(5)
|
||||||
|
background: #abbd81
|
||||||
|
animation-delay: -1.92s
|
||||||
|
|
||||||
|
@keyframes loading-ball
|
||||||
|
0%
|
||||||
|
transform: translate(9.24px, 61.6px) scale(0)
|
||||||
|
|
||||||
|
25%
|
||||||
|
transform: translate(9.24px, 61.6px) scale(0)
|
||||||
|
|
||||||
|
50%
|
||||||
|
transform: translate(9.24px, 61.6px) scale(1)
|
||||||
|
|
||||||
|
75%
|
||||||
|
transform: translate(61.6px, 61.6px) scale(1)
|
||||||
|
|
||||||
|
100%
|
||||||
|
transform: translate(113.96px, 61.6px) scale(1)
|
||||||
|
|
||||||
|
@keyframes loading-ball-r
|
||||||
|
0%
|
||||||
|
transform: translate(113.96px, 61.6px) scale(1)
|
||||||
|
|
||||||
|
100%
|
||||||
|
transform: translate(113.96px, 61.6px) scale(0)
|
||||||
|
|
||||||
|
@keyframes loading-ball-c
|
||||||
|
0%
|
||||||
|
background: #e15b64
|
||||||
|
|
||||||
|
25%
|
||||||
|
background: #abbd81
|
||||||
|
|
||||||
|
50%
|
||||||
|
background: #f8b26a
|
||||||
|
|
||||||
|
75%
|
||||||
|
background: #f47e60
|
||||||
|
|
||||||
|
100%
|
||||||
|
background: #e15b64
|
||||||
|
|||||||
@@ -15,43 +15,36 @@
|
|||||||
background: var(--tab-botton-bg)
|
background: var(--tab-botton-bg)
|
||||||
|
|
||||||
> .tab
|
> .tab
|
||||||
margin: 0
|
flex-grow: 1
|
||||||
padding: 0
|
padding: 8px 18px
|
||||||
list-style: none
|
border-top: 2px solid var(--tab-border-color)
|
||||||
|
background: var(--tab-botton-bg)
|
||||||
|
color: var(--tab-botton-color)
|
||||||
|
line-height: 2
|
||||||
|
transition: all .4s
|
||||||
|
|
||||||
+maxWidth768()
|
i
|
||||||
flex-grow: 1
|
width: 1.5em
|
||||||
|
|
||||||
button
|
|
||||||
display: block
|
|
||||||
padding: 8px 18px
|
|
||||||
width: 100%
|
|
||||||
border-top: 2px solid var(--tab-border-color)
|
|
||||||
background: var(--tab-botton-bg)
|
|
||||||
color: var(--tab-botton-color)
|
|
||||||
line-height: 2
|
|
||||||
transition: all .4s
|
|
||||||
|
|
||||||
i
|
|
||||||
width: 1.5em
|
|
||||||
|
|
||||||
&.active
|
&.active
|
||||||
button
|
border-top: 2px solid $tab-active-border-color
|
||||||
border-top: 2px solid $tab-active-border-color
|
background: var(--tab-button-active-bg)
|
||||||
background: var(--tab-button-active-bg)
|
cursor: default
|
||||||
cursor: default
|
|
||||||
|
|
||||||
&:not(.active)
|
&:not(.active)
|
||||||
button
|
&:hover
|
||||||
&:hover
|
border-top: 2px solid var(--tab-button-hover-bg)
|
||||||
border-top: 2px solid var(--tab-button-hover-bg)
|
background: var(--tab-button-hover-bg)
|
||||||
background: var(--tab-button-hover-bg)
|
|
||||||
|
&.no-default
|
||||||
|
& ~ .tab-to-top
|
||||||
|
display: none
|
||||||
|
|
||||||
> .tab-contents
|
> .tab-contents
|
||||||
.tab-item-content
|
.tab-item-content
|
||||||
position: relative
|
position: relative
|
||||||
display: none
|
display: none
|
||||||
padding: 36px 24px
|
padding: 36px 24px 10px
|
||||||
|
|
||||||
+maxWidth768()
|
+maxWidth768()
|
||||||
padding: 24px 14px
|
padding: 24px 14px
|
||||||
@@ -60,11 +53,16 @@
|
|||||||
display: block
|
display: block
|
||||||
animation: tabshow .5s
|
animation: tabshow .5s
|
||||||
|
|
||||||
.tab-to-top
|
> .tab-to-top
|
||||||
position: absolute
|
padding: 0 16px 10px 0
|
||||||
right: 15px
|
width: 100%
|
||||||
display: block
|
text-align: right
|
||||||
color: $tab-to-top-color
|
|
||||||
|
button
|
||||||
|
color: $tab-to-top-color
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
color: $tab-to-top-hover-color
|
||||||
|
|
||||||
@keyframes tabshow
|
@keyframes tabshow
|
||||||
0%
|
0%
|
||||||
|
|||||||
@@ -179,6 +179,7 @@ $tab-button-hover-bg = darken($tab-border-color, 8)
|
|||||||
$tab-active-border-color = $theme-color
|
$tab-active-border-color = $theme-color
|
||||||
$tab-button-active-bg = $card-bg
|
$tab-button-active-bg = $card-bg
|
||||||
$tab-to-top-color = #99a9bf
|
$tab-to-top-color = #99a9bf
|
||||||
|
$tab-to-top-hover-color = $theme-color
|
||||||
// Tag Plugins - timeline
|
// Tag Plugins - timeline
|
||||||
$timeline-default-color = $theme-color
|
$timeline-default-color = $theme-color
|
||||||
// archor
|
// archor
|
||||||
|
|||||||
@@ -4,9 +4,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
|
|
||||||
const adjustMenu = init => {
|
const adjustMenu = init => {
|
||||||
const getAllWidth = ele => {
|
const getAllWidth = ele => {
|
||||||
let width = 0
|
return Array.from(ele).reduce((width, i) => width + i.offsetWidth, 0)
|
||||||
ele.length && Array.from(ele).forEach(i => { width += i.offsetWidth })
|
|
||||||
return width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (init) {
|
if (init) {
|
||||||
@@ -16,15 +14,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
$nav = document.getElementById('nav')
|
$nav = document.getElementById('nav')
|
||||||
}
|
}
|
||||||
|
|
||||||
let hideMenuIndex = ''
|
const hideMenuIndex = window.innerWidth <= 768 || headerContentWidth > $nav.offsetWidth - 120
|
||||||
if (window.innerWidth <= 768) hideMenuIndex = true
|
$nav.classList.toggle('hide-menu', hideMenuIndex)
|
||||||
else hideMenuIndex = headerContentWidth > $nav.offsetWidth - 120
|
|
||||||
|
|
||||||
if (hideMenuIndex) {
|
|
||||||
$nav.classList.add('hide-menu')
|
|
||||||
} else {
|
|
||||||
$nav.classList.remove('hide-menu')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化header
|
// 初始化header
|
||||||
@@ -56,17 +47,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
* 首頁top_img底下的箭頭
|
* 首頁top_img底下的箭頭
|
||||||
*/
|
*/
|
||||||
const scrollDownInIndex = () => {
|
const scrollDownInIndex = () => {
|
||||||
const $scrollDownEle = document.getElementById('scroll-down')
|
const handleScrollToDest = () => {
|
||||||
$scrollDownEle && $scrollDownEle.addEventListener('click', function () {
|
|
||||||
btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300)
|
btf.scrollToDest(document.getElementById('content-inner').offsetTop, 300)
|
||||||
})
|
}
|
||||||
|
|
||||||
|
const $scrollDownEle = document.getElementById('scroll-down')
|
||||||
|
$scrollDownEle && btf.addEventListenerPjax($scrollDownEle, 'click', handleScrollToDest)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 代碼
|
* 代碼
|
||||||
* 只適用於Hexo默認的代碼渲染
|
* 只適用於Hexo默認的代碼渲染
|
||||||
*/
|
*/
|
||||||
const addHighlightTool = function () {
|
const addHighlightTool = () => {
|
||||||
const highLight = GLOBAL_CONFIG.highlight
|
const highLight = GLOBAL_CONFIG.highlight
|
||||||
if (!highLight) return
|
if (!highLight) return
|
||||||
|
|
||||||
@@ -79,7 +72,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
|
|
||||||
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 ${highlightShrinkClass}"></i>` : ''
|
const highlightShrinkEle = isHighlightShrink !== undefined ? '<i class="fas fa-angle-down expand"></i>' : ''
|
||||||
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 copy = (text, ctx) => {
|
const copy = (text, ctx) => {
|
||||||
@@ -103,7 +96,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// click events
|
// click events
|
||||||
const highlightCopyFn = (ele) => {
|
const highlightCopyFn = ele => {
|
||||||
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()
|
||||||
@@ -118,14 +111,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
$buttonParent.classList.remove('copy-true')
|
$buttonParent.classList.remove('copy-true')
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightShrinkFn = (ele) => {
|
const highlightShrinkFn = ele => {
|
||||||
const $nextEle = [...ele.parentNode.children].slice(1)
|
ele.classList.toggle('closed')
|
||||||
ele.firstChild.classList.toggle('closed')
|
|
||||||
if (btf.isHidden($nextEle[$nextEle.length - 1])) {
|
|
||||||
$nextEle.forEach(e => { e.style.display = 'block' })
|
|
||||||
} else {
|
|
||||||
$nextEle.forEach(e => { e.style.display = 'none' })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlightToolsFn = function (e) {
|
const highlightToolsFn = function (e) {
|
||||||
@@ -138,14 +125,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
this.classList.toggle('expand-done')
|
this.classList.toggle('expand-done')
|
||||||
}
|
}
|
||||||
|
|
||||||
function createEle (lang, item, service) {
|
const createEle = (lang, item, service) => {
|
||||||
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 = highlightShrinkEle + lang + highlightCopyEle
|
||||||
hlTools.addEventListener('click', highlightToolsFn)
|
btf.addEventListenerPjax(hlTools, 'click', highlightToolsFn)
|
||||||
fragment.appendChild(hlTools)
|
fragment.appendChild(hlTools)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +140,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const ele = document.createElement('div')
|
const ele = document.createElement('div')
|
||||||
ele.className = 'code-expand-btn'
|
ele.className = 'code-expand-btn'
|
||||||
ele.innerHTML = '<i class="fas fa-angle-double-down"></i>'
|
ele.innerHTML = '<i class="fas fa-angle-double-down"></i>'
|
||||||
ele.addEventListener('click', expandCode)
|
btf.addEventListenerPjax(ele, 'click', expandCode)
|
||||||
fragment.appendChild(ele)
|
fragment.appendChild(ele)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -177,7 +164,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
$figureHighlight.forEach(function (item) {
|
$figureHighlight.forEach(item => {
|
||||||
if (highlightLang) {
|
if (highlightLang) {
|
||||||
let langName = item.getAttribute('class').split(' ')[1]
|
let langName = item.getAttribute('class').split(' ')[1]
|
||||||
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
if (langName === 'plain' || langName === undefined) langName = 'Code'
|
||||||
@@ -193,16 +180,14 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
/**
|
/**
|
||||||
* PhotoFigcaption
|
* PhotoFigcaption
|
||||||
*/
|
*/
|
||||||
function addPhotoFigcaption () {
|
const addPhotoFigcaption = () => {
|
||||||
document.querySelectorAll('#article-container img').forEach(function (item) {
|
document.querySelectorAll('#article-container img').forEach(item => {
|
||||||
const parentEle = item.parentNode
|
|
||||||
const altValue = item.title || item.alt
|
const altValue = item.title || item.alt
|
||||||
if (altValue && !parentEle.parentNode.classList.contains('justified-gallery')) {
|
if (!altValue) return
|
||||||
const ele = document.createElement('div')
|
const ele = document.createElement('div')
|
||||||
ele.className = 'img-alt is-center'
|
ele.className = 'img-alt is-center'
|
||||||
ele.textContent = altValue
|
ele.textContent = altValue
|
||||||
parentEle.insertBefore(ele, item.nextSibling)
|
item.insertAdjacentElement('afterend', ele)
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -216,97 +201,173 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
/**
|
/**
|
||||||
* justified-gallery 圖庫排版
|
* justified-gallery 圖庫排版
|
||||||
*/
|
*/
|
||||||
const runJustifiedGallery = function (ele) {
|
|
||||||
const htmlStr = arr => {
|
const fetchUrl = async (url) => {
|
||||||
let str = ''
|
const response = await fetch(url)
|
||||||
const replaceDq = str => str.replace(/"/g, '"') // replace double quotes to "
|
return await response.json()
|
||||||
arr.forEach(i => {
|
}
|
||||||
const alt = i.alt ? `alt="${replaceDq(i.alt)}"` : ''
|
|
||||||
const title = i.title ? `title="${replaceDq(i.title)}"` : ''
|
const runJustifiedGallery = (item, data, isButton = false, tabs) => {
|
||||||
str += `<div class="fj-gallery-item"><img src="${i.url}" ${alt + title}"></div>`
|
const dataLength = data.length
|
||||||
})
|
|
||||||
return str
|
const ig = new InfiniteGrid.JustifiedInfiniteGrid(item, {
|
||||||
|
gap: 5,
|
||||||
|
isConstantSize: true,
|
||||||
|
sizeRange: [150, 600],
|
||||||
|
useResizeObserver: true,
|
||||||
|
observeChildren: true,
|
||||||
|
useTransform: true
|
||||||
|
// useRecycle: false
|
||||||
|
})
|
||||||
|
|
||||||
|
if (tabs) {
|
||||||
|
btf.addGlobalFn('igOfTabs', () => { ig.destroy() }, false, tabs)
|
||||||
}
|
}
|
||||||
|
|
||||||
const lazyloadFn = (i, arr, limit) => {
|
const replaceDq = str => str.replace(/"/g, '"') // replace double quotes to "
|
||||||
const loadItem = limit
|
|
||||||
const arrLength = arr.length
|
|
||||||
if (arrLength > loadItem) i.insertAdjacentHTML('beforeend', htmlStr(arr.splice(0, loadItem)))
|
|
||||||
else {
|
|
||||||
i.insertAdjacentHTML('beforeend', htmlStr(arr))
|
|
||||||
i.classList.remove('lazyload')
|
|
||||||
}
|
|
||||||
return arrLength > loadItem ? loadItem : arrLength
|
|
||||||
}
|
|
||||||
|
|
||||||
const fetchUrl = async (url) => {
|
const getItems = (nextGroupKey, count) => {
|
||||||
const response = await fetch(url)
|
const nextItems = []
|
||||||
return await response.json()
|
const startCount = (nextGroupKey - 1) * count
|
||||||
}
|
|
||||||
|
|
||||||
const runJustifiedGallery = (item, arr) => {
|
for (let i = 0; i < count; ++i) {
|
||||||
if (!item.classList.contains('lazyload')) item.innerHTML = htmlStr(arr)
|
const num = startCount + i
|
||||||
else {
|
if (num >= dataLength) {
|
||||||
const limit = item.getAttribute('data-limit')
|
break
|
||||||
lazyloadFn(item, arr, limit)
|
|
||||||
const clickBtnFn = () => {
|
|
||||||
const lastItemLength = lazyloadFn(item, arr, limit)
|
|
||||||
fjGallery(item, 'appendImages', item.querySelectorAll(`.fj-gallery-item:nth-last-child(-n+${lastItemLength})`))
|
|
||||||
btf.loadLightbox(item.querySelectorAll('img'))
|
|
||||||
lastItemLength < limit && item.nextElementSibling.removeEventListener('click', clickBtnFn)
|
|
||||||
}
|
}
|
||||||
item.nextElementSibling.addEventListener('click', clickBtnFn)
|
|
||||||
|
const item = data[num]
|
||||||
|
const alt = item.alt ? `alt="${replaceDq(item.alt)}"` : ''
|
||||||
|
const title = item.title ? `title="${replaceDq(item.title)}"` : ''
|
||||||
|
|
||||||
|
nextItems.push(`<div class="item ">
|
||||||
|
<img src="${item.url}" data-grid-maintained-target="true" ${alt + title} />
|
||||||
|
</div>`)
|
||||||
}
|
}
|
||||||
btf.initJustifiedGallery(item)
|
return nextItems
|
||||||
btf.loadLightbox(item.querySelectorAll('img'))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const addJustifiedGallery = () => {
|
const buttonText = GLOBAL_CONFIG.infinitegrid.buttonText
|
||||||
ele.forEach(item => {
|
const addButton = item => {
|
||||||
item.classList.contains('url')
|
const button = document.createElement('button')
|
||||||
? fetchUrl(item.textContent).then(res => { runJustifiedGallery(item, res) })
|
button.textContent = buttonText
|
||||||
: runJustifiedGallery(item, JSON.parse(item.textContent))
|
|
||||||
})
|
const buttonFn = e => {
|
||||||
|
e.target.removeEventListener('click', buttonFn)
|
||||||
|
e.target.remove()
|
||||||
|
btf.setLoading.add(item)
|
||||||
|
appendItem(ig.getGroups().length + 1, 10)
|
||||||
|
}
|
||||||
|
|
||||||
|
button.addEventListener('click', buttonFn)
|
||||||
|
item.insertAdjacentElement('afterend', button)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.fjGallery) {
|
const appendItem = (nextGroupKey, count) => {
|
||||||
addJustifiedGallery()
|
ig.append(getItems(nextGroupKey, count), nextGroupKey)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getCSS(`${GLOBAL_CONFIG.source.justifiedGallery.css}`)
|
const maxGroupKey = Math.ceil(dataLength / 10)
|
||||||
getScript(`${GLOBAL_CONFIG.source.justifiedGallery.js}`).then(addJustifiedGallery)
|
|
||||||
|
const completeFn = e => {
|
||||||
|
const { updated, isResize, mounted } = e
|
||||||
|
if (!updated.length || !mounted.length || isResize) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
btf.loadLightbox(item.querySelectorAll('img:not(.medium-zoom-image)'))
|
||||||
|
|
||||||
|
if (ig.getGroups().length === maxGroupKey) {
|
||||||
|
btf.setLoading.remove(item)
|
||||||
|
ig.off('renderComplete', completeFn)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isButton) {
|
||||||
|
btf.setLoading.remove(item)
|
||||||
|
addButton(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestAppendFn = btf.debounce(e => {
|
||||||
|
const nextGroupKey = (+e.groupKey || 0) + 1
|
||||||
|
appendItem(nextGroupKey, 10)
|
||||||
|
|
||||||
|
if (nextGroupKey === maxGroupKey) {
|
||||||
|
ig.off('requestAppend', requestAppendFn)
|
||||||
|
}
|
||||||
|
}, 300)
|
||||||
|
|
||||||
|
btf.setLoading.add(item)
|
||||||
|
ig.on('renderComplete', completeFn)
|
||||||
|
|
||||||
|
if (isButton) {
|
||||||
|
appendItem(1, 10)
|
||||||
|
} else {
|
||||||
|
ig.on('requestAppend', requestAppendFn)
|
||||||
|
ig.renderItems()
|
||||||
|
}
|
||||||
|
|
||||||
|
btf.addGlobalFn('justifiedGallery', () => { ig.destroy() })
|
||||||
|
}
|
||||||
|
|
||||||
|
const addJustifiedGallery = async (ele, tabs = false) => {
|
||||||
|
const init = async () => {
|
||||||
|
for (const item of ele) {
|
||||||
|
if (btf.isHidden(item)) continue
|
||||||
|
if (tabs && item.classList.contains('loaded')) {
|
||||||
|
item.querySelector('.gallery-items').innerHTML = ''
|
||||||
|
const button = item.querySelector(':scope > button')
|
||||||
|
const loadingContainer = item.querySelector(':scope > .loading-container')
|
||||||
|
button && button.remove()
|
||||||
|
loadingContainer && loadingContainer.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
const isButton = item.getAttribute('data-button') === 'true'
|
||||||
|
const text = item.firstElementChild.textContent
|
||||||
|
item.classList.add('loaded')
|
||||||
|
const content = item.getAttribute('data-type') === 'url' ? await fetchUrl(text) : JSON.parse(text)
|
||||||
|
runJustifiedGallery(item.lastElementChild, content, isButton, tabs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof InfiniteGrid === 'function') {
|
||||||
|
init()
|
||||||
|
} else {
|
||||||
|
await getScript(`${GLOBAL_CONFIG.infinitegrid.js}`)
|
||||||
|
init()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rightside scroll percent
|
* rightside scroll percent
|
||||||
*/
|
*/
|
||||||
const rightsideScrollPercent = currentTop => {
|
const rightsideScrollPercent = currentTop => {
|
||||||
const perNum = btf.getScrollPercent(currentTop, document.body)
|
const scrollPercent = btf.getScrollPercent(currentTop, document.body)
|
||||||
const $goUp = document.getElementById('go-up')
|
const goUpElement = document.getElementById('go-up')
|
||||||
if (perNum < 95) {
|
|
||||||
$goUp.classList.add('show-percent')
|
if (scrollPercent < 95) {
|
||||||
$goUp.querySelector('.scroll-percent').textContent = perNum
|
goUpElement.classList.add('show-percent')
|
||||||
|
goUpElement.querySelector('.scroll-percent').textContent = scrollPercent
|
||||||
} else {
|
} else {
|
||||||
$goUp.classList.remove('show-percent')
|
goUpElement.classList.remove('show-percent')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 滾動處理
|
* 滾動處理
|
||||||
*/
|
*/
|
||||||
const scrollFn = function () {
|
const scrollFn = () => {
|
||||||
const $rightside = document.getElementById('rightside')
|
const $rightside = document.getElementById('rightside')
|
||||||
const innerHeight = window.innerHeight + 56
|
const innerHeight = window.innerHeight + 56
|
||||||
let initTop = 0
|
let initTop = 0
|
||||||
let isChatShow = true
|
|
||||||
const $header = document.getElementById('page-header')
|
const $header = document.getElementById('page-header')
|
||||||
const isChatBtn = typeof chatBtn !== 'undefined'
|
const isChatBtn = typeof chatBtn !== 'undefined'
|
||||||
const isShowPercent = GLOBAL_CONFIG.percent.rightside
|
const isShowPercent = GLOBAL_CONFIG.percent.rightside
|
||||||
|
|
||||||
// 當滾動條小于 56 的時候
|
// 當滾動條小于 56 的時候
|
||||||
if (document.body.scrollHeight <= innerHeight) {
|
if (document.body.scrollHeight <= innerHeight) {
|
||||||
$rightside.style.cssText = 'opacity: 1; transform: translateX(-58px)'
|
$rightside.classList.add('rightside-show')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,50 +378,51 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let flag = ''
|
||||||
const scrollTask = btf.throttle(() => {
|
const scrollTask = btf.throttle(() => {
|
||||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||||
const isDown = scrollDirection(currentTop)
|
const isDown = scrollDirection(currentTop)
|
||||||
if (currentTop > 56) {
|
if (currentTop > 56) {
|
||||||
|
if (flag === '') {
|
||||||
|
$header.classList.add('nav-fixed')
|
||||||
|
$rightside.classList.add('rightside-show')
|
||||||
|
}
|
||||||
|
|
||||||
if (isDown) {
|
if (isDown) {
|
||||||
if ($header.classList.contains('nav-visible')) $header.classList.remove('nav-visible')
|
if (flag !== 'down') {
|
||||||
if (isChatBtn && isChatShow === true) {
|
$header.classList.remove('nav-visible')
|
||||||
window.chatBtn.hide()
|
isChatBtn && window.chatBtn.hide()
|
||||||
isChatShow = false
|
flag = 'down'
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!$header.classList.contains('nav-visible')) $header.classList.add('nav-visible')
|
if (flag !== 'up') {
|
||||||
if (isChatBtn && isChatShow === false) {
|
$header.classList.add('nav-visible')
|
||||||
window.chatBtn.show()
|
isChatBtn && window.chatBtn.show()
|
||||||
isChatShow = true
|
flag = 'up'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$header.classList.add('nav-fixed')
|
|
||||||
if (window.getComputedStyle($rightside).getPropertyValue('opacity') === '0') {
|
|
||||||
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
|
flag = ''
|
||||||
if (currentTop === 0) {
|
if (currentTop === 0) {
|
||||||
$header.classList.remove('nav-fixed', 'nav-visible')
|
$header.classList.remove('nav-fixed', 'nav-visible')
|
||||||
}
|
}
|
||||||
$rightside.style.cssText = "opacity: ''; transform: ''"
|
$rightside.classList.remove('rightside-show')
|
||||||
}
|
}
|
||||||
|
|
||||||
isShowPercent && rightsideScrollPercent(currentTop)
|
isShowPercent && rightsideScrollPercent(currentTop)
|
||||||
|
|
||||||
if (document.body.scrollHeight <= innerHeight) {
|
if (document.body.scrollHeight <= innerHeight) {
|
||||||
$rightside.style.cssText = 'opacity: 0.8; transform: translateX(-58px)'
|
$rightside.classList.add('rightside-show')
|
||||||
}
|
}
|
||||||
}, 200)
|
}, 300)
|
||||||
|
|
||||||
window.scrollCollect = scrollTask
|
btf.addEventListenerPjax(window, 'scroll', scrollTask, { passive: true })
|
||||||
|
|
||||||
window.addEventListener('scroll', scrollCollect)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* toc,anchor
|
* toc,anchor
|
||||||
*/
|
*/
|
||||||
const scrollFnToDo = function () {
|
const scrollFnToDo = () => {
|
||||||
const isToc = GLOBAL_CONFIG_SITE.isToc
|
const isToc = GLOBAL_CONFIG_SITE.isToc
|
||||||
const isAnchor = GLOBAL_CONFIG.isAnchor
|
const isAnchor = GLOBAL_CONFIG.isAnchor
|
||||||
const $article = document.getElementById('article-container')
|
const $article = document.getElementById('article-container')
|
||||||
@@ -371,37 +433,24 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
|
|
||||||
if (isToc) {
|
if (isToc) {
|
||||||
const $cardTocLayout = document.getElementById('card-toc')
|
const $cardTocLayout = document.getElementById('card-toc')
|
||||||
$cardToc = $cardTocLayout.getElementsByClassName('toc-content')[0]
|
$cardToc = $cardTocLayout.querySelector('.toc-content')
|
||||||
$tocLink = $cardToc.querySelectorAll('.toc-link')
|
$tocLink = $cardToc.querySelectorAll('.toc-link')
|
||||||
$tocPercentage = $cardTocLayout.querySelector('.toc-percentage')
|
$tocPercentage = $cardTocLayout.querySelector('.toc-percentage')
|
||||||
isExpand = $cardToc.classList.contains('is-expand')
|
isExpand = $cardToc.classList.contains('is-expand')
|
||||||
|
|
||||||
window.mobileToc = {
|
// toc元素點擊
|
||||||
open: () => {
|
const tocItemClickFn = e => {
|
||||||
$cardTocLayout.style.cssText = 'animation: toc-open .3s; opacity: 1; right: 55px'
|
const target = e.target.closest('.toc-link')
|
||||||
},
|
if (!target) return
|
||||||
|
|
||||||
close: () => {
|
e.preventDefault()
|
||||||
$cardTocLayout.style.animation = 'toc-close .2s'
|
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI(target.getAttribute('href')).replace('#', ''))), 300)
|
||||||
setTimeout(() => {
|
if (window.innerWidth < 900) {
|
||||||
$cardTocLayout.style.cssText = "opacity:''; animation: ''; right: ''"
|
$cardTocLayout.classList.remove('open')
|
||||||
}, 100)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// toc元素點擊
|
btf.addEventListenerPjax($cardToc, 'click', tocItemClickFn)
|
||||||
$cardToc.addEventListener('click', e => {
|
|
||||||
e.preventDefault()
|
|
||||||
const target = e.target.classList
|
|
||||||
if (target.contains('toc-content')) return
|
|
||||||
const $target = target.contains('toc-link')
|
|
||||||
? e.target
|
|
||||||
: e.target.parentElement
|
|
||||||
btf.scrollToDest(btf.getEleTop(document.getElementById(decodeURI($target.getAttribute('href')).replace('#', ''))), 300)
|
|
||||||
if (window.innerWidth < 900) {
|
|
||||||
window.mobileToc.close()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
autoScrollToc = item => {
|
autoScrollToc = item => {
|
||||||
const activePosition = item.getBoundingClientRect().top
|
const activePosition = item.getBoundingClientRect().top
|
||||||
@@ -416,9 +465,9 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// find head position & add active class
|
// find head position & add active class
|
||||||
const list = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
const $articleList = $article.querySelectorAll('h1,h2,h3,h4,h5,h6')
|
||||||
let detectItem = ''
|
let detectItem = ''
|
||||||
const findHeadPosition = function (top) {
|
const findHeadPosition = top => {
|
||||||
if (top === 0) {
|
if (top === 0) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@@ -426,7 +475,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
let currentId = ''
|
let currentId = ''
|
||||||
let currentIndex = ''
|
let currentIndex = ''
|
||||||
|
|
||||||
list.forEach(function (ele, index) {
|
$articleList.forEach((ele, index) => {
|
||||||
if (top > btf.getEleTop(ele) - 80) {
|
if (top > btf.getEleTop(ele) - 80) {
|
||||||
const id = ele.id
|
const id = ele.id
|
||||||
currentId = id ? '#' + encodeURI(id) : ''
|
currentId = id ? '#' + encodeURI(id) : ''
|
||||||
@@ -464,7 +513,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// main of scroll
|
// main of scroll
|
||||||
window.tocScrollFn = btf.throttle(() => {
|
const tocScrollFn = btf.throttle(() => {
|
||||||
const currentTop = window.scrollY || document.documentElement.scrollTop
|
const currentTop = window.scrollY || document.documentElement.scrollTop
|
||||||
if (isToc && GLOBAL_CONFIG.percent.toc) {
|
if (isToc && GLOBAL_CONFIG.percent.toc) {
|
||||||
$tocPercentage.textContent = btf.getScrollPercent(currentTop, $article)
|
$tocPercentage.textContent = btf.getScrollPercent(currentTop, $article)
|
||||||
@@ -472,21 +521,22 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
findHeadPosition(currentTop)
|
findHeadPosition(currentTop)
|
||||||
}, 100)
|
}, 100)
|
||||||
|
|
||||||
window.addEventListener('scroll', tocScrollFn)
|
btf.addEventListenerPjax(window, 'scroll', tocScrollFn, { passive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
const modeChangeFn = mode => {
|
const handleThemeChange = mode => {
|
||||||
if (!window.themeChange) {
|
const globalFn = window.globalFn || {}
|
||||||
|
const themeChange = globalFn.themeChange || {}
|
||||||
|
if (!themeChange) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const turnMode = item => window.themeChange[item](mode)
|
Object.keys(themeChange).forEach(key => {
|
||||||
|
const themeChangeFn = themeChange[key]
|
||||||
Object.keys(window.themeChange).forEach(item => {
|
if (['disqus', 'disqusjs'].includes(key)) {
|
||||||
if (['disqus', 'disqusjs'].includes(item)) {
|
setTimeout(() => themeChangeFn(mode), 300)
|
||||||
setTimeout(() => turnMode(item), 300)
|
|
||||||
} else {
|
} else {
|
||||||
turnMode(item)
|
themeChangeFn(mode)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -495,7 +545,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
* Rightside
|
* Rightside
|
||||||
*/
|
*/
|
||||||
const rightSideFn = {
|
const rightSideFn = {
|
||||||
switchReadMode: () => { // read-mode
|
readmode: () => { // read mode
|
||||||
const $body = document.body
|
const $body = document.body
|
||||||
$body.classList.add('read-mode')
|
$body.classList.add('read-mode')
|
||||||
const newEle = document.createElement('button')
|
const newEle = document.createElement('button')
|
||||||
@@ -511,74 +561,53 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
|
|
||||||
newEle.addEventListener('click', clickFn)
|
newEle.addEventListener('click', clickFn)
|
||||||
},
|
},
|
||||||
switchDarkMode: () => { // Switch Between Light And Dark Mode
|
darkmode: () => { // switch between light and dark mode
|
||||||
const willChangeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
|
const willChangeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'light' : 'dark'
|
||||||
if (willChangeMode === 'dark') {
|
if (willChangeMode === 'dark') {
|
||||||
activateDarkMode()
|
activateDarkMode()
|
||||||
saveToLocal.set('theme', 'dark', 2)
|
|
||||||
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
|
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
|
||||||
} else {
|
} else {
|
||||||
activateLightMode()
|
activateLightMode()
|
||||||
saveToLocal.set('theme', 'light', 2)
|
|
||||||
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
|
GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.night_to_day)
|
||||||
}
|
}
|
||||||
modeChangeFn(willChangeMode)
|
saveToLocal.set('theme', willChangeMode, 2)
|
||||||
|
handleThemeChange(willChangeMode)
|
||||||
},
|
},
|
||||||
showOrHideBtn: (e) => { // rightside 點擊設置 按鈕 展開
|
'rightside-config': item => { // Show or hide rightside-hide-btn
|
||||||
const rightsideHideClassList = document.getElementById('rightside-config-hide').classList
|
const hideLayout = item.firstElementChild
|
||||||
rightsideHideClassList.toggle('show')
|
if (hideLayout.classList.contains('show')) {
|
||||||
if (e.classList.contains('show')) {
|
hideLayout.classList.add('status')
|
||||||
rightsideHideClassList.add('status')
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
rightsideHideClassList.remove('status')
|
hideLayout.classList.remove('status')
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
e.classList.toggle('show')
|
|
||||||
|
hideLayout.classList.toggle('show')
|
||||||
},
|
},
|
||||||
scrollToTop: () => { // Back to top
|
'go-up': () => { // Back to top
|
||||||
btf.scrollToDest(0, 500)
|
btf.scrollToDest(0, 500)
|
||||||
},
|
},
|
||||||
hideAsideBtn: () => { // Hide aside
|
'hide-aside-btn': () => { // Hide aside
|
||||||
const $htmlDom = document.documentElement.classList
|
const $htmlDom = document.documentElement.classList
|
||||||
const saveStatus = $htmlDom.contains('hide-aside') ? 'show' : 'hide'
|
const saveStatus = $htmlDom.contains('hide-aside') ? 'show' : 'hide'
|
||||||
saveToLocal.set('aside-status', saveStatus, 2)
|
saveToLocal.set('aside-status', saveStatus, 2)
|
||||||
$htmlDom.toggle('hide-aside')
|
$htmlDom.toggle('hide-aside')
|
||||||
},
|
},
|
||||||
runMobileToc: () => {
|
'mobile-toc-button': () => { // Show mobile toc
|
||||||
if (window.getComputedStyle(document.getElementById('card-toc')).getPropertyValue('opacity') === '0') window.mobileToc.open()
|
document.getElementById('card-toc').classList.toggle('open')
|
||||||
else window.mobileToc.close()
|
|
||||||
},
|
},
|
||||||
toggleChatDisplay: () => {
|
'chat-btn': () => { // Show chat
|
||||||
window.chatBtnFn()
|
window.chatBtnFn()
|
||||||
|
},
|
||||||
|
translateLink: () => { // switch between traditional and simplified chinese
|
||||||
|
window.translateFn.translatePage()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('rightside').addEventListener('click', function (e) {
|
document.getElementById('rightside').addEventListener('click', function (e) {
|
||||||
const $target = e.target.id ? e.target : e.target.parentNode
|
const $target = e.target.closest('[id]')
|
||||||
switch ($target.id) {
|
if ($target && rightSideFn[$target.id]) {
|
||||||
case 'go-up':
|
rightSideFn[$target.id](this)
|
||||||
rightSideFn.scrollToTop()
|
|
||||||
break
|
|
||||||
case 'rightside_config':
|
|
||||||
rightSideFn.showOrHideBtn($target)
|
|
||||||
break
|
|
||||||
case 'mobile-toc-button':
|
|
||||||
rightSideFn.runMobileToc()
|
|
||||||
break
|
|
||||||
case 'readmode':
|
|
||||||
rightSideFn.switchReadMode()
|
|
||||||
break
|
|
||||||
case 'darkmode':
|
|
||||||
rightSideFn.switchDarkMode()
|
|
||||||
break
|
|
||||||
case 'hide-aside-btn':
|
|
||||||
rightSideFn.hideAsideBtn()
|
|
||||||
break
|
|
||||||
case 'chat-btn':
|
|
||||||
rightSideFn.toggleChatDisplay()
|
|
||||||
break
|
|
||||||
default:
|
|
||||||
break
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -587,24 +616,35 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
* 側邊欄sub-menu 展開/收縮
|
* 側邊欄sub-menu 展開/收縮
|
||||||
*/
|
*/
|
||||||
const clickFnOfSubMenu = () => {
|
const clickFnOfSubMenu = () => {
|
||||||
document.querySelectorAll('#sidebar-menus .site-page.group').forEach(function (item) {
|
const handleClickOfSubMenu = e => {
|
||||||
item.addEventListener('click', function () {
|
const target = e.target.closest('.site-page.group')
|
||||||
this.classList.toggle('hide')
|
if (!target) return
|
||||||
})
|
target.classList.toggle('hide')
|
||||||
})
|
}
|
||||||
|
|
||||||
|
document.querySelector('#sidebar-menus .menus_items').addEventListener('click', handleClickOfSubMenu)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 手机端目录点击
|
||||||
|
*/
|
||||||
|
const openMobileMenu = () => {
|
||||||
|
const handleClick = () => { sidebarFn.open() }
|
||||||
|
btf.addEventListenerPjax(document.getElementById('toggle-menu'), 'click', handleClick)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 複製時加上版權信息
|
* 複製時加上版權信息
|
||||||
*/
|
*/
|
||||||
const addCopyright = () => {
|
const addCopyright = () => {
|
||||||
const copyright = GLOBAL_CONFIG.copyright
|
const { limitCount, languages } = GLOBAL_CONFIG.copyright
|
||||||
document.body.oncopy = (e) => {
|
|
||||||
|
const handleCopy = (e) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const copyFont = window.getSelection(0).toString()
|
const copyFont = window.getSelection(0).toString()
|
||||||
let textFont = copyFont
|
let textFont = copyFont
|
||||||
if (copyFont.length > copyright.limitCount) {
|
if (copyFont.length > limitCount) {
|
||||||
textFont = `${copyFont}\n\n\n${copyright.languages.author}\n${copyright.languages.link}${window.location.href}\n${copyright.languages.source}\n${copyright.languages.info}`
|
textFont = `${copyFont}\n\n\n${languages.author}\n${languages.link}${window.location.href}\n${languages.source}\n${languages.info}`
|
||||||
}
|
}
|
||||||
if (e.clipboardData) {
|
if (e.clipboardData) {
|
||||||
return e.clipboardData.setData('text', textFont)
|
return e.clipboardData.setData('text', textFont)
|
||||||
@@ -612,6 +652,8 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
return window.clipboardData.setData('text', textFont)
|
return window.clipboardData.setData('text', textFont)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.body.addEventListener('copy', handleCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -640,114 +682,119 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
* table overflow
|
* table overflow
|
||||||
*/
|
*/
|
||||||
const addTableWrap = () => {
|
const addTableWrap = () => {
|
||||||
const $table = document.querySelectorAll('#article-container :not(.highlight) > table, #article-container > table')
|
const $table = document.querySelectorAll('#article-container table')
|
||||||
if ($table.length) {
|
if (!$table.length) return
|
||||||
$table.forEach(item => {
|
|
||||||
|
$table.forEach(item => {
|
||||||
|
if (!item.closest('.highlight')) {
|
||||||
btf.wrap(item, 'div', { class: 'table-wrap' })
|
btf.wrap(item, 'div', { class: 'table-wrap' })
|
||||||
})
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* tag-hide
|
* tag-hide
|
||||||
*/
|
*/
|
||||||
const clickFnOfTagHide = function () {
|
const clickFnOfTagHide = () => {
|
||||||
const $hideInline = document.querySelectorAll('#article-container .hide-button')
|
const hideButtons = document.querySelectorAll('#article-container .hide-button')
|
||||||
if ($hideInline.length) {
|
if (!hideButtons.length) return
|
||||||
$hideInline.forEach(function (item) {
|
const handleClick = function (e) {
|
||||||
item.addEventListener('click', function (e) {
|
const $this = this
|
||||||
const $this = this
|
$this.classList.add('open')
|
||||||
$this.classList.add('open')
|
const $fjGallery = $this.nextElementSibling.querySelectorAll('.gallery-container')
|
||||||
const $fjGallery = $this.nextElementSibling.querySelectorAll('.fj-gallery')
|
$fjGallery.length && addJustifiedGallery($fjGallery)
|
||||||
$fjGallery.length && btf.initJustifiedGallery($fjGallery)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
const tabsFn = {
|
hideButtons.forEach(item => {
|
||||||
clickFnOfTabs: function () {
|
item.addEventListener('click', handleClick, { once: true })
|
||||||
document.querySelectorAll('#article-container .tab > button').forEach(function (item) {
|
|
||||||
item.addEventListener('click', function (e) {
|
|
||||||
const $this = this
|
|
||||||
const $tabItem = $this.parentNode
|
|
||||||
|
|
||||||
if (!$tabItem.classList.contains('active')) {
|
|
||||||
const $tabContent = $tabItem.parentNode.nextElementSibling
|
|
||||||
const $siblings = btf.siblings($tabItem, '.active')[0]
|
|
||||||
$siblings && $siblings.classList.remove('active')
|
|
||||||
$tabItem.classList.add('active')
|
|
||||||
const tabId = $this.getAttribute('data-href').replace('#', '')
|
|
||||||
const childList = [...$tabContent.children]
|
|
||||||
childList.forEach(item => {
|
|
||||||
if (item.id === tabId) item.classList.add('active')
|
|
||||||
else item.classList.remove('active')
|
|
||||||
})
|
|
||||||
const $isTabJustifiedGallery = $tabContent.querySelectorAll(`#${tabId} .fj-gallery`)
|
|
||||||
if ($isTabJustifiedGallery.length > 0) {
|
|
||||||
btf.initJustifiedGallery($isTabJustifiedGallery)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
},
|
|
||||||
backToTop: () => {
|
|
||||||
document.querySelectorAll('#article-container .tabs .tab-to-top').forEach(function (item) {
|
|
||||||
item.addEventListener('click', function () {
|
|
||||||
btf.scrollToDest(btf.getEleTop(btf.getParents(this, '.tabs')), 300)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const toggleCardCategory = function () {
|
|
||||||
const $cardCategory = document.querySelectorAll('#aside-cat-list .card-category-list-item.parent i')
|
|
||||||
if ($cardCategory.length) {
|
|
||||||
$cardCategory.forEach(function (item) {
|
|
||||||
item.addEventListener('click', function (e) {
|
|
||||||
e.preventDefault()
|
|
||||||
const $this = this
|
|
||||||
$this.classList.toggle('expand')
|
|
||||||
const $parentEle = $this.parentNode.nextElementSibling
|
|
||||||
if (btf.isHidden($parentEle)) {
|
|
||||||
$parentEle.style.display = 'block'
|
|
||||||
} else {
|
|
||||||
$parentEle.style.display = 'none'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const switchComments = function () {
|
|
||||||
let switchDone = false
|
|
||||||
const $switchBtn = document.querySelector('#comment-switch > .switch-btn')
|
|
||||||
$switchBtn && $switchBtn.addEventListener('click', function () {
|
|
||||||
this.classList.toggle('move')
|
|
||||||
document.querySelectorAll('#post-comment > .comment-wrap > div').forEach(function (item) {
|
|
||||||
if (btf.isHidden(item)) {
|
|
||||||
item.style.cssText = 'display: block;animation: tabshow .5s'
|
|
||||||
} else {
|
|
||||||
item.style.cssText = "display: none;animation: ''"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if (!switchDone && typeof loadOtherComment === 'function') {
|
|
||||||
switchDone = true
|
|
||||||
loadOtherComment()
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
const addPostOutdateNotice = function () {
|
const tabsFn = () => {
|
||||||
const data = GLOBAL_CONFIG.noticeOutdate
|
const navTabsElement = document.querySelectorAll('#article-container .tabs')
|
||||||
|
if (!navTabsElement.length) return
|
||||||
|
|
||||||
|
const removeAndAddActiveClass = (elements, detect) => {
|
||||||
|
Array.from(elements).forEach(element => {
|
||||||
|
element.classList.remove('active')
|
||||||
|
if (element === detect || element.id === detect) {
|
||||||
|
element.classList.add('active')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const addTabNavEventListener = (item, isJustifiedGallery) => {
|
||||||
|
const navClickHandler = function (e) {
|
||||||
|
const target = e.target.closest('button')
|
||||||
|
if (target.classList.contains('active')) return
|
||||||
|
removeAndAddActiveClass(this.children, target)
|
||||||
|
this.classList.remove('no-default')
|
||||||
|
const tabId = target.getAttribute('data-href')
|
||||||
|
const tabContent = this.nextElementSibling
|
||||||
|
removeAndAddActiveClass(tabContent.children, tabId)
|
||||||
|
if (isJustifiedGallery) {
|
||||||
|
btf.removeGlobalFnEvent('igOfTabs', this)
|
||||||
|
const justifiedGalleryItems = tabContent.querySelectorAll(`:scope > #${tabId} .gallery-container`)
|
||||||
|
justifiedGalleryItems.length && addJustifiedGallery(justifiedGalleryItems, this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btf.addEventListenerPjax(item.firstElementChild, 'click', navClickHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addTabToTopEventListener = item => {
|
||||||
|
const btnClickHandler = (e) => {
|
||||||
|
const target = e.target.closest('button')
|
||||||
|
if (!target) return
|
||||||
|
btf.scrollToDest(btf.getEleTop(item), 300)
|
||||||
|
}
|
||||||
|
btf.addEventListenerPjax(item.lastElementChild, 'click', btnClickHandler)
|
||||||
|
}
|
||||||
|
|
||||||
|
navTabsElement.forEach(item => {
|
||||||
|
const isJustifiedGallery = !!item.querySelectorAll('.gallery-container')
|
||||||
|
addTabNavEventListener(item, isJustifiedGallery)
|
||||||
|
addTabToTopEventListener(item)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const toggleCardCategory = () => {
|
||||||
|
const cardCategory = document.querySelector('#aside-cat-list.expandBtn')
|
||||||
|
if (!cardCategory) return
|
||||||
|
|
||||||
|
const handleToggleBtn = (e) => {
|
||||||
|
const target = e.target
|
||||||
|
if (target.nodeName === 'I') {
|
||||||
|
e.preventDefault()
|
||||||
|
target.parentNode.classList.toggle('expand')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btf.addEventListenerPjax(cardCategory, 'click', handleToggleBtn, true)
|
||||||
|
}
|
||||||
|
|
||||||
|
const switchComments = () => {
|
||||||
|
const switchBtn = document.getElementById('switch-btn')
|
||||||
|
if (!switchBtn) return
|
||||||
|
let switchDone = false
|
||||||
|
const commentContainer = document.getElementById('post-comment')
|
||||||
|
const handleSwitchBtn = () => {
|
||||||
|
commentContainer.classList.toggle('move')
|
||||||
|
if (!switchDone) {
|
||||||
|
switchDone = true
|
||||||
|
loadOtherComment()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
btf.addEventListenerPjax(switchBtn, 'click', handleSwitchBtn)
|
||||||
|
}
|
||||||
|
|
||||||
|
const addPostOutdateNotice = () => {
|
||||||
|
const { limitDay, messagePrev, messageNext, position } = GLOBAL_CONFIG.noticeOutdate
|
||||||
const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
|
const diffDay = btf.diffDate(GLOBAL_CONFIG_SITE.postUpdate)
|
||||||
if (diffDay >= data.limitDay) {
|
if (diffDay >= limitDay) {
|
||||||
const ele = document.createElement('div')
|
const ele = document.createElement('div')
|
||||||
ele.className = 'post-outdate-notice'
|
ele.className = 'post-outdate-notice'
|
||||||
ele.textContent = data.messagePrev + ' ' + diffDay + ' ' + data.messageNext
|
ele.textContent = `${messagePrev} ${diffDay} ${messageNext}`
|
||||||
const $targetEle = document.getElementById('article-container')
|
const $targetEle = document.getElementById('article-container')
|
||||||
if (data.position === 'top') {
|
if (position === 'top') {
|
||||||
$targetEle.insertBefore(ele, $targetEle.firstChild)
|
$targetEle.insertBefore(ele, $targetEle.firstChild)
|
||||||
} else {
|
} else {
|
||||||
$targetEle.appendChild(ele)
|
$targetEle.appendChild(ele)
|
||||||
@@ -774,7 +821,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
const unRefreshFn = function () {
|
const unRefreshFn = function () {
|
||||||
window.addEventListener('resize', () => {
|
window.addEventListener('resize', () => {
|
||||||
adjustMenu(false)
|
adjustMenu(false)
|
||||||
btf.isHidden(document.getElementById('toggle-menu')) && mobileSidebarOpen && sidebarFn.close()
|
mobileSidebarOpen && btf.isHidden(document.getElementById('toggle-menu')) && sidebarFn.close()
|
||||||
})
|
})
|
||||||
|
|
||||||
document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() })
|
document.getElementById('menu-mask').addEventListener('click', e => { sidebarFn.close() })
|
||||||
@@ -786,7 +833,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
if (GLOBAL_CONFIG.autoDarkmode) {
|
if (GLOBAL_CONFIG.autoDarkmode) {
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', e => {
|
||||||
if (saveToLocal.get('theme') !== undefined) return
|
if (saveToLocal.get('theme') !== undefined) return
|
||||||
e.matches ? modeChangeFn('dark') : modeChangeFn('light')
|
e.matches ? handleThemeChange('dark') : handleThemeChange('light')
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -810,16 +857,16 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption()
|
GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption()
|
||||||
scrollFn()
|
scrollFn()
|
||||||
|
|
||||||
const $jgEle = document.querySelectorAll('#article-container .fj-gallery')
|
btf.removeGlobalFnEvent('justifiedGallery')
|
||||||
$jgEle.length && runJustifiedGallery($jgEle)
|
const galleryContainer = document.querySelectorAll('#article-container .gallery-container')
|
||||||
|
galleryContainer.length && addJustifiedGallery(galleryContainer)
|
||||||
|
|
||||||
runLightbox()
|
runLightbox()
|
||||||
addTableWrap()
|
addTableWrap()
|
||||||
clickFnOfTagHide()
|
clickFnOfTagHide()
|
||||||
tabsFn.clickFnOfTabs()
|
tabsFn()
|
||||||
tabsFn.backToTop()
|
|
||||||
switchComments()
|
switchComments()
|
||||||
document.getElementById('toggle-menu').addEventListener('click', () => { sidebarFn.open() })
|
openMobileMenu()
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshFn()
|
refreshFn()
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ window.addEventListener('load', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const searchClickFn = () => {
|
const searchClickFn = () => {
|
||||||
document.querySelector('#search-button > .search').addEventListener('click', openSearch)
|
btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch)
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchFnOnce = () => {
|
const searchFnOnce = () => {
|
||||||
|
|||||||
@@ -330,7 +330,7 @@ window.addEventListener('load', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const searchClickFn = () => {
|
const searchClickFn = () => {
|
||||||
document.querySelector('#search-button > .search').addEventListener('click', openSearch)
|
btf.addEventListenerPjax(document.querySelector('#search-button > .search'), 'click', openSearch)
|
||||||
}
|
}
|
||||||
|
|
||||||
const searchFnOnce = () => {
|
const searchFnOnce = () => {
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
return Traditionalized(txt)
|
return Traditionalized(txt)
|
||||||
} else return txt
|
} else return txt
|
||||||
}
|
}
|
||||||
|
|
||||||
function translateBody (fobj) {
|
function translateBody (fobj) {
|
||||||
let objs
|
let objs
|
||||||
if (typeof fobj === 'object') objs = fobj.childNodes
|
if (typeof fobj === 'object') objs = fobj.childNodes
|
||||||
@@ -107,9 +108,15 @@ document.addEventListener('DOMContentLoaded', function () {
|
|||||||
setLang()
|
setLang()
|
||||||
setTimeout(translateBody, translateDelay)
|
setTimeout(translateBody, translateDelay)
|
||||||
}
|
}
|
||||||
translateButtonObject.addEventListener('click', translatePage, false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.translateFn = {
|
||||||
|
translatePage,
|
||||||
|
Traditionalized,
|
||||||
|
Simplized
|
||||||
|
}
|
||||||
|
|
||||||
translateInitialization()
|
translateInitialization()
|
||||||
document.addEventListener('pjax:complete', translateInitialization)
|
document.addEventListener('pjax:complete', translateInitialization)
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,38 +1,35 @@
|
|||||||
const btf = {
|
const btf = {
|
||||||
debounce: function (func, wait, immediate) {
|
debounce: (func, wait = 0, immediate = false) => {
|
||||||
let timeout
|
let timeout
|
||||||
return function () {
|
return (...args) => {
|
||||||
const context = this
|
const later = () => {
|
||||||
const args = arguments
|
|
||||||
const later = function () {
|
|
||||||
timeout = null
|
timeout = null
|
||||||
if (!immediate) func.apply(context, args)
|
if (!immediate) func(...args)
|
||||||
}
|
}
|
||||||
const callNow = immediate && !timeout
|
const callNow = immediate && !timeout
|
||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
timeout = setTimeout(later, wait)
|
timeout = setTimeout(later, wait)
|
||||||
if (callNow) func.apply(context, args)
|
if (callNow) func(...args)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
throttle: function (func, wait, options) {
|
throttle: function (func, wait, options = {}) {
|
||||||
let timeout, context, args
|
let timeout, context, args
|
||||||
let previous = 0
|
let previous = 0
|
||||||
if (!options) options = {}
|
|
||||||
|
|
||||||
const later = function () {
|
const later = () => {
|
||||||
previous = options.leading === false ? 0 : new Date().getTime()
|
previous = options.leading === false ? 0 : new Date().getTime()
|
||||||
timeout = null
|
timeout = null
|
||||||
func.apply(context, args)
|
func.apply(context, args)
|
||||||
if (!timeout) context = args = null
|
if (!timeout) context = args = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const throttled = function () {
|
const throttled = (...params) => {
|
||||||
const now = new Date().getTime()
|
const now = new Date().getTime()
|
||||||
if (!previous && options.leading === false) previous = now
|
if (!previous && options.leading === false) previous = now
|
||||||
const remaining = wait - (now - previous)
|
const remaining = wait - (now - previous)
|
||||||
context = this
|
context = this
|
||||||
args = arguments
|
args = params
|
||||||
if (remaining <= 0 || remaining > wait) {
|
if (remaining <= 0 || remaining > wait) {
|
||||||
if (timeout) {
|
if (timeout) {
|
||||||
clearTimeout(timeout)
|
clearTimeout(timeout)
|
||||||
@@ -155,27 +152,6 @@ const btf = {
|
|||||||
ele.style.animation = text
|
ele.style.animation = text
|
||||||
},
|
},
|
||||||
|
|
||||||
getParents: (elem, selector) => {
|
|
||||||
for (; elem && elem !== document; elem = elem.parentNode) {
|
|
||||||
if (elem.matches(selector)) return elem
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
},
|
|
||||||
|
|
||||||
siblings: (ele, selector) => {
|
|
||||||
return [...ele.parentNode.children].filter((child) => {
|
|
||||||
if (selector) {
|
|
||||||
return child !== ele && child.matches(selector)
|
|
||||||
}
|
|
||||||
return child !== ele
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {*} selector
|
|
||||||
* @param {*} eleType the type of create element
|
|
||||||
* @param {*} options object key: value
|
|
||||||
*/
|
|
||||||
wrap: (selector, eleType, options) => {
|
wrap: (selector, eleType, options) => {
|
||||||
const createEle = document.createElement(eleType)
|
const createEle = document.createElement(eleType)
|
||||||
for (const [key, value] of Object.entries(options)) {
|
for (const [key, value] of Object.entries(options)) {
|
||||||
@@ -185,13 +161,6 @@ const btf = {
|
|||||||
createEle.appendChild(selector)
|
createEle.appendChild(selector)
|
||||||
},
|
},
|
||||||
|
|
||||||
unwrap: el => {
|
|
||||||
const parent = el.parentNode
|
|
||||||
if (parent && parent !== document.body) {
|
|
||||||
parent.replaceChild(el, parent)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
|
isHidden: ele => ele.offsetHeight === 0 && ele.offsetWidth === 0,
|
||||||
|
|
||||||
getEleTop: ele => {
|
getEleTop: ele => {
|
||||||
@@ -214,7 +183,7 @@ const btf = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (service === 'fancybox') {
|
if (service === 'fancybox') {
|
||||||
ele.forEach(i => {
|
Array.from(ele).forEach(i => {
|
||||||
if (i.parentNode.tagName !== 'A') {
|
if (i.parentNode.tagName !== 'A') {
|
||||||
const dataSrc = i.dataset.lazySrc || i.src
|
const dataSrc = i.dataset.lazySrc || i.src
|
||||||
const dataCaption = i.title || i.alt || ''
|
const dataCaption = i.title || i.alt || ''
|
||||||
@@ -257,22 +226,20 @@ const btf = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
initJustifiedGallery: function (selector) {
|
setLoading: {
|
||||||
const runJustifiedGallery = i => {
|
add: ele => {
|
||||||
if (!btf.isHidden(i)) {
|
const html = `
|
||||||
fjGallery(i, {
|
<div class="loading-container">
|
||||||
itemSelector: '.fj-gallery-item',
|
<div class="loading-item">
|
||||||
rowHeight: i.getAttribute('data-rowHeight'),
|
<div></div><div></div><div></div><div></div><div></div>
|
||||||
gutter: 4,
|
</div>
|
||||||
onJustify: function () {
|
</div>
|
||||||
this.$container.style.opacity = '1'
|
`
|
||||||
}
|
ele.insertAdjacentHTML('afterend', html)
|
||||||
})
|
},
|
||||||
}
|
remove: ele => {
|
||||||
|
ele.nextElementSibling.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.from(selector).length === 0) runJustifiedGallery(selector)
|
|
||||||
else selector.forEach(i => { runJustifiedGallery(i) })
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateAnchor: (anchor) => {
|
updateAnchor: (anchor) => {
|
||||||
@@ -297,11 +264,33 @@ const btf = {
|
|||||||
return percentage
|
return percentage
|
||||||
},
|
},
|
||||||
|
|
||||||
addModeChange: (name, fn) => {
|
addGlobalFn: (key, fn, name = false, parent = window) => {
|
||||||
if (window.themeChange && window.themeChange[name]) return
|
const globalFn = parent.globalFn || {}
|
||||||
window.themeChange = {
|
const keyObj = globalFn[key] || {}
|
||||||
...window.themeChange,
|
|
||||||
[name]: fn
|
if (name && keyObj[name]) return
|
||||||
}
|
|
||||||
|
name = name || Object.keys(keyObj).length
|
||||||
|
keyObj[name] = fn
|
||||||
|
globalFn[key] = keyObj
|
||||||
|
parent.globalFn = globalFn
|
||||||
|
},
|
||||||
|
|
||||||
|
addEventListenerPjax: (ele, event, fn, option = false) => {
|
||||||
|
ele.addEventListener(event, fn, option)
|
||||||
|
btf.addGlobalFn('pjax', () => {
|
||||||
|
ele.removeEventListener(event, fn, option)
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
removeGlobalFnEvent: (key, parent = window) => {
|
||||||
|
const { globalFn = {} } = parent
|
||||||
|
const keyObj = globalFn[key] || {}
|
||||||
|
const keyArr = Object.keys(keyObj)
|
||||||
|
if (!keyArr.length) return
|
||||||
|
keyArr.forEach(i => {
|
||||||
|
keyObj[i]()
|
||||||
|
})
|
||||||
|
delete parent.globalFn[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user