summaryrefslogtreecommitdiff
path: root/_includes/scripts
diff options
context:
space:
mode:
Diffstat (limited to '_includes/scripts')
-rw-r--r--_includes/scripts/archieve.js135
-rw-r--r--_includes/scripts/article.js24
-rw-r--r--_includes/scripts/aside/affix.js26
-rw-r--r--_includes/scripts/aside/toc.js35
-rw-r--r--_includes/scripts/common.js7
-rw-r--r--_includes/scripts/components/lightbox.js49
-rw-r--r--_includes/scripts/components/search.js86
-rw-r--r--_includes/scripts/components/sidebar.js30
-rw-r--r--_includes/scripts/home.js3
-rw-r--r--_includes/scripts/lib/affix.js111
-rw-r--r--_includes/scripts/lib/gallery.js192
-rw-r--r--_includes/scripts/lib/lazyload.js143
-rw-r--r--_includes/scripts/lib/modal.js64
-rw-r--r--_includes/scripts/lib/scroll-to.js13
-rw-r--r--_includes/scripts/lib/swiper.js203
-rw-r--r--_includes/scripts/lib/throttle.js28
-rw-r--r--_includes/scripts/lib/toc.js107
-rw-r--r--_includes/scripts/page.js3
-rw-r--r--_includes/scripts/utils/imagesLoad.js28
-rw-r--r--_includes/scripts/utils/utils.js39
-rw-r--r--_includes/scripts/variables.html35
21 files changed, 1361 insertions, 0 deletions
diff --git a/_includes/scripts/archieve.js b/_includes/scripts/archieve.js
new file mode 100644
index 0000000..96549b5
--- /dev/null
+++ b/_includes/scripts/archieve.js
@@ -0,0 +1,135 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ function queryString() {
+ // This function is anonymous, is executed immediately and
+ // the return value is assigned to QueryString!
+ var i = 0, queryObj = {}, pair;
+ var queryStr = window.location.search.substring(1);
+ var queryArr = queryStr.split('&');
+ for (i = 0; i < queryArr.length; i++) {
+ pair = queryArr[i].split('=');
+ // If first entry with this name
+ if (typeof queryObj[pair[0]] === 'undefined') {
+ queryObj[pair[0]] = pair[1];
+ // If second entry with this name
+ } else if (typeof queryObj[pair[0]] === 'string') {
+ queryObj[pair[0]] = [queryObj[pair[0]], pair[1]];
+ // If third or later entry with this name
+ } else {
+ queryObj[pair[0]].push(pair[1]);
+ }
+ }
+ return queryObj;
+ }
+
+ var setUrlQuery = (function() {
+ var baseUrl = window.location.href.split('?')[0];
+ return function(query) {
+ if (typeof query === 'string') {
+ window.history.replaceState(null, '', baseUrl + query);
+ } else {
+ window.history.replaceState(null, '', baseUrl);
+ }
+ };
+ })();
+
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $tags = $('.js-tags');
+ var $articleTags = $tags.find('button');
+ var $tagShowAll = $tags.find('.tag-button--all');
+ var $result = $('.js-result');
+ var $sections = $result.find('section');
+ var sectionArticles = [];
+ var $lastFocusButton = null;
+ var sectionTopArticleIndex = [];
+ var hasInit = false;
+
+ $sections.each(function() {
+ sectionArticles.push($(this).find('.item'));
+ });
+
+ function init() {
+ var i, index = 0;
+ for (i = 0; i < $sections.length; i++) {
+ sectionTopArticleIndex.push(index);
+ index += $sections.eq(i).find('.item').length;
+ }
+ sectionTopArticleIndex.push(index);
+ }
+
+ function searchButtonsByTag(_tag/*raw tag*/) {
+ if (!_tag) {
+ return $tagShowAll;
+ }
+ var _buttons = $articleTags.filter('[data-encode="' + _tag + '"]');
+ if (_buttons.length === 0) {
+ return $tagShowAll;
+ }
+ return _buttons;
+ }
+ function buttonFocus(target) {
+ if (target) {
+ target.addClass('focus');
+ $lastFocusButton && !$lastFocusButton.is(target) && $lastFocusButton.removeClass('focus');
+ $lastFocusButton = target;
+ }
+ }
+
+ function tagSelect (tag/*raw tag*/, target) {
+ var result = {}, $articles;
+ var i, j, k, _tag;
+
+ for (i = 0; i < sectionArticles.length; i++) {
+ $articles = sectionArticles[i];
+ for (j = 0; j < $articles.length; j++) {
+ if (tag === '' || tag === undefined) {
+ result[i] || (result[i] = {});
+ result[i][j] = true;
+ } else {
+ var tags = $articles.eq(j).data('tags').split(',');
+ for (k = 0; k < tags.length; k++) {
+ if (tags[k] === tag) {
+ result[i] || (result[i] = {});
+ result[i][j] = true; break;
+ }
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < sectionArticles.length; i++) {
+ result[i] && $sections.eq(i).removeClass('d-none');
+ result[i] || $sections.eq(i).addClass('d-none');
+ for (j = 0; j < sectionArticles[i].length; j++) {
+ if (result[i] && result[i][j]) {
+ sectionArticles[i].eq(j).removeClass('d-none');
+ } else {
+ sectionArticles[i].eq(j).addClass('d-none');
+ }
+ }
+ }
+
+ hasInit || ($result.removeClass('d-none'), hasInit = true);
+
+
+ if (target) {
+ buttonFocus(target);
+ _tag = target.attr('data-encode');
+ if (_tag === '' || typeof _tag !== 'string') {
+ setUrlQuery();
+ } else {
+ setUrlQuery('?tag=' + _tag);
+ }
+ } else {
+ buttonFocus(searchButtonsByTag(tag));
+ }
+ }
+
+ var query = queryString(), _tag = query.tag;
+ init(); tagSelect(_tag);
+ $tags.on('click', 'button', function() {
+ tagSelect($(this).data('encode'), $(this));
+ });
+
+ });
+})();
diff --git a/_includes/scripts/article.js b/_includes/scripts/article.js
new file mode 100644
index 0000000..9b18ef5
--- /dev/null
+++ b/_includes/scripts/article.js
@@ -0,0 +1,24 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ $(function() {
+ var $this ,$scroll;
+ var $articleContent = $('.js-article-content');
+ var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
+ var scroll = hasSidebar ? '.js-page-main' : 'html, body';
+ $scroll = $(scroll);
+
+ $articleContent.find('.highlight').each(function() {
+ $this = $(this);
+ $this.attr('data-lang', $this.find('code').attr('data-lang'));
+ });
+ $articleContent.find('h1[id], h2[id], h3[id], h4[id], h5[id], h6[id]').each(function() {
+ $this = $(this);
+ $this.append($('<a class="anchor d-print-none" aria-hidden="true"></a>').html('<i class="fas fa-anchor"></i>'));
+ });
+ $articleContent.on('click', '.anchor', function() {
+ $scroll.scrollToAnchor('#' + $(this).parent().attr('id'), 400);
+ });
+ });
+ });
+})();
diff --git a/_includes/scripts/aside/affix.js b/_includes/scripts/aside/affix.js
new file mode 100644
index 0000000..1db3b8e
--- /dev/null
+++ b/_includes/scripts/aside/affix.js
@@ -0,0 +1,26 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $window = $(window), $pageFooter = $('.js-page-footer');
+ var $pageAside = $('.js-page-aside');
+ var affix;
+ var tocDisabled = false;
+ var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
+
+ affix = $pageAside.affix({
+ offsetBottom: $pageFooter.outerHeight(),
+ scrollTarget: hasSidebar ? '.js-page-main' : null,
+ scroller: hasSidebar ? '.js-page-main' : null,
+ scroll: hasSidebar ? $('.js-page-main').children() : null,
+ disabled: tocDisabled
+ });
+
+ $window.on('resize', window.throttle(function() {
+ affix && affix.setOptions({
+ disabled: tocDisabled
+ });
+ }, 100));
+
+ window.pageAsideAffix = affix;
+ });
+})();
diff --git a/_includes/scripts/aside/toc.js b/_includes/scripts/aside/toc.js
new file mode 100644
index 0000000..a19ea95
--- /dev/null
+++ b/_includes/scripts/aside/toc.js
@@ -0,0 +1,35 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ var TOC_SELECTOR = window.TEXT_VARIABLES.site.toc.selectors;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $window = $(window);
+ var $articleContent = $('.js-article-content');
+ var $tocRoot = $('.js-toc-root'), $col2 = $('.js-col-aside');
+ var toc;
+ var tocDisabled = false;
+ var hasSidebar = $('.js-page-root').hasClass('layout--page--sidebar');
+ var hasToc = $articleContent.find(TOC_SELECTOR).length > 0;
+
+ function disabled() {
+ return $col2.css('display') === 'none' || !hasToc;
+ }
+
+ tocDisabled = disabled();
+
+ toc = $tocRoot.toc({
+ selectors: TOC_SELECTOR,
+ container: $articleContent,
+ scrollTarget: hasSidebar ? '.js-page-main' : null,
+ scroller: hasSidebar ? '.js-page-main' : null,
+ disabled: tocDisabled
+ });
+
+ $window.on('resize', window.throttle(function() {
+ tocDisabled = disabled();
+ toc && toc.setOptions({
+ disabled: tocDisabled
+ });
+ }, 100));
+
+ });
+})();
diff --git a/_includes/scripts/common.js b/_includes/scripts/common.js
new file mode 100644
index 0000000..09400a2
--- /dev/null
+++ b/_includes/scripts/common.js
@@ -0,0 +1,7 @@
+(function () {
+ var $root = document.getElementsByClassName('root')[0];
+ if (window.hasEvent('touchstart')) {
+ $root.dataset.isTouch = true;
+ document.addEventListener('touchstart', function(){}, false);
+ }
+})();
diff --git a/_includes/scripts/components/lightbox.js b/_includes/scripts/components/lightbox.js
new file mode 100644
index 0000000..51689c2
--- /dev/null
+++ b/_includes/scripts/components/lightbox.js
@@ -0,0 +1,49 @@
+{%- include scripts/utils/imagesLoad.js -%}
+(function () {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $pageGalleryModal = $('.js-page-gallery-modal');
+ var $images = $('.page__content').find('img:not(.lightbox-ignore)');
+ window.imagesLoad($images).then(function() {
+ /* global Gallery */
+ var pageGalleryModal = $pageGalleryModal.modal({ onChange: handleModalChange });
+ var gallery = null;
+ var modalVisible = false;
+ var i, items = [], image, item;
+ if($images && $images.length > 0) {
+ for (i = 0; i < $images.length; i++) {
+ image = $images.eq(i);
+ if (image.get(0).naturalWidth > 800) {
+ items.push({ src: image.attr('src'), w: image.get(0).naturalWidth, h: image.get(0).naturalHeight, $el: image});
+ }
+ }
+ }
+
+ if(items.length > 0) {
+ gallery = new Gallery('.gallery', items);
+ gallery.setOptions({ disabled: !modalVisible });
+ gallery.init();
+ for (i = 0; i < items.length; i++) {
+ item = items[i];
+ item.$el && (item.$el.addClass('popup-image'), item.$el.on('click', (function() {
+ var index = i;
+ return function() {
+ pageGalleryModal.show();
+ gallery.setOptions({ initialSlide: index });
+ gallery.refresh(true, { animation: false });
+ };
+ })()));
+ }
+ }
+
+ function handleModalChange(visible) {
+ modalVisible = visible;
+ gallery && gallery.setOptions({ disabled: !modalVisible });
+ }
+
+ $pageGalleryModal.on('click', function() {
+ pageGalleryModal.hide();
+ });
+ });
+ });
+})();
diff --git a/_includes/scripts/components/search.js b/_includes/scripts/components/search.js
new file mode 100644
index 0000000..e1c8c27
--- /dev/null
+++ b/_includes/scripts/components/search.js
@@ -0,0 +1,86 @@
+
+(function () {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ // search panel
+ var search = (window.search || (window.search = {}));
+ var useDefaultSearchBox = window.useDefaultSearchBox === undefined ?
+ true : window.useDefaultSearchBox ;
+
+ var $searchModal = $('.js-page-search-modal');
+ var $searchToggle = $('.js-search-toggle');
+ var searchModal = $searchModal.modal({ onChange: handleModalChange, hideWhenWindowScroll: true });
+ var modalVisible = false;
+ search.searchModal = searchModal;
+
+ var $searchBox = null;
+ var $searchInput = null;
+ var $searchClear = null;
+
+ function getModalVisible() {
+ return modalVisible;
+ }
+ search.getModalVisible = getModalVisible;
+
+ function handleModalChange(visible) {
+ modalVisible = visible;
+ if (visible) {
+ search.onShow && search.onShow();
+ useDefaultSearchBox && $searchInput[0] && $searchInput[0].focus();
+ } else {
+ search.onShow && search.onHide();
+ useDefaultSearchBox && $searchInput[0] && $searchInput[0].blur();
+ setTimeout(function() {
+ useDefaultSearchBox && ($searchInput.val(''), $searchBox.removeClass('not-empty'));
+ search.clear && search.clear();
+ window.pageAsideAffix && window.pageAsideAffix.refresh();
+ }, 400);
+ }
+ }
+
+ $searchToggle.on('click', function() {
+ modalVisible ? searchModal.hide() : searchModal.show();
+ });
+ // Char Code: 83 S, 191 /
+ $(window).on('keyup', function(e) {
+ if (!modalVisible && !window.isFormElement(e.target || e.srcElement) && (e.which === 83 || e.which === 191)) {
+ modalVisible || searchModal.show();
+ }
+ });
+
+ if (useDefaultSearchBox) {
+ $searchBox = $('.js-search-box');
+ $searchInput = $searchBox.children('input');
+ $searchClear = $searchBox.children('.js-icon-clear');
+ search.getSearchInput = function() {
+ return $searchInput.get(0);
+ };
+ search.getVal = function() {
+ return $searchInput.val();
+ };
+ search.setVal = function(val) {
+ $searchInput.val(val);
+ };
+
+ $searchInput.on('focus', function() {
+ $(this).addClass('focus');
+ });
+ $searchInput.on('blur', function() {
+ $(this).removeClass('focus');
+ });
+ $searchInput.on('input', window.throttle(function() {
+ var val = $(this).val();
+ if (val === '' || typeof val !== 'string') {
+ search.clear && search.clear();
+ } else {
+ $searchBox.addClass('not-empty');
+ search.onInputNotEmpty && search.onInputNotEmpty(val);
+ }
+ }, 400));
+ $searchClear.on('click', function() {
+ $searchInput.val(''); $searchBox.removeClass('not-empty');
+ search.clear && search.clear();
+ });
+ }
+ });
+})();
diff --git a/_includes/scripts/components/sidebar.js b/_includes/scripts/components/sidebar.js
new file mode 100644
index 0000000..92c5591
--- /dev/null
+++ b/_includes/scripts/components/sidebar.js
@@ -0,0 +1,30 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $pageMask = $('.js-page-mask');
+ var $pageRoot = $('.js-page-root');
+ var $sidebarShow = $('.js-sidebar-show');
+ var $sidebarHide = $('.js-sidebar-hide');
+
+ function freeze(e) {
+ if (e.target === $pageMask[0]) {
+ e.preventDefault();
+ }
+ }
+ function stopBodyScrolling(bool) {
+ if (bool === true) {
+ window.addEventListener('touchmove', freeze, { passive: false });
+ } else {
+ window.removeEventListener('touchmove', freeze, { passive: false });
+ }
+ }
+
+ $sidebarShow.on('click', function() {
+ stopBodyScrolling(true); $pageRoot.addClass('show-sidebar');
+ });
+ $sidebarHide.on('click', function() {
+ stopBodyScrolling(false); $pageRoot.removeClass('show-sidebar');
+ });
+ });
+})();
diff --git a/_includes/scripts/home.js b/_includes/scripts/home.js
new file mode 100644
index 0000000..91d05b9
--- /dev/null
+++ b/_includes/scripts/home.js
@@ -0,0 +1,3 @@
+/*(function () {
+
+})();*/
diff --git a/_includes/scripts/lib/affix.js b/_includes/scripts/lib/affix.js
new file mode 100644
index 0000000..779442f
--- /dev/null
+++ b/_includes/scripts/lib/affix.js
@@ -0,0 +1,111 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ function affix(options) {
+ var $root = this, $window = $(window), $scrollTarget, $scroll,
+ offsetBottom = 0, scrollTarget = window, scroll = window.document, disabled = false, isOverallScroller = true,
+ rootTop, rootLeft, rootHeight, scrollBottom, rootBottomTop,
+ hasInit = false, curState;
+
+ function setOptions(options) {
+ var _options = options || {};
+ _options.offsetBottom && (offsetBottom = _options.offsetBottom);
+ _options.scrollTarget && (scrollTarget = _options.scrollTarget);
+ _options.scroll && (scroll = _options.scroll);
+ _options.disabled !== undefined && (disabled = _options.disabled);
+ $scrollTarget = $(scrollTarget);
+ isOverallScroller = window.isOverallScroller($scrollTarget[0]);
+ $scroll = $(scroll);
+ }
+ function preCalc() {
+ top();
+ rootHeight = $root.outerHeight();
+ rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
+ rootLeft = $root.offset().left;
+ }
+ function calc(needPreCalc) {
+ needPreCalc && preCalc();
+ scrollBottom = $scroll.outerHeight() - offsetBottom - rootHeight;
+ rootBottomTop = scrollBottom - rootTop;
+ }
+ function top() {
+ if (curState !== 'top') {
+ $root.removeClass('fixed').css({
+ left: 0,
+ top: 0
+ });
+ curState = 'top';
+ }
+ }
+ function fixed() {
+ if (curState !== 'fixed') {
+ $root.addClass('fixed').css({
+ left: rootLeft + 'px',
+ top: 0
+ });
+ curState = 'fixed';
+ }
+ }
+ function bottom() {
+ if (curState !== 'bottom') {
+ $root.removeClass('fixed').css({
+ left: 0,
+ top: rootBottomTop + 'px'
+ });
+ curState = 'bottom';
+ }
+ }
+ function setState() {
+ var scrollTop = $scrollTarget.scrollTop();
+ if (scrollTop >= rootTop && scrollTop <= scrollBottom) {
+ fixed();
+ } else if (scrollTop < rootTop) {
+ top();
+ } else {
+ bottom();
+ }
+ }
+ function init() {
+ if(!hasInit) {
+ var interval, timeout;
+ calc(true); setState();
+ // run calc every 100 millisecond
+ interval = setInterval(function() {
+ calc();
+ }, 100);
+ timeout = setTimeout(function() {
+ clearInterval(interval);
+ }, 45000);
+ window.pageLoad.then(function() {
+ setTimeout(function() {
+ clearInterval(interval);
+ clearTimeout(timeout);
+ }, 3000);
+ });
+ $scrollTarget.on('scroll', function() {
+ disabled || setState();
+ });
+ $window.on('resize', function() {
+ disabled || (calc(true), setState());
+ });
+ hasInit = true;
+ }
+ }
+
+ setOptions(options);
+ if (!disabled) {
+ init();
+ }
+ $window.on('resize', window.throttle(function() {
+ init();
+ }, 200));
+ return {
+ setOptions: setOptions,
+ refresh: function() {
+ calc(true, { animation: false }); setState();
+ }
+ };
+ }
+ $.fn.affix = affix;
+ });
+})();
diff --git a/_includes/scripts/lib/gallery.js b/_includes/scripts/lib/gallery.js
new file mode 100644
index 0000000..1793f04
--- /dev/null
+++ b/_includes/scripts/lib/gallery.js
@@ -0,0 +1,192 @@
+(function() {
+ {%- include scripts/lib/swiper.js -%}
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var template =
+ '<div class="swiper gallery__swiper">' +
+ '<div class="swiper__wrapper">' +
+ '</div>' +
+ '<div class="swiper__button swiper__button--prev fas fa-chevron-left"></div>' +
+ '<div class="swiper__button swiper__button--next fas fa-chevron-right"></div>' +
+ '</div>';
+ function setState($item, zoom, translate) {
+ $item.css('transform', 'scale(' + zoom + ') translate(' + translate.x + 'px,' + translate.y + 'px)');
+ }
+ function Gallery(root, items) {
+ this.$root = $(root);
+ this.$swiper = null;
+ this.$swiperWrapper = null;
+ this.$activeItem = null;
+ this.$items = [];
+ this.contentWidth = 0;
+ this.contentHeight = 0;
+ this.swiper = null;
+ this.items = items;
+ this.disabled = false;
+ this.curIndex = 0;
+ this.touchCenter = null;
+ this.lastTouchCenter = null;
+ this.zoomRect = null;
+ this.lastZoomRect = null;
+ this.lastTranslate = null;
+ this.translate = null;
+ this.lastZoom = 1;
+ this.preZoom = 1;
+ this.zoom = 1;
+ }
+ Gallery.prototype.init = function() {
+ var i, item, items = this.items, size, self = this, touchstartFingerCount = 0;
+ this.$root.append(template);
+ this.$swiper = this.$root.find('.gallery__swiper');
+ this.$swiperWrapper = this.$root.find('.swiper__wrapper');
+ this.contentWidth = this.$swiperWrapper && this.$swiperWrapper.width();
+ this.contentHeight = this.$swiperWrapper && this.$swiperWrapper.height();
+ for (i = 0; i < items.length; i++) {
+ item = items[i];
+ size = this._calculateImageSize(item.w, item.h);
+ this.$items.push($(
+ '<div class="swiper__slide">' +
+ '<div class="gallery-item">' +
+ '<div class="gallery-item__content">' +
+ '<img src="' + item.src + '" style="width:' + size.w + 'px;height:' + size.h + 'px"/>' +
+ '</div>' +
+ '</div>' +
+ '</div>'
+ ));
+ }
+ this.$swiperWrapper && this.$swiperWrapper.append(this.$items);
+ this.swiper = this.$swiper && this.$swiper.swiper({
+ onChangeEnd: function() {
+ self._handleChangeEnd.apply(self, Array.prototype.slice.call(arguments));
+ }
+ });
+ $(window).on('resize', function() {
+ if (self.disabled) { return; }
+ self._resizeImageSize();
+ });
+ // Char Code: 37 ⬅, 39 ➡
+ $(window).on('keyup', function(e) {
+ if (window.isFormElement(e.target || e.srcElement) || self.disabled) { return; }
+ if (e.which === 37) {
+ self.swiper && self.swiper.previous();
+ } else if (e.which === 39) {
+ self.swiper && self.swiper.next();
+ }
+ });
+ function getRect(touch0, touch1) {
+ return {
+ o: {
+ x: (touch0.pageX + touch1.pageX) / 2,
+ y: (touch0.pageY + touch1.pageY) / 2
+ },
+ w: Math.abs(touch0.pageX - touch1.pageX),
+ h: Math.abs(touch0.pageY - touch1.pageY)
+ };
+ }
+ function getTouches(e) {
+ return e.touches || e;
+ }
+ function getTouchesCount(e) {
+ if (e.touches) {
+ return e.touches.length;
+ } else {
+ return 1;
+ }
+ }
+ this.$swiperWrapper.on('touchstart', function(e) {
+ var touch0, touch1, rect;
+ touchstartFingerCount = getTouchesCount(e);
+ if (touchstartFingerCount > 1) {
+ touch0 = e.touches[0];
+ touch1 = e.touches[1];
+ rect = getRect(touch0, touch1);
+ self.lastZoomRect = { w: rect.w, h: rect.h };
+ self.lastTouchCenter = rect.o;
+ } else {
+ var touch = getTouches(e)[0];
+ self.lastTouchCenter = { x: touch.pageX, y: touch.pageY };
+ }
+ });
+ this.$swiperWrapper.on('touchmove', function(e) {
+ if (touchstartFingerCount === getTouchesCount(e)) {
+ if (touchstartFingerCount > 1) {
+ var touch0 = e.touches[0];
+ var touch1 = e.touches[1];
+ var rect = getRect(touch0, touch1);
+ self.zoomRect = { w: rect.w, h: rect.h };
+ self.touchCenter = rect.o;
+ self._zoom(); self._translate();
+ setState(self.$activeItem, self.zoom, self.translate);
+ } else {
+ var touch = getTouches(e)[0];
+ self.touchCenter = { x: touch.pageX, y: touch.pageY };
+ self._translate();
+ setState(self.$activeItem, self.zoom, self.translate);
+ }
+ }
+ });
+ this.$swiperWrapper.on('touchend', function(e) {
+ self.lastZoom = self.zoom;
+ self.lastTranslate = self.translate;
+ touchstartFingerCount = 0;
+ });
+ this.$root.on('touchmove', function(e) {
+ if (self.disabled) { return; }
+ e.preventDefault();
+ });
+ };
+
+ Gallery.prototype._translate = function() {
+ this.translate = this.touchCenter && this.lastTouchCenter && this.lastTranslate ? {
+ x: (this.touchCenter.x - this.lastTouchCenter.x) / this.zoom + this.lastTranslate.x,
+ y: (this.touchCenter.y - this.lastTouchCenter.y) / this.zoom + this.lastTranslate.y
+ } : { x: 0, y: 0 };
+ }
+ Gallery.prototype._zoom = function() {
+ this.zoom = (this.zoomRect.w + this.zoomRect.h) / (this.lastZoomRect.w + this.lastZoomRect.h) * this.lastZoom;
+ this.zoom > 1 ? this.$activeItem.addClass('zoom') : this.$activeItem.removeClass('zoom');
+ this.preZoom = this.zoom;
+ }
+
+ Gallery.prototype._calculateImageSize = function(w, h) {
+ var scale = 1;
+ if (this.contentWidth > 0 && this.contentHeight > 0 && w > 0 && h > 0) {
+ scale = Math.min(
+ Math.min(w, this.contentWidth) / w,
+ Math.min(h, this.contentHeight) / h);
+ }
+ return { w: Math.floor(w * scale), h: Math.floor(h * scale) };
+ };
+
+ Gallery.prototype._resizeImageSize = function() {
+ var i, $item, $items = this.$items, item, size;
+ this.contentWidth = this.$swiperWrapper && this.$swiperWrapper.width();
+ this.contentHeight = this.$swiperWrapper && this.$swiperWrapper.height();
+ if ($items.length < 1) { return; }
+ for (i = 0; i < $items.length; i++) {
+ item = this.items[i], $item = $items[i];
+ size = this._calculateImageSize(item.w, item.h);
+ item.width = size.w; item.height = size.h;
+ $item && $item.find('img').css({ width: size.w, height: size.h });
+ }
+ };
+ Gallery.prototype._handleChangeEnd = function(index, $dom, preIndex, $preDom) {
+ this.curIndex = index;
+ this.lastZoomRect = null; this.lastZoomRect = null;
+ this.lastTranslate = this.translate = { x: 0, y:0 };
+ this.lastZoom = this.preZoom = this.zoom = 1;
+ this.$activeItem = $dom.find('.gallery-item__content');
+ setState($preDom.find('.gallery-item__content'), this.zoom, this.translate);
+ };
+
+ Gallery.prototype.refresh = function() {
+ this.swiper && this.swiper.refresh();
+ this._resizeImageSize();
+ };
+ Gallery.prototype.setOptions = function(options) {
+ this.disabled = options.disabled;
+ this.swiper && this.swiper.setOptions(options);
+ };
+ window.Gallery = Gallery;
+ });
+})(); \ No newline at end of file
diff --git a/_includes/scripts/lib/lazyload.js b/_includes/scripts/lib/lazyload.js
new file mode 100644
index 0000000..9911535
--- /dev/null
+++ b/_includes/scripts/lib/lazyload.js
@@ -0,0 +1,143 @@
+(function() {
+ var Set = (function() {
+ var add = function(item) {
+ var i, data = this._data;
+ for (i = 0; i < data.length; i++) {
+ if (data[i] === item) {
+ return;
+ }
+ }
+ this.size ++;
+ data.push(item);
+ return data;
+ };
+
+ var Set = function(data) {
+ this.size = 0;
+ this._data = [];
+ var i;
+ if (data.length > 0) {
+ for (i = 0; i < data.length; i++) {
+ add.call(this, data[i]);
+ }
+ }
+ };
+ Set.prototype.add = add;
+ Set.prototype.get = function(index) { return this._data[index]; };
+ Set.prototype.has = function(item) {
+ var i, data = this._data;
+ for (i = 0; i < data.length; i++) {
+ if (this.get(i) === item) {
+ return true;
+ }
+ }
+ return false;
+ };
+ Set.prototype.is = function(map) {
+ if (map._data.length !== this._data.length) { return false; }
+ var i, j, flag, tData = this._data, mData = map._data;
+ for (i = 0; i < tData.length; i++) {
+ for (flag = false, j = 0; j < mData.length; j++) {
+ if (tData[i] === mData[j]) {
+ flag = true;
+ break;
+ }
+ }
+ if (!flag) { return false; }
+ }
+ return true;
+ };
+ Set.prototype.values = function() {
+ return this._data;
+ };
+ return Set;
+ })();
+
+ window.Lazyload = (function(doc) {
+ var queue = {js: [], css: []}, sources = {js: {}, css: {}}, context = this;
+ var createNode = function(name, attrs) {
+ var node = doc.createElement(name), attr;
+ for (attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ node.setAttribute(attr, attrs[attr]);
+ }
+ }
+ return node;
+ };
+ var end = function(type, url) {
+ var s, q, qi, cbs, i, j, cur, val, flag;
+ if (type === 'js' || type ==='css') {
+ s = sources[type], q = queue[type];
+ s[url] = true;
+ for (i = 0; i < q.length; i++) {
+ cur = q[i];
+ if (cur.urls.has(url)) {
+ qi = cur, val = qi.urls.values();
+ qi && (cbs = qi.callbacks);
+ for (flag = true, j = 0; j < val.length; j++) {
+ cur = val[j];
+ if (!s[cur]) {
+ flag = false;
+ }
+ }
+ if (flag && cbs && cbs.length > 0) {
+ for (j = 0; j < cbs.length; j++) {
+ cbs[j].call(context);
+ }
+ qi.load = true;
+ }
+ }
+ }
+ }
+ };
+ var load = function(type, urls, callback) {
+ var s, q, qi, node, i, cur,
+ _urls = typeof urls === 'string' ? new Set([urls]) : new Set(urls), val, url;
+ if (type === 'js' || type ==='css') {
+ s = sources[type], q = queue[type];
+ for (i = 0; i < q.length; i++) {
+ cur = q[i];
+ if (_urls.is(cur.urls)) {
+ qi = cur;
+ break;
+ }
+ }
+ val = _urls.values();
+ if (qi) {
+ callback && (qi.load || qi.callbacks.push(callback));
+ callback && (qi.load && callback());
+ } else {
+ q.push({
+ urls: _urls,
+ callbacks: callback ? [callback] : [],
+ load: false
+ });
+ for (i = 0; i < val.length; i++) {
+ node = null, url = val[i];
+ if (s[url] === undefined) {
+ (type === 'js' ) && (node = createNode('script', { src: url }));
+ (type === 'css') && (node = createNode('link', { rel: 'stylesheet', href: url }));
+ if (node) {
+ node.onload = (function(type, url) {
+ return function() {
+ end(type, url);
+ };
+ })(type, url);
+ (doc.head || doc.body).appendChild(node);
+ s[url] = false;
+ }
+ }
+ }
+ }
+ }
+ };
+ return {
+ js: function(url, callback) {
+ load('js', url, callback);
+ },
+ css: function(url, callback) {
+ load('css', url, callback);
+ }
+ };
+ })(this.document);
+})();
diff --git a/_includes/scripts/lib/modal.js b/_includes/scripts/lib/modal.js
new file mode 100644
index 0000000..cb5d188
--- /dev/null
+++ b/_includes/scripts/lib/modal.js
@@ -0,0 +1,64 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ var $body = $('body'), $window = $(window);
+ var $pageRoot = $('.js-page-root'), $pageMain = $('.js-page-main');
+ var activeCount = 0;
+ function modal(options) {
+ var $root = this, visible, onChange, hideWhenWindowScroll = false;
+ var scrollTop;
+ function setOptions(options) {
+ var _options = options || {};
+ visible = _options.initialVisible === undefined ? false : show;
+ onChange = _options.onChange;
+ hideWhenWindowScroll = _options.hideWhenWindowScroll;
+ }
+ function init() {
+ setState(visible);
+ }
+ function setState(isShow) {
+ if (isShow === visible) {
+ return;
+ }
+ visible = isShow;
+ if (visible) {
+ activeCount++;
+ scrollTop = $(window).scrollTop() || $pageMain.scrollTop();
+ $root.addClass('modal--show');
+ $pageMain.scrollTop(scrollTop);
+ activeCount === 1 && ($pageRoot.addClass('show-modal'), $body.addClass('of-hidden'));
+ hideWhenWindowScroll && window.hasEvent('touchstart') && $window.on('scroll', hide);
+ $window.on('keyup', handleKeyup);
+ } else {
+ activeCount > 0 && activeCount--;
+ $root.removeClass('modal--show');
+ $window.scrollTop(scrollTop);
+ activeCount === 0 && ($pageRoot.removeClass('show-modal'), $body.removeClass('of-hidden'));
+ hideWhenWindowScroll && window.hasEvent('touchstart') && $window.off('scroll', hide);
+ $window.off('keyup', handleKeyup);
+ }
+ onChange && onChange(visible);
+ }
+ function show() {
+ setState(true);
+ }
+ function hide() {
+ setState(false);
+ }
+ function handleKeyup(e) {
+ // Char Code: 27 ESC
+ if (e.which === 27) {
+ hide();
+ }
+ }
+ setOptions(options);
+ init();
+ return {
+ show: show,
+ hide: hide,
+ $el: $root
+ };
+ }
+ $.fn.modal = modal;
+ });
+})();
diff --git a/_includes/scripts/lib/scroll-to.js b/_includes/scripts/lib/scroll-to.js
new file mode 100644
index 0000000..e5a0ea2
--- /dev/null
+++ b/_includes/scripts/lib/scroll-to.js
@@ -0,0 +1,13 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ function scrollToAnchor(anchor, duration, callback) {
+ var $root = this;
+ $root.animate({ scrollTop: $(anchor).position().top }, duration, function() {
+ window.history.replaceState(null, '', window.location.href.split('#')[0] + anchor);
+ callback && callback();
+ });
+ }
+ $.fn.scrollToAnchor = scrollToAnchor;
+ });
+})();
diff --git a/_includes/scripts/lib/swiper.js b/_includes/scripts/lib/swiper.js
new file mode 100644
index 0000000..3d06419
--- /dev/null
+++ b/_includes/scripts/lib/swiper.js
@@ -0,0 +1,203 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ function swiper(options) {
+ var $window = $(window), $root = this, $swiperWrapper, $swiperSlides, $swiperButtonPrev, $swiperButtonNext,
+ initialSlide, animation, onChange, onChangeEnd,
+ rootWidth, count, preIndex, curIndex, translateX, CRITICAL_ANGLE = Math.PI / 3;
+
+ function setOptions(options) {
+ var _options = options || {};
+ initialSlide = _options.initialSlide || 0;
+ animation = _options.animation === undefined && true;
+ onChange = onChange || _options.onChange;
+ onChangeEnd = onChangeEnd || _options.onChangeEnd;
+ }
+
+ function init() {
+ $swiperWrapper = $root.find('.swiper__wrapper');
+ $swiperSlides = $root.find('.swiper__slide');
+ $swiperButtonPrev = $root.find('.swiper__button--prev');
+ $swiperButtonNext = $root.find('.swiper__button--next');
+ animation && $swiperWrapper.addClass('swiper__wrapper--animation');
+ calc(true);
+ }
+
+ function preCalc() {
+ rootWidth = $root.width();
+ count = $swiperWrapper.children('.swiper__slide').length;
+ if (count < 2) {
+ $swiperButtonPrev.addClass('d-none');
+ $swiperButtonNext.addClass('d-none');
+ }
+ curIndex = initialSlide || 0;
+ translateX = getTranslateXFromCurIndex();
+ }
+
+ var calc = (function() {
+ var preAnimation, $swiperSlide, $preSwiperSlide;
+ return function (needPreCalc, params) {
+ needPreCalc && preCalc();
+ var _animation = (params && params.animation !== undefined) ? params.animation : animation;
+ if (preAnimation === undefined || preAnimation !== _animation) {
+ preAnimation = _animation ? $swiperWrapper.addClass('swiper__wrapper--animation') :
+ $swiperWrapper.removeClass('swiper__wrapper--animation');
+ }
+ if (preIndex !== curIndex) {
+ ($preSwiperSlide = $swiperSlides.eq(preIndex)).removeClass('active');
+ ($swiperSlide = $swiperSlides.eq(curIndex)).addClass('active');
+ onChange && onChange(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
+ if (onChangeEnd) {
+ if (_animation) {
+ setTimeout(function() {
+ onChangeEnd(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
+ }, 400);
+ } else {
+ onChangeEnd(curIndex, $swiperSlides.eq(curIndex), $swiperSlide, $preSwiperSlide);
+ }
+ }
+ preIndex = curIndex;
+ }
+ $swiperWrapper.css('transform', 'translate(' + translateX + 'px, 0)');
+ if (count > 1) {
+ if (curIndex <= 0) {
+ $swiperButtonPrev.addClass('disabled');
+ } else {
+ $swiperButtonPrev.removeClass('disabled');
+ }
+ if (curIndex >= count - 1) {
+ $swiperButtonNext.addClass('disabled');
+ } else {
+ $swiperButtonNext.removeClass('disabled');
+ }
+ }
+ };
+ })();
+
+ function getTranslateXFromCurIndex() {
+ return curIndex <= 0 ? 0 : - rootWidth * curIndex;
+ }
+
+ function moveToIndex(index ,params) {
+ preIndex = curIndex;
+ curIndex = index;
+ translateX = getTranslateXFromCurIndex();
+ calc(false, params);
+ }
+
+ function move(type) {
+ var nextIndex = curIndex, unstableTranslateX;
+ if (type === 'prev') {
+ nextIndex > 0 && nextIndex--;
+ } else if (type === 'next') {
+ nextIndex < count - 1 && nextIndex++;
+ }
+ if (type === 'cur') {
+ moveToIndex(curIndex, { animation: true });
+ return;
+ }
+ unstableTranslateX = translateX % rootWidth !== 0;
+ if (nextIndex !== curIndex || unstableTranslateX) {
+ unstableTranslateX ? moveToIndex(nextIndex, { animation: true }) : moveToIndex(nextIndex);
+ }
+ }
+
+ setOptions(options);
+ init();
+ preIndex = curIndex;
+
+ $swiperButtonPrev.on('click', function(e) {
+ e.stopPropagation();
+ move('prev');
+ });
+ $swiperButtonNext.on('click', function(e) {
+ e.stopPropagation();
+ move('next');
+ });
+ $window.on('resize', function() {
+ calc(true, { animation: false });
+ });
+
+ (function() {
+ var pageX, pageY, velocityX, preTranslateX = translateX, timeStamp, touching;
+ function handleTouchstart(e) {
+ var point = e.touches ? e.touches[0] : e;
+ pageX = point.pageX;
+ pageY = point.pageY;
+ velocityX = 0;
+ preTranslateX = translateX;
+ }
+ function handleTouchmove(e) {
+ if (e.touches && e.touches.length > 1) {
+ return;
+ }
+ var point = e.touches ? e.touches[0] : e;
+ var deltaX = point.pageX - pageX;
+ var deltaY = point.pageY - pageY;
+ velocityX = deltaX / (e.timeStamp - timeStamp);
+ timeStamp = e.timeStamp;
+ if (e.cancelable && Math.abs(Math.atan(deltaY / deltaX)) < CRITICAL_ANGLE) {
+ touching = true;
+ translateX += deltaX;
+ calc(false, { animation: false });
+ }
+ pageX = point.pageX;
+ pageY = point.pageY;
+ }
+ function handleTouchend() {
+ touching = false;
+ var deltaX = translateX - preTranslateX;
+ var distance = deltaX + velocityX * rootWidth;
+ if (Math.abs(distance) > rootWidth / 2) {
+ distance > 0 ? move('prev') : move('next');
+ } else {
+ move('cur');
+ }
+ }
+ $swiperWrapper.on('touchstart', handleTouchstart);
+ $swiperWrapper.on('touchmove', handleTouchmove);
+ $swiperWrapper.on('touchend', handleTouchend);
+ $swiperWrapper.on('touchcancel', handleTouchend);
+
+ (function() {
+ var pressing = false, moved = false;
+ $swiperWrapper.on('mousedown', function(e) {
+ pressing = true; handleTouchstart(e);
+ });
+ $swiperWrapper.on('mousemove', function(e) {
+ pressing && (e.preventDefault(), moved = true, handleTouchmove(e));
+ });
+ $swiperWrapper.on('mouseup', function(e) {
+ pressing && (pressing = false, handleTouchend(e));
+ });
+ $swiperWrapper.on('mouseleave', function(e) {
+ pressing && (pressing = false, handleTouchend(e));
+ });
+ $swiperWrapper.on('click', function(e) {
+ moved && (e.stopPropagation(), moved = false);
+ });
+ })();
+
+ $root.on('touchmove', function(e) {
+ if (e.cancelable & touching) {
+ e.preventDefault();
+ }
+ });
+ })();
+
+ return {
+ setOptions: setOptions,
+ previous: function(){
+ move('prev');
+ },
+ next: function(){
+ move('next');
+ },
+ refresh: function() {
+ calc(true, { animation: false });
+ }
+ };
+ }
+ $.fn.swiper = swiper;
+ });
+})();
diff --git a/_includes/scripts/lib/throttle.js b/_includes/scripts/lib/throttle.js
new file mode 100644
index 0000000..2add23c
--- /dev/null
+++ b/_includes/scripts/lib/throttle.js
@@ -0,0 +1,28 @@
+(function() {
+ window.throttle = function(func, wait) {
+ var args, result, thisArg, timeoutId, lastCalled = 0;
+
+ function trailingCall() {
+ lastCalled = new Date;
+ timeoutId = null;
+ result = func.apply(thisArg, args);
+ }
+ return function() {
+ var now = new Date,
+ remaining = wait - (now - lastCalled);
+
+ args = arguments;
+ thisArg = this;
+
+ if (remaining <= 0) {
+ clearTimeout(timeoutId);
+ timeoutId = null;
+ lastCalled = now;
+ result = func.apply(thisArg, args);
+ } else if (!timeoutId) {
+ timeoutId = setTimeout(trailingCall, remaining);
+ }
+ return result;
+ };
+ };
+})();
diff --git a/_includes/scripts/lib/toc.js b/_includes/scripts/lib/toc.js
new file mode 100644
index 0000000..fb43857
--- /dev/null
+++ b/_includes/scripts/lib/toc.js
@@ -0,0 +1,107 @@
+(function() {
+ var SOURCES = window.TEXT_VARIABLES.sources;
+ window.Lazyload.js(SOURCES.jquery, function() {
+ function toc(options) {
+ var $root = this, $window = $(window), $scrollTarget, $scroller, $tocUl = $('<ul class="toc toc--ellipsis"></ul>'), $tocLi, $headings, $activeLast, $activeCur,
+ selectors = 'h1,h2,h3', container = 'body', scrollTarget = window, scroller = 'html, body', disabled = false,
+ headingsPos, scrolling = false, hasRendered = false, hasInit = false;
+
+ function setOptions(options) {
+ var _options = options || {};
+ _options.selectors && (selectors = _options.selectors);
+ _options.container && (container = _options.container);
+ _options.scrollTarget && (scrollTarget = _options.scrollTarget);
+ _options.scroller && (scroller = _options.scroller);
+ _options.disabled !== undefined && (disabled = _options.disabled);
+ $headings = $(container).find(selectors).filter('[id]');
+ $scrollTarget = $(scrollTarget);
+ $scroller = $(scroller);
+ }
+ function calc() {
+ headingsPos = [];
+ $headings.each(function() {
+ headingsPos.push(Math.floor($(this).position().top));
+ });
+ }
+ function setState(element, disabled) {
+ var scrollTop = $scrollTarget.scrollTop(), i;
+ if (disabled || !headingsPos || headingsPos.length < 1) { return; }
+ if (element) {
+ $activeCur = element;
+ } else {
+ for (i = 0; i < headingsPos.length; i++) {
+ if (scrollTop >= headingsPos[i]) {
+ $activeCur = $tocLi.eq(i);
+ } else {
+ $activeCur || ($activeCur = $tocLi.eq(i));
+ break;
+ }
+ }
+ }
+ $activeLast && $activeLast.removeClass('active');
+ ($activeLast = $activeCur).addClass('active');
+ }
+ function render() {
+ if(!hasRendered) {
+ $root.append($tocUl);
+ $headings.each(function() {
+ var $this = $(this);
+ $tocUl.append($('<li></li>').addClass('toc-' + $this.prop('tagName').toLowerCase())
+ .append($('<a></a>').text($this.text()).attr('href', '#' + $this.prop('id'))));
+ });
+ $tocLi = $tocUl.children('li');
+ $tocUl.on('click', 'a', function(e) {
+ e.preventDefault();
+ var $this = $(this);
+ scrolling = true;
+ setState($this.parent());
+ $scroller.scrollToAnchor($this.attr('href'), 400, function() {
+ scrolling = false;
+ });
+ });
+ }
+ hasRendered = true;
+ }
+ function init() {
+ var interval, timeout;
+ if(!hasInit) {
+ render(); calc(); setState(null, scrolling);
+ // run calc every 100 millisecond
+ interval = setInterval(function() {
+ calc();
+ }, 100);
+ timeout = setTimeout(function() {
+ clearInterval(interval);
+ }, 45000);
+ window.pageLoad.then(function() {
+ setTimeout(function() {
+ clearInterval(interval);
+ clearTimeout(timeout);
+ }, 3000);
+ });
+ $scrollTarget.on('scroll', function() {
+ disabled || setState(null, scrolling);
+ });
+ $window.on('resize', window.throttle(function() {
+ if (!disabled) {
+ render(); calc(); setState(null, scrolling);
+ }
+ }, 100));
+ }
+ hasInit = true;
+ }
+
+ setOptions(options);
+ if (!disabled) {
+ init();
+ }
+ $window.on('resize', window.throttle(function() {
+ init();
+ }, 200));
+ return {
+ setOptions: setOptions
+ };
+ }
+ $.fn.toc = toc;
+ });
+})();
diff --git a/_includes/scripts/page.js b/_includes/scripts/page.js
new file mode 100644
index 0000000..91d05b9
--- /dev/null
+++ b/_includes/scripts/page.js
@@ -0,0 +1,3 @@
+/*(function () {
+
+})();*/
diff --git a/_includes/scripts/utils/imagesLoad.js b/_includes/scripts/utils/imagesLoad.js
new file mode 100644
index 0000000..63a6bdf
--- /dev/null
+++ b/_includes/scripts/utils/imagesLoad.js
@@ -0,0 +1,28 @@
+(function() {
+ window.imagesLoad = function(images) {
+ images = images || document.getElementsByTagName('img');
+ var imagesCount = images.length, loadedCount = 0, image;
+ var i, j, loaded = false, cbs = [];
+ imagesCount < 1 && (loaded = true);
+ for (i = 0; i < imagesCount; i++) {
+ image = images[i];
+ image.complete ? handleImageLoad() : image.addEventListener('load', handleImageLoad);
+ }
+ function handleImageLoad() {
+ loadedCount++;
+ if (loadedCount === imagesCount) {
+ loaded = true;
+ if (cbs.length > 0) {
+ for (j = 0; j < cbs.length; j++) {
+ cbs[j]();
+ }
+ }
+ }
+ }
+ return {
+ then: function(cb) {
+ cb && (loaded ? cb() : (cbs.push(cb)));
+ }
+ };
+ };
+})();
diff --git a/_includes/scripts/utils/utils.js b/_includes/scripts/utils/utils.js
new file mode 100644
index 0000000..e7bce45
--- /dev/null
+++ b/_includes/scripts/utils/utils.js
@@ -0,0 +1,39 @@
+(function() {
+ window.isArray = function(val) {
+ return Object.prototype.toString.call(val) === '[object Array]';
+ };
+ window.isString = function(val) {
+ return typeof val === 'string';
+ };
+
+ window.hasEvent = function(event) {
+ return 'on'.concat(event) in window.document;
+ };
+
+ window.isOverallScroller = function(node) {
+ return node === document.documentElement || node === document.body || node === window;
+ };
+
+ window.isFormElement = function(node) {
+ var tagName = node.tagName;
+ return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
+ };
+
+ window.pageLoad = (function () {
+ var loaded = false, cbs = [];
+ window.addEventListener('load', function () {
+ var i;
+ loaded = true;
+ if (cbs.length > 0) {
+ for (i = 0; i < cbs.length; i++) {
+ cbs[i]();
+ }
+ }
+ });
+ return {
+ then: function(cb) {
+ cb && (loaded ? cb() : (cbs.push(cb)));
+ }
+ };
+ })();
+})();
diff --git a/_includes/scripts/variables.html b/_includes/scripts/variables.html
new file mode 100644
index 0000000..5bd1770
--- /dev/null
+++ b/_includes/scripts/variables.html
@@ -0,0 +1,35 @@
+{%- include snippets/get-sources.html -%}
+{%- assign _sources = __return -%}
+
+{%- include snippets/get-nav-url.html path="/assets/search.js" -%}
+{%- assign _paths_search_js = __return -%}
+
+<script>
+ (function() {
+ var TEXT_VARIABLES = {
+ version: '2.2.6',
+ sources: {
+ font_awesome: '{{ _sources.font_awesome }}',
+ jquery: '{{ _sources.jquery }}',
+ leancloud_js_sdk: '{{ _sources.leancloud_js_sdk }}',
+ chart: '{{ _sources.chart }}',
+ gitalk: {
+ js: '{{ _sources.gitalk.js }}',
+ css: '{{ _sources.gitalk.css }}'
+ },
+ valine: '{{ _sources.valine }}',
+ mathjax: '{{ _sources.mathjax }}',
+ mermaid: '{{ _sources.mermaid }}'
+ },
+ site: {
+ toc: {
+ selectors: '{{ site.toc.selectors | default: site.data.variables.default.toc.selectors }}'
+ }
+ },
+ paths: {
+ search_js: '{{ _paths_search_js }}'
+ }
+ };
+ window.TEXT_VARIABLES = TEXT_VARIABLES;
+ })();
+</script>