This commit is contained in:
2019-05-30 18:52:14 +08:00
commit aa360a22bf
341 changed files with 30369 additions and 0 deletions

View File

@ -0,0 +1,168 @@
/* ========================================================================
* Bootstrap: affix.js v3.3.5
* http://getbootstrap.com/javascript/#affix
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
/**
* Customized by Ivan.Nginx
*
* - Refactored with eslint-config-theme-next style.
*/
(function($) {
'use strict';
// AFFIX CLASS DEFINITION
// ======================
var Affix = function(element, options) {
this.options = $.extend({}, Affix.DEFAULTS, options);
this.$target = $(this.options.target)
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this));
this.$element = $(element);
this.affixed = null;
this.unpin = null;
this.pinnedOffset = null;
this.checkPosition();
};
Affix.VERSION = '3.3.5';
Affix.RESET = 'affix affix-top affix-bottom';
Affix.DEFAULTS = {
offset: 0,
target: window
};
Affix.prototype.getState = function(scrollHeight, height, offsetTop, offsetBottom) {
var scrollTop = this.$target.scrollTop();
var position = this.$element.offset();
var targetHeight = this.$target.height();
if (offsetTop != null && this.affixed === 'top') return scrollTop < offsetTop ? 'top' : false;
if (this.affixed === 'bottom') {
if (offsetTop != null) return scrollTop + this.unpin <= position.top ? false : 'bottom';
return scrollTop + targetHeight <= scrollHeight - offsetBottom ? false : 'bottom';
}
var initializing = this.affixed == null;
var colliderTop = initializing ? scrollTop : position.top;
var colliderHeight = initializing ? targetHeight : height;
if (offsetTop != null && scrollTop <= offsetTop) return 'top';
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom';
return false;
};
Affix.prototype.getPinnedOffset = function() {
if (this.pinnedOffset) return this.pinnedOffset;
this.$element.removeClass(Affix.RESET).addClass('affix');
var scrollTop = this.$target.scrollTop();
var position = this.$element.offset();
return (this.pinnedOffset = position.top - scrollTop);
};
Affix.prototype.checkPositionWithEventLoop = function() {
setTimeout($.proxy(this.checkPosition, this), 1);
};
Affix.prototype.checkPosition = function() {
if (!this.$element.is(':visible')) return;
var height = this.$element.height();
var offset = this.options.offset;
var offsetTop = offset.top;
var offsetBottom = offset.bottom;
var scrollHeight = Math.max($(document).height(), $(document.body).height());
/* eslint-disable */
if (typeof offset !== 'object') offsetBottom = offsetTop = offset;
if (typeof offsetTop === 'function') offsetTop = offset.top(this.$element);
if (typeof offsetBottom === 'function') offsetBottom = offset.bottom(this.$element);
/* eslint-enable */
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom);
if (this.affixed !== affix) {
if (this.unpin != null) this.$element.css('top', '');
var affixType = 'affix' + (affix ? '-' + affix : '');
var e = new $.Event(affixType + '.bs.affix');
this.$element.trigger(e);
if (e.isDefaultPrevented()) return;
this.affixed = affix;
this.unpin = affix === 'bottom' ? this.getPinnedOffset() : null;
this.$element
.removeClass(Affix.RESET)
.addClass(affixType)
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix');
}
if (affix === 'bottom') {
this.$element.offset({
top: scrollHeight - height - offsetBottom
});
}
};
// AFFIX PLUGIN DEFINITION
// =======================
function Plugin(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data('bs.affix');
var options = typeof option === 'object' && option;
if (!data) $this.data('bs.affix', data = new Affix(this, options));
if (typeof option === 'string') data[option]();
});
}
var old = $.fn.affix;
$.fn.affix = Plugin;
$.fn.affix.Constructor = Affix;
// AFFIX NO CONFLICT
// =================
$.fn.affix.noConflict = function() {
$.fn.affix = old;
return this;
};
// AFFIX DATA-API
// ==============
$(window).on('load', function() {
$('[data-spy="affix"]').each(function() {
var $spy = $(this);
var data = $spy.data();
data.offset = data.offset || {};
/* eslint-disable */
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom;
if (data.offsetTop != null) data.offset.top = data.offsetTop;
/* eslint-enable */
Plugin.call($spy, data);
});
});
}(jQuery));

View File

@ -0,0 +1,114 @@
/* global instantsearch, CONFIG */
$(document).ready(function() {
var algoliaSettings = CONFIG.algolia;
var isAlgoliaSettingsValid = algoliaSettings.applicationID
&& algoliaSettings.apiKey
&& algoliaSettings.indexName;
if (!isAlgoliaSettingsValid) {
window.console.error('Algolia Settings are invalid.');
return;
}
var search = instantsearch({
appId : algoliaSettings.applicationID,
apiKey : algoliaSettings.apiKey,
indexName : algoliaSettings.indexName,
searchFunction: function(helper) {
var searchInput = $('#algolia-search-input').find('input');
if (searchInput.val()) {
helper.search();
}
}
});
// Registering Widgets
[
instantsearch.widgets.searchBox({
container : '#algolia-search-input',
placeholder: algoliaSettings.labels.input_placeholder
}),
instantsearch.widgets.hits({
container : '#algolia-hits',
hitsPerPage: algoliaSettings.hits.per_page || 10,
templates : {
item: function(data) {
var link = data.permalink ? data.permalink : CONFIG.root + data.path;
return (
'<a href="' + link + '" class="algolia-hit-item-link">'
+ data._highlightResult.title.value
+ '</a>'
);
},
empty: function(data) {
return (
'<div id="algolia-hits-empty">'
+ algoliaSettings.labels.hits_empty.replace(/\$\{query}/, data.query)
+ '</div>'
);
}
},
cssClasses: {
item: 'algolia-hit-item'
}
}),
instantsearch.widgets.stats({
container: '#algolia-stats',
templates: {
body: function(data) {
var stats = algoliaSettings.labels.hits_stats
.replace(/\$\{hits}/, data.nbHits)
.replace(/\$\{time}/, data.processingTimeMS);
return (
stats
+ '<span class="algolia-powered">'
+ ' <img src="' + CONFIG.root + 'images/algolia_logo.svg" alt="Algolia" />'
+ '</span>'
+ '<hr />'
);
}
}
}),
instantsearch.widgets.pagination({
container : '#algolia-pagination',
scrollTo : false,
showFirstLast: false,
labels : {
first : '<i class="fa fa-angle-double-left"></i>',
last : '<i class="fa fa-angle-double-right"></i>',
previous: '<i class="fa fa-angle-left"></i>',
next : '<i class="fa fa-angle-right"></i>'
},
cssClasses: {
root : 'pagination',
item : 'pagination-item',
link : 'page-number',
active : 'current',
disabled: 'disabled-item'
}
})
].forEach(search.addWidget, search);
search.start();
$('.popup-trigger').on('click', function(e) {
e.stopPropagation();
$('body')
.append('<div class="search-popup-overlay algolia-pop-overlay"></div>')
.css('overflow', 'hidden');
$('.popup').toggle();
$('#algolia-search-input').find('input').focus();
});
$('.popup-btn-close').click(function() {
$('.popup').hide();
$('.algolia-pop-overlay').remove();
$('body').css('overflow', '');
});
});

