diff --git a/README.md b/README.md index b1d6def..f9d97b5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,9 @@ +
+ Language: + 🇺🇸 + 🇨🇳 +
+ # hexo-theme-butterfly ![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master) diff --git a/README_CN.md b/README_CN.md index 4ed5d2e..659d1ba 100644 --- a/README_CN.md +++ b/README_CN.md @@ -1,3 +1,9 @@ +
+ 語言: + 中文 + 英文 +
+ # hexo-theme-butterfly ![master version](https://img.shields.io/github/package-json/v/jerryc127/hexo-theme-butterfly/master?color=%231ab1ad&label=master) diff --git a/_config.yml b/_config.yml index b4761c6..16cf395 100644 --- a/_config.yml +++ b/_config.yml @@ -12,8 +12,8 @@ menu: # Tags: /tags/ || fas fa-tags # Categories: /categories/ || fas fa-folder-open # List||fas fa-list: - # - Music || /music/ || fas fa-music - # - Movie || /movies/ || fas fa-video + # Music: /music/ || fas fa-music + # Movie: /movies/ || fas fa-video # Link: /link/ || fas fa-link # About: /about/ || fas fa-heart @@ -27,6 +27,7 @@ highlight_theme: light # darker / pale night / light / ocean / mac / mac light highlight_copy: true # copy button highlight_lang: true # show the code language highlight_shrink: false # true: shrink the code blocks / false: expand the code blocks | none: expand code blocks and hide the button +highlight_height_limit: false # unit: px code_word_wrap: false # copy settings @@ -83,7 +84,7 @@ favicon: /img/favicon.png # Avatar (頭像) avatar: - img: + img: https://i.loli.net/2021/02/24/5O1day2nriDzjSu.png effect: false # Disable all banner image @@ -304,6 +305,7 @@ gitalk: distractionFreeMode: false # Facebook-like distraction free mode. pagerDirection: last # Comment sorting direction, available values are last and first. createIssueManually: false # Gitalk will create a corresponding github issue for your every single page automatically + option: # valine # https://valine.js.org @@ -321,6 +323,7 @@ valine: emojiCDN: # emoji CDN enableQQ: false # enable the Nickname box to automatically get QQ Nickname and QQ Avatar requiredFields: nick,mail # required fields (nick/mail) + visitor: false option: # waline - A simple comment system with backend support fork from Valine @@ -330,6 +333,7 @@ waline: avatar: monsterid # gravatar style https://zh-tw.gravatar.com/site/implement/images/#default-image emojiCDN: # emoji CDN bg: # waline background + visitor: false option: # utterances @@ -356,6 +360,7 @@ facebook_comments: twikoo: envId: region: + visitor: false option: # Chat Services @@ -788,14 +793,7 @@ note: # other # -------------------------------------- -# Artitalk -# see https://artitalk.js.org/ -artitalk: - appId: - appKey: - option: - -# Pjax [Beta] +# Pjax # It may contain bugs and unstable, give feedback when you find the bugs. # https://github.com/MoOx/pjax pjax: @@ -899,8 +897,8 @@ CDN: # math mathjax: https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js katex: https://cdn.jsdelivr.net/npm/katex@latest/dist/katex.min.css - katex_copytex: https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.js - katex_copytex_css: https://cdn.jsdelivr.net/npm/katex-copytex@latest/dist/katex-copytex.min.css + katex_copytex: https://cdn.jsdelivr.net/npm/katex@latest/dist/contrib/copy-tex.min.js + katex_copytex_css: https://cdn.jsdelivr.net/npm/katex@latest/dist/contrib/copy-tex.css mermaid: https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js # count @@ -949,6 +947,4 @@ CDN: # Prism.js prismjs_js: https://cdn.jsdelivr.net/npm/prismjs/prism.min.js prismjs_lineNumber_js: https://cdn.jsdelivr.net/npm/prismjs/plugins/line-numbers/prism-line-numbers.min.js - prismjs_autoloader: https://cdn.jsdelivr.net/npm/prismjs/plugins/autoloader/prism-autoloader.min.js - - artitalk: https://cdn.jsdelivr.net/npm/artitalk + prismjs_autoloader: https://cdn.jsdelivr.net/npm/prismjs/plugins/autoloader/prism-autoloader.min.js \ No newline at end of file diff --git a/layout/includes/head/Open_Graph.pug b/layout/includes/head/Open_Graph.pug index 7d5c59c..1702985 100644 --- a/layout/includes/head/Open_Graph.pug +++ b/layout/includes/head/Open_Graph.pug @@ -1,6 +1,6 @@ if theme.Open_Graph_meta - let contentType = is_post() ? 'article' : 'website' - - let metaImage = full_url_for(page.cover || theme.avatar.img) + - let metaImage = (page.cover || theme.avatar.img) ? full_url_for(page.cover || theme.avatar.img) : '' - let fb_appId = theme.facebook_comments.app_id || '' - let fb_admins = theme.facebook_comments.user_id || '' diff --git a/layout/includes/head/config.pug b/layout/includes/head/config.pug index 710345d..9dd4f3b 100644 --- a/layout/includes/head/config.pug +++ b/layout/includes/head/config.pug @@ -78,7 +78,8 @@ highlight = JSON.stringify({ plugin: config.highlight.enable ? 'highlighjs' : 'prismjs', highlightCopy: theme.highlight_copy, - highlightLang: theme.highlight_lang + highlightLang: theme.highlight_lang, + highlightHeightLimit: theme.highlight_height_limit }) } diff --git a/layout/includes/header/index.pug b/layout/includes/header/index.pug index ed02549..2476015 100644 --- a/layout/includes/header/index.pug +++ b/layout/includes/header/index.pug @@ -1,6 +1,6 @@ if !theme.disable_top_img && page.top_img !== false if is_post() - - var top_img = page.top_img || page.cover || page.randomcover || theme.default_top_img + - var top_img = page.top_img || page.cover || page.randomcover else if is_page() - var top_img = page.top_img || theme.default_top_img else if is_tag() diff --git a/layout/includes/header/menu_item.pug b/layout/includes/header/menu_item.pug index 7feff6b..5a63994 100644 --- a/layout/includes/header/menu_item.pug +++ b/layout/includes/header/menu_item.pug @@ -4,7 +4,7 @@ if theme.menu .menus_items each value, label in theme.menu - if !Array.isArray(value) + if typeof value !== 'object' .menus_item a.site-page(href=url_for(trim(value.split('||')[0]))) if value.split('||')[1] @@ -18,9 +18,9 @@ if theme.menu span=' '+ trim(label.split('||')[0]) i.fas.fa-chevron-down.expand(class=sidebarChildHide) ul.menus_item_child - each i in value + each val,lab in value li - a.site-page(href=url_for(trim(i.split('||')[1]))) - if i.split('||')[2] - i.fa-fw(class=trim(i.split('||')[2])) - span=' '+trim(i.split('||')[0]) \ No newline at end of file + a.site-page.child(href=url_for(trim(val.split('||')[0]))) + if val.split('||')[1] + i.fa-fw(class=trim(val.split('||')[1])) + span=' '+ lab \ No newline at end of file diff --git a/layout/includes/header/nav.pug b/layout/includes/header/nav.pug index e5660e1..2b4d3da 100644 --- a/layout/includes/header/nav.pug +++ b/layout/includes/header/nav.pug @@ -8,7 +8,7 @@ nav#nav a.site-page.social-icon.search i.fas.fa-search.fa-fw span=' '+_p('search') - !=fragment_cache('menus', function(){return partial('includes/header/menu_item')}) + !=partial('includes/header/menu_item', {}, {cache: true}) #toggle-menu a.site-page diff --git a/layout/includes/header/post-info.pug b/layout/includes/header/post-info.pug index 7e2d4c1..1edae72 100644 --- a/layout/includes/header/post-info.pug +++ b/layout/includes/header/post-info.pug @@ -1,3 +1,4 @@ +- let comments = theme.comments #post-info h1.post-title= page.title || _p('no_title') if theme.post_edit.enable @@ -51,15 +52,28 @@ span.post-meta-label= _p('post.min2read') + ':' span= min2read(page.content, {cn: 350, en: 160}) + _p('post.min2read_unit') - if theme.busuanzi.page_pv + //- for pv and count + mixin pvBlock(parent_id,parent_class,parent_title) span.post-meta-separator | - span.post-meta-pv-cv + span(class=parent_class id=parent_id data-flag-title=page.title) i.far.fa-eye.fa-fw.post-meta-icon span.post-meta-label=_p('post.page_pv') + ':' - span#busuanzi_value_page_pv + if block + block - if !theme.comments.lazyload && page.comments !== false && theme.comments.use && theme.comments.count - - var whichCount = theme.comments.use[0] + if theme.busuanzi.page_pv + +pvBlock('','post-meta-pv-cv','') + span#busuanzi_value_page_pv + else if comments.use && !comments.lazyload + if (comments.use.includes('Valine') && theme.valine.visitor) || (comments.use.includes('Waline') && theme.waline.visitor) + +pvBlock(url_for(page.path),'leancloud_visitors',page.title) + span.leancloud-visitors-count + else if (comments.use.includes('Twikoo') && theme.twikoo.visitor) + +pvBlock('','','') + span#twikoo_visitors + + if comments.count && !comments.lazyload && page.comments !== false && comments.use + - var whichCount = comments.use[0] mixin countBlock span.post-meta-separator | diff --git a/layout/includes/page/artitalk.pug b/layout/includes/page/artitalk.pug deleted file mode 100644 index c2d1dde..0000000 --- a/layout/includes/page/artitalk.pug +++ /dev/null @@ -1,28 +0,0 @@ -- let option = theme.artitalk.option ? JSON.stringify(theme.artitalk.option) : false - -if top_img === false - h1.page-title= page.title - -#artitalk_main -script. - (()=>{ - let setting = { - appId: '!{theme.artitalk.appId}', - appKey: '!{theme.artitalk.appKey}', - } - - if (!{Boolean(option)}) { - const otherSetting = !{option} - setting = Object.assign(setting, otherSetting) - } - - const init = () => { - new Artitalk(setting) - } - - if (typeof Artitalk === 'function') { - init() - } else { - getScript('!{theme.CDN.artitalk}').then(init) - } - })() \ No newline at end of file diff --git a/layout/includes/pagination.pug b/layout/includes/pagination.pug index 86f0faf..8bb76a9 100644 --- a/layout/includes/pagination.pug +++ b/layout/includes/pagination.pug @@ -6,11 +6,7 @@ escape: false } -if(!is_post()) - nav#pagination - div.pagination - !=paginator(options) -else +if is_post() - let prev = theme.post_pagination === 1 ? page.prev : page.next - let next = theme.post_pagination === 1 ? page.next : page.prev nav#pagination.pagination-post @@ -38,4 +34,10 @@ else img.next-cover(src=url_for(pagination_cover) onerror=`onerror=null;src='${url_for(theme.error_img.post_page)}'` alt='cover of next post') .pagination-info .label=_p('pagination.next') - .next_info=next.title \ No newline at end of file + .next_info=next.title +else + nav#pagination + .pagination + if is_home() + - options.format = 'page/%d/#content-inner' + !=paginator(options) \ No newline at end of file diff --git a/layout/includes/sidebar.pug b/layout/includes/sidebar.pug index 43c0b2c..639dd79 100644 --- a/layout/includes/sidebar.pug +++ b/layout/includes/sidebar.pug @@ -28,4 +28,4 @@ .headline= _p('aside.categories') .length-num= site.categories.length hr - !=fragment_cache('menus', function(){return partial('includes/header/menu_item')}) + !=partial('includes/header/menu_item', {}, {cache: true}) diff --git a/layout/includes/third-party/comments/gitalk.pug b/layout/includes/third-party/comments/gitalk.pug index dcd6eb6..8e78386 100644 --- a/layout/includes/third-party/comments/gitalk.pug +++ b/layout/includes/third-party/comments/gitalk.pug @@ -8,7 +8,7 @@ script. function loadGitalk () { function initGitalk () { - var gitalk = new Gitalk({ + var gitalk = new Gitalk(Object.assign({ clientID: '!{theme.gitalk.client_id}', clientSecret: '!{theme.gitalk.client_secret}', repo: '!{theme.gitalk.repo}', @@ -21,7 +21,8 @@ script. pagerDirection: '!{theme.gitalk.pagerDirection}', createIssueManually: !{theme.gitalk.createIssueManually}, updateCountCallback: commentCount - }) + },!{JSON.stringify(theme.gitalk.option)})) + gitalk.render('gitalk-container') } diff --git a/layout/includes/third-party/comments/twikoo.pug b/layout/includes/third-party/comments/twikoo.pug index d47a5d5..8fcf32f 100644 --- a/layout/includes/third-party/comments/twikoo.pug +++ b/layout/includes/third-party/comments/twikoo.pug @@ -1,21 +1,12 @@ -- let option = theme.twikoo.option ? JSON.stringify(theme.twikoo.option) : false - script. (()=>{ const $countDom = document.getElementById('twikoo-count') const init = () => { - let initData = { + twikoo.init(Object.assign({ el: '#twikoo-wrap', envId: '!{theme.twikoo.envId}', region: '!{theme.twikoo.region}' - } - - if (!{Boolean(option)}) { - const otherData = !{option} - initData = Object.assign(initData, otherData) - } - - twikoo.init(initData) + }, !{JSON.stringify(theme.twikoo.option)})) } const getCount = () => { diff --git a/layout/includes/third-party/comments/valine.pug b/layout/includes/third-party/comments/valine.pug index e67f92b..d5121bc 100644 --- a/layout/includes/third-party/comments/valine.pug +++ b/layout/includes/third-party/comments/valine.pug @@ -1,4 +1,3 @@ -- let option = theme.valine.option ? JSON.stringify(theme.valine.option) : false - let emojiMaps = '""' if site.data.valine - emojiMaps = JSON.stringify(site.data.valine) @@ -6,7 +5,7 @@ if site.data.valine script. function loadValine () { function initValine () { - let initData = { + const valine = new Valine(Object.assign({ el: '#vcomment', appId: '#{theme.valine.appId}', appKey: '#{theme.valine.appKey}', @@ -21,18 +20,9 @@ script. emojiMaps: !{emojiMaps}, enableQQ: #{theme.valine.enableQQ}, path: window.location.pathname, - } - - if (!{Boolean(theme.valine.requiredFields)}) { - initData.requiredFields= ('!{theme.valine.requiredFields}'.split(',')) - } - - if (!{Boolean(option)}) { - const otherData = !{option} - initData = Object.assign(initData, otherData) - } - - const valine = new Valine(initData) + requiredFields: [!{theme.valine.requiredFields ? JSON.stringify(theme.valine.requiredFields).split(',') : ''}], + visitor: #{theme.valine.visitor} + }, !{JSON.stringify(theme.valine.option)})) } if (typeof Valine === 'function') initValine() diff --git a/layout/includes/third-party/comments/waline.pug b/layout/includes/third-party/comments/waline.pug index 027a312..9588049 100644 --- a/layout/includes/third-party/comments/waline.pug +++ b/layout/includes/third-party/comments/waline.pug @@ -1,4 +1,3 @@ -- let option = theme.waline.option ? JSON.stringify(theme.waline.option) : false - let emojiMaps = '""' if site.data.waline - emojiMaps = JSON.stringify(site.data.waline) @@ -6,21 +5,15 @@ if site.data.waline script. function loadWaline () { function initWaline () { - let initData = { + const waline = new Waline(Object.assign({ el: '#waline-wrap', serverURL: '!{theme.waline.serverURL}', avatar: '#{theme.waline.avatar}', path: location.pathname, emojiCDN: '#{theme.waline.emojiCDN}', emojiMaps: !{emojiMaps}, - } - - if (!{Boolean(option)}) { - const otherData = !{option} - initData = Object.assign(initData, otherData) - } - - const waline = new Waline(initData) + visitor: #{theme.waline.visitor} + }, !{JSON.stringify(theme.waline.option)})) } if (typeof Waline === 'function') initWaline() diff --git a/layout/includes/third-party/pjax.pug b/layout/includes/third-party/pjax.pug index 92c389c..853c627 100644 --- a/layout/includes/third-party/pjax.pug +++ b/layout/includes/third-party/pjax.pug @@ -42,9 +42,11 @@ script. typeof chatBtnFn === 'function' && chatBtnFn() typeof panguInit === 'function' && panguInit() - if (typeof gtag === 'function') { - gtag('config', '!{theme.google_analytics}', {'page_path': window.location.pathname}); - } + // google analytics + typeof gtag === 'function' && gtag('config', '!{theme.google_analytics}', {'page_path': window.location.pathname}); + + // baidu analytics + typeof _hmt === 'object' && _hmt.push(['_trackPageview',window.location.pathname]); typeof loadMeting === 'function' && document.getElementsByClassName('aplayer').length && loadMeting() diff --git a/layout/includes/third-party/subtitle.pug b/layout/includes/third-party/subtitle.pug index 84830d1..ee0f583 100644 --- a/layout/includes/third-party/subtitle.pug +++ b/layout/includes/third-party/subtitle.pug @@ -69,7 +69,7 @@ case source when 3 script. function subtitleType () { - getScript('http://yijuzhan.com/api/word.php?m=js').then(() => { + getScript('https://yijuzhan.com/api/word.php?m=js').then(() => { var con = str[0] if (!{theme.subtitle.effect}) { var from = '出自 ' + str[1] diff --git a/layout/includes/widget/card_author.pug b/layout/includes/widget/card_author.pug index 933b7ce..b694bd8 100644 --- a/layout/includes/widget/card_author.pug +++ b/layout/includes/widget/card_author.pug @@ -4,7 +4,7 @@ if theme.aside.card_author.enable if theme.lazyload.enable img.avatar-img(data-lazy-src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar") else - img.avatar-img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar") + img.avatar-img(src=url_for(theme.avatar.img) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt="avatar") .author-info__name= config.author .author-info__description!= theme.aside.card_author.description || config.description diff --git a/layout/includes/widget/card_tags.pug b/layout/includes/widget/card_tags.pug index 2293d82..de40e90 100644 --- a/layout/includes/widget/card_tags.pug +++ b/layout/includes/widget/card_tags.pug @@ -7,6 +7,6 @@ if theme.aside.card_tags.enable - let tagLimit = theme.aside.card_tags.limit === 0 ? 0 : theme.aside.card_tags.limit || 40 if theme.aside.card_tags.color - .card-tag-cloud!= cloudTags({source: site.tags, minfontsize: 1.1, maxfontsize: 1.5, limit: tagLimit, unit: 'em'}) + .card-tag-cloud!= cloudTags({source: site.tags, minfontsize: 1.15, maxfontsize: 1.45, limit: tagLimit, unit: 'em'}) else .card-tag-cloud!= tagcloud({min_font: 1.1, max_font: 1.5, amount: tagLimit , color: true, start_color: '#999', end_color: '#99a9bf', unit: 'em'}) diff --git a/layout/page.pug b/layout/page.pug index 7287546..2fb8b7e 100644 --- a/layout/page.pug +++ b/layout/page.pug @@ -9,8 +9,6 @@ block content include includes/page/flink.pug when 'categories' include includes/page/categories.pug - when 'artitalk' - include includes/page/artitalk.pug default include includes/page/default-page.pug diff --git a/package.json b/package.json index 4421098..ac48e90 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hexo-theme-butterfly", - "version": "3.6.2", + "version": "3.7.0", "description": "A Simple and Card UI Design theme for Hexo", "main": "package.json", "scripts": { diff --git a/scripts/filters/random_cover.js b/scripts/filters/random_cover.js index 8455d60..827059f 100644 --- a/scripts/filters/random_cover.js +++ b/scripts/filters/random_cover.js @@ -39,7 +39,7 @@ function randomCover () { return cover } } else { - cover = 'https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg' + cover = theme.default_top_img || 'https://cdn.jsdelivr.net/npm/butterfly-extsrc@1/img/default.jpg' return cover } } diff --git a/scripts/tag/inlineImg.js b/scripts/tag/inlineImg.js new file mode 100644 index 0000000..9bcbfdb --- /dev/null +++ b/scripts/tag/inlineImg.js @@ -0,0 +1,17 @@ +/** + * inlineImg 圖片 + * {% inlineImg src height %} + */ + +'use strict' + +const urlFor = require('hexo-util').url_for.bind(hexo) + +function inlineImg (args) { + const img = args[0] + const height = args[1] ? `style="height:${args[1]}"` : '' + + return `` +} + +hexo.extend.tag.register('inlineImg', inlineImg, { ends: false }) diff --git a/source/css/_highlight/highlight.styl b/source/css/_highlight/highlight.styl index 29e9f27..5f82677 100644 --- a/source/css/_highlight/highlight.styl +++ b/source/css/_highlight/highlight.styl @@ -1,4 +1,3 @@ -// https://github.com/equinusocio/vsc-material-theme $highlight_theme = hexo-config('highlight_theme') $highlighEnable = hexo-config('highlight_settings') && hexo-config('highlight_settings.enable') $prismjsEnable = hexo-config('prismjs_settings') && hexo-config('prismjs_settings.enable') @@ -6,6 +5,16 @@ wordWrap = !hexo-config('highlight_settings.line_number') && hexo-config('code_w @require 'theme' +:root + --hl-color: $highlight-foreground + --hl-bg: $highlight-background + --hltools-bg: $highlight-tools.bg-color + --hltools-color: $highlight-tools.color + --hlnumber-bg: $highlight-gutter.bg-color + --hlnumber-color: $highlight-gutter.color + --hlscrollbar-bg: $highlight-scrollbar + --hlexpand-bg: linear-gradient(180deg, rgba($highlight-background, .6), rgba($highlight-background, .9)) + if $highlighEnable @require 'highlight/index' @@ -16,8 +25,8 @@ $code-block overflow: auto margin: 0 0 1rem padding: 0 - background: $highlight-background - color: $highlight-foreground + background: var(--hl-bg) + color: var(--hl-color) line-height: $line-height-code-block if wordWrap @@ -56,9 +65,6 @@ blockquote padding: .1rem .2rem background: $code-background color: $code-foreground - word-wrap: break-word - word-break: break-word - overflow-wrap: break-word pre @extend $code-block @@ -67,7 +73,7 @@ blockquote code padding: 0 background: none - color: $highlight-foreground + color: var(--hl-color) text-shadow: none figure.highlight @@ -88,10 +94,10 @@ blockquote a float: right padding-right: 10px - color: $highlight-foreground + color: var(--hl-color) &:hover - border-bottom-color: $highlight-foreground + border-bottom-color: var(--hl-color) .highlight-tools position: relative @@ -100,8 +106,8 @@ blockquote overflow: hidden min-height: 1.2rem height: 2.15em - background: $highlight-tools.bg-color - color: $highlight-tools.color + background: var(--hltools-bg) + color: var(--hltools-color) font-size: $code-font-size &.closed + table @@ -185,3 +191,38 @@ blockquote .code-lang left: 3.8rem !important + + if hexo-config('highlight_height_limit') + .code-expand-btn + position: absolute + bottom: 0 + z-index: 10 + width: 100% + background: var(--hlexpand-bg) + text-align: center + font-size: $code-font-size + cursor: pointer + + i + padding: .3rem 0 + color: var(--hlnumber-color) + animation: code-expand-key 1.2s infinite + + &.expand-done + display: none !important + + &:not(.expand-done) + & ~ table, + & ~ pre + overflow: hidden + height: unit(hexo-config('highlight_height_limit'), px) + +@keyframes code-expand-key + 0% + opacity: .6 + + 50% + opacity: .1 + + 100% + opacity: .6 \ No newline at end of file diff --git a/source/css/_highlight/highlight/diff.styl b/source/css/_highlight/highlight/diff.styl index 486754c..6a6eefe 100644 --- a/source/css/_highlight/highlight/diff.styl +++ b/source/css/_highlight/highlight/diff.styl @@ -1,7 +1,7 @@ figure.highlight table &::-webkit-scrollbar-thumb - background: $highlight-scrollbar + background: var(--hlscrollbar-bg) pre .deletion color: $highlight-deletion diff --git a/source/css/_highlight/highlight/index.styl b/source/css/_highlight/highlight/index.styl index 9c3d4f9..cb214c0 100644 --- a/source/css/_highlight/highlight/index.styl +++ b/source/css/_highlight/highlight/index.styl @@ -9,7 +9,7 @@ if $highlight_theme != false display: inline-block padding: 0 .3rem 0 0 min-width: 1.6rem - color: $highlight-gutter.color + color: var(--hlnumber-color) content: counter(line) counter-increment: line text-align: left @@ -29,8 +29,8 @@ if $highlight_theme != false .gutter pre padding-right: .5rem padding-left: .5rem - background-color: $highlight-gutter.bg-color - color: $highlight-gutter.color + background-color: var(--hlnumber-bg) + color: var(--hlnumber-color) text-align: right .code pre diff --git a/source/css/_highlight/prismjs/index.styl b/source/css/_highlight/prismjs/index.styl index 5ac7f4f..b21c5bf 100644 --- a/source/css/_highlight/prismjs/index.styl +++ b/source/css/_highlight/prismjs/index.styl @@ -7,7 +7,7 @@ if $highlight_theme != false #article-container pre[class*='language-'] &::-webkit-scrollbar-thumb - background: $highlight-scrollbar + background: var(--hlscrollbar-bg) &:not(.line-numbers) padding: 10px 20px diff --git a/source/css/_highlight/prismjs/line-number.styl b/source/css/_highlight/prismjs/line-number.styl index a6bd858..69f2787 100644 --- a/source/css/_highlight/prismjs/line-number.styl +++ b/source/css/_highlight/prismjs/line-number.styl @@ -8,9 +8,16 @@ > code position: relative - white-space: inherit line-height: $line-height-code-block + if hexo-config('code_word_wrap') + white-space: pre-wrap + else + white-space: inherit + word-wrap: normal + word-break: normal + overflow-wrap: normal + .line-numbers-rows position: absolute top: 0 @@ -29,6 +36,6 @@ &:before display: block padding-right: .8em - color: $highlight-gutter.color + color: var(--hlnumber-color) content: counter(linenumber) text-align: right diff --git a/source/css/_layout/aside.styl b/source/css/_layout/aside.styl index cee1701..6198f62 100644 --- a/source/css/_layout/aside.styl +++ b/source/css/_layout/aside.styl @@ -115,7 +115,7 @@ .card-tag-cloud a display: inline-block - padding: 0 .1rem + padding: 0 .2rem &:hover color: $text-hover !important diff --git a/source/css/_layout/head.styl b/source/css/_layout/head.styl index 37ca649..d9cb609 100644 --- a/source/css/_layout/head.styl +++ b/source/css/_layout/head.styl @@ -303,22 +303,6 @@ _:future, padding: 4px transition: transform .3s - & > a - &:after - position: absolute - bottom: 0 - left: 0 - z-index: -1 - width: 0 - height: 3px - background-color: lighten($theme-color, 30%) - content: '' - transition: all .3s ease-in-out - - &:hover - &:after - width: 100% - .menus_item_child position: absolute right: 0 @@ -377,3 +361,19 @@ _:future, text-shadow: .05rem .05rem .1rem rgba($dark-black, .3) font-size: .78em cursor: pointer + + &:not(.child) + &:after + position: absolute + bottom: 0 + left: 0 + z-index: -1 + width: 0 + height: 3px + background-color: lighten($theme-color, 30%) + content: '' + transition: all .3s ease-in-out + + &:hover + &:after + width: 100% diff --git a/source/css/_layout/post.styl b/source/css/_layout/post.styl index bce034a..c4f9099 100644 --- a/source/css/_layout/post.styl +++ b/source/css/_layout/post.styl @@ -161,6 +161,20 @@ no-beautify() iframe margin: 0 0 1rem + kbd + margin: 0 3px + padding: 3px 5px + border: 1px solid #b4b4b4 + border-radius: 3px + background-color: #f8f8f8 + box-shadow: 0 1px 3px rgba(0, 0, 0, .25), 0 2px 1px 0 rgba(255, 255, 255, .6) inset + color: #34495e + white-space: nowrap + font-weight: 600 + font-size: .9em + font-family: Monaco, 'Ubuntu Mono', monospace + line-height: 1em + if hexo-config('beautify.enable') && hexo-config('beautify.field') == 'site' beautify() else if hexo-config('beautify.enable') && hexo-config('beautify.field') == 'post' diff --git a/source/css/_mode/darkmode.styl b/source/css/_mode/darkmode.styl index ad4b4de..da9b673 100644 --- a/source/css/_mode/darkmode.styl +++ b/source/css/_mode/darkmode.styl @@ -27,6 +27,14 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' --blockquote-bg: lighten(#121212, 10) --reward-pop: lighten(#121212, 10) --toc-link-color: alpha(#FFFFFF, .6) + --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)) #web_bg:before, #footer:before, @@ -42,7 +50,10 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' background: #2c2c2c pre > code - background: 0 + background: lighten(#121212, 2) + + figure.highlight + box-shadow: none .note code @@ -51,6 +62,11 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' .aplayer filter: brightness(.8) + kbd + border-color: #696969 + background-color: #525252 + color: #e2f1ff + // 頭部 #page-header &.nav-fixed > #nav, @@ -58,33 +74,6 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' background: alpha(#121212, .8) box-shadow: 0 5px 6px -5px rgba(133, 133, 133, 0) - // 代碼框 - #article-container - pre, - .highlight:not(.js-file-line-container) - background-color: lighten(#121212, 2) !important - color: alpha(#FFFFFF, .7) !important - - figure.highlight - box-shadow: none - - if hexo-config('highlight_settings') && hexo-config('highlight_settings.enable') - table::-webkit-scrollbar-thumb - background: lighten(#121212, 5) - - .line:before - color: alpha(#FFFFFF, .7) !important - - .hljs - background-color: lighten(#121212, 2) !important - - pre[class*='language-']::-webkit-scrollbar-thumb - background: lighten(#121212, 5) - - .highlight-tools - background: lighten(#121212, 3) !important - color: #90a4ae !important - #post-comment #comment-switch if hexo-config('comments.text') @@ -113,16 +102,6 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' #aside-content .aside-list > .aside-list-item:not(:last-child) border-bottom: 1px dashed alpha(#FFFFFF, .1) - // 第三方 - // 插件 hexo-blog-encrypt - #hexo-blog-encrypt - label, - input - color: alpha(#FFFFFF, .7) !important - - input - background-color: #121212 - // Gitalk #gitalk-container filter: brightness(.8) @@ -130,7 +109,7 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' svg fill: alpha(#FFFFFF, .9) !important - // Disqus and Disqusjs + // Disqusjs 反代模式下的適配 #disqus_thread #dsqjs .dsqjs-tab-active, @@ -154,4 +133,4 @@ if hexo-config('darkmode.enable') || hexo-config('display_mode') == 'dark' background: #121212 #operare_artitalk .c2 - background: #121212 \ No newline at end of file + background: #121212 diff --git a/source/css/_mode/readmode.styl b/source/css/_mode/readmode.styl index dbe2308..0ef3b36 100644 --- a/source/css/_mode/readmode.styl +++ b/source/css/_mode/readmode.styl @@ -163,6 +163,12 @@ if hexo-config('readmode') border-left: .2rem solid var(--gray) background-color: var(--readmode-light-color) + kbd + border: 1px solid var(--gray) + background-color: transparent + box-shadow: none + color: var(--font-color) + .hide-toggle border: 1px solid var(--gray) !important diff --git a/source/css/_tags/inlineImg.styl b/source/css/_tags/inlineImg.styl new file mode 100644 index 0000000..c8bb0c1 --- /dev/null +++ b/source/css/_tags/inlineImg.styl @@ -0,0 +1,6 @@ +#article-container + .inline-img + display: inline + margin: 0 3px + height: 1.1em + vertical-align: text-bottom \ No newline at end of file diff --git a/source/css/var.styl b/source/css/var.styl index f3f0267..87e1503 100644 --- a/source/css/var.styl +++ b/source/css/var.styl @@ -28,7 +28,7 @@ $title-prefix-icon = $beautifyEnable ? hexo-config('beautify.title-prefix-icon') $title-prefix-icon-color = $beautifyEnable ? convert(hexo-config('beautify.title-prefix-icon-color')) : $light-red // Global Variables $font-size = hexo-config('font.global-font-size') ? convert(hexo-config('font.global-font-size')) : 14px -$code-font-size = hexo-config('font.code-font-size') ? convert(hexo-config('font.code-font-size')) : $font-size +$code-font-size = hexo-config('font.code-font-size') ? convert(hexo-config('font.code-font-size')) : var(--global-font-size) $font-color = #1F2D3D $rem = 20px $text-line-height = 2 diff --git a/source/js/main.js b/source/js/main.js index da5be46..9658c73 100644 --- a/source/js/main.js +++ b/source/js/main.js @@ -81,123 +81,142 @@ document.addEventListener('DOMContentLoaded', function () { * 只適用於Hexo默認的代碼渲染 */ const addHighlightTool = function () { - const isHighlightCopy = GLOBAL_CONFIG.highlight.highlightCopy - const isHighlightLang = GLOBAL_CONFIG.highlight.highlightLang + const highLight = GLOBAL_CONFIG.highlight + if (!highLight) return + + const isHighlightCopy = highLight.highlightCopy + const isHighlightLang = highLight.highlightLang const isHighlightShrink = GLOBAL_CONFIG_SITE.isHighlightShrink + const highlightHeightLimit = highLight.highlightHeightLimit const isShowTool = isHighlightCopy || isHighlightLang || isHighlightShrink !== undefined - const $figureHighlight = GLOBAL_CONFIG.highlight.plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]') + const $figureHighlight = highLight.plugin === 'highlighjs' ? document.querySelectorAll('figure.highlight') : document.querySelectorAll('pre[class*="language-"]') - if (isShowTool && $figureHighlight.length) { - const isPrismjs = GLOBAL_CONFIG.highlight.plugin === 'prismjs' + if (!((isShowTool || highlightHeightLimit) && $figureHighlight.length)) return - let highlightShrinkEle = '' - let highlightCopyEle = '' - const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' + const isPrismjs = highLight.plugin === 'prismjs' - if (isHighlightShrink !== undefined) { - highlightShrinkEle = `` - } + let highlightShrinkEle = '' + let highlightCopyEle = '' + const highlightShrinkClass = isHighlightShrink === true ? 'closed' : '' - if (isHighlightCopy) { - highlightCopyEle = '
' - } + if (isHighlightShrink !== undefined) { + highlightShrinkEle = `` + } - const copy = (text, ctx) => { - if (document.queryCommandSupported && document.queryCommandSupported('copy')) { - document.execCommand('copy') - if (GLOBAL_CONFIG.Snackbar !== undefined) { - btf.snackbarShow(GLOBAL_CONFIG.copy.success) - } else { - const prevEle = ctx.previousElementSibling - prevEle.innerText = GLOBAL_CONFIG.copy.success - prevEle.style.opacity = 1 - setTimeout(() => { prevEle.style.opacity = 0 }, 700) - } + if (isHighlightCopy) { + highlightCopyEle = '
' + } + + const copy = (text, ctx) => { + if (document.queryCommandSupported && document.queryCommandSupported('copy')) { + document.execCommand('copy') + if (GLOBAL_CONFIG.Snackbar !== undefined) { + btf.snackbarShow(GLOBAL_CONFIG.copy.success) } else { - if (GLOBAL_CONFIG.Snackbar !== undefined) { - btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport) - } else { - ctx.previousElementSibling.innerText = GLOBAL_CONFIG.copy.noSupport - } - } - } - - // click events - const highlightCopyFn = (ele) => { - const $buttonParent = ele.parentNode - $buttonParent.classList.add('copy-true') - const selection = window.getSelection() - const range = document.createRange() - if (isPrismjs) range.selectNodeContents($buttonParent.querySelectorAll('pre code')[0]) - else range.selectNodeContents($buttonParent.querySelectorAll('table .code pre')[0]) - selection.removeAllRanges() - selection.addRange(range) - const text = selection.toString() - copy(text, ele.lastChild) - selection.removeAllRanges() - $buttonParent.classList.remove('copy-true') - } - - const highlightShrinkFn = (ele) => { - const $nextEle = [...ele.parentNode.children].slice(1) - ele.firstChild.classList.toggle('closed') - if (btf.isHidden($nextEle[0])) { - $nextEle.forEach(e => { e.style.display = 'block' }) - } else { - $nextEle.forEach(e => { e.style.display = 'none' }) - } - } - - const highlightToolsFn = function (e) { - const $target = e.target.classList - if ($target.contains('expand')) highlightShrinkFn(this) - else if ($target.contains('copy-button')) highlightCopyFn(this) - } - - const createEle = () => { - const newEle = document.createElement('div') - newEle.className = `highlight-tools ${highlightShrinkClass}` - newEle.addEventListener('click', highlightToolsFn) - return newEle - } - - if (isHighlightLang) { - if (isPrismjs) { - $figureHighlight.forEach(function (item) { - const langName = item.getAttribute('data-language') !== undefined ? item.getAttribute('data-language') : 'Code' - const highlightLangEle = `
${langName}
` - btf.wrap(item, 'figure', '', 'highlight') - const newEle = createEle() - newEle.innerHTML = highlightShrinkEle + highlightLangEle + highlightCopyEle - item.parentNode.insertBefore(newEle, item) - }) - } else { - $figureHighlight.forEach(function (item) { - let langName = item.getAttribute('class').split(' ')[1] - if (langName === 'plain' || langName === undefined) langName = 'Code' - const highlightLangEle = `
${langName}
` - const newEle = createEle() - newEle.innerHTML = highlightShrinkEle + highlightLangEle + highlightCopyEle - item.insertBefore(newEle, item.firstChild) - }) + const prevEle = ctx.previousElementSibling + prevEle.innerText = GLOBAL_CONFIG.copy.success + prevEle.style.opacity = 1 + setTimeout(() => { prevEle.style.opacity = 0 }, 700) } } else { - if (isPrismjs) { - $figureHighlight.forEach(function (item) { - btf.wrap(item, 'figure', '', 'highlight') - const newEle = createEle() - newEle.innerHTML = highlightShrinkEle + highlightCopyEle - item.parentNode.insertBefore(newEle, item) - }) + if (GLOBAL_CONFIG.Snackbar !== undefined) { + btf.snackbarShow(GLOBAL_CONFIG.copy.noSupport) } else { - $figureHighlight.forEach(function (item) { - const newEle = createEle() - newEle.innerHTML = highlightShrinkEle + highlightCopyEle - item.insertBefore(newEle, item.firstChild) - }) + ctx.previousElementSibling.innerText = GLOBAL_CONFIG.copy.noSupport } } } + + // click events + const highlightCopyFn = (ele) => { + const $buttonParent = ele.parentNode + $buttonParent.classList.add('copy-true') + const selection = window.getSelection() + const range = document.createRange() + if (isPrismjs) range.selectNodeContents($buttonParent.querySelectorAll('pre code')[0]) + else range.selectNodeContents($buttonParent.querySelectorAll('table .code pre')[0]) + selection.removeAllRanges() + selection.addRange(range) + const text = selection.toString() + copy(text, ele.lastChild) + selection.removeAllRanges() + $buttonParent.classList.remove('copy-true') + } + + const highlightShrinkFn = (ele) => { + const $nextEle = [...ele.parentNode.children].slice(1) + 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 $target = e.target.classList + if ($target.contains('expand')) highlightShrinkFn(this) + else if ($target.contains('copy-button')) highlightCopyFn(this) + } + + const expandCode = function () { + this.classList.toggle('expand-done') + } + + function createEle (lang, item, service) { + const fragment = document.createDocumentFragment() + + if (isShowTool) { + const hlTools = document.createElement('div') + hlTools.className = `highlight-tools ${highlightShrinkClass}` + hlTools.innerHTML = highlightShrinkEle + lang + highlightCopyEle + hlTools.addEventListener('click', highlightToolsFn) + fragment.appendChild(hlTools) + } + + if (highlightHeightLimit && item.offsetHeight > highlightHeightLimit + 30) { + const ele = document.createElement('div') + ele.className = 'code-expand-btn' + ele.innerHTML = '' + ele.addEventListener('click', expandCode) + fragment.appendChild(ele) + } + + if (service === 'hl') { + item.insertBefore(fragment, item.firstChild) + } else { + item.parentNode.insertBefore(fragment, item) + } + } + + if (isHighlightLang) { + if (isPrismjs) { + $figureHighlight.forEach(function (item) { + const langName = item.getAttribute('data-language') ? item.getAttribute('data-language') : 'Code' + const highlightLangEle = `
${langName}
` + btf.wrap(item, 'figure', '', 'highlight') + createEle(highlightLangEle, item) + }) + } else { + $figureHighlight.forEach(function (item) { + let langName = item.getAttribute('class').split(' ')[1] + if (langName === 'plain' || langName === undefined) langName = 'Code' + const highlightLangEle = `
${langName}
` + createEle(highlightLangEle, item, 'hl') + }) + } + } else { + if (isPrismjs) { + $figureHighlight.forEach(function (item) { + btf.wrap(item, 'figure', '', 'highlight') + createEle('', item) + }) + } else { + $figureHighlight.forEach(function (item) { + createEle('', item, 'hl') + }) + } + } } /** @@ -819,7 +838,7 @@ document.addEventListener('DOMContentLoaded', function () { sidebarFn() GLOBAL_CONFIG_SITE.isHome && scrollDownInIndex() - GLOBAL_CONFIG.highlight && addHighlightTool() + addHighlightTool() GLOBAL_CONFIG.isPhotoFigcaption && addPhotoFigcaption() jqLoadAndRun() GLOBAL_CONFIG.lightbox === 'mediumZoom' && addMediumZoom()