├── pv.txt ├── favicon.ico ├── fonts ├── Monaco.ttf ├── Skranji-Regular.ttf └── Ubuntu-Regular.ttf ├── live2d ├── model │ └── xiaoban │ │ ├── model.moc │ │ ├── model.2048 │ │ └── texture_00.png │ │ └── model.json ├── message.json ├── js │ └── message.js └── css │ └── live2d.css ├── cool ├── banner.js ├── clicklove.js ├── sitetime.js └── cooltext.js ├── js ├── app.js └── search.js ├── categories └── Coding │ ├── PSR │ └── index.html │ └── Design │ └── index.html └── tags ├── Cool └── index.html ├── 设计模式 └── index.html └── Swoole └── index.html /pv.txt: -------------------------------------------------------------------------------- 1 | shuapv -------------------------------------------------------------------------------- /favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/favicon.ico -------------------------------------------------------------------------------- /fonts/Monaco.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/fonts/Monaco.ttf -------------------------------------------------------------------------------- /fonts/Skranji-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/fonts/Skranji-Regular.ttf -------------------------------------------------------------------------------- /fonts/Ubuntu-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/fonts/Ubuntu-Regular.ttf -------------------------------------------------------------------------------- /live2d/model/xiaoban/model.moc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/live2d/model/xiaoban/model.moc -------------------------------------------------------------------------------- /live2d/model/xiaoban/model.2048/texture_00.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/writeBlog/writeblog.github.io/master/live2d/model/xiaoban/model.2048/texture_00.png -------------------------------------------------------------------------------- /live2d/message.json: -------------------------------------------------------------------------------- 1 | {"mouseover":[{"selector":".title a","text":["要看看 {text} 么?"]},{"selector":".searchbox","text":["在找什么东西呢,需要帮忙吗?"]}],"click":[{"selector":"#landlord #live2d","text":["不要动手动脚的哦!我家小主可是会打你的~~","你…你在调皮,人家…人家就不帮你止血了!","Hentai!","再摸的话我可要通知我家主人了了!⌇●﹏●⌇","110吗,这里有个调皮鬼一直在摸我(ó﹏ò。)"]}]} -------------------------------------------------------------------------------- /live2d/model/xiaoban/model.json: -------------------------------------------------------------------------------- 1 | {"type":"Live2D Model Setting","name":"model","model":"model.moc","textures":["model.2048/texture_00.png"],"motions":{"idle":[{"file":"motions/Idle.mtn"}],"sleepy":[{"file":"motions/Nemui.mtn"}],"flick_head":[{"file":"motions/Anone_Synced.mtn"}],"tap_body":[{"file":"motions/Dance.mtn"}]}} -------------------------------------------------------------------------------- /cool/banner.js: -------------------------------------------------------------------------------- 1 | $(function(){ 2 | $('.banner').mouseenter(function(){ 3 | const boxHeight = $(this).outerHeight() 4 | const boxWidth = $(this).outerWidth() 5 | let elementX = $(this).offset().left 6 | let elementY =$(this).offset().top 7 | //console.log(boxHeight,boxWidth,elementX,elementY) 8 | $('.banner').mousemove(function(e){ 9 | let X = e.pageX - elementX 10 | let Y = e.pageY - elementY 11 | let offsetX,offsetY 12 | offsetX = X - boxWidth/2 13 | offsetY = boxHeight/2 - Y 14 | $(this).css({ 15 | "-webkit-transform": "rotateY(" + offsetX / 20 + "deg) " + "rotateX(" + offsetY / 20 + "deg)" 16 | }) 17 | }) 18 | }) 19 | $(this).mouseleave(function(){ 20 | $('.banner').css({ 21 | "-webkit-transform": "rotateY(0deg) " + "rotateX(0deg)" 22 | }) 23 | }) 24 | }) -------------------------------------------------------------------------------- /cool/clicklove.js: -------------------------------------------------------------------------------- 1 | !function(e,t,a){function n(){c(".heart{width: 10px;height: 10px;position: fixed;background: #f00;transform: rotate(45deg);-webkit-transform: rotate(45deg);-moz-transform: rotate(45deg);}.heart:after,.heart:before{content: '';width: inherit;height: inherit;background: inherit;border-radius: 50%;-webkit-border-radius: 50%;-moz-border-radius: 50%;position: fixed;}.heart:after{top: -5px;}.heart:before{left: -5px;}"),o(),r()}function r(){for(var e=0;e0.5?-1:1);var u=r*(Math.random()>0.5?-1:1);document.body.style.marginLeft=q+"px";document.body.style.marginTop=u+"px";setTimeout(function(){document.body.style.marginLeft="";document.body.style.marginTop=""},75)}}o.colorful=false;function i(){if(f>0){requestAnimationFrame(i);f--;p=true}else{p=false}a.clearRect(0,0,d.width,d.height);for(var q=0;qparseInt(j.height)){g.overflowY="scroll"}}else{g.overflow="hidden"}f.textContent=k.value.substring(0,l);if(k.nodeName==="INPUT"){f.textContent=f.textContent.replace(/\s/g,"\u00a0")}var n=document.createElement("span");n.textContent=k.value.substring(l)||".";f.appendChild(n);var m={top:n.offsetTop+parseInt(j["borderTopWidth"]),left:n.offsetLeft+parseInt(j["borderLeftWidth"])};if(h){n.style.backgroundColor="#aaa"}else{document.body.removeChild(f)}return m}if(typeof b!="undefined"&&typeof b.exports!="undefined"){b.exports=c}else{window.getCaretCoordinates=c}}())}])}); 2 | POWERMODE.colorful=true;POWERMODE.shake=false;document.body.addEventListener("input",POWERMODE); -------------------------------------------------------------------------------- /live2d/js/message.js: -------------------------------------------------------------------------------- 1 | function renderTip(template, context) { 2 | var tokenReg = /(\\)?\{([^\{\}\\]+)(\\)?\}/g; 3 | return template.replace(tokenReg, function (word, slash1, token, slash2) { 4 | if (slash1 || slash2) { 5 | return word.replace('\\', ''); 6 | } 7 | var variables = token.replace(/\s/g, '').split('.'); 8 | var currentObject = context; 9 | var i, length, variable; 10 | for (i = 0, length = variables.length; i < length; ++i) { 11 | variable = variables[i]; 12 | currentObject = currentObject[variable]; 13 | if (currentObject === undefined || currentObject === null) return ''; 14 | } 15 | return currentObject; 16 | }); 17 | } 18 | 19 | String.prototype.renderTip = function (context) { 20 | return renderTip(this, context); 21 | }; 22 | 23 | var re = /x/; 24 | console.log(re); 25 | re.toString = function() { 26 | showMessage('哈哈,你打开了控制台,是想要看看我的秘密吗?', 5000); 27 | return ''; 28 | }; 29 | 30 | $(document).on('copy', function (){ 31 | showMessage('你都复制了些什么呀,转载要记得加上出处哦~~', 5000); 32 | }); 33 | 34 | function initTips(){ 35 | $.ajax({ 36 | cache: true, 37 | url: `${message_Path}message.json`, 38 | dataType: "json", 39 | success: function (result){ 40 | $.each(result.mouseover, function (index, tips){ 41 | $(tips.selector).mouseover(function (){ 42 | var text = tips.text; 43 | if(Array.isArray(tips.text)) text = tips.text[Math.floor(Math.random() * tips.text.length + 1)-1]; 44 | text = text.renderTip({text: $(this).text()}); 45 | showMessage(text, 3000); 46 | }); 47 | }); 48 | $.each(result.click, function (index, tips){ 49 | $(tips.selector).click(function (){ 50 | var text = tips.text; 51 | if(Array.isArray(tips.text)) text = tips.text[Math.floor(Math.random() * tips.text.length + 1)-1]; 52 | text = text.renderTip({text: $(this).text()}); 53 | showMessage(text, 3000); 54 | }); 55 | }); 56 | } 57 | }); 58 | } 59 | initTips(); 60 | 61 | (function (){ 62 | var text; 63 | if(document.referrer !== ''){ 64 | var referrer = document.createElement('a'); 65 | referrer.href = document.referrer; 66 | text = '嗨!来自 ' + referrer.hostname + ' 的朋友!'; 67 | var domain = referrer.hostname.split('.')[1]; 68 | if (domain == 'baidu') { 69 | text = '嗨! 来自 百度搜索 的朋友!
欢迎访问「 ' + document.title.split(' - ')[0] + ' 」'; 70 | }else if (domain == 'so') { 71 | text = '嗨! 来自 360搜索 的朋友!
欢迎访问「 ' + document.title.split(' - ')[0] + ' 」'; 72 | }else if (domain == 'google') { 73 | text = '嗨! 来自 谷歌搜索 的朋友!
欢迎访问「 ' + document.title.split(' - ')[0] + ' 」'; 74 | } 75 | }else { 76 | if (window.location.href == `${home_Path}`) { //主页URL判断,需要斜杠结尾 77 | var now = (new Date()).getHours(); 78 | if (now > 23 || now <= 5) { 79 | text = '你是夜猫子呀?这么晚还不睡觉,明天起的来嘛?'; 80 | } else if (now > 5 && now <= 7) { 81 | text = '早上好!一日之计在于晨,美好的一天就要开始了!'; 82 | } else if (now > 7 && now <= 11) { 83 | text = '上午好!工作顺利嘛,不要久坐,多起来走动走动哦!'; 84 | } else if (now > 11 && now <= 14) { 85 | text = '中午了,工作了一个上午,现在是午餐时间!'; 86 | } else if (now > 14 && now <= 17) { 87 | text = '午后很容易犯困呢,今天的运动目标完成了吗?'; 88 | } else if (now > 17 && now <= 19) { 89 | text = '傍晚了!窗外夕阳的景色很美丽呢,最美不过夕阳红~~'; 90 | } else if (now > 19 && now <= 21) { 91 | text = '晚上好,今天过得怎么样?'; 92 | } else if (now > 21 && now <= 23) { 93 | text = '已经这么晚了呀,早点休息吧,晚安~~'; 94 | } else { 95 | text = '嗨~ 快来逗我玩吧!'; 96 | } 97 | }else { 98 | text = '欢迎阅读「 ' + document.title.split(' - ')[0] + ' 」'; 99 | } 100 | } 101 | showMessage(text, 12000); 102 | })(); 103 | 104 | window.setInterval(showHitokoto,30000); 105 | 106 | function showHitokoto(){ 107 | $.getJSON('https://v1.hitokoto.cn/',function(result){ 108 | showMessage(result.hitokoto, 5000); 109 | }); 110 | } 111 | 112 | function showMessage(text, timeout){ 113 | if(Array.isArray(text)) text = text[Math.floor(Math.random() * text.length + 1)-1]; 114 | //console.log('showMessage', text); 115 | $('.message').stop(); 116 | $('.message').html(text).fadeTo(200, 1); 117 | if (timeout === null) timeout = 5000; 118 | hideMessage(timeout); 119 | } 120 | 121 | function hideMessage(timeout){ 122 | $('.message').stop().css('opacity',1); 123 | if (timeout === null) timeout = 5000; 124 | $('.message').delay(timeout).fadeTo(200, 0); 125 | } 126 | 127 | function initLive2d (){ 128 | $('.hide-button').fadeOut(0).on('click', () => { 129 | $('#landlord').css('display', 'none') 130 | }) 131 | $('#landlord').hover(() => { 132 | $('.hide-button').fadeIn(600) 133 | }, () => { 134 | $('.hide-button').fadeOut(600) 135 | }) 136 | } 137 | initLive2d (); 138 | -------------------------------------------------------------------------------- /live2d/css/live2d.css: -------------------------------------------------------------------------------- 1 | #landlord { 2 | user-select: none; 3 | position: fixed; 4 | right: 100px; 5 | bottom: 0; 6 | width: 280px; 7 | height: 250px; 8 | z-index: 10; 9 | font-size: 0; 10 | transition: all .3s ease-in-out; 11 | } 12 | 13 | #live2d { 14 | position: relative; 15 | } 16 | .live2d{ 17 | width: 280px; 18 | height: 250px; 19 | } 20 | 21 | .message { 22 | opacity: 0; 23 | width: 300px; 24 | height: auto; 25 | margin: auto; 26 | padding: 7px; 27 | top: -80px; 28 | left: -10px; 29 | text-align: center; 30 | border: 1px solid rgba(255,137,255,.4); 31 | border-radius: 12px; 32 | background-color: rgba(255, 137, 255, 0.877); 33 | box-shadow: 0 3px 15px 2px rgba(255,137,255,.4); 34 | font-size: 13px; 35 | font-weight: 400; 36 | text-overflow: ellipsis; 37 | text-transform: uppercase; 38 | overflow: hidden; 39 | position: absolute; 40 | animation-delay: 5s; 41 | animation-duration: 50s; 42 | animation-iteration-count: infinite; 43 | animation-name: shake; 44 | animation-timing-function: ease-in-out; 45 | z-index: 10000; 46 | } 47 | 48 | .hide-button { 49 | position: absolute; 50 | top: 10px; 51 | right: 0; 52 | /* bottom: 30px; */ 53 | display: none; 54 | overflow: hidden; 55 | /* padding: 4px; */ 56 | width: 60px; 57 | height: 20px; 58 | border: 1px solid rgba(255,137,255,.4); 59 | border-radius: 12px; 60 | background: rgba(255,137,255,.2); 61 | box-shadow: 0 3px 15px 2px rgba(255,137,255,.4); 62 | text-align: center; 63 | font-size: 12px; 64 | cursor: pointer; 65 | } 66 | 67 | .hide-button:hover { 68 | border: 1px solid #f4a7b9; 69 | background: #f4f6f8; 70 | } 71 | 72 | @media (max-width: 860px) { 73 | #landlord { 74 | /* display: none; */ 75 | 76 | } 77 | #live2d{ 78 | width: 200; 79 | height: 170; 80 | } 81 | } 82 | 83 | @keyframes shake { 84 | 2% { 85 | transform: translate(0.5px, -1.5px) rotate(-0.5deg); 86 | } 87 | 88 | 4% { 89 | transform: translate(0.5px, 1.5px) rotate(1.5deg); 90 | } 91 | 92 | 6% { 93 | transform: translate(1.5px, 1.5px) rotate(1.5deg); 94 | } 95 | 96 | 8% { 97 | transform: translate(2.5px, 1.5px) rotate(0.5deg); 98 | } 99 | 100 | 10% { 101 | transform: translate(0.5px, 2.5px) rotate(0.5deg); 102 | } 103 | 104 | 12% { 105 | transform: translate(1.5px, 1.5px) rotate(0.5deg); 106 | } 107 | 108 | 14% { 109 | transform: translate(0.5px, 0.5px) rotate(0.5deg); 110 | } 111 | 112 | 16% { 113 | transform: translate(-1.5px, -0.5px) rotate(1.5deg); 114 | } 115 | 116 | 18% { 117 | transform: translate(0.5px, 0.5px) rotate(1.5deg); 118 | } 119 | 120 | 20% { 121 | transform: translate(2.5px, 2.5px) rotate(1.5deg); 122 | } 123 | 124 | 22% { 125 | transform: translate(0.5px, -1.5px) rotate(1.5deg); 126 | } 127 | 128 | 24% { 129 | transform: translate(-1.5px, 1.5px) rotate(-0.5deg); 130 | } 131 | 132 | 26% { 133 | transform: translate(1.5px, 0.5px) rotate(1.5deg); 134 | } 135 | 136 | 28% { 137 | transform: translate(-0.5px, -0.5px) rotate(-0.5deg); 138 | } 139 | 140 | 30% { 141 | transform: translate(1.5px, -0.5px) rotate(-0.5deg); 142 | } 143 | 144 | 32% { 145 | transform: translate(2.5px, -1.5px) rotate(1.5deg); 146 | } 147 | 148 | 34% { 149 | transform: translate(2.5px, 2.5px) rotate(-0.5deg); 150 | } 151 | 152 | 36% { 153 | transform: translate(0.5px, -1.5px) rotate(0.5deg); 154 | } 155 | 156 | 38% { 157 | transform: translate(2.5px, -0.5px) rotate(-0.5deg); 158 | } 159 | 160 | 40% { 161 | transform: translate(-0.5px, 2.5px) rotate(0.5deg); 162 | } 163 | 164 | 42% { 165 | transform: translate(-1.5px, 2.5px) rotate(0.5deg); 166 | } 167 | 168 | 44% { 169 | transform: translate(-1.5px, 1.5px) rotate(0.5deg); 170 | } 171 | 172 | 46% { 173 | transform: translate(1.5px, -0.5px) rotate(-0.5deg); 174 | } 175 | 176 | 48% { 177 | transform: translate(2.5px, -0.5px) rotate(0.5deg); 178 | } 179 | 180 | 50% { 181 | transform: translate(-1.5px, 1.5px) rotate(0.5deg); 182 | } 183 | 184 | 52% { 185 | transform: translate(-0.5px, 1.5px) rotate(0.5deg); 186 | } 187 | 188 | 54% { 189 | transform: translate(-1.5px, 1.5px) rotate(0.5deg); 190 | } 191 | 192 | 56% { 193 | transform: translate(0.5px, 2.5px) rotate(1.5deg); 194 | } 195 | 196 | 58% { 197 | transform: translate(2.5px, 2.5px) rotate(0.5deg); 198 | } 199 | 200 | 60% { 201 | transform: translate(2.5px, -1.5px) rotate(1.5deg); 202 | } 203 | 204 | 62% { 205 | transform: translate(-1.5px, 0.5px) rotate(1.5deg); 206 | } 207 | 208 | 64% { 209 | transform: translate(-1.5px, 1.5px) rotate(1.5deg); 210 | } 211 | 212 | 66% { 213 | transform: translate(0.5px, 2.5px) rotate(1.5deg); 214 | } 215 | 216 | 68% { 217 | transform: translate(2.5px, -1.5px) rotate(1.5deg); 218 | } 219 | 220 | 70% { 221 | transform: translate(2.5px, 2.5px) rotate(0.5deg); 222 | } 223 | 224 | 72% { 225 | transform: translate(-0.5px, -1.5px) rotate(1.5deg); 226 | } 227 | 228 | 74% { 229 | transform: translate(-1.5px, 2.5px) rotate(1.5deg); 230 | } 231 | 232 | 76% { 233 | transform: translate(-1.5px, 2.5px) rotate(1.5deg); 234 | } 235 | 236 | 78% { 237 | transform: translate(-1.5px, 2.5px) rotate(0.5deg); 238 | } 239 | 240 | 80% { 241 | transform: translate(-1.5px, 0.5px) rotate(-0.5deg); 242 | } 243 | 244 | 82% { 245 | transform: translate(-1.5px, 0.5px) rotate(-0.5deg); 246 | } 247 | 248 | 84% { 249 | transform: translate(-0.5px, 0.5px) rotate(1.5deg); 250 | } 251 | 252 | 86% { 253 | transform: translate(2.5px, 1.5px) rotate(0.5deg); 254 | } 255 | 256 | 88% { 257 | transform: translate(-1.5px, 0.5px) rotate(1.5deg); 258 | } 259 | 260 | 90% { 261 | transform: translate(-1.5px, -0.5px) rotate(-0.5deg); 262 | } 263 | 264 | 92% { 265 | transform: translate(-1.5px, -1.5px) rotate(1.5deg); 266 | } 267 | 268 | 94% { 269 | transform: translate(0.5px, 0.5px) rotate(-0.5deg); 270 | } 271 | 272 | 96% { 273 | transform: translate(2.5px, -0.5px) rotate(-0.5deg); 274 | } 275 | 276 | 98% { 277 | transform: translate(-1.5px, -1.5px) rotate(-0.5deg); 278 | } 279 | 280 | 0%, 100% { 281 | transform: translate(0, 0) rotate(0); 282 | } 283 | } 284 | -------------------------------------------------------------------------------- /js/app.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var customSearch; 3 | (function ($) { 4 | 5 | "use strict"; 6 | var scrollCorrection = 80; // (header height = 64px) + (gap = 16px) 7 | const $headerAnchor = $('.l_header', '.cover-wrapper'); 8 | if ($headerAnchor[0]) { 9 | scrollCorrection = $headerAnchor[0].clientHeight + 16; 10 | } 11 | 12 | function scrolltoElement(elem, correction) { 13 | correction = correction || scrollCorrection; 14 | const $elem = elem.href ? $(elem.getAttribute('href')) : $(elem); 15 | $('html, body').animate({ 'scrollTop': $elem.offset().top - correction }, 400); 16 | }; 17 | 18 | function setScrollAnchor(){ 19 | // button 20 | const $postsBtn = $('.menu .active'); 21 | const $topBtn = $('.s-top'); 22 | const $titleBtn = $('h1.title', '#header-meta'); 23 | // anchor 24 | const $bodyAnchor = $('.l_body'); 25 | // action 26 | if ($postsBtn.length && $bodyAnchor) { 27 | $postsBtn.click(e => { e.preventDefault(); e.stopPropagation(); scrolltoElement($bodyAnchor); }); 28 | } 29 | if ($titleBtn.length && $bodyAnchor) { 30 | $titleBtn.click(e => { e.preventDefault(); e.stopPropagation(); scrolltoElement($bodyAnchor); }); 31 | } 32 | if ($topBtn.length && $bodyAnchor) { 33 | $topBtn.click(e => { e.preventDefault(); e.stopPropagation(); scrolltoElement($bodyAnchor); }); 34 | } 35 | 36 | const $coverAnchor = $('.cover-wrapper'); 37 | var showHeaderPoint = 0; 38 | if ($coverAnchor[0]) { 39 | showHeaderPoint = $coverAnchor[0].clientHeight - 164; 40 | } 41 | var pos = document.body.scrollTop; 42 | $(document, window).scroll(() => { 43 | const scrollTop = $(window).scrollTop(); 44 | const del = scrollTop - pos; 45 | pos = scrollTop; 46 | if (scrollTop > 150) { 47 | $topBtn.addClass('show'); 48 | if (del > 0) { 49 | $topBtn.removeClass('hl'); 50 | } else { 51 | $topBtn.addClass('hl'); 52 | } 53 | } else { 54 | $topBtn.removeClass('show').removeClass('hl'); 55 | } 56 | if (scrollTop > showHeaderPoint) { 57 | $headerAnchor.addClass('show'); 58 | } else { 59 | $headerAnchor.removeClass('show'); 60 | } 61 | }); 62 | } 63 | 64 | function setHeader() { 65 | if (!window.subData) return; 66 | const $wrapper = $('header .wrapper'); 67 | const $comment = $('.s-comment', $wrapper); 68 | const $toc = $('.s-toc', $wrapper); 69 | 70 | $wrapper.find('.nav-sub .logo').text(window.subData.title); 71 | let pos = document.body.scrollTop; 72 | $(document, window).scroll(() => { 73 | const scrollTop = $(window).scrollTop(); 74 | const del = scrollTop - pos; 75 | if (del >= 50 && scrollTop > 100) { 76 | pos = scrollTop; 77 | $wrapper.addClass('sub'); 78 | } else if (del <= -50) { 79 | pos = scrollTop; 80 | $wrapper.removeClass('sub'); 81 | } 82 | }); 83 | 84 | // bind events to every btn 85 | const $commentTarget = $('#comments'); 86 | if ($commentTarget.length) { 87 | $comment.click(e => { e.preventDefault(); e.stopPropagation(); scrolltoElement($commentTarget); }); 88 | } else $comment.remove(); 89 | 90 | const $tocTarget = $('.toc-wrapper'); 91 | if ($tocTarget.length && $tocTarget.children().length) { 92 | $toc.click((e) => { e.stopPropagation(); $tocTarget.toggleClass('active'); }); 93 | } else $toc.remove(); 94 | 95 | 96 | 97 | } 98 | 99 | function setHeaderMenuSelection() { 100 | var $headerMenu = $('body .navgation'); 101 | // 先把已经激活的取消激活 102 | $headerMenu.find('li a.active').removeClass('active'); 103 | // var $underline = $headerMenu.find('.underline'); 104 | function setUnderline($item) { 105 | // if (!transition) $underline.addClass('disable-trans'); 106 | if ($item && $item.length) { 107 | $item.addClass('active').siblings().removeClass('active'); 108 | } 109 | } 110 | //set current active nav 111 | var $active_link = null; 112 | var idname = location.pathname.replace(/\/|%/g, ""); 113 | if (idname.length == 0) { 114 | idname = "home"; 115 | } 116 | var page = idname.match(/page\d{0,}$/g); 117 | if (page) { 118 | page = page[0]; 119 | idname = idname.split(page)[0]; 120 | } 121 | var index = idname.match(/index.html/); 122 | if (index) { 123 | index = index[0]; 124 | idname = idname.split(index)[0]; 125 | } 126 | if (idname && $headerMenu) { 127 | $active_link = $('#' + idname, $headerMenu); 128 | setUnderline($active_link); 129 | } 130 | } 131 | 132 | function setHeaderMenuPhone() { 133 | var $switcher = $('.l_header .switcher .s-menu'); 134 | $switcher.click(function (e) { 135 | e.stopPropagation(); 136 | $('body').toggleClass('z_menu-open'); 137 | $switcher.toggleClass('active'); 138 | }); 139 | $(document).click(function (e) { 140 | $('body').removeClass('z_menu-open'); 141 | $switcher.removeClass('active'); 142 | }); 143 | } 144 | 145 | function setHeaderSearch() { 146 | var $switcher = $('.l_header .switcher .s-search'); 147 | var $header = $('.l_header'); 148 | var $search = $('.l_header .m_search'); 149 | if ($switcher.length === 0) return; 150 | $switcher.click(function (e) { 151 | e.stopPropagation(); 152 | $header.toggleClass('z_search-open'); 153 | $search.find('input').focus(); 154 | }); 155 | $(document).click(function (e) { 156 | $header.removeClass('z_search-open'); 157 | }); 158 | $search.click(function (e) { 159 | e.stopPropagation(); 160 | }); 161 | $header.ready(function () { 162 | $header.bind('keydown', function (event) { 163 | if (event.keyCode == 9) { 164 | return false; 165 | } else { 166 | var isie = (document.all) ? true: false; 167 | var key; 168 | var ev; 169 | if (isie) { //IE浏览器 170 | key = window.event.keyCode; 171 | ev = window.event; 172 | } else { //火狐浏览器 173 | key = e.which; 174 | ev = e; 175 | } 176 | if (key == 9) { //IE浏览器 177 | if (isie) { 178 | ev.keyCode = 0; 179 | ev.returnValue = false; 180 | } else { //火狐浏览器 181 | ev.which = 0; 182 | ev.preventDefault(); 183 | } 184 | } 185 | } 186 | }); 187 | }); 188 | } 189 | 190 | function setTocToggle() { 191 | const $toc = $('.toc-wrapper'); 192 | if ($toc.length === 0) return; 193 | // $toc.click((e) => { 194 | // e.stopPropagation(); 195 | // $toc.addClass('active'); 196 | // }); 197 | $(document).click(() => $toc.removeClass('active')); 198 | 199 | $toc.on('click', 'a', (e) => { 200 | e.preventDefault(); 201 | e.stopPropagation(); 202 | if (e.target.tagName === 'A') { 203 | scrolltoElement(e.target); 204 | } else if (e.target.tagName === 'SPAN') { 205 | scrolltoElement(e.target.parentElement); 206 | } 207 | $toc.removeClass('active'); 208 | }); 209 | 210 | const liElements = Array.from($toc.find('li a')); 211 | //function animate above will convert float to int. 212 | const getAnchor = () => liElements.map(elem => Math.floor($(elem.getAttribute('href')).offset().top - scrollCorrection)); 213 | 214 | let anchor = getAnchor(); 215 | const scrollListener = () => { 216 | const scrollTop = $('html').scrollTop() || $('body').scrollTop(); 217 | if (!anchor) return; 218 | //binary search. 219 | let l = 0, r = anchor.length - 1, mid; 220 | while (l < r) { 221 | mid = (l + r + 1) >> 1; 222 | if (anchor[mid] === scrollTop) l = r = mid; 223 | else if (anchor[mid] < scrollTop) l = mid; 224 | else r = mid - 1; 225 | } 226 | $(liElements).removeClass('active').eq(l).addClass('active'); 227 | } 228 | $(window) 229 | .resize(() => { 230 | anchor = getAnchor(); 231 | scrollListener(); 232 | }) 233 | .scroll(() => { 234 | scrollListener() 235 | }); 236 | scrollListener(); 237 | } 238 | 239 | 240 | $(function () { 241 | //set header 242 | setHeader(); 243 | setHeaderMenuSelection(); 244 | setHeaderMenuPhone(); 245 | setHeaderSearch(); 246 | 247 | setTocToggle(); 248 | setScrollAnchor(); 249 | // $(".article .video-container").fitVids(); 250 | 251 | setTimeout(function () { 252 | $('#loading-bar-wrapper').fadeOut(500); 253 | }, 300); 254 | 255 | 256 | if (SEARCH_SERVICE === 'google') { 257 | customSearch = new GoogleCustomSearch({ 258 | apiKey: GOOGLE_CUSTOM_SEARCH_API_KEY, 259 | engineId: GOOGLE_CUSTOM_SEARCH_ENGINE_ID, 260 | imagePath: "/images/" 261 | }); 262 | } 263 | else if (SEARCH_SERVICE === 'algolia') { 264 | customSearch = new AlgoliaSearch({ 265 | apiKey: ALGOLIA_API_KEY, 266 | appId: ALGOLIA_APP_ID, 267 | indexName: ALGOLIA_INDEX_NAME, 268 | imagePath: "/images/" 269 | }); 270 | } 271 | else if (SEARCH_SERVICE === 'hexo') { 272 | customSearch = new HexoSearch({ 273 | imagePath: "/images/" 274 | }); 275 | } 276 | else if (SEARCH_SERVICE === 'azure') { 277 | customSearch = new AzureSearch({ 278 | serviceName: AZURE_SERVICE_NAME, 279 | indexName: AZURE_INDEX_NAME, 280 | queryKey: AZURE_QUERY_KEY, 281 | imagePath: "/images/" 282 | }); 283 | } 284 | else if (SEARCH_SERVICE === 'baidu') { 285 | customSearch = new BaiduSearch({ 286 | apiId: BAIDU_API_ID, 287 | imagePath: "/images/" 288 | }); 289 | } 290 | 291 | }); 292 | 293 | })(jQuery); 294 | -------------------------------------------------------------------------------- /js/search.js: -------------------------------------------------------------------------------- 1 | /* eslint-disable */ 2 | var SearchService = ""; 3 | 4 | (function($) { 5 | /** 6 | * A super class of common logics for all search services 7 | * @param options : (object) 8 | */ 9 | SearchService = function(options) { 10 | var self = this; 11 | 12 | self.config = $.extend({ 13 | per_page: 10, 14 | selectors: { 15 | body: "body", 16 | form: ".u-search-form", 17 | input: ".u-search-input", 18 | container: "#u-search", 19 | modal: "#u-search .modal", 20 | modal_body: "#u-search .modal-body", 21 | modal_footer: "#u-search .modal-footer", 22 | modal_overlay: "#u-search .modal-overlay", 23 | modal_results: "#u-search .modal-results", 24 | modal_metadata: "#u-search .modal-metadata", 25 | modal_error: "#u-search .modal-error", 26 | modal_loading_bar: "#u-search .modal-loading-bar", 27 | modal_ajax_content: "#u-search .modal-ajax-content", 28 | modal_logo: '#u-search .modal-footer .logo', 29 | btn_close: "#u-search .btn-close", 30 | btn_next: "#u-search .btn-next", 31 | btn_prev: "#u-search .btn-prev" 32 | }, 33 | brands: { 34 | 'google': {logo: 'google.svg', url: 'https://cse.google.com'}, 35 | 'algolia': {logo: 'algolia.svg', url: 'https://www.algolia.com'}, 36 | 'hexo': {logo: '', url: ''}, 37 | 'azure': {logo: 'azure.svg', url: 'https://azure.microsoft.com/en-us/services/search/'}, 38 | 'baidu': {logo: 'baidu.svg', url: 'http://zn.baidu.com/cse/home/index'} 39 | }, 40 | imagePath: ROOT + "img/" 41 | }, options); 42 | 43 | self.dom = {}; 44 | self.percentLoaded = 0; 45 | self.open = false; 46 | self.queryText = ""; 47 | self.nav = { 48 | next: -1, 49 | prev: -1, 50 | total: 0, 51 | current: 1 52 | }; 53 | 54 | self.parseSelectors = function() { 55 | for (var key in self.config.selectors) { 56 | self.dom[key] = $(self.config.selectors[key]); 57 | } 58 | }; 59 | 60 | self.beforeQuery = function() { 61 | if (!self.open) { 62 | self.dom.container.fadeIn(); 63 | self.dom.body.addClass('modal-active'); 64 | } 65 | self.dom.input.each(function(index,elem) { 66 | $(elem).val(self.queryText); 67 | }); 68 | document.activeElement.blur(); 69 | self.dom.modal_error.hide(); 70 | self.dom.modal_ajax_content.removeClass('loaded'); 71 | self.startLoading(); 72 | }; 73 | 74 | self.afterQuery = function() { 75 | self.dom.modal_body.scrollTop(0); 76 | self.dom.modal_ajax_content.addClass('loaded'); 77 | self.stopLoading(); 78 | }; 79 | 80 | /** 81 | * Perform a complete serach operation including UI updates and query 82 | * @param startIndex {int} start index or page number 83 | */ 84 | self.search = function(startIndex, callback) { 85 | self.beforeQuery(); 86 | if (self.search instanceof Function) { 87 | self.query(self.queryText, startIndex, function() { 88 | self.afterQuery(); 89 | }); 90 | } 91 | else { 92 | console.log("query() does not exist."); 93 | self.onQueryError(self.queryText, ''); 94 | self.afterQuery(); 95 | } 96 | }; 97 | 98 | /** 99 | * Query error handler 100 | * @param queryText: (string) 101 | * @param status: (string) 102 | */ 103 | self.onQueryError = function(queryText, status) { 104 | var errMsg = ""; 105 | if (status === "success") errMsg = "No result found for \"" +queryText+ "\"."; 106 | else if (status === "timeout") errMsg = "Unfortunate timeout."; 107 | else errMsg = "Mysterious failure."; 108 | self.dom.modal_results.html(""); 109 | self.dom.modal_error.html(errMsg); 110 | self.dom.modal_error.show(); 111 | }; 112 | 113 | self.nextPage = function() { 114 | if (self.nav.next !== -1) { 115 | self.search(self.nav.next); 116 | } 117 | }; 118 | 119 | self.prevPage = function() { 120 | if (self.nav.prev !== -1) { 121 | self.search(self.nav.prev); 122 | } 123 | }; 124 | 125 | /** 126 | * Generate html for one result 127 | * @param url : (string) url 128 | * @param title : (string) title 129 | * @param digest : (string) digest 130 | */ 131 | self.buildResult = function(url, title, digest) { 132 | var html = ""; 133 | html = "
  • "; 134 | html += ""; 135 | html += "" +title+ ""; 136 | html += "" +digest+ ""; 137 | html += ""; 138 | html += ""; 139 | html += "
  • "; 140 | return html; 141 | }; 142 | 143 | /** 144 | * Close the modal, resume body scrolling 145 | * no param 146 | */ 147 | self.close = function() { 148 | self.open = false; 149 | self.dom.container.fadeOut(); 150 | self.dom.body.removeClass('modal-active'); 151 | }; 152 | 153 | /** 154 | * Searchform submit event handler 155 | * @param queryText : (string) the query text 156 | */ 157 | self.onSubmit = function(event) { 158 | event.preventDefault(); 159 | self.queryText = $(this).find('.u-search-input').val(); 160 | if (self.queryText) { 161 | self.search(1); 162 | } 163 | }; 164 | 165 | /** 166 | * Start loading bar animation 167 | * no param 168 | */ 169 | self.startLoading = function() { 170 | self.dom.modal_loading_bar.show(); 171 | self.loadingTimer = setInterval(function() { 172 | self.percentLoaded = Math.min(self.percentLoaded+5,95); 173 | self.dom.modal_loading_bar.css('width', self.percentLoaded+'%'); 174 | }, 100); 175 | }; 176 | 177 | /** 178 | * Stop loading bar animation 179 | * no param 180 | */ 181 | self.stopLoading = function() { 182 | clearInterval(self.loadingTimer); 183 | self.dom.modal_loading_bar.css('width', '100%'); 184 | self.dom.modal_loading_bar.fadeOut(); 185 | setTimeout(function() { 186 | self.percentLoaded = 0; 187 | self.dom.modal_loading_bar.css('width', '0%'); 188 | }, 300); 189 | }; 190 | 191 | /** 192 | * Add service branding 193 | * @param service {String} service name 194 | */ 195 | self.addLogo = function(service) { 196 | var html = ""; 197 | if (self.config.brands[service] && self.config.brands[service].logo) { 198 | html += ""; 199 | html += ''; 200 | html += ""; 201 | self.dom.modal_logo.html(html); 202 | } 203 | }; 204 | 205 | self.destroy = function() { 206 | self.dom.form.each(function(index,elem) { 207 | $(elem).off('submit'); 208 | }); 209 | self.dom.modal_overlay.off('click'); 210 | self.dom.btn_close.off('click'); 211 | self.dom.btn_next.off('click'); 212 | self.dom.btn_prev.off('click'); 213 | self.dom.container.remove(); 214 | }; 215 | 216 | /** 217 | * Load template and register event handlers 218 | * no param 219 | */ 220 | self.init = function() { 221 | $('body').append(template); 222 | self.parseSelectors(); 223 | self.dom.modal_footer.show(); 224 | self.dom.form.each(function(index,elem) { 225 | $(elem).on('submit', self.onSubmit); 226 | }); 227 | self.dom.modal_overlay.on('click', self.close); 228 | self.dom.btn_close.on('click', self.close); 229 | self.dom.btn_next.on('click', self.nextPage); 230 | self.dom.btn_prev.on('click', self.prevPage); 231 | }; 232 | 233 | self.init(); 234 | }; 235 | 236 | var template = ''; 237 | })(jQuery); 238 | 239 | var AlgoliaSearch; 240 | 241 | (function($) { 242 | 'use strict'; 243 | 244 | /** 245 | * Search by Algolia Search 246 | * @param options : (object) 247 | */ 248 | AlgoliaSearch = function(options) { 249 | SearchService.apply(this, arguments); 250 | var self = this; 251 | var endpoint = "https://" +self.config.app_id+ "-dsn.algolia.net/1/indexes/" +self.config.indexName; 252 | self.addLogo('algolia'); 253 | 254 | /** 255 | * Generate result list html 256 | * @param data : (array) result items 257 | */ 258 | self.buildResultList = function(data) { 259 | var html = ""; 260 | $.each(data, function(index, row) { 261 | var url = row.permalink || row.path || ""; 262 | if (!row.permalink && row.path) { 263 | url = ROOT + url; 264 | } 265 | var title = row.title; 266 | var digest = row._highlightResult.excerptStrip.value || ""; 267 | html += self.buildResult(url, title, digest); 268 | }); 269 | return html; 270 | }; 271 | 272 | /** 273 | * Generate metadata after a successful query 274 | * @param data : (object) the raw search response data 275 | */ 276 | self.buildMetadata = function(data) { 277 | self.nav.current = data.page * data.hitsPerPage + 1; 278 | self.nav.currentCount = data.hits.length; 279 | self.nav.total = parseInt(data.nbHits); 280 | self.dom.modal_metadata.children('.total').html(self.nav.total); 281 | self.dom.modal_metadata.children('.range').html(self.nav.current + "-" + (self.nav.current+self.nav.currentCount-1)); 282 | if (self.nav.total > 0) { 283 | self.dom.modal_metadata.show(); 284 | } 285 | else { 286 | self.dom.modal_metadata.hide(); 287 | } 288 | 289 | if (data.page < data.nbPages-1) { 290 | self.nav.next = (data.page+1)+1; 291 | self.dom.btn_next.show(); 292 | } 293 | else { 294 | self.nav.next = -1; 295 | self.dom.btn_next.hide(); 296 | } 297 | if (data.page > 0) { 298 | self.nav.prev = (data.page+1)-1; 299 | self.dom.btn_prev.show(); 300 | } 301 | else { 302 | self.nav.prev = -1; 303 | self.dom.btn_prev.hide(); 304 | } 305 | }; 306 | 307 | /** 308 | * Send a GET request 309 | * @param queryText : (string) the query text 310 | * @param page : (int) the current page (start from 1) 311 | * @param callback : (function) 312 | */ 313 | self.query = function(queryText, page, callback) { 314 | $.get(endpoint, { 315 | query: queryText, 316 | page: page-1, 317 | hitsPerPage: self.config.per_page, 318 | "x-algolia-application-id": self.config.app_id, 319 | "x-algolia-api-key": self.config.apiKey 320 | }, function(data, status) { 321 | if (status === 'success' && data.hits && data.hits.length > 0) { 322 | var results = self.buildResultList(data.hits); 323 | self.dom.modal_results.html(results); 324 | } 325 | else { 326 | self.onQueryError(queryText, status); 327 | } 328 | self.buildMetadata(data); 329 | if (callback) { 330 | callback(data); 331 | } 332 | }); 333 | }; 334 | 335 | return self; 336 | }; 337 | 338 | })(jQuery); 339 | var AzureSearch; 340 | 341 | (function($) { 342 | 'use strict'; 343 | 344 | /** 345 | * Search by Azure Search API 346 | * @param options : (object) 347 | */ 348 | AzureSearch = function(options) { 349 | SearchService.apply(this, arguments); 350 | var self = this; 351 | var endpoint = "https://" +self.config.serviceName+ ".search.windows.net/indexes/" +self.config.indexName+ "/docs?api-version=2015-02-28"; 352 | self.nav.current = 1; 353 | self.addLogo('azure'); 354 | 355 | /** 356 | * Generate result list html 357 | * @param data : (array) result items 358 | */ 359 | self.buildResultList = function(data) { 360 | var html = ""; 361 | $.each(data, function(index, row) { 362 | var url = row.permalink || row.path || ""; 363 | if (!row.permalink && row.path) { 364 | url = "/" + url; 365 | } 366 | var title = row.title; 367 | var digest = row.excerpt || ""; 368 | html += self.buildResult(url, title, digest); 369 | }); 370 | return html; 371 | }; 372 | 373 | /** 374 | * Generate metadata after a successful query 375 | * @param data : (object) the raw response data 376 | * @param startIndex : (int) requested start index of current query 377 | */ 378 | self.buildMetadata = function(data, startIndex) { 379 | self.nav.current = startIndex; 380 | self.nav.currentCount = data.value.length; 381 | self.nav.total = parseInt(data['@odata.count']); 382 | self.dom.modal_metadata.children('.total').html(self.nav.total); 383 | self.dom.modal_metadata.children('.range').html(self.nav.current + "-" + (self.nav.current+self.nav.currentCount-1)); 384 | if (self.nav.total > 0) { 385 | self.dom.modal_metadata.show(); 386 | } 387 | else { 388 | self.dom.modal_metadata.hide(); 389 | } 390 | 391 | if (self.nav.current+self.nav.currentCount <= self.nav.total) { 392 | self.nav.next = self.nav.current+self.nav.currentCount; 393 | self.dom.btn_next.show(); 394 | } 395 | else { 396 | self.nav.next = -1; 397 | self.dom.btn_next.hide(); 398 | } 399 | if (self.nav.current > 1) { 400 | self.nav.prev = self.nav.current-self.config.per_page; 401 | self.dom.btn_prev.show(); 402 | } 403 | else { 404 | self.nav.prev = -1; 405 | self.dom.btn_prev.hide(); 406 | } 407 | }; 408 | 409 | /** 410 | * Send a GET request 411 | * @param queryText : (string) the query text 412 | * @param page : (int) the current page (start from 1) 413 | * @param callback : (function) 414 | */ 415 | self.query = function(queryText, startIndex, callback) { 416 | $.ajax({ 417 | url: endpoint, 418 | headers: { 419 | "Accept": "application/json", 420 | "api-key": self.config.queryKey 421 | }, 422 | data: { 423 | search: queryText, 424 | $orderby: "date desc", 425 | $skip: startIndex-1, 426 | $top: self.config.per_page, 427 | $count: true 428 | }, 429 | type: "GET", 430 | success: function(data, status) { 431 | if (status === 'success' && data.value && data.value.length > 0) { 432 | var results = self.buildResultList(data.value); 433 | self.dom.modal_results.html(results); 434 | } 435 | else { 436 | self.onQueryError(queryText, status); 437 | } 438 | self.buildMetadata(data, startIndex); 439 | if (callback) { 440 | callback(data); 441 | } 442 | } 443 | }); 444 | }; 445 | 446 | return self; 447 | }; 448 | 449 | })(jQuery); 450 | var BaiduSearch; 451 | 452 | (function($) { 453 | 'use strict'; 454 | 455 | /** 456 | * TODO 457 | * Search by Baidu Search API 458 | * @param options : (object) 459 | */ 460 | BaiduSearch = function(options) { 461 | SearchService.apply(this, arguments); 462 | var self = this; 463 | var endpoint = ""; 464 | self.addLogo('baidu'); 465 | 466 | /** 467 | * Generate result list html 468 | * @param data : (array) result items 469 | */ 470 | self.buildResultList = function(data, queryText) { 471 | var results = [], 472 | html = ""; 473 | $.each(data, function(index, post) { 474 | if (self.contentSearch(post, queryText)) 475 | html += self.buildResult(post.linkUrl, post.title, post.abstract); 476 | }); 477 | return html; 478 | }; 479 | 480 | /** 481 | * Generate metadata after a successful query 482 | * @param data : (object) the raw google custom search response data 483 | */ 484 | self.buildMetadata = function(data) { 485 | 486 | }; 487 | 488 | self.loadScript = function() { 489 | self.dom.input.each(function(index,elem) { 490 | $(elem).attr('disabled', true); 491 | }); 492 | var script = ""; 493 | self.dom.body.append(script); 494 | }; 495 | 496 | self.initBaidu = function() { 497 | self.cse = new BCse.Search(self.config.apiId); 498 | //self.cse.setPageNum(self.config.per_page); 499 | self.dom.input.each(function(index,elem) { 500 | $(elem).attr('disabled', false); 501 | }); 502 | }; 503 | 504 | /** 505 | * Get search results 506 | * @param queryText {String} 507 | * @param page {Integer} 508 | * @param callback {Function} 509 | */ 510 | self.query = function(queryText, page, callback) { 511 | self.cse.getResult(queryText, function(data) { 512 | console.log("Searching: " + queryText); 513 | self.cse.getError(function(data) { 514 | console.log(data); 515 | }); 516 | if (data.length > 0) { 517 | self.buildResultList(data, queryText); 518 | self.cse.getSearchInfo(queryText, function(data) { 519 | console.log(data); 520 | self.buildMetadata(data); 521 | }); 522 | } 523 | else { 524 | self.nav.total = 0; 525 | self.nav.next = -1; 526 | self.nav.prev = -1; 527 | self.dom.modal_metadata.hide(); 528 | self.dom.btn_next.hide(); 529 | self.dom.btn_prev.hide(); 530 | self.onQueryError(queryText, "success"); 531 | } 532 | if (callback instanceof Function) { 533 | callback(); 534 | } 535 | }); 536 | }; 537 | 538 | self.loadScript(); 539 | 540 | return self; 541 | }; 542 | 543 | })(jQuery); 544 | var GoogleCustomSearch = ""; 545 | 546 | (function($) { 547 | 'use strict'; 548 | 549 | /** 550 | * Search by Google Custom Search Engine JSON API 551 | * @param options : (object) 552 | */ 553 | GoogleCustomSearch = function(options) { 554 | SearchService.apply(this, arguments); 555 | var self = this; 556 | var endpoint = "https://www.googleapis.com/customsearch/v1"; 557 | self.addLogo('google'); 558 | 559 | /** 560 | * Generate result list html 561 | * @param data : (array) result items 562 | */ 563 | self.buildResultList = function(data) { 564 | var html = ""; 565 | $.each(data, function(index, row) { 566 | var url = row.link; 567 | var title = row.title; 568 | var digest = (row.htmlSnippet || "").replace('
    ',''); 569 | html += self.buildResult(url, title, digest); 570 | }); 571 | return html; 572 | }; 573 | 574 | /** 575 | * Generate metadata after a successful query 576 | * @param data : (object) the raw google custom search response data 577 | */ 578 | self.buildMetadata = function(data) { 579 | if (data.queries && data.queries.request && data.queries.request[0].totalResults !== '0') { 580 | self.nav.current = data.queries.request[0].startIndex; 581 | self.nav.currentCount = data.queries.request[0].count; 582 | self.nav.total = parseInt(data.queries.request[0].totalResults); 583 | self.dom.modal_metadata.children('.total').html(self.nav.total); 584 | self.dom.modal_metadata.children('.range').html(self.nav.current + "-" + (self.nav.current+self.nav.currentCount-1)); 585 | self.dom.modal_metadata.show(); 586 | } 587 | else { 588 | self.dom.modal_metadata.hide(); 589 | } 590 | if (data.queries && data.queries.nextPage) { 591 | self.nav.next = data.queries.nextPage[0].startIndex; 592 | self.dom.btn_next.show(); 593 | } 594 | else { 595 | self.nav.next = -1; 596 | self.dom.btn_next.hide(); 597 | } 598 | if (data.queries && data.queries.previousPage) { 599 | self.nav.prev = data.queries.previousPage[0].startIndex; 600 | self.dom.btn_prev.show(); 601 | } 602 | else { 603 | self.nav.prev = -1; 604 | self.dom.btn_prev.hide(); 605 | } 606 | }; 607 | 608 | /** 609 | * Send a GET request 610 | * @param queryText : (string) the query text 611 | * @param startIndex : (int) the index of first item (start from 1) 612 | * @param callback : (function) 613 | */ 614 | self.query = function(queryText, startIndex, callback) { 615 | $.get(endpoint, { 616 | key: self.config.apiKey, 617 | cx: self.config.engineId, 618 | q: queryText, 619 | start: startIndex, 620 | num: self.config.per_page 621 | }, function(data, status) { 622 | if (status === 'success' && data.items && data.items.length > 0) { 623 | var results = self.buildResultList(data.items); 624 | self.dom.modal_results.html(results); 625 | } 626 | else { 627 | self.onQueryError(queryText, status); 628 | } 629 | self.buildMetadata(data); 630 | if (callback) { 631 | callback(); 632 | } 633 | }); 634 | }; 635 | 636 | return self; 637 | }; 638 | })(jQuery); 639 | var HexoSearch; 640 | 641 | (function($) { 642 | 'use strict'; 643 | 644 | /** 645 | * Search by Hexo generator json content 646 | * @param options : (object) 647 | */ 648 | HexoSearch = function(options) { 649 | SearchService.apply(this, arguments); 650 | var self = this; 651 | self.config.endpoint = ROOT + ((options||{}).endpoint || "content.json"); 652 | self.config.endpoint = self.config.endpoint.replace("//","/"); //make sure the url is correct 653 | self.cache = ""; 654 | 655 | /** 656 | * Search queryText in title and content of a post 657 | * Credit to: http://hahack.com/codes/local-search-engine-for-hexo/ 658 | * @param post : the post object 659 | * @param queryText : the search query 660 | */ 661 | self.contentSearch = function(post, queryText) { 662 | var post_title = post.title.trim().toLowerCase(), 663 | post_content = post.text.trim().toLowerCase(), 664 | keywords = queryText.trim().toLowerCase().split(" "), 665 | foundMatch = false, 666 | index_title = -1, 667 | index_content = -1, 668 | first_occur = -1; 669 | if (post_title !== '' && post_content !== '') { 670 | $.each(keywords, function(index, word) { 671 | index_title = post_title.indexOf(word); 672 | index_content = post_content.indexOf(word); 673 | if (index_title < 0 && index_content < 0) { 674 | foundMatch = false; 675 | } 676 | else { 677 | foundMatch = true; 678 | if (index_content < 0) { 679 | index_content = 0; 680 | } 681 | if (index === 0) { 682 | first_occur = index_content; 683 | } 684 | } 685 | if (foundMatch) { 686 | post_content = post.text.trim(); 687 | var start = 0, end = 0; 688 | if (first_occur >= 0) { 689 | start = Math.max(first_occur-30, 0); 690 | end = (start === 0) ? Math.min(200, post_content.length) : Math.min(first_occur+170, post_content.length); 691 | var match_content = post_content.substring(start, end); 692 | keywords.forEach(function(keyword) { 693 | var regS = new RegExp(keyword, "gi"); 694 | match_content = match_content.replace(regS, ""+keyword+""); 695 | }); 696 | post.digest = match_content; 697 | } 698 | else { 699 | end = Math.min(200, post_content.length); 700 | post.digest = post_content.trim().substring(0, end); 701 | } 702 | } 703 | }); 704 | } 705 | return foundMatch; 706 | }; 707 | 708 | /** 709 | * Generate result list html 710 | * @param data : (array) result items 711 | */ 712 | self.buildResultList = function(data, queryText) { 713 | var results = [], 714 | html = ""; 715 | $.each(data, function(index, post) { 716 | if (self.contentSearch(post, queryText)) 717 | html += self.buildResult(post.permalink, post.title, post.digest); 718 | }); 719 | return html; 720 | }; 721 | 722 | /** 723 | * Generate metadata after a successful query 724 | * @param data : (object) the raw google custom search response data 725 | */ 726 | self.buildMetadata = function(data) { 727 | self.dom.modal_footer.hide(); 728 | }; 729 | 730 | /** 731 | * Send a GET request 732 | * @param queryText : (string) the query text 733 | * @param startIndex : (int) the index of first item (start from 1) 734 | * @param callback : (function) 735 | */ 736 | self.query = function(queryText, startIndex, callback) { 737 | if (!self.cache) { 738 | $.get(self.config.endpoint, { 739 | key: self.config.apiKey, 740 | cx: self.config.engineId, 741 | q: queryText, 742 | start: startIndex, 743 | num: self.config.per_page 744 | }, function(data, status) { 745 | if (status !== 'success' || 746 | !data || 747 | (!data.posts && !data.pages) || 748 | (data.posts.length < 1 && data.pages.length < 1) 749 | ) { 750 | self.onQueryError(queryText, status); 751 | } 752 | else { 753 | self.cache = data; 754 | var results = ""; 755 | results += self.buildResultList(data.pages, queryText); 756 | results += self.buildResultList(data.posts, queryText); 757 | self.dom.modal_results.html(results); 758 | } 759 | self.buildMetadata(data); 760 | if (callback) { 761 | callback(data); 762 | } 763 | }); 764 | } 765 | else { 766 | var results = ""; 767 | results += self.buildResultList(self.cache.pages, queryText); 768 | results += self.buildResultList(self.cache.posts, queryText); 769 | self.dom.modal_results.html(results); 770 | self.buildMetadata(self.cache); 771 | if (callback) { 772 | callback(self.cache); 773 | } 774 | } 775 | }; 776 | 777 | return self; 778 | }; 779 | 780 | })(jQuery); 781 | -------------------------------------------------------------------------------- /categories/Coding/PSR/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Category: PSR | 搅拌糖 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 113 | 114 | 115 | 116 | 194 | 236 | 237 | 238 |
    239 | 240 | 241 |
    242 |
    243 | 244 |
    245 | 246 | 247 | 248 |
    249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
    260 | 355 | 356 |
    357 | 358 | 359 | 360 |
    361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 |
    374 | 716 | 717 |
    718 | 719 | 720 | 755 | 756 |
    757 |
    758 | 762 | 763 |
    764 | 766 |
    767 | 本站使用 768 | Material X 769 | 作为主题 770 | 771 | , 772 | 总访问量为 773 | 774 | 次 775 | 776 | 。 777 |
    778 |
    779 |
    780 | 781 | 782 | 783 |
    784 |
    785 | 786 |
    隐藏
    787 |
    788 | 789 | 792 | 793 | 794 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 |
    806 | 807 |
    808 | 809 | 810 | 824 | 825 | 826 | 827 | 828 | 829 | 837 | 838 | 839 | 840 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 984 | 985 | 986 | 987 | 988 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | -------------------------------------------------------------------------------- /tags/Cool/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Tag: Cool | 搅拌糖 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 113 | 114 | 115 | 116 | 194 | 236 | 237 | 238 |
    239 | 240 | 241 |
    242 |
    243 | 244 |
    245 | 246 | 247 | 248 |
    249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
    260 | 355 | 356 |
    357 | 358 | 359 | 360 |
    361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |
    373 | 715 | 716 |
    717 | 718 | 719 | 754 | 755 |
    756 |
    757 | 761 | 762 |
    763 | 765 |
    766 | 本站使用 767 | Material X 768 | 作为主题 769 | 770 | , 771 | 总访问量为 772 | 773 | 次 774 | 775 | 。 776 |
    777 |
    778 |
    779 | 780 | 781 | 782 |
    783 |
    784 | 785 |
    隐藏
    786 |
    787 | 788 | 791 | 792 | 793 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 |
    805 | 806 |
    807 | 808 | 809 | 823 | 824 | 825 | 826 | 827 | 828 | 836 | 837 | 838 | 839 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 983 | 984 | 985 | 986 | 987 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | -------------------------------------------------------------------------------- /tags/设计模式/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Tag: 设计模式 | 搅拌糖 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 113 | 114 | 115 | 116 | 194 | 236 | 237 | 238 |
    239 | 240 | 241 |
    242 |
    243 | 244 |
    245 | 246 | 247 | 248 |
    249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
    260 | 355 | 356 |
    357 | 358 | 359 | 360 |
    361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |
    373 | 715 | 716 |
    717 | 718 | 719 | 754 | 755 |
    756 |
    757 | 761 | 762 |
    763 | 765 |
    766 | 本站使用 767 | Material X 768 | 作为主题 769 | 770 | , 771 | 总访问量为 772 | 773 | 次 774 | 775 | 。 776 |
    777 |
    778 |
    779 | 780 | 781 | 782 |
    783 |
    784 | 785 |
    隐藏
    786 |
    787 | 788 | 791 | 792 | 793 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 |
    805 | 806 |
    807 | 808 | 809 | 823 | 824 | 825 | 826 | 827 | 828 | 836 | 837 | 838 | 839 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 983 | 984 | 985 | 986 | 987 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | -------------------------------------------------------------------------------- /categories/Coding/Design/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Category: Design | 搅拌糖 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 113 | 114 | 115 | 116 | 194 | 236 | 237 | 238 |
    239 | 240 | 241 |
    242 |
    243 | 244 |
    245 | 246 | 247 | 248 |
    249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
    260 | 355 | 356 |
    357 | 358 | 359 | 360 |
    361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 |
    374 | 716 | 717 |
    718 | 719 | 720 | 755 | 756 |
    757 |
    758 | 762 | 763 |
    764 | 766 |
    767 | 本站使用 768 | Material X 769 | 作为主题 770 | 771 | , 772 | 总访问量为 773 | 774 | 次 775 | 776 | 。 777 |
    778 |
    779 |
    780 | 781 | 782 | 783 |
    784 |
    785 | 786 |
    隐藏
    787 |
    788 | 789 | 792 | 793 | 794 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 | 805 |
    806 | 807 |
    808 | 809 | 810 | 824 | 825 | 826 | 827 | 828 | 829 | 837 | 838 | 839 | 840 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 862 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 903 | 984 | 985 | 986 | 987 | 988 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | 1013 | -------------------------------------------------------------------------------- /tags/Swoole/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Tag: Swoole | 搅拌糖 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
    53 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 113 | 114 | 115 | 116 | 194 | 236 | 237 | 238 |
    239 | 240 | 241 |
    242 |
    243 | 244 |
    245 | 246 | 247 | 248 |
    249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 |
    260 | 355 | 356 |
    357 | 358 | 359 | 360 |
    361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 |
    373 | 715 | 716 |
    717 | 718 | 719 | 754 | 755 |
    756 |
    757 | 761 | 762 |
    763 | 765 |
    766 | 本站使用 767 | Material X 768 | 作为主题 769 | 770 | , 771 | 总访问量为 772 | 773 | 次 774 | 775 | 。 776 |
    777 |
    778 |
    779 | 780 | 781 | 782 |
    783 |
    784 | 785 |
    隐藏
    786 |
    787 | 788 | 791 | 792 | 793 | 796 | 797 | 798 | 799 | 800 | 801 | 802 | 803 | 804 |
    805 | 806 |
    807 | 808 | 809 | 823 | 824 | 825 | 826 | 827 | 828 | 836 | 837 | 838 | 839 | 850 | 851 | 852 | 853 | 854 | 855 | 856 | 857 | 858 | 859 | 860 | 861 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | 893 | 894 | 895 | 896 | 897 | 898 | 899 | 900 | 901 | 902 | 983 | 984 | 985 | 986 | 987 | 1004 | 1005 | 1006 | 1007 | 1008 | 1009 | 1010 | 1011 | 1012 | --------------------------------------------------------------------------------