View File

@ -0,0 +1,14 @@
$(document).ready(function() {
// Create Base64 Object
/* eslint-disable */
var Base64={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(e){var t="";var n,r,i,s,o,u,a;var f=0;e=Base64._utf8_encode(e);while(f<e.length){n=e.charCodeAt(f++);r=e.charCodeAt(f++);i=e.charCodeAt(f++);s=n>>2;o=(n&3)<<4|r>>4;u=(r&15)<<2|i>>6;a=i&63;if(isNaN(r)){u=a=64}else if(isNaN(i)){a=64}t=t+this._keyStr.charAt(s)+this._keyStr.charAt(o)+this._keyStr.charAt(u)+this._keyStr.charAt(a)}return t},decode:function(e){var t="";var n,r,i;var s,o,u,a;var f=0;e=e.replace(/[^A-Za-z0-9+/=]/g,"");while(f<e.length){s=this._keyStr.indexOf(e.charAt(f++));o=this._keyStr.indexOf(e.charAt(f++));u=this._keyStr.indexOf(e.charAt(f++));a=this._keyStr.indexOf(e.charAt(f++));n=s<<2|o>>4;r=(o&15)<<4|u>>2;i=(u&3)<<6|a;t=t+String.fromCharCode(n);if(u!=64){t=t+String.fromCharCode(r)}if(a!=64){t=t+String.fromCharCode(i)}}t=Base64._utf8_decode(t);return t},_utf8_encode:function(e){e=e.replace(/rn/g,"n");var t="";for(var n=0;n<e.length;n++){var r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r)}else if(r>127&&r<2048){t+=String.fromCharCode(r>>6|192);t+=String.fromCharCode(r&63|128)}else{t+=String.fromCharCode(r>>12|224);t+=String.fromCharCode(r>>6&63|128);t+=String.fromCharCode(r&63|128)}}return t},_utf8_decode:function(e){var t="";var n=0;var r=c1=c2=0;while(n<e.length){r=e.charCodeAt(n);if(r<128){t+=String.fromCharCode(r);n++}else if(r>191&&r<224){c2=e.charCodeAt(n+1);t+=String.fromCharCode((r&31)<<6|c2&63);n+=2}else{c2=e.charCodeAt(n+1);c3=e.charCodeAt(n+2);t+=String.fromCharCode((r&15)<<12|(c2&63)<<6|c3&63);n+=3}}return t}};
$('.exturl').on('click', function() {
var $exturl = $(this).attr('data-url');
var $decurl = Base64.decode($exturl);
window.open($decurl, '_blank');
return false;
});
});

View File

