diff --git a/_config.template.yml b/_config.template.yml index 852167cfb..6b21b5073 100644 --- a/_config.template.yml +++ b/_config.template.yml @@ -197,4 +197,4 @@ busuanzi: enable: false all_site_uv: false post_pv: false - busuanzi_pure_mini_js: "https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js" + busuanzi_pure_mini_js: "https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js" \ No newline at end of file diff --git a/layout/_partial/Paradox-post-thumbnail.ejs b/layout/_partial/Paradox-post-thumbnail.ejs index 5198193b1..1eefb8183 100644 --- a/layout/_partial/Paradox-post-thumbnail.ejs +++ b/layout/_partial/Paradox-post-thumbnail.ejs @@ -1,4 +1,4 @@ - - + <%- jsLsload(theme.materialcdn.base + '/js/jquery.min.js') %> + <%- jsLsload(theme.materialcdn.base + '/js/queue.js') %> <%}else{%> - <%- css('css/material.min') %> - <%- css('css/style.min') %> + <%- cssLsload('css/material.min') %> + <%- cssLsload('css/style.min') %> <%- partial('_partial/config_css') %> - <%- js('js/jquery.min') %> - <%- js('js/queue') %> + <%- jsLsload('js/jquery.min') %> + <%- jsLsload('js/queue') %> <%}%> <% if(theme.analytics.baidu_id) { %> diff --git a/layout/_partial/import_js.ejs b/layout/_partial/import_js.ejs index caaa962db..ab7ebc183 100644 --- a/layout/_partial/import_js.ejs +++ b/layout/_partial/import_js.ejs @@ -1,19 +1,20 @@ + <% if(theme.materialcdn.use === true) { %> - - + <%- jsLsload(theme.materialcdn.base + "/js/lazyload.min.js") %> + <%- jsLsload(theme.materialcdn.base + "/js/js.min.js") %> <%}else{%> - <%- js('js/lazyload.min') %> - <%- js('js/js.min') %> + <%- jsLsload('js/lazyload.min.js') %> + <%- jsLsload('js/js.min') %> <%}%> <%- partial('_widget/nprogress') %> <% if( theme.js_effect.smoothscroll === true ) { %> <% if(theme.materialcdn.use === true) { %> - + <%- jsLsload(theme.materialcdn.base + "/js/smoothscroll.js") %> <%}else{%> - <%- js('js/smoothscroll') %> + <%- jsLsload('js/smoothscroll') %> <%}%> <% } %> @@ -29,7 +30,7 @@ <% if( theme.search.use === 'local' ) { %> <%- partial('_widget/search-local-js') %> - - diff --git a/layout/_widget/disqus.ejs b/layout/_widget/disqus.ejs index da7116408..10f113bba 100644 --- a/layout/_widget/disqus.ejs +++ b/layout/_widget/disqus.ejs @@ -1,5 +1,5 @@
- - + <%- jsLsload(theme.materialcdn.base + "/js/nprogress.js") %> <%}else{%> - <%- js('js/nprogress') %> + <%- jsLsload('js/nprogress') %> <%}%> - - - + <%- jsLsload(theme.materialcdn.base + "/js/jquery.min.js") %> + <%- jsLsload(theme.materialcdn.base + "/js/gallery/gallery.js") %> + <%- jsLsload(theme.materialcdn.base + "/js/lazyload.min.js") %> <%}else{%> - <%- js('js/jquery.min') %> - <%- js('js/gallery/gallery') %> - <%- js('js/lazyload.min') %> + <%- jsLsload('js/jquery.min') %> + <%- jsLsload('js/gallery/gallery') %> + <%- jsLsload('js/lazyload.min') %> <%}%> - ' + } + } + return result; +} + +module.exports = cssHelper; \ No newline at end of file diff --git a/scripts/lib/font_lsload.js b/scripts/lib/font_lsload.js new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/lib/get_file_hex.js b/scripts/lib/get_file_hex.js new file mode 100644 index 000000000..ce06283d0 --- /dev/null +++ b/scripts/lib/get_file_hex.js @@ -0,0 +1,14 @@ +var fs = require('fs'); +var crypto = require('crypto'); + + +function getFileHexSync(filepath) { + var buffer = fs.readFileSync(filepath); + var fsHash = crypto.createHash('md5'); + + fsHash.update(buffer); + var sha384 = fsHash.digest('base64'); + return sha384; +} + +module.exports = getFileHexSync \ No newline at end of file diff --git a/scripts/lib/js_hex.js b/scripts/lib/js_hex.js new file mode 100644 index 000000000..49047089e --- /dev/null +++ b/scripts/lib/js_hex.js @@ -0,0 +1,26 @@ +'use strict'; + +var path_for = require("./path_for"); +var get_file_hex = require("./get_file_hex"); + +function jsHelper() { + var result = ''; + var path = ''; + + for (var i = 0, len = arguments.length; i < len; i++) { + path = arguments[i]; + + if (i) result += '\n'; + + if (Array.isArray(path)) { + result += jsHelper.apply(this, path); + } else { + if (path.indexOf('?') < 0 && path.substring(path.length - 3, path.length) !== '.js') path += '.js'; + result += ''; + } + } + + return result; +} + +module.exports = jsHelper; \ No newline at end of file diff --git a/scripts/lib/js_lsload.js b/scripts/lib/js_lsload.js new file mode 100644 index 000000000..20620a731 --- /dev/null +++ b/scripts/lib/js_lsload.js @@ -0,0 +1,30 @@ +'use strict'; + +var path_for = require("./path_for"); +var get_file_hex = require("./get_file_hex"); +var fs = require('fs'); + +function jsHelper() { + var result = ''; + var path = ''; + + for (var i = 0, len = arguments.length; i < len; i++) { + path = arguments[i]; + + if (i) result += '\n'; + + var localpath = path_for.call(this,path); + + if (Array.isArray(path)) { + result += jsHelper.apply(this, path); + } else { + if (path.indexOf('?') < 0 && path.substring(path.length - 3, path.length) !== '.js') path += '.js'; + result += '' + } + } + return result; +} + +module.exports = jsHelper; \ No newline at end of file diff --git a/scripts/lib/path_for.js b/scripts/lib/path_for.js new file mode 100644 index 000000000..88f52905f --- /dev/null +++ b/scripts/lib/path_for.js @@ -0,0 +1,13 @@ +var path = require('path'); +var fs = require('fs'); + +function pathFor(paths) { + var res = ""; + res = path.join(this.theme_dir,"source" , paths); + if(!fs.existsSync(res)){ + res = path.join(this.source_dir, paths); + } + return res; +} + +module.exports = pathFor; \ No newline at end of file diff --git a/source/css/style.css b/source/css/style.css index 100cce6f7..15c36e45f 100644 --- a/source/css/style.css +++ b/source/css/style.css @@ -2404,13 +2404,6 @@ a { /* Material_icon */ /*****************/ -@font-face { - font-family: 'Material Icons'; - font-style: normal; - font-weight: 400; - src: url(../fonts/MaterialIcons-Regular.eot); - src: url(../fonts/MaterialIcons-Regular.woff2) format('woff2'), url(../fonts/MaterialIcons-Regular.woff) format('woff'), url(../fonts/MaterialIcons-Regular.ttf) format('truetype') -} .material-icons { font-family: 'Material Icons'; font-weight: 400; @@ -2655,25 +2648,6 @@ a { } } - - - - -/****************/ -/* Font_Awesome */ -/****************/ -/*! - * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */ - -@font-face { - font-family: 'FontAwesome'; - src: url(../fonts/fontawesome-webfont.eot?v=4.5.0); - src: url(../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'), url(../fonts/fontawesome-webfont.woff2?v=4.5.0) format('woff2'), url(../fonts/fontawesome-webfont.woff?v=4.5.0) format('woff'), url(../fonts/fontawesome-webfont.ttf?v=4.5.0) format('truetype'), url(../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg'); - font-weight: 400; - font-style: normal -} .fa { font: normal normal normal 14px/1 FontAwesome; font-size: inherit; diff --git a/source/css/style.min.css b/source/css/style.min.css index c997364aa..da6f9abdc 100644 --- a/source/css/style.min.css +++ b/source/css/style.min.css @@ -203,7 +203,7 @@ html{display:block}body{display:block;margin:0;padding:0;top:0;right:0;bottom:0; }@keyframes MD-burger-icon-line{0%{-webkit-transform:rotate(-180deg);transform:rotate(-180deg)}}@-webkit-keyframes MD-burger-icon-before-line{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin:3% 37%;width:75%} }@keyframes MD-burger-icon-before-line{0%{-webkit-transform:rotate(45deg);transform:rotate(45deg);margin:3% 37%;width:75%}}@-webkit-keyframes MD-burger-icon-after-line{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);margin:3% 37%;width:75%} }@keyframes MD-burger-icon-after-line{0%{-webkit-transform:rotate(-45deg);transform:rotate(-45deg);margin:3% 37%;width:75%}}.post-toc{width:auto;word-wrap:normal;white-space:nowrap;padding:0;list-style:none;padding:0 16px} -.post-toc-child{list-style:none}.post-toc a{color:#727272;text-decoration:none}@font-face{font-family:'Material Icons';font-style:normal;font-weight:400;src:url(../fonts/MaterialIcons-Regular.eot);src:url(../fonts/MaterialIcons-Regular.woff2) format('woff2'),url(../fonts/MaterialIcons-Regular.woff) format('woff'),url(../fonts/MaterialIcons-Regular.ttf) format('truetype')} +.post-toc-child{list-style:none}.post-toc a{color:#727272;text-decoration:none} .material-icons{font-family:'Material Icons';font-weight:400;font-style:normal;font-size:24px;display:inline-block;line-height:1;text-transform:none;letter-spacing:normal;word-wrap:normal;white-space:nowrap;direction:ltr;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;font-feature-settings:'liga'} .toTop-wrap{position:absolute;bottom:100px;right:34.61px;z-index:8}@media screen and (max-width:840px){.toTop-wrap{bottom:180px;right:28px}}.toTop{display:block;width:40px;height:40px;border-radius:50%;text-align:center;color:#FFF;background:#00bcd4;box-shadow:0 0 3px 0 rgba(0,0,0,.12),0 3px 3px 0 rgba(0,0,0,.24);cursor:pointer;-webkit-transition:all .1s ease-out;-moz-transition:all .1s ease-out;-o-transition:all .1s ease-out;transition:all .1s ease-out;position:relative;overflow:hidden} .toTop:hover{box-shadow:0 0 4px rgba(0,0,0,.14),0 4px 8px rgba(0,0,0,.28)}.toTop i{font-size:24px;margin:8px}.footer_top-i{width:24px;height:24px}@keyframes status-active{from{transform:rotate(0)} @@ -217,11 +217,7 @@ to{transform:rotate(135deg)}}@keyframes status-inactive{from{transform:rotate(13 #nprogress .spinner{display:block;position:fixed;z-index:10;top:15px;right:15px}.fa,.fa-stack{display:inline-block}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:nprogress-spinner 400ms linear infinite;animation:nprogress-spinner 400ms linear infinite} .nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute} @-webkit-keyframes nprogress-spinner{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(360deg)}}@keyframes nprogress-spinner{0%{transform:rotate(0)} -100%{transform:rotate(360deg)}}/*! - * Font Awesome 4.5.0 by @davegandy - http://fontawesome.io - @fontawesome - * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) - */@font-face{font-family:'FontAwesome';src:url(../fonts/fontawesome-webfont.eot?v=4.5.0);src:url(../fonts/fontawesome-webfont.eot?#iefix&v=4.5.0) format('embedded-opentype'),url(../fonts/fontawesome-webfont.woff2?v=4.5.0) format('woff2'),url(../fonts/fontawesome-webfont.woff?v=4.5.0) format('woff'),url(../fonts/fontawesome-webfont.ttf?v=4.5.0) format('truetype'),url(../fonts/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular) format('svg');font-weight:400;font-style:normal} -.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%} +100%{transform:rotate(360deg)}}.fa{font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%} .fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none} .fa.fa-pull-right,.fa.pull-right{margin-left:.3em}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center} .fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:.08em solid #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right,.pull-right{float:right} diff --git a/source/js/lsloader.js b/source/js/lsloader.js new file mode 100644 index 000000000..4961e44d4 --- /dev/null +++ b/source/js/lsloader.js @@ -0,0 +1,389 @@ +/** + * lsloader 动态异步加载,css需要注意防止reflow ,js需要注意所有同步顺序脚本都要用lsloader编译,避免出错 + * codestartv1 ls版本号,改动这个版本号 所有ls作废. + * lsloader.load(name,path) + * name 根据路径生成的唯一localStorage key + * path 线上的打包后文件路径 + * onload css 文件加载完成后回调 用于避免异步css造成的reflow + */ + +(function(){ + var combo = 'http://'+location.host+'/combo?combo=';//线上combo服务地址,配置后可用AMDModule build缓存文件 + + window.lsloader = { + jsRunSequence:[], //js 运行队列 {name:代码name,code:代码,status:状态 failed/loading/comboJS,path:线上路径} + jsnamemap:{}, //js name map 防fallback 重复请求资源 + cssnamemap:{} //css name map 防fallback 重复请求资源 + }; + + /* + * 封装localStorage get set remove 方法 + * try catch保证ls写满或者不支持本地缓存环境能继续运行js + * */ + lsloader.removeLS = function(key){ + try{ + localStorage.removeItem(key) + }catch (e){} + }; + lsloader.setLS = function (key,val){ + try{ + localStorage.setItem(key,val); + }catch(e){ + } + } + lsloader.getLS = function(key){ + var val = '' + try{ + val = localStorage.getItem(key); + }catch (e){ + val = ''; + } + return val + } + + + /* + * load资源 + * name 作为key path/分割符/代码值 作为value ,存储资源 + * 如果value值中取出的版本号和线上模版的一致,命中缓存用本地, + * 否则 调用requestResource 请求资源 + * jsname 文件name值,取相对路径,对应存在localStroage里的key + * jspath 文件线上路径,带md5版本号,用于加载资源,区分资源版本 + * cssonload css加载成功时候调用,用于配合页面展现 + * */ + lsloader.load = function(jsname,jspath,cssonload){ + cssonload = cssonload || function(){}; + var code; + code = this.getLS(jsname); + if(!/\/\*codestartv1\*\//.test(code)){ //ls 版本 codestartv1 每次换这个版本 所有ls作废 + this.removeLS(jsname); + this.requestResource(jsname,jspath,cssonload); + return + } + //取出对应文件名下的code + if(code){ + var versionNumber = code.split('/*codestartv1*/')[0]; //取出路径版本号 如果要加载的和ls里的不同,清理,重写 + if(versionNumber!=jspath){ + console.log("reload:" + jspath) + this.removeLS(jsname); + this.requestResource(jsname,jspath,cssonload); + return + } + code = code.split('/*codestartv1*/')[1]; + if(/\.js?.+$/.test(versionNumber)){ + this.jsRunSequence.push({name:jsname,code:code}) + this.runjs(jspath,jsname,code); + }else{ + document.getElementById(jsname).appendChild(document.createTextNode(code)); + cssonload(); + } + }else{ + //null xhr获取资源 + this.requestResource(jsname,jspath,cssonload); + } + }; + + + /* + * load请求资源 + * 根据文件名尾部不同加载,js走runjs方法,加入运行队列中 + * css 直接加载并且写入对应的