From 3ed87f0a271360112236ce6a8dcb72543705bba9 Mon Sep 17 00:00:00 2001 From: FoxerLee Date: Mon, 5 Oct 2020 11:00:02 -0400 Subject: [PATCH 1/5] :sparkles: add gitalk support --- _config.yml | 18 ++- layout/_page/post.ejs | 4 + layout/_partials/gitalk.ejs | 20 +++ layout/_partials/head.ejs | 6 +- source/js/md5.js | 280 ++++++++++++++++++++++++++++++++++++ 5 files changed, 325 insertions(+), 3 deletions(-) create mode 100644 layout/_partials/gitalk.ejs create mode 100755 source/js/md5.js diff --git a/_config.yml b/_config.yml index 72e9f42..9f71551 100644 --- a/_config.yml +++ b/_config.yml @@ -83,7 +83,21 @@ stylesheets: # scripts loaded in the end of the body scripts: - /js/hexo-theme-terran.js - +- /js/md5.js + +gitalk: + enable: true + ClientID: # Client ID + ClientSecret: # Client Secret + repo: # repo which stores your blog + owner: FoxerLee # Github account name + adminUser: ['FoxerLee'] + ID: location.pathname + labels: ['Gitalk'] # GitHub issues' tag + perPage: 10 # How many comments in per page + pagerDirection: last # first - old to new; last - new to old + createIssueManually: false # if need admin user to create issue + distractionFreeMode: false # if cmd|ctrl + enter can submit comment about: avatar: /images/avatar.jpeg @@ -98,4 +112,4 @@ about: 3: Research Intern, National Instruments 4: Software Intern, Microsoft interest: Machine Learning, Computer Vision, OCR, Segmentation, Few-shot Learning, Cybersecurity, Coding, Reading, Dota2, Fitness - github_chart: Foxerlee \ No newline at end of file + github_chart: Foxerlee diff --git a/layout/_page/post.ejs b/layout/_page/post.ejs index d0929b2..da24dae 100644 --- a/layout/_page/post.ejs +++ b/layout/_page/post.ejs @@ -70,4 +70,8 @@ <% } %> + + <% if (theme.gitalk.enable) { %> + <%- partial('_partials/gitalk') %> + <% } %> \ No newline at end of file diff --git a/layout/_partials/gitalk.ejs b/layout/_partials/gitalk.ejs new file mode 100644 index 0000000..c09ed42 --- /dev/null +++ b/layout/_partials/gitalk.ejs @@ -0,0 +1,20 @@ +
+ + + + \ No newline at end of file diff --git a/layout/_partials/head.ejs b/layout/_partials/head.ejs index 9b2f87b..812ab80 100644 --- a/layout/_partials/head.ejs +++ b/layout/_partials/head.ejs @@ -17,5 +17,9 @@ if (is_tag()){ + +<% if (is_post()) { %> + +<% } %> -<%- partial('_partials/mathjax',{cache: true}) %> \ No newline at end of file +<%- partial('_partials/mathjax',{cache: true}) %> diff --git a/source/js/md5.js b/source/js/md5.js new file mode 100755 index 0000000..762de3c --- /dev/null +++ b/source/js/md5.js @@ -0,0 +1,280 @@ +/* + * JavaScript MD5 + * https://github.com/blueimp/JavaScript-MD5 + * + * Copyright 2011, Sebastian Tschan + * https://blueimp.net + * + * Licensed under the MIT license: + * https://opensource.org/licenses/MIT + * + * Based on + * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message + * Digest Algorithm, as defined in RFC 1321. + * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009 + * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet + * Distributed under the BSD License + * See http://pajhome.org.uk/crypt/md5 for more info. + */ + +/* global define */ + +;(function ($) { + 'use strict' + + /* + * Add integers, wrapping at 2^32. This uses 16-bit operations internally + * to work around bugs in some JS interpreters. + */ + function safeAdd (x, y) { + var lsw = (x & 0xffff) + (y & 0xffff) + var msw = (x >> 16) + (y >> 16) + (lsw >> 16) + return (msw << 16) | (lsw & 0xffff) + } + + /* + * Bitwise rotate a 32-bit number to the left. + */ + function bitRotateLeft (num, cnt) { + return (num << cnt) | (num >>> (32 - cnt)) + } + + /* + * These functions implement the four basic operations the algorithm uses. + */ + function md5cmn (q, a, b, x, s, t) { + return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b) + } + function md5ff (a, b, c, d, x, s, t) { + return md5cmn((b & c) | (~b & d), a, b, x, s, t) + } + function md5gg (a, b, c, d, x, s, t) { + return md5cmn((b & d) | (c & ~d), a, b, x, s, t) + } + function md5hh (a, b, c, d, x, s, t) { + return md5cmn(b ^ c ^ d, a, b, x, s, t) + } + function md5ii (a, b, c, d, x, s, t) { + return md5cmn(c ^ (b | ~d), a, b, x, s, t) + } + + /* + * Calculate the MD5 of an array of little-endian words, and a bit length. + */ + function binlMD5 (x, len) { + /* append padding */ + x[len >> 5] |= 0x80 << (len % 32) + x[((len + 64) >>> 9 << 4) + 14] = len + + var i + var olda + var oldb + var oldc + var oldd + var a = 1732584193 + var b = -271733879 + var c = -1732584194 + var d = 271733878 + + for (i = 0; i < x.length; i += 16) { + olda = a + oldb = b + oldc = c + oldd = d + + a = md5ff(a, b, c, d, x[i], 7, -680876936) + d = md5ff(d, a, b, c, x[i + 1], 12, -389564586) + c = md5ff(c, d, a, b, x[i + 2], 17, 606105819) + b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330) + a = md5ff(a, b, c, d, x[i + 4], 7, -176418897) + d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426) + c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341) + b = md5ff(b, c, d, a, x[i + 7], 22, -45705983) + a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416) + d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417) + c = md5ff(c, d, a, b, x[i + 10], 17, -42063) + b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162) + a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682) + d = md5ff(d, a, b, c, x[i + 13], 12, -40341101) + c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290) + b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329) + + a = md5gg(a, b, c, d, x[i + 1], 5, -165796510) + d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632) + c = md5gg(c, d, a, b, x[i + 11], 14, 643717713) + b = md5gg(b, c, d, a, x[i], 20, -373897302) + a = md5gg(a, b, c, d, x[i + 5], 5, -701558691) + d = md5gg(d, a, b, c, x[i + 10], 9, 38016083) + c = md5gg(c, d, a, b, x[i + 15], 14, -660478335) + b = md5gg(b, c, d, a, x[i + 4], 20, -405537848) + a = md5gg(a, b, c, d, x[i + 9], 5, 568446438) + d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690) + c = md5gg(c, d, a, b, x[i + 3], 14, -187363961) + b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501) + a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467) + d = md5gg(d, a, b, c, x[i + 2], 9, -51403784) + c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473) + b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734) + + a = md5hh(a, b, c, d, x[i + 5], 4, -378558) + d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463) + c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562) + b = md5hh(b, c, d, a, x[i + 14], 23, -35309556) + a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060) + d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353) + c = md5hh(c, d, a, b, x[i + 7], 16, -155497632) + b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640) + a = md5hh(a, b, c, d, x[i + 13], 4, 681279174) + d = md5hh(d, a, b, c, x[i], 11, -358537222) + c = md5hh(c, d, a, b, x[i + 3], 16, -722521979) + b = md5hh(b, c, d, a, x[i + 6], 23, 76029189) + a = md5hh(a, b, c, d, x[i + 9], 4, -640364487) + d = md5hh(d, a, b, c, x[i + 12], 11, -421815835) + c = md5hh(c, d, a, b, x[i + 15], 16, 530742520) + b = md5hh(b, c, d, a, x[i + 2], 23, -995338651) + + a = md5ii(a, b, c, d, x[i], 6, -198630844) + d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415) + c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905) + b = md5ii(b, c, d, a, x[i + 5], 21, -57434055) + a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571) + d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606) + c = md5ii(c, d, a, b, x[i + 10], 15, -1051523) + b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799) + a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359) + d = md5ii(d, a, b, c, x[i + 15], 10, -30611744) + c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380) + b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649) + a = md5ii(a, b, c, d, x[i + 4], 6, -145523070) + d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379) + c = md5ii(c, d, a, b, x[i + 2], 15, 718787259) + b = md5ii(b, c, d, a, x[i + 9], 21, -343485551) + + a = safeAdd(a, olda) + b = safeAdd(b, oldb) + c = safeAdd(c, oldc) + d = safeAdd(d, oldd) + } + return [a, b, c, d] + } + + /* + * Convert an array of little-endian words to a string + */ + function binl2rstr (input) { + var i + var output = '' + var length32 = input.length * 32 + for (i = 0; i < length32; i += 8) { + output += String.fromCharCode((input[i >> 5] >>> (i % 32)) & 0xff) + } + return output + } + + /* + * Convert a raw string to an array of little-endian words + * Characters >255 have their high-byte silently ignored. + */ + function rstr2binl (input) { + var i + var output = [] + output[(input.length >> 2) - 1] = undefined + for (i = 0; i < output.length; i += 1) { + output[i] = 0 + } + var length8 = input.length * 8 + for (i = 0; i < length8; i += 8) { + output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << (i % 32) + } + return output + } + + /* + * Calculate the MD5 of a raw string + */ + function rstrMD5 (s) { + return binl2rstr(binlMD5(rstr2binl(s), s.length * 8)) + } + + /* + * Calculate the HMAC-MD5, of a key and some data (raw strings) + */ + function rstrHMACMD5 (key, data) { + var i + var bkey = rstr2binl(key) + var ipad = [] + var opad = [] + var hash + ipad[15] = opad[15] = undefined + if (bkey.length > 16) { + bkey = binlMD5(bkey, key.length * 8) + } + for (i = 0; i < 16; i += 1) { + ipad[i] = bkey[i] ^ 0x36363636 + opad[i] = bkey[i] ^ 0x5c5c5c5c + } + hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8) + return binl2rstr(binlMD5(opad.concat(hash), 512 + 128)) + } + + /* + * Convert a raw string to a hex string + */ + function rstr2hex (input) { + var hexTab = '0123456789abcdef' + var output = '' + var x + var i + for (i = 0; i < input.length; i += 1) { + x = input.charCodeAt(i) + output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f) + } + return output + } + + /* + * Encode a string as utf-8 + */ + function str2rstrUTF8 (input) { + return unescape(encodeURIComponent(input)) + } + + /* + * Take string arguments and return either raw or hex encoded strings + */ + function rawMD5 (s) { + return rstrMD5(str2rstrUTF8(s)) + } + function hexMD5 (s) { + return rstr2hex(rawMD5(s)) + } + function rawHMACMD5 (k, d) { + return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d)) + } + function hexHMACMD5 (k, d) { + return rstr2hex(rawHMACMD5(k, d)) + } + + function md5 (string, key, raw) { + if (!key) { + if (!raw) { + return hexMD5(string) + } + return rawMD5(string) + } + if (!raw) { + return hexHMACMD5(key, string) + } + return rawHMACMD5(key, string) + } + + if (typeof define === 'function' && define.amd) { + define(function () { + return md5 + }) + } else if (typeof module === 'object' && module.exports) { + module.exports = md5 + } else { + $.md5 = md5 + } +})(this) From d03fdf008de6dde02fbb340dcb48a691430bb9b1 Mon Sep 17 00:00:00 2001 From: FoxerLee Date: Tue, 6 Oct 2020 23:21:06 -0400 Subject: [PATCH 2/5] :sparkles: favicon support --- .travis.yml | 7 ++++++- _config.yml | 2 ++ layout/_partials/head.ejs | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index e6b0a57..ea94bf9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,4 +21,9 @@ before_script: script: - cd ../../ - - hexo g \ No newline at end of file + - hexo g + + +branches: + only: + - master \ No newline at end of file diff --git a/_config.yml b/_config.yml index 9f71551..e7b7e9d 100644 --- a/_config.yml +++ b/_config.yml @@ -14,6 +14,8 @@ menu: Friends: /friends About: /about +favicon: /images/logo.jpeg + # Profile profile_title: Foxerlee's Journal diff --git a/layout/_partials/head.ejs b/layout/_partials/head.ejs index 812ab80..de9559a 100644 --- a/layout/_partials/head.ejs +++ b/layout/_partials/head.ejs @@ -23,3 +23,7 @@ if (is_tag()){ <% } %> <%- partial('_partials/mathjax',{cache: true}) %> + +<% if (theme.favicon){ %> + +<% } %> \ No newline at end of file From 8e197a764ad8a9a00a20146d5ca35f38a7b2855a Mon Sep 17 00:00:00 2001 From: FoxerLee Date: Wed, 7 Oct 2020 19:28:43 -0400 Subject: [PATCH 3/5] :bug: fix gitalk ID not correct --- layout/_partials/gitalk.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/layout/_partials/gitalk.ejs b/layout/_partials/gitalk.ejs index c09ed42..45a03af 100644 --- a/layout/_partials/gitalk.ejs +++ b/layout/_partials/gitalk.ejs @@ -9,7 +9,7 @@ repo: '<%= theme.gitalk.repo %>', owner: '<%= theme.gitalk.owner %>', admin: '<%= theme.gitalk.adminUser %>', - id: md5('<%= theme.gitalk.ID %>'), + id: md5(<%= theme.gitalk.ID %>), labels: '<%= theme.gitalk.labels %>'.split(',').filter(l => l), perPage: <%= theme.gitalk.perPage %>, pagerDirection: '<%= theme.gitalk.pagerDirection %>', From 10a8ad1c5e2c672407ae4441e53801f18766bc67 Mon Sep 17 00:00:00 2001 From: FoxerLee Date: Mon, 12 Oct 2020 10:56:19 -0400 Subject: [PATCH 4/5] :zap: lazyload support --- _config.yml | 6 ++++++ scripts/index.js | 5 +++++ scripts/lazyLoad.js | 12 ++++++++++++ scripts/lazyProcess.js | 21 +++++++++++++++++++++ scripts/replace.js | 12 ++++++------ source/js/lazyLoad.js | 29 +++++++++++++++++++++++++++++ source/loading.gif | Bin 0 -> 13999 bytes 7 files changed, 79 insertions(+), 6 deletions(-) create mode 100644 scripts/index.js create mode 100644 scripts/lazyLoad.js create mode 100644 scripts/lazyProcess.js create mode 100644 source/js/lazyLoad.js create mode 100644 source/loading.gif diff --git a/_config.yml b/_config.yml index e7b7e9d..e29f922 100644 --- a/_config.yml +++ b/_config.yml @@ -86,6 +86,7 @@ stylesheets: scripts: - /js/hexo-theme-terran.js - /js/md5.js +- /js/lazyLoad.js gitalk: enable: true @@ -115,3 +116,8 @@ about: 4: Software Intern, Microsoft interest: Machine Learning, Computer Vision, OCR, Segmentation, Few-shot Learning, Cybersecurity, Coding, Reading, Dota2, Fitness github_chart: Foxerlee + +lazyload: + enable: true + onlypost: false + loadingImage: https://cdn.jsdelivr.net/npm/skx@0.0.9/img/lazy.gif diff --git a/scripts/index.js b/scripts/index.js new file mode 100644 index 0000000..366f685 --- /dev/null +++ b/scripts/index.js @@ -0,0 +1,5 @@ + +hexo.on('generateBefore', function () { + require('./replace').replace(hexo); + require('./lazyLoad').lazyload(hexo); + }) diff --git a/scripts/lazyLoad.js b/scripts/lazyLoad.js new file mode 100644 index 0000000..851e322 --- /dev/null +++ b/scripts/lazyLoad.js @@ -0,0 +1,12 @@ +'use strict'; + +module.exports.lazyload = function (hexo) { + if (!hexo.theme.config.lazyload || !hexo.theme.config.lazyload.enable) { + return; + } + if (hexo.theme.config.lazyload.onlypost) { + hexo.extend.filter.register('after_post_render', require('./lazyProcess').processPost); + } else { + hexo.extend.filter.register('after_render:html', require('./lazyProcess').processSite); + } +} \ No newline at end of file diff --git a/scripts/lazyProcess.js b/scripts/lazyProcess.js new file mode 100644 index 0000000..96228f4 --- /dev/null +++ b/scripts/lazyProcess.js @@ -0,0 +1,21 @@ +'use strict'; + +function lazyProcess(htmlContent) { + let loadingImage = this.theme.config.lazyload.loadingImage; + let className = 'lazyload'; + return htmlContent.replace(/]*)src="([^"]*)"([^>]*)>/gim, function (match, attrBegin, src, attrEnd) { + if (!src || /class="(.*?)"/gi.test(match)) { + return match; + } + return ``; + }); +} + +module.exports.processPost = function(data) { + data.content = lazyProcess.call(this, data.content); + return data; +}; + +module.exports.processSite = function (htmlContent) { + return lazyProcess.call(this, htmlContent); +}; \ No newline at end of file diff --git a/scripts/replace.js b/scripts/replace.js index b5b2749..7511518 100644 --- a/scripts/replace.js +++ b/scripts/replace.js @@ -1,9 +1,9 @@ /** * Note: configs in _data/temp.yml will replace configs in hexo.theme.config. */ -hexo.on('generateBefore', function () { - if (hexo.locals.get) { - var data = hexo.locals.get('data') // 获取_data文件夹下的内容 - data && data.temp && (hexo.theme.config = data.temp) // 如果temp.yml 存在,就把内容替换掉主题的config - } - }) \ No newline at end of file +module.exports.replace = function (hexo) { + if (hexo.locals.get) { + var data = hexo.locals.get('data') // 获取_data文件夹下的内容 + data && data.temp && (hexo.theme.config = data.temp) // 如果temp.yml 存在,就把内容替换掉主题的config + } +} \ No newline at end of file diff --git a/source/js/lazyLoad.js b/source/js/lazyLoad.js new file mode 100644 index 0000000..9cdebbd --- /dev/null +++ b/source/js/lazyLoad.js @@ -0,0 +1,29 @@ +document.addEventListener("DOMContentLoaded", function() { + var lazyloadImages = document.querySelectorAll("img.lazyload"); + var lazyloadThrottleTimeout; + + function lazyload () { + if(lazyloadThrottleTimeout) { + clearTimeout(lazyloadThrottleTimeout); + } + + lazyloadThrottleTimeout = setTimeout(function() { + var scrollTop = window.pageYOffset; + lazyloadImages.forEach(function(img) { + if(img.offsetTop < (window.innerHeight + scrollTop)) { + img.setAttribute('src', img.getAttribute('data-src')); + img.classList.remove('lazyload'); + } + }); + if(lazyloadImages.length == 0) { + document.removeEventListener("scroll", lazyload); + window.removeEventListener("resize", lazyload); + window.removeEventListener("orientationChange", lazyload); + } + }, 20); + } + + document.addEventListener("scroll", lazyload); + window.addEventListener("resize", lazyload); + window.addEventListener("orientationChange", lazyload); + }); diff --git a/source/loading.gif b/source/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..071ecd65ad5be0414dd952d84d0ba298e76dc59e GIT binary patch literal 13999 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 literal 0 HcmV?d00001 From d602438717db4a3624ca7e495352614351c25491 Mon Sep 17 00:00:00 2001 From: FoxerLee Date: Sat, 17 Oct 2020 12:13:23 -0400 Subject: [PATCH 5/5] :memo: update changlog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b89c5d..dd81069 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # 更新日志 +## v0.9.1 (Oct-17-2020) + +- 增加 gitalk 支持 +- 可自定义 favicon +- 增加 lazyload 支持 + ## v0.8.2 (Sep-30-2020) - 修复了主页文章顺序错误的 bug