@ -0,0 +1,166 @@
/*!
* JavaScript Cookie v2.1.4
* https://github.com/js-cookie/js-cookie
*
* Copyright 2006, 2015 Klaus Hartl & Fagner Brack
* Released under the MIT license
*/
;(function (factory) {
var registeredInModuleLoader = false;
if (typeof define === 'function' && define.amd) {
define(factory);
registeredInModuleLoader = true;
}
if (typeof exports === 'object') {
module.exports = factory();
registeredInModuleLoader = true;
}
if (!registeredInModuleLoader) {
var OldCookies = window.Cookies;
var api = window.Cookies = factory();
api.noConflict = function () {
window.Cookies = OldCookies;
return api;
};
}
}(function () {
function extend () {
var i = 0;
var result = {};
for (; i < arguments.length; i++) {
var attributes = arguments[ i ];
for (var key in attributes) {
result[key] = attributes[key];
}
}
return result;
}
function init (converter) {
function api (key, value, attributes) {
var result;
if (typeof document === 'undefined') {
return;
}
// Write
if (arguments.length > 1) {
attributes = extend({
path: '/'
}, api.defaults, attributes);
if (typeof attributes.expires === 'number') {
var expires = new Date();
expires.setMilliseconds(expires.getMilliseconds() + attributes.expires * 864e+5);
attributes.expires = expires;
}
// We're using "expires" because "max-age" is not supported by IE
attributes.expires = attributes.expires ? attributes.expires.toUTCString() : '';
try {
result = JSON.stringify(value);
if (/^[\{\[]/.test(result)) {
value = result;
}
} catch (e) {}
if (!converter.write) {
value = encodeURIComponent(String(value))
.replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g, decodeURIComponent);
} else {
value = converter.write(value, key);
}
key = encodeURIComponent(String(key));
key = key.replace(/%(23|24|26|2B|5E|60|7C)/g, decodeURIComponent);
key = key.replace(/[\(\)]/g, escape);
var stringifiedAttributes = '';
for (var attributeName in attributes) {
if (!attributes[attributeName]) {
continue;
}
stringifiedAttributes += '; ' + attributeName;
if (attributes[attributeName] === true) {
continue;
}
stringifiedAttributes += '=' + attributes[attributeName];
}
return (document.cookie = key + '=' + value + stringifiedAttributes);
}
// Read
if (!key) {
result = {};
}
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling "get()"
var cookies = document.cookie ? document.cookie.split('; ') : [];
var rdecode = /(%[0-9A-Z]{2})+/g;
var i = 0;
for (; i < cookies.length; i++) {
var parts = cookies[i].split('=');
var cookie = parts.slice(1).join('=');
if (cookie.charAt(0) === '"') {
cookie = cookie.slice(1, -1);
}
try {
var name = parts[0].replace(rdecode, decodeURIComponent);
cookie = converter.read ?
converter.read(cookie, name) : converter(cookie, name) ||
cookie.replace(rdecode, decodeURIComponent);
if (this.json) {
try {
cookie = JSON.parse(cookie);
} catch (e) {}
}
if (key === name) {
result = cookie;
break;
}
if (!key) {
result[name] = cookie;
}
} catch (e) {}
}
return result;
}
api.set = api;
api.get = function (key) {
return api.call(api, key);
};
api.getJSON = function () {
return api.apply({
json: true
}, [].slice.call(arguments));
};
api.defaults = {};
api.remove = function (key, attributes) {
api(key, '', extend(attributes, {
expires: -1
}));
};
api.withConverter = init;
return api;
}
return init(function () {});
}));

View File

@ -0,0 +1,372 @@
/* global NexT, CONFIG */
$(document).ready(function() {
NexT.motion = {};
var sidebarToggleLines = {
lines: [],
push : function(line) {
this.lines.push(line);
},
init: function() {
this.lines.forEach(function(line) {
line.init();
});
},
arrow: function() {
this.lines.forEach(function(line) {
line.arrow();
});
},
close: function() {
this.lines.forEach(function(line) {
line.close();
});
}
};
function SidebarToggleLine(settings) {
this.el = $(settings.el);
this.status = $.extend({}, {
init: {
width : '100%',
opacity: 1,
left : 0,
rotateZ: 0,
top : 0
}
}, settings.status);
}
SidebarToggleLine.prototype.init = function() {
this.transform('init');
};
SidebarToggleLine.prototype.arrow = function() {
this.transform('arrow');
};
SidebarToggleLine.prototype.close = function() {
this.transform('close');
};
SidebarToggleLine.prototype.transform = function(status) {
this.el.velocity('stop').velocity(this.status[status]);
};
var sidebarToggleLine1st = new SidebarToggleLine({
el : '.sidebar-toggle-line-first',
status: {
arrow: {width: '50%', rotateZ: '-45deg', top: '2px'},
close: {width: '100%', rotateZ: '-45deg', top: '5px'}
}
});
var sidebarToggleLine2nd = new SidebarToggleLine({
el : '.sidebar-toggle-line-middle',
status: {
arrow: {width: '90%'},
close: {opacity: 0}
}
});
var sidebarToggleLine3rd = new SidebarToggleLine({
el : '.sidebar-toggle-line-last',
status: {
arrow: {width: '50%', rotateZ: '45deg', top: '-2px'},
close: {width: '100%', rotateZ: '45deg', top: '-5px'}
}
});
sidebarToggleLines.push(sidebarToggleLine1st);
sidebarToggleLines.push(sidebarToggleLine2nd);
sidebarToggleLines.push(sidebarToggleLine3rd);
var SIDEBAR_WIDTH = CONFIG.sidebar.width ? CONFIG.sidebar.width : '320px';
var SIDEBAR_DISPLAY_DURATION = 200;
var xPos, yPos;
var sidebarToggleMotion = {
toggleEl : $('.sidebar-toggle'),
dimmerEl : $('#sidebar-dimmer'),
sidebarEl : $('.sidebar'),
isSidebarVisible: false,
init : function() {
this.toggleEl.on('click', this.clickHandler.bind(this));
this.dimmerEl.on('click', this.clickHandler.bind(this));
this.toggleEl.on('mouseenter', this.mouseEnterHandler.bind(this));
this.toggleEl.on('mouseleave', this.mouseLeaveHandler.bind(this));
this.sidebarEl.on('touchstart', this.touchstartHandler.bind(this));
this.sidebarEl.on('touchend', this.touchendHandler.bind(this));
this.sidebarEl.on('touchmove', function(e) { e.preventDefault(); });
$(document)
.on('sidebar.isShowing', function() {
NexT.utils.isDesktop() && $('body').velocity('stop').velocity(
{paddingRight: SIDEBAR_WIDTH},
SIDEBAR_DISPLAY_DURATION
);
})
.on('sidebar.isHiding', function() {
});
},
clickHandler: function() {
this.isSidebarVisible ? this.hideSidebar() : this.showSidebar();
this.isSidebarVisible = !this.isSidebarVisible;
},
mouseEnterHandler: function() {
if (this.isSidebarVisible) {
return;
}
sidebarToggleLines.arrow();
},
mouseLeaveHandler: function() {
if (this.isSidebarVisible) {
return;
}
sidebarToggleLines.init();
},
touchstartHandler: function(e) {
xPos = e.originalEvent.touches[0].clientX;
yPos = e.originalEvent.touches[0].clientY;
},
touchendHandler: function(e) {
var _xPos = e.originalEvent.changedTouches[0].clientX;
var _yPos = e.originalEvent.changedTouches[0].clientY;
if (_xPos - xPos > 30 && Math.abs(_yPos - yPos) < 20) {
this.clickHandler();
}
},
showSidebar: function() {
var self = this;
sidebarToggleLines.close();
this.sidebarEl.velocity('stop').velocity({
width: SIDEBAR_WIDTH
}, {
display : 'block',
duration: SIDEBAR_DISPLAY_DURATION,
begin : function() {
$('.sidebar .motion-element').not('.site-state').velocity(
'transition.slideRightIn', {
stagger : 50,
drag : true,
complete: function() {
self.sidebarEl.trigger('sidebar.motion.complete');
}
}
);
$('.site-state').velocity(
'transition.slideRightIn', {
stagger : 50,
drag : true,
display : 'flex'
}
);
},
complete: function() {
self.sidebarEl.addClass('sidebar-active');
self.sidebarEl.trigger('sidebar.didShow');
}
});
this.sidebarEl.trigger('sidebar.isShowing');
},
hideSidebar: function() {
NexT.utils.isDesktop() && $('body').velocity('stop').velocity({paddingRight: 0});
this.sidebarEl.find('.motion-element').velocity('stop').css('display', 'none');
this.sidebarEl.velocity('stop').velocity({width: 0}, {display: 'none'});
sidebarToggleLines.init();
this.sidebarEl.removeClass('sidebar-active');
this.sidebarEl.trigger('sidebar.isHiding');
// Prevent adding TOC to Overview if Overview was selected when close & open sidebar.
if ($('.post-toc-wrap')) {
if ($('.site-overview-wrap').css('display') === 'block') {
$('.post-toc-wrap').removeClass('motion-element');
} else {
$('.post-toc-wrap').addClass('motion-element');
}
}
}
};
sidebarToggleMotion.init();
NexT.motion.integrator = {
queue : [],
cursor: -1,
add : function(fn) {
this.queue.push(fn);
return this;
},
next: function() {
this.cursor++;
var fn = this.queue[this.cursor];
$.isFunction(fn) && fn(NexT.motion.integrator);
},
bootstrap: function() {
this.next();
}
};
NexT.motion.middleWares = {
logo: function(integrator) {
var sequence = [];
var $brand = $('.brand');
var $image = $('.custom-logo-image');
var $title = $('.site-title');
var $subtitle = $('.site-subtitle');
var $logoLineTop = $('.logo-line-before i');
var $logoLineBottom = $('.logo-line-after i');
$brand.length > 0 && sequence.push({
e: $brand,
p: {opacity: 1},
o: {duration: 200}
});
/**
* Check if $elements exist.
* @param {jQuery|Array} $elements
* @returns {boolean}
*/
function hasElement($elements) {
$elements = Array.isArray($elements) ? $elements : [$elements];
return $elements.every(function($element) {
return $element.length > 0;
});
}
function getMistLineSettings(element, translateX) {
return {
e: $(element),
p: {translateX: translateX},
o: {
duration : 500,
sequenceQueue: false
}
};
}
function pushImageToSequence() {
sequence.push({
e: $image,
p: {opacity: 1, top: 0},
o: {duration: 200}
});
}
NexT.utils.isMist() && hasElement([$logoLineTop, $logoLineBottom])
&& sequence.push(
getMistLineSettings($logoLineTop, '100%'),
getMistLineSettings($logoLineBottom, '-100%')
);
NexT.utils.isMuse() && hasElement($image) && pushImageToSequence();
hasElement($title) && sequence.push({
e: $title,
p: {opacity: 1, top: 0},
o: {duration: 200}
});
hasElement($subtitle) && sequence.push({
e: $subtitle,
p: {opacity: 1, top: 0},
o: {duration: 200}
});
(NexT.utils.isPisces() || NexT.utils.isGemini()) && hasElement($image) && pushImageToSequence();
if (CONFIG.motion.async) {
integrator.next();
}
if (sequence.length > 0) {
sequence[sequence.length - 1].o.complete = function() {
integrator.next();
};
/* eslint-disable */
$.Velocity.RunSequence(sequence);
/* eslint-enable */
} else {
integrator.next();
}
},
menu: function(integrator) {
if (CONFIG.motion.async) {
integrator.next();
}
$('.menu-item').velocity('transition.slideDownIn', {
display : null,
duration: 200,
complete: function() {
integrator.next();
}
});
},
postList: function(integrator) {
//var $post = $('.post');
var $postBlock = $('.post-block, .pagination, .comments');
var $postBlockTransition = CONFIG.motion.transition.post_block;
var $postHeader = $('.post-header');
var $postHeaderTransition = CONFIG.motion.transition.post_header;
var $postBody = $('.post-body');
var $postBodyTransition = CONFIG.motion.transition.post_body;
var $collHeader = $('.collection-title, .archive-year');
var $collHeaderTransition = CONFIG.motion.transition.coll_header;
var $sidebarAffix = $('.sidebar-inner');
var $sidebarAffixTransition = CONFIG.motion.transition.sidebar;
var hasPost = $postBlock.length > 0;
function postMotion() {
var postMotionOptions = window.postMotionOptions || {
stagger: 100,
drag : true
};
postMotionOptions.complete = function() {
// After motion complete need to remove transform from sidebar to let affix work on Pisces | Gemini.
if (CONFIG.motion.transition.sidebar && (NexT.utils.isPisces() || NexT.utils.isGemini())) {
$sidebarAffix.css({ 'transform': 'initial' });
}
integrator.next();
};
//$post.velocity('transition.slideDownIn', postMotionOptions);
if (CONFIG.motion.transition.post_block) {
$postBlock.velocity('transition.' + $postBlockTransition, postMotionOptions);
}
if (CONFIG.motion.transition.post_header) {
$postHeader.velocity('transition.' + $postHeaderTransition, postMotionOptions);
}
if (CONFIG.motion.transition.post_body) {
$postBody.velocity('transition.' + $postBodyTransition, postMotionOptions);
}
if (CONFIG.motion.transition.coll_header) {
$collHeader.velocity('transition.' + $collHeaderTransition, postMotionOptions);
}
// Only for Pisces | Gemini.
if (CONFIG.motion.transition.sidebar && (NexT.utils.isPisces() || NexT.utils.isGemini())) {
$sidebarAffix.velocity('transition.' + $sidebarAffixTransition, postMotionOptions);
}
}
hasPost ? postMotion() : integrator.next();
if (CONFIG.motion.async) {
integrator.next();
}
},
sidebar: function(integrator) {
if (CONFIG.sidebar.display === 'always') {
NexT.utils.displaySidebar();
}
integrator.next();
}
};
});

View File

@ -0,0 +1,53 @@
/* global NexT, CONFIG */
$(document).ready(function() {
$(document).trigger('bootstrap:before');
/**
* Register JS handlers by condition option.
* Need to add config option in Front-End at 'layout/_partials/head.swig' file.
*/
CONFIG.fastclick && NexT.utils.isMobile() && window.FastClick.attach(document.body);
CONFIG.lazyload && NexT.utils.lazyLoadPostsImages();
NexT.utils.registerESCKeyEvent();
CONFIG.back2top && NexT.utils.registerBackToTop();
// Mobile top menu bar.
$('.site-nav-toggle button').on('click', function() {
var $siteNav = $('.site-nav');
var ON_CLASS_NAME = 'site-nav-on';
var isSiteNavOn = $siteNav.hasClass(ON_CLASS_NAME);
var animateAction = isSiteNavOn ? 'slideUp' : 'slideDown';
var animateCallback = isSiteNavOn ? 'removeClass' : 'addClass';
$siteNav.stop()[animateAction]('fast', function() {
$siteNav[animateCallback](ON_CLASS_NAME);
});
});
/**
* Register JS handlers by condition option.
* Need to add config option in Front-End at 'layout/_partials/head.swig' file.
*/
CONFIG.fancybox && NexT.utils.wrapImageWithFancyBox();
CONFIG.tabs && NexT.utils.registerTabsTag();
NexT.utils.embeddedVideoTransformer();
// Define Motion Sequence.
NexT.motion.integrator
.add(NexT.motion.middleWares.logo)
.add(NexT.motion.middleWares.menu)
.add(NexT.motion.middleWares.postList)
.add(NexT.motion.middleWares.sidebar);
$(document).trigger('motion:before');
// Bootstrap Motion.
CONFIG.motion.enable && NexT.motion.integrator.bootstrap();
$(document).trigger('bootstrap:after');
});

View File

@ -0,0 +1,104 @@
/* global NexT, CONFIG */
$(document).ready(function() {
function initScrollSpy() {
var tocSelector = '.post-toc';
var $tocElement = $(tocSelector);
var activeCurrentSelector = '.active-current';
function removeCurrentActiveClass() {
$(tocSelector + ' ' + activeCurrentSelector)
.removeClass(activeCurrentSelector.substring(1));
}
$tocElement
.on('activate.bs.scrollspy', function() {
var $currentActiveElement = $(tocSelector + ' .active').last();
removeCurrentActiveClass();
$currentActiveElement.addClass('active-current');
// Scrolling to center active TOC element if TOC content is taller then viewport.
$tocElement.scrollTop($currentActiveElement.offset().top - $tocElement.offset().top + $tocElement.scrollTop() - ($tocElement.height() / 2));
})
.on('clear.bs.scrollspy', removeCurrentActiveClass);
$('body').scrollspy({ target: tocSelector });
}
initScrollSpy();
});
$(document).ready(function() {
var html = $('html');
var TAB_ANIMATE_DURATION = 200;
var hasVelocity = $.isFunction(html.velocity);
$('.sidebar-nav li').on('click', function() {
var item = $(this);
var activeTabClassName = 'sidebar-nav-active';
var activePanelClassName = 'sidebar-panel-active';
if (item.hasClass(activeTabClassName)) {
return;
}
var currentTarget = $('.' + activePanelClassName);
var target = $('.' + item.data('target'));
hasVelocity
? currentTarget.velocity('transition.slideUpOut', TAB_ANIMATE_DURATION, function() {
target
.velocity('stop')
.velocity('transition.slideDownIn', TAB_ANIMATE_DURATION)
.addClass(activePanelClassName);
})
: currentTarget.animate({ opacity: 0 }, TAB_ANIMATE_DURATION, function() {
currentTarget.hide();
target
.stop()
.css({'opacity': 0, 'display': 'block'})
.animate({ opacity: 1 }, TAB_ANIMATE_DURATION, function() {
currentTarget.removeClass(activePanelClassName);
target.addClass(activePanelClassName);
});
});
item.siblings().removeClass(activeTabClassName);
item.addClass(activeTabClassName);
});
// TOC item animation navigate & prevent #item selector in adress bar.
$('.post-toc a').on('click', function(e) {
e.preventDefault();
var targetSelector = NexT.utils.escapeSelector(this.getAttribute('href'));
var offset = $(targetSelector).offset().top;
hasVelocity
? html.velocity('stop').velocity('scroll', {
offset : offset + 'px',
mobileHA: false
})
: $('html, body').stop().animate({
scrollTop: offset
}, 500);
});
// Expand sidebar on post detail page by default, when post has a toc.
var $tocContent = $('.post-toc-content');
var display = CONFIG.page.sidebar;
if (typeof display !== 'boolean') {
// There's no definition sidebar in the page front-matter
var isSidebarCouldDisplay = CONFIG.sidebar.display === 'post'
|| CONFIG.sidebar.display === 'always';
var hasTOC = $tocContent.length > 0 && $tocContent.html().trim().length > 0;
display = isSidebarCouldDisplay && hasTOC;
}
if (display) {
CONFIG.motion.enable
? NexT.motion.middleWares.sidebar = function() {
NexT.utils.displaySidebar();
}
: NexT.utils.displaySidebar();
}
});

View File

@ -0,0 +1,9 @@
$(document).ready(function() {
function updateFooterPosition() {
var containerHeight = $('#footer').attr('position') ? $('.container').height() + $('#footer').outerHeight(true) : $('.container').height();
if (containerHeight < window.innerHeight) $('#footer').css({ 'position': 'fixed', 'bottom': 0, 'left': 0, 'right': 0 }).attr('position', 'fixed');
else $('#footer').removeAttr('style position');
}
updateFooterPosition();
$(window).on('resize scroll', updateFooterPosition);
});

View File

@ -0,0 +1,57 @@
/* global NexT, CONFIG */
$(document).ready(function() {
var sidebarInner = $('.sidebar-inner');
var sidebarOffset = CONFIG.sidebar.offset || 12;
function getHeaderOffset() {
return $('.header-inner').height() + sidebarOffset;
}
function getFooterOffset() {
var footer = $('#footer');
var footerInner = $('.footer-inner');
var footerMargin = footer.outerHeight() - footerInner.outerHeight();
var footerOffset = footer.outerHeight() + footerMargin;
return footerOffset;
}
function initAffix() {
var headerOffset = getHeaderOffset();
var footerOffset = getFooterOffset();
var sidebarHeight = $('#sidebar').height() + NexT.utils.getSidebarb2tHeight();
var contentHeight = $('#content').height();
// Not affix if sidebar taller than content (to prevent bottom jumping).
if (headerOffset + sidebarHeight < contentHeight) {
sidebarInner.affix({
offset: {
top : headerOffset - sidebarOffset,
bottom: footerOffset
}
});
sidebarInner.affix('checkPosition');
}
$('#sidebar').css({ 'margin-top': headerOffset, 'margin-left': 'auto' });
}
function recalculateAffixPosition() {
$(window).off('.affix');
sidebarInner.removeData('bs.affix').removeClass('affix affix-top affix-bottom');
initAffix();
}
function resizeListener() {
var mql = window.matchMedia('(min-width: 992px)');
mql.addListener(function(e) {
if (e.matches) {
recalculateAffixPosition();
}
});
}
initAffix();
resizeListener();
});

View File

@ -0,0 +1,25 @@
$(document).ready(function() {
/* global Cookies */
// Set relative link path (without domain)
var rpath = window.location.href.replace(window.location.origin, '');
// Write position in cookie
var timeout;
$(window).on('scroll', function() {
clearTimeout(timeout);
timeout = setTimeout(function() {
Cookies.set('scroll-cookie', $(window).scrollTop() + '|' + rpath, { expires: 365, path: '' });
}, 250);
});
// Read position from cookie
if (Cookies.get('scroll-cookie') !== undefined) {
var cvalues = Cookies.get('scroll-cookie').split('|');
if (cvalues[1] === rpath) {
$(window).scrollTop(cvalues[0]);
}
}
});

View File

@ -0,0 +1,179 @@
/* ========================================================================
* Bootstrap: scrollspy.js v3.3.2
* http://getbootstrap.com/javascript/#scrollspy
* ========================================================================
* Copyright 2011-2015 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
/**
* Customized by iissnan & Ivan.Nginx
*
* - Add a `clear.bs.scrollspy` event.
* - Esacpe targets selector.
* - Refactored with eslint-config-theme-next style.
*/
/* global NexT */
(function($) {
'use strict';
// SCROLLSPY CLASS DEFINITION
// ==========================
function ScrollSpy(element, options) {
this.$body = $(document.body);
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element);
this.options = $.extend({}, ScrollSpy.DEFAULTS, options);
this.selector = (this.options.target || '') + ' .nav li > a';
this.offsets = [];
this.targets = [];
this.activeTarget = null;
this.scrollHeight = 0;
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this));
this.refresh();
this.process();
}
ScrollSpy.VERSION = '3.3.2';
ScrollSpy.DEFAULTS = {
offset: 10
};
ScrollSpy.prototype.getScrollHeight = function() {
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight);
};
ScrollSpy.prototype.refresh = function() {
var that = this;
var offsetMethod = 'offset';
var offsetBase = 0;
this.offsets = [];
this.targets = [];
this.scrollHeight = this.getScrollHeight();
if (!$.isWindow(this.$scrollElement[0])) {
offsetMethod = 'position';
offsetBase = this.$scrollElement.scrollTop();
}
this.$body
.find(this.selector)
.map(function() {
var $el = $(this);
var href = $el.data('target') || $el.attr('href');
var $href = /^#./.test(href) && $(NexT.utils.escapeSelector(href)); // Need to escape selector.
return ($href
&& $href.length
&& $href.is(':visible')
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null;
})
.sort(function(a, b) {
return a[0] - b[0];
})
.each(function() {
that.offsets.push(this[0]);
that.targets.push(this[1]);
});
};
ScrollSpy.prototype.process = function() {
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset;
var scrollHeight = this.getScrollHeight();
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height();
var offsets = this.offsets;
var targets = this.targets;
var activeTarget = this.activeTarget;
var i;
if (this.scrollHeight !== scrollHeight) {
this.refresh();
}
if (scrollTop >= maxScroll) {
return activeTarget !== (i = targets[targets.length - 1]) && this.activate(i);
}
if (activeTarget && scrollTop < offsets[0]) {
$(this.selector).trigger('clear.bs.scrollspy'); // Add a custom event.
this.activeTarget = null;
return this.clear();
}
for (i = offsets.length; i--;) {
activeTarget !== targets[i]
&& scrollTop >= offsets[i]
&& (!offsets[i + 1] || scrollTop <= offsets[i + 1])
&& this.activate(targets[i]);
}
};
ScrollSpy.prototype.activate = function(target) {
this.activeTarget = target;
this.clear();
var selector = this.selector
+ '[data-target="' + target + '"],'
+ this.selector + '[href="' + target + '"]';
var active = $(selector)
.parents('li')
.addClass('active');
if (active.parent('.dropdown-menu').length) {
active = active
.closest('li.dropdown')
.addClass('active');
}
active.trigger('activate.bs.scrollspy');
};
ScrollSpy.prototype.clear = function() {
$(this.selector)
.parentsUntil(this.options.target, '.active')
.removeClass('active');
};
// SCROLLSPY PLUGIN DEFINITION
// ===========================
function Plugin(option) {
return this.each(function() {
var $this = $(this);
var data = $this.data('bs.scrollspy');
var options = typeof option === 'object' && option;
if (!data) $this.data('bs.scrollspy', data = new ScrollSpy(this, options));
if (typeof option === 'string') data[option]();
});
}
var old = $.fn.scrollspy;
$.fn.scrollspy = Plugin;
$.fn.scrollspy.Constructor = ScrollSpy;
// SCROLLSPY NO CONFLICT
// =====================
$.fn.scrollspy.noConflict = function() {
$.fn.scrollspy = old;
return this;
};
// SCROLLSPY DATA-API
// ==================
$(window).on('load.bs.scrollspy.data-api', function() {
$('[data-spy="scroll"]').each(function() {
var $spy = $(this);
Plugin.call($spy, $spy.data());
});
});
}(jQuery));

View File

@ -0,0 +1,340 @@
/* global NexT, CONFIG */
NexT.utils = NexT.$u = {
/**
* Wrap images with fancybox support.
*/
wrapImageWithFancyBox: function() {
$('.content img')
.not(':hidden')
.each(function() {
var $image = $(this);
var imageTitle = $image.attr('title') || $image.attr('alt');
var $imageWrapLink = $image.parent('a');
if ($imageWrapLink.length < 1) {
var imageLink = $image.attr('data-original') || $image.attr('src');
$imageWrapLink = $image.wrap('<a class="fancybox fancybox.image" href="' + imageLink + '" itemscope itemtype="http://schema.org/ImageObject" itemprop="url"></a>').parent('a');
if ($image.is('.post-gallery img')) {
$imageWrapLink.addClass('post-gallery-img');
$imageWrapLink.attr('data-fancybox', 'gallery').attr('rel', 'gallery');
}
else if ($image.is('.group-picture img')) {
$imageWrapLink.attr('data-fancybox', 'group').attr('rel', 'group');
}
else {
$imageWrapLink.attr('data-fancybox', 'default').attr('rel', 'default');
}
}
if (imageTitle) {
$imageWrapLink.append('<p class="image-caption">' + imageTitle + '</p>');
// Make sure img title tag will show correctly in fancybox
$imageWrapLink.attr('title', imageTitle).attr('data-caption', imageTitle);
}
});
$('.fancybox').fancybox({
loop: true,
helpers: {
overlay: {
locked: false
}
}
});
},
lazyLoadPostsImages: function() {
$('#posts').find('img').lazyload({
//placeholder: '/images/loading.gif',
effect : 'fadeIn',
threshold: 0
});
},
/**
* Tabs tag listener (without twitter bootstrap).
*/
registerTabsTag: function() {
var tNav = '.tabs ul.nav-tabs ';
// Binding `nav-tabs` & `tab-content` by real time permalink changing.
$(function() {
$(window).bind('hashchange', function() {
var tHash = location.hash;
if (tHash !== '' && !tHash.match(/%\S{2}/)) {
$(tNav + 'li:has(a[href="' + tHash + '"])').addClass('active').siblings().removeClass('active');
$(tHash).addClass('active').siblings().removeClass('active');
}
}).trigger('hashchange');
});
$(tNav + '.tab').on('click', function(href) {
href.preventDefault();
// Prevent selected tab to select again.
if (!$(this).hasClass('active')) {
// Add & Remove active class on `nav-tabs` & `tab-content`.
$(this).addClass('active').siblings().removeClass('active');
var tActive = $(this).find('a').attr('href');
$(tActive).addClass('active').siblings().removeClass('active');
// Clear location hash in browser if #permalink exists.
if (location.hash !== '') {
history.pushState('', document.title, window.location.pathname + window.location.search);
}
}
});
},
registerESCKeyEvent: function() {
$(document).on('keyup', function(event) {
var shouldDismissSearchPopup = event.which === 27
&& $('.search-popup').is(':visible');
if (shouldDismissSearchPopup) {
$('.search-popup').hide();
$('.search-popup-overlay').remove();
$('body').css('overflow', '');
}
});
},
registerBackToTop: function() {
var THRESHOLD = 50;
var $top = $('.back-to-top');
function initBackToTop() {
$top.toggleClass('back-to-top-on', window.pageYOffset > THRESHOLD);
var scrollTop = $(window).scrollTop();
var contentVisibilityHeight = NexT.utils.getContentVisibilityHeight();
var scrollPercent = scrollTop / contentVisibilityHeight;
var scrollPercentRounded = Math.round(scrollPercent * 100);
var scrollPercentMaxed = scrollPercentRounded > 100 ? 100 : scrollPercentRounded;
$('#scrollpercent>span').html(scrollPercentMaxed);
}
// For init back to top in sidebar if page was scrolled after page refresh.
$(window).on('load', function() {
initBackToTop();
});
$(window).on('scroll', function() {
initBackToTop();
});
$top.on('click', function() {
$.isFunction($('html').velocity) ? $('body').velocity('scroll') : $('html, body').animate({ scrollTop: 0 });
});
},
/**
* Transform embedded video to support responsive layout.
* @see http://toddmotto.com/fluid-and-responsive-youtube-and-vimeo-videos-with-fluidvids-js/
*/
embeddedVideoTransformer: function() {
var $iframes = $('iframe');
// Supported Players. Extend this if you need more players.
var SUPPORTED_PLAYERS = [
'www.youtube.com',
'player.vimeo.com',
'player.youku.com',
'music.163.com',
'www.tudou.com'
];
var pattern = new RegExp(SUPPORTED_PLAYERS.join('|'));
function getDimension($element) {
return {
width : $element.width(),
height: $element.height()
};
}
function getAspectRadio(width, height) {
return height / width * 100;
}
$iframes.each(function() {
var iframe = this;
var $iframe = $(this);
var oldDimension = getDimension($iframe);
var newDimension;
if (this.src.search(pattern) > 0) {
// Calculate the video ratio based on the iframe's w/h dimensions
var videoRatio = getAspectRadio(oldDimension.width, oldDimension.height);
// Replace the iframe's dimensions and position the iframe absolute
// This is the trick to emulate the video ratio
$iframe.width('100%').height('100%')
.css({
position: 'absolute',
top : '0',
left : '0'
});
// Wrap the iframe in a new <div> which uses a dynamically fetched padding-top property
// based on the video's w/h dimensions
var wrap = document.createElement('div');
wrap.className = 'fluid-vids';
wrap.style.position = 'relative';
wrap.style.marginBottom = '20px';
wrap.style.width = '100%';
wrap.style.paddingTop = videoRatio + '%';
// Fix for appear inside tabs tag.
(wrap.style.paddingTop === '') && (wrap.style.paddingTop = '50%');
// Add the iframe inside our newly created <div>
var iframeParent = iframe.parentNode;
iframeParent.insertBefore(wrap, iframe);
wrap.appendChild(iframe);
// Additional adjustments for 163 Music
if (this.src.search('music.163.com') > 0) {
newDimension = getDimension($iframe);
var shouldRecalculateAspect = newDimension.width > oldDimension.width
|| newDimension.height < oldDimension.height;
// 163 Music Player has a fixed height, so we need to reset the aspect radio
if (shouldRecalculateAspect) {
wrap.style.paddingTop = getAspectRadio(newDimension.width, oldDimension.height) + '%';
}
}
}
});
},
hasMobileUA: function() {
var nav = window.navigator;
var ua = nav.userAgent;
var pa = /iPad|iPhone|Android|Opera Mini|BlackBerry|webOS|UCWEB|Blazer|PSP|IEMobile|Symbian/g;
return pa.test(ua);
},
isTablet: function() {
return window.screen.width < 992 && window.screen.width > 767 && this.hasMobileUA();
},
isMobile: function() {
return window.screen.width < 767 && this.hasMobileUA();
},
isDesktop: function() {
return !this.isTablet() && !this.isMobile();
},
/**
* Escape meta symbols in jQuery selectors.
*
* @param selector
* @returns {string|void|XML|*}
*/
escapeSelector: function(selector) {
return selector.replace(/[!"$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, '\\$&');
},
displaySidebar: function() {
if (!this.isDesktop() || this.isPisces() || this.isGemini()) {
return;
}
$('.sidebar-toggle').trigger('click');
},
isMuse: function() {
return CONFIG.scheme === 'Muse';
},
isMist: function() {
return CONFIG.scheme === 'Mist';
},
isPisces: function() {
return CONFIG.scheme === 'Pisces';
},
isGemini: function() {
return CONFIG.scheme === 'Gemini';
},
getScrollbarWidth: function() {
var $div = $('<div />').addClass('scrollbar-measure').prependTo('body');
var div = $div[0];
var scrollbarWidth = div.offsetWidth - div.clientWidth;
$div.remove();
return scrollbarWidth;
},
getContentVisibilityHeight: function() {
var docHeight = $('.container').height();
var winHeight = $(window).height();
var contentVisibilityHeight = docHeight > winHeight ? docHeight - winHeight : $(document).height() - winHeight;
return contentVisibilityHeight;
},
getSidebarb2tHeight: function() {
var sidebarb2tHeight = (CONFIG.back2top && CONFIG.back2top_sidebar) ? $('.back-to-top').height() : 0;
return sidebarb2tHeight;
},
getSidebarSchemePadding: function() {
var sidebarNavHeight = $('.sidebar-nav').css('display') === 'block' ? $('.sidebar-nav').outerHeight(true) : 0;
var sidebarInner = $('.sidebar-inner');
var sidebarPadding = sidebarInner.innerWidth() - sidebarInner.width();
var sidebarOffset = CONFIG.sidebar.offset ? CONFIG.sidebar.offset : 12;
var sidebarSchemePadding = this.isPisces() || this.isGemini()
? (sidebarPadding * 2) + sidebarNavHeight + sidebarOffset + this.getSidebarb2tHeight()
: (sidebarPadding * 2) + (sidebarNavHeight / 2);
return sidebarSchemePadding;
}
};
$(document).ready(function() {
function wrapTable() {
$('table').not('.gist table').wrap('<div class="table-container"></div>');
}
/**
* Init Sidebar & TOC inner dimensions on all pages and for all schemes.
* Need for Sidebar/TOC inner scrolling if content taller then viewport.
*/
function updateSidebarHeight(height) {
height = height || 'auto';
$('.site-overview, .post-toc').css('max-height', height);
}
function initSidebarDimension() {
var updateSidebarHeightTimer;
$(window).on('resize', function() {
updateSidebarHeightTimer && clearTimeout(updateSidebarHeightTimer);
updateSidebarHeightTimer = setTimeout(function() {
var sidebarWrapperHeight = document.body.clientHeight - NexT.utils.getSidebarSchemePadding();
updateSidebarHeight(sidebarWrapperHeight);
}, 0);
});
// Initialize Sidebar & TOC Width.
var scrollbarWidth = NexT.utils.getScrollbarWidth();
if ($('.site-overview-wrap').height() > (document.body.clientHeight - NexT.utils.getSidebarSchemePadding())) {
$('.site-overview').css('width', 'calc(100% + ' + scrollbarWidth + 'px)');
}
if ($('.post-toc-wrap').height() > (document.body.clientHeight - NexT.utils.getSidebarSchemePadding())) {
$('.post-toc').css('width', 'calc(100% + ' + scrollbarWidth + 'px)');
}
// Initialize Sidebar & TOC Height.
updateSidebarHeight(document.body.clientHeight - NexT.utils.getSidebarSchemePadding());
}
initSidebarDimension();
wrapTable();
});