jekyll-text-theme 2.0.2 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +2 -2
  3. data/_data/locale.yml +12 -0
  4. data/_includes/analytics-providers/google.html +7 -9
  5. data/_includes/article-info.html +19 -35
  6. data/_includes/article-list.html +73 -0
  7. data/_includes/author-links.html +7 -0
  8. data/_includes/header.html +13 -9
  9. data/_includes/markdown-enhancements.html +3 -3
  10. data/_includes/paginator.html +73 -72
  11. data/_includes/scripts/archieve.js +57 -160
  12. data/_includes/scripts/aside/affix.js +2 -0
  13. data/_includes/scripts/lib/affix.js +8 -6
  14. data/_includes/scripts/lib/toc.js +3 -5
  15. data/_includes/scripts/search-data.js +14 -0
  16. data/_includes/scripts/search.js +177 -0
  17. data/_includes/scripts/utils.js +1 -1
  18. data/_includes/scripts/variables.html +6 -0
  19. data/_includes/search.html +24 -0
  20. data/_includes/snippets/is_collection.html +6 -0
  21. data/_includes/snippets/prepend-baseurl.html +4 -1
  22. data/_includes/snippets/prepend-path.html +1 -0
  23. data/_includes/svg/icon/social/npm.svg +9 -0
  24. data/_includes/tags.html +2 -2
  25. data/_layouts/archive.html +3 -9
  26. data/_layouts/base.html +1 -0
  27. data/_layouts/home.html +1 -28
  28. data/_layouts/landing.html +11 -4
  29. data/_layouts/page.html +18 -8
  30. data/_sass/common/_classes.scss +1 -0
  31. data/_sass/common/_function.scss +2 -2
  32. data/_sass/common/_reset.scss +5 -5
  33. data/_sass/common/_variables.scss +22 -14
  34. data/_sass/common/classes/_animation.scss +1 -1
  35. data/_sass/common/classes/_clearfix.scss +7 -3
  36. data/_sass/common/classes/_clickable.scss +13 -13
  37. data/_sass/common/classes/_display.scss +3 -0
  38. data/_sass/common/classes/_flex.scss +131 -131
  39. data/_sass/common/classes/_grid.scss +3 -3
  40. data/_sass/common/classes/_horizontal-rules.scss +3 -3
  41. data/_sass/common/classes/_overflow.scss +3 -3
  42. data/_sass/common/classes/_spacing.scss +24 -24
  43. data/_sass/common/classes/_transform.scss +1 -1
  44. data/_sass/common/classes/_transition.scss +1 -1
  45. data/_sass/common/classes/_user-select.scss +3 -3
  46. data/_sass/common/components/_button.scss +19 -9
  47. data/_sass/common/components/_card.scss +2 -2
  48. data/_sass/common/components/_item.scss +90 -0
  49. data/_sass/common/components/_menu.scss +8 -4
  50. data/_sass/common/components/_toc.scss +7 -2
  51. data/_sass/components/_article-content.scss +25 -18
  52. data/_sass/components/_article-info.scss +2 -2
  53. data/_sass/components/_article-list.scss +3 -0
  54. data/_sass/components/_author-links.scss +3 -0
  55. data/_sass/components/_author-profile.scss +5 -5
  56. data/_sass/components/_footer.scss +13 -5
  57. data/_sass/components/_header.scss +80 -46
  58. data/_sass/components/_main.scss +3 -3
  59. data/_sass/components/_search.scss +97 -0
  60. data/_sass/components/_tags.scss +3 -2
  61. data/_sass/layout/_archive.scss +5 -82
  62. data/_sass/layout/_article.scss +2 -2
  63. data/_sass/layout/_base.scss +1 -1
  64. data/_sass/layout/_home.scss +10 -68
  65. data/_sass/layout/_landing.scss +5 -6
  66. data/_sass/layout/_page.scss +34 -12
  67. data/_sass/skins/_chocolate.scss +2 -1
  68. data/_sass/skins/_dark.scss +3 -2
  69. data/_sass/skins/_default.scss +2 -1
  70. data/_sass/skins/_forest.scss +2 -1
  71. data/_sass/skins/_ocean.scss +2 -1
  72. data/_sass/skins/_orange.scss +2 -1
  73. data/_sass/skins/highlight/tomorrow/_highlight.scss +65 -65
  74. data/_sass/skins/highlight/tomorrow/_night-blue.scss +2 -2
  75. data/_sass/skins/highlight/tomorrow/_night-bright.scss +1 -1
  76. data/_sass/skins/highlight/tomorrow/_night-eighties.scss +7 -7
  77. data/_sass/skins/highlight/tomorrow/_night.scss +1 -1
  78. data/assets/css/main.scss +4 -1
  79. data/assets/search.js +3 -0
  80. metadata +14 -3
  81. data/_includes/scripts/article-list.html +0 -25
@@ -22,32 +22,6 @@
22
22
  return queryObj;
23
23
  }
24
24
 
25
- function memorize(f) {
26
- var cache = {};
27
- return function () {
28
- var key = Array.prototype.join.call(arguments, ',');
29
- if (key in cache) return cache[key];
30
- else return cache[key] = f.apply(this, arguments);
31
- };
32
- }
33
-
34
- function initData(json) {
35
- var _data = JSON.parse(json), i, j, cur, _tags;
36
- Object.keys(_data).forEach(function(year) {
37
- for (i = 0; i < _data[year].length; i++) {
38
- cur = _data[year][i], _tags = cur.tags;
39
- cur.title = window.decodeUrl(cur.title);
40
- cur.url = window.decodeUrl(cur.url);
41
- if (_tags && _tags.length > 0) {
42
- for (j = 0; j < _tags.length; j++) {
43
- _tags[j] = window.decodeUrl(_tags[j]);
44
- }
45
- }
46
- }
47
- });
48
- return _data;
49
- }
50
-
51
25
  var setUrlQuery = (function() {
52
26
  var baseUrl = window.location.href.split('?')[0];
53
27
  return function(query) {
@@ -59,81 +33,28 @@
59
33
  };
60
34
  })();
61
35
 
62
- var data = initData('{%- include scripts/article-list.html -%}');
63
-
64
- var searchByTag = memorize(function(tag) {
65
- var i, j, cur, _tags, _tag, _data = {};
66
- Object.keys(data).forEach(function(year) {
67
- for (i = 0; i < data[year].length; i++) {
68
- cur = data[year][i], _tags = cur.tags;
69
- if (_tags && _tags.length > 0) {
70
- for (j = 0; j < _tags.length; j++) {
71
- _tag = _tags[j];
72
- if (_tag === tag) {
73
- if (!_data[year]) {
74
- _data[year] = [];
75
- }
76
- _data[year].push(cur);
77
- break;
78
- }
79
- }
80
- }
81
- }
82
- });
83
- return _data;
84
- });
85
-
86
- var searchByQuery = function(query) {
87
- var i, cur, _title, _data = { _: [] };
88
- Object.keys(data).forEach(function(year) {
89
- for (i = 0; i < data[year].length; i++) {
90
- cur = data[year][i], _title = cur.title;
91
- if (_title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
92
- _data._.push(cur);
93
- }
94
- }
95
- });
96
- return _data;
97
- };
98
-
99
36
  window.Lazyload.js(SOURCES.jquery, function() {
100
- var $root = $('.js-all');
101
- var $searchBox = $('.js-search-box');
102
- var $searchInput = $searchBox.children('input');
103
- var $searchClear = $searchBox.children('.js-icon-clear');
104
37
  var $tags = $('.js-tags');
105
- var $articleTags = $('.js-article-tag');
106
- var $tagShowAll = $('.js-tag-show-all');
38
+ var $articleTags = $tags.find('button');
39
+ var $tagShowAll = $tags.find('.tag-button--all');
107
40
  var $result = $('.js-result');
41
+ var $sections = $result.find('section');
42
+ var sectionArticles = [];
108
43
  var $lastFocusButton = null;
44
+ var sectionTopArticleIndex = [];
45
+ var hasInit = false;
109
46
 
110
- function addClass(dom, className) {
111
- dom.hasClass(className) || dom.addClass(className);
112
- }
113
- function removeClass(dom, className) {
114
- dom.hasClass(className) && dom.removeClass(className);
115
- }
116
-
117
- var renderHeading = memorize(function (year) {
118
- return $('<h2 class="year">' + year + '</h2>');
47
+ $sections.each(function() {
48
+ sectionArticles.push($(this).find('.item'));
119
49
  });
120
- var renderItem = memorize(function (key, title, date, url) {
121
- return $('<li><span class="date">' + date + '</span><a class="link" href="' + url + '">' + title + '</a></li>');
122
- });
123
- function render(data) {
124
- var $dom = $('<div></div>'), $section, $ul, i, cur;
125
- Object.keys(data).sort(function(a, b) {
126
- return b.localeCompare(a);
127
- }).forEach(function(year) {
128
- $section = $('<section></section>'), $ul = $('<ul></ul>');
129
- (year === '_') || $section.append(renderHeading(year));
130
- for (i = 0; i < data[year].length; i++) {
131
- cur = data[year][i];
132
- $ul.append(renderItem(cur.key, cur.title, cur.date, cur.url, cur.tags));
133
- }
134
- $dom.append($section.append($ul));
135
- });
136
- return $dom;
50
+
51
+ function init() {
52
+ var i, index = 0;
53
+ for (i = 0; i < $sections.length; i++) {
54
+ sectionTopArticleIndex.push(index);
55
+ index += $sections.eq(i).find('.item').length;
56
+ }
57
+ sectionTopArticleIndex.push(index);
137
58
  }
138
59
 
139
60
  function searchButtonsByTag(_tag/*raw tag*/) {
@@ -148,42 +69,49 @@
148
69
  }
149
70
  function buttonFocus(target) {
150
71
  if (target) {
151
- addClass(target, 'focus');
152
- $lastFocusButton && !$lastFocusButton.is(target) && removeClass($lastFocusButton, 'focus');
72
+ target.addClass('focus');
73
+ $lastFocusButton && !$lastFocusButton.is(target) && $lastFocusButton.removeClass('focus');
153
74
  $lastFocusButton = target;
154
75
  }
155
76
  }
156
77
 
157
- function setIsSearch() {
158
- addClass($root, 'search');
159
- }
160
- function setNotSearch() {
161
- removeClass($root, 'search');
162
- }
163
- function setIsEmpty() {
164
- removeClass($searchBox, 'not-empty');
165
- }
166
- function setNotEmpty() {
167
- addClass($searchBox, 'not-empty');
168
- }
169
- function setSearchBoxVal(val) {
170
- ($searchInput.val() === val) || $searchInput.val(val);
171
- }
172
- function clearSearchBox() {
173
- setSearchBoxVal(''); queryInput('');
174
- }
78
+ function tagSelect (tag/*raw tag*/, target) {
79
+ var result = {}, $articles;
80
+ var i, j, k, _tag;
81
+
82
+ for (i = 0; i < sectionArticles.length; i++) {
83
+ $articles = sectionArticles[i];
84
+ for (j = 0; j < $articles.length; j++) {
85
+ if (tag === '' || tag === undefined) {
86
+ result[i] || (result[i] = {});
87
+ result[i][j] = true;
88
+ } else {
89
+ var tags = $articles.eq(j).data('tags').split(',');
90
+ for (k = 0; k < tags.length; k++) {
91
+ if (tags[k] === tag) {
92
+ result[i] || (result[i] = {});
93
+ result[i][j] = true; break;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
175
99
 
176
- function showAll() {
177
- setNotSearch(); setIsEmpty(); buttonFocus($tagShowAll); setUrlQuery();
178
- $result.html(render(data));
179
- }
180
- function tagSelect(tag/*decode tag*/, target) {
181
- var _tag;
182
- if (tag === '' || tag === undefined) {
183
- showAll();
184
- } else {
185
- $result.html(render(searchByTag(tag)));
100
+ for (i = 0; i < sectionArticles.length; i++) {
101
+ result[i] && $sections.eq(i).removeClass('d-none');
102
+ result[i] || $sections.eq(i).addClass('d-none');
103
+ for (j = 0; j < sectionArticles[i].length; j++) {
104
+ if (result[i] && result[i][j]) {
105
+ sectionArticles[i].eq(j).removeClass('d-none');
106
+ } else {
107
+ sectionArticles[i].eq(j).addClass('d-none');
108
+ }
109
+ }
186
110
  }
111
+
112
+ hasInit || ($result.removeClass('d-none'), hasInit = true);
113
+
114
+
187
115
  if (target) {
188
116
  buttonFocus(target);
189
117
  _tag = target.attr('data-encode');
@@ -192,47 +120,16 @@
192
120
  } else {
193
121
  setUrlQuery('?tag=' + _tag);
194
122
  }
195
- }
196
- }
197
- function queryInput(query) {
198
- if (query === '' || typeof query !== 'string') {
199
- showAll();
200
123
  } else {
201
- $result.html(render(searchByQuery(query))); setIsSearch(); setNotEmpty(); setUrlQuery('?q=' + query);
202
-
124
+ buttonFocus(searchButtonsByTag(tag));
203
125
  }
204
126
  }
205
127
 
206
- (function() {
207
- $articleTags.removeClass('inactive');
208
- var query = queryString(), _tag = query.tag, _q = query.q;
209
- if (_tag !== undefined) {
210
- query.tag === undefined || (_tag = query.tag);
211
- tagSelect(window.decodeUrl(_tag));
212
- buttonFocus(searchButtonsByTag(_tag));
213
- } else if (_q !== undefined) {
214
- _q = window.decodeUrl(_q);
215
- queryInput(_q); setSearchBoxVal(_q);
216
- } else {
217
- showAll();
218
- }
219
- })();
220
-
128
+ var query = queryString(), _tag = query.tag;
129
+ init(); tagSelect(_tag);
221
130
  $tags.on('click', 'button', function() {
222
- tagSelect($(this).children('span').text(), $(this));
131
+ tagSelect($(this).data('encode'), $(this));
223
132
  });
224
133
 
225
- $searchInput.on('input', window.throttle(function() {
226
- queryInput($(this).val());
227
- }, 400));
228
- $searchInput.on('focus', function() {
229
- addClass($(this), 'focus');
230
- });
231
- $searchInput.on('blur', function() {
232
- removeClass($(this), 'focus');
233
- });
234
- $searchClear.on('click', function() {
235
- clearSearchBox();
236
- });
237
134
  });
238
135
  })();
@@ -20,5 +20,7 @@
20
20
  disabled: tocDisabled
21
21
  });
22
22
  }, 100));
23
+
24
+ window.pageAsideAffix = affix;
23
25
  });
24
26
  })();
@@ -15,14 +15,13 @@
15
15
  _options.disabled !== undefined && (disabled = _options.disabled);
16
16
  $scrollTarget = $(scrollTarget);
17
17
  $scroller = $(scroller);
18
- isOverallScroller = window.isOverallScroller($scroller[0]);
18
+ isOverallScroller = window.isOverallScroller($scrollTarget[0]);
19
19
  $scroll = $(scroll);
20
- calc(true);
21
20
  }
22
21
  function initData() {
23
22
  top();
24
23
  rootHeight = $root.outerHeight();
25
- rootTop = $root.offset().top + (isOverallScroller ? 0 : $scroller.scrollTop());
24
+ rootTop = $root.offset().top + (isOverallScroller ? 0 : $scrollTarget.scrollTop());
26
25
  rootLeft = $root.offset().left;
27
26
  }
28
27
  function calc(needInitData) {
@@ -77,12 +76,12 @@
77
76
  }, 100);
78
77
  timeout = setTimeout(function() {
79
78
  clearInterval(interval);
80
- }, 60000);
79
+ }, 45000);
81
80
  window.pageLoad.then(function() {
82
81
  setTimeout(function() {
83
82
  clearInterval(interval);
84
83
  clearTimeout(timeout);
85
- }, 1500);
84
+ }, 3000);
86
85
  });
87
86
  $scrollTarget.on('scroll', function() {
88
87
  disabled || setState();
@@ -104,7 +103,10 @@
104
103
  init();
105
104
  }, 200));
106
105
  return {
107
- setOptions: setOptions
106
+ setOptions: setOptions,
107
+ refresh: function() {
108
+ calc(true); setState();
109
+ }
108
110
  };
109
111
  }
110
112
  $.fn.affix = affix;
@@ -14,7 +14,6 @@
14
14
  $headings = $(container).find(selectors);
15
15
  $scrollTarget = $(scrollTarget);
16
16
  $scroller = $(scroller);
17
- calc();
18
17
  }
19
18
  function calc() {
20
19
  headingsPos = [];
@@ -23,7 +22,7 @@
23
22
  });
24
23
  }
25
24
  function setState(element, disabled) {
26
- var scrollTop = $scroller.scrollTop(), i;
25
+ var scrollTop = $scrollTarget.scrollTop(), i;
27
26
  if (disabled || !headingsPos || headingsPos.length < 1) { return; }
28
27
  if (element) {
29
28
  $activeCur = element;
@@ -71,12 +70,12 @@
71
70
  }, 100);
72
71
  timeout = setTimeout(function() {
73
72
  clearInterval(interval);
74
- }, 60000);
73
+ }, 45000);
75
74
  window.pageLoad.then(function() {
76
75
  setTimeout(function() {
77
76
  clearInterval(interval);
78
77
  clearTimeout(timeout);
79
- }, 1500);
78
+ }, 3000);
80
79
  });
81
80
  $scrollTarget.on('scroll', function() {
82
81
  disabled || setState(null, scrolling);
@@ -102,7 +101,6 @@
102
101
  setOptions: setOptions
103
102
  };
104
103
  }
105
- toc.setOptions = setOptions;
106
104
  $.fn.toc = toc;
107
105
  });
108
106
  })();
@@ -0,0 +1,14 @@
1
+ window.TEXT_SEARCH_DATA={
2
+ {%- for _collection in site.collections -%}
3
+ {%- unless forloop.first -%},{%- endunless -%}
4
+ '{{ _collection.label }}':[
5
+ {%- for _article in _collection.docs -%}
6
+ {%- unless forloop.first -%},{%- endunless -%}
7
+ {'title':'{{ _article.title | url_encode }}',
8
+ {%- include snippets/prepend-baseurl.html path=_article.url -%}
9
+ {%- assign _url = __return -%}
10
+ 'url':'{{ _url | url_encode }}'}
11
+ {%- endfor -%}
12
+ ]
13
+ {%- endfor -%}
14
+ };
@@ -0,0 +1,177 @@
1
+ var SOURCES = window.TEXT_VARIABLES.sources;
2
+ var PAHTS = window.TEXT_VARIABLES.paths;
3
+ window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() {
4
+ var searchData = window.TEXT_SEARCH_DATA ? initData(window.TEXT_SEARCH_DATA) : {};
5
+
6
+ function memorize(f) {
7
+ var cache = {};
8
+ return function () {
9
+ var key = Array.prototype.join.call(arguments, ',');
10
+ if (key in cache) return cache[key];
11
+ else return cache[key] = f.apply(this, arguments);
12
+ };
13
+ }
14
+
15
+ function initData(data) {
16
+ var _data = [], i, j, key, keys, cur;
17
+ keys = Object.keys(data);
18
+ for (i = 0; i < keys.length; i++) {
19
+ key = keys[i], _data[key] = [];
20
+ for (j = 0; j < data[key].length; j++) {
21
+ cur = data[key][j];
22
+ cur.title = window.decodeUrl(cur.title);
23
+ cur.url = window.decodeUrl(cur.url);
24
+ _data[key].push(cur);
25
+ }
26
+ }
27
+ return _data;
28
+ }
29
+
30
+ /// search
31
+ function searchByQuery(query) {
32
+ var i, j, key, keys, cur, _title, result = {};
33
+ keys = Object.keys(searchData);
34
+ for (i = 0; i < keys.length; i++) {
35
+ key = keys[i];
36
+ for (j = 0; j < searchData[key].length; j++) {
37
+ cur = searchData[key][j], _title = cur.title;
38
+ if ((result[key] === undefined || result[key] && result[key].length < 4 )
39
+ && _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) {
40
+ if (result[key] === undefined) {
41
+ result[key] = [];
42
+ }
43
+ result[key].push(cur);
44
+ }
45
+ }
46
+ }
47
+ return result;
48
+ }
49
+
50
+ var renderHeader = memorize(function(header) {
51
+ return $('<p class="search-result__header">' + header + '</p>');
52
+ });
53
+
54
+ var renderItem = function(index, title, url) {
55
+ return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>');
56
+ };
57
+
58
+ function render(data) {
59
+ if (!data) {
60
+ return null;
61
+ }
62
+ var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0;
63
+ keys = Object.keys(data);
64
+ for (i = 0; i < keys.length; i++) {
65
+ key = keys[i];
66
+ $root.append(renderHeader(key));
67
+ for (j = 0; j < data[key].length; j++) {
68
+ cur = data[key][j];
69
+ $root.append(renderItem(itemIndex++, cur.title, cur.url));
70
+ }
71
+ }
72
+ return $root;
73
+ }
74
+
75
+ // search box
76
+ var $searchBox = $('.js-search-box');
77
+ var $searchInput = $searchBox.children('input');
78
+ var $searchClear = $searchBox.children('.js-icon-clear');
79
+ var $result = $('.js-search-result'), $resultItems;
80
+ var lastActiveIndex, activeIndex;
81
+
82
+ function searchBoxEmpty() {
83
+ $searchBox.removeClass('not-empty'); $result.html(null);
84
+ $resultItems = $('.search-result__item'); activeIndex = 0;
85
+ }
86
+
87
+ $searchInput.on('input', window.throttle(function() {
88
+ var val = $(this).val();
89
+ if (val === '' || typeof val !== 'string') {
90
+ searchBoxEmpty();
91
+ } else {
92
+ $searchBox.addClass('not-empty'); $result.html(render(searchByQuery(val)));
93
+ $resultItems = $('.search-result__item'); activeIndex = 0;
94
+ $resultItems.eq(0).addClass('active');
95
+ }
96
+ }, 400));
97
+ $searchInput.on('focus', function() {
98
+ $(this).addClass('focus');
99
+ });
100
+ $searchInput.on('blur', function() {
101
+ $(this).removeClass('focus');
102
+ });
103
+ $searchClear.on('click', function() {
104
+ $searchInput.val(''); searchBoxEmpty();
105
+ });
106
+
107
+ // search panel
108
+ var $pageRoot = $('.js-page-root');
109
+ var $searchToggle = $('.js-search-toggle');
110
+ var showSearch = false;
111
+
112
+ function closeSearchPanel() {
113
+ $pageRoot.removeClass('show-search-panel');
114
+ $searchInput[0].blur();
115
+ setTimeout(function() {
116
+ $searchInput.val(''); searchBoxEmpty();
117
+ window.pageAsideAffix && window.pageAsideAffix.refresh();
118
+ }, 400);
119
+ }
120
+ function openSearchPanel() {
121
+ $pageRoot.addClass('show-search-panel');
122
+ $searchInput[0].focus();
123
+ }
124
+
125
+ // Char Code: 13 Enter, 27 ESC, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇, 83 S, 191 /
126
+ function isFormElement(e) {
127
+ var tagName = e.target.tagName || e.srcElement.tagName;
128
+ return tagName === 'INPUT' || tagName === 'SELECT' || tagName === 'TEXTAREA';
129
+ }
130
+ function charCodeFilter(e) {
131
+ return e.target === $searchInput[0] && (e.which === 13 || e.which === 27 || e.which === 38 || e.which === 40);
132
+ }
133
+
134
+ function updateResultItems() {
135
+ lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active');
136
+ activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active');
137
+ }
138
+
139
+ function moveActiveIndex(direction) {
140
+ var itemsCount = $resultItems ? $resultItems.length : 0;
141
+ if (itemsCount > 1) {
142
+ lastActiveIndex = activeIndex;
143
+ if (direction === 'up') {
144
+ activeIndex = (activeIndex - 1 + itemsCount) % itemsCount;
145
+ } else if (direction === 'down') {
146
+ activeIndex = (activeIndex + 1 + itemsCount) % itemsCount;
147
+ }
148
+ updateResultItems();
149
+ }
150
+ }
151
+
152
+ $(document).on('keyup', function(e) {
153
+ if (!isFormElement(e) || charCodeFilter(e)) {
154
+ if (e.which === 83 || e.which === 191) {
155
+ showSearch || (showSearch = true, openSearchPanel());
156
+ } else if (e.which === 27) {
157
+ showSearch && (showSearch = false, closeSearchPanel());
158
+ } else if (e.which === 38) {
159
+ showSearch && moveActiveIndex('up');
160
+ } else if (e.which === 40) {
161
+ showSearch && moveActiveIndex('down');
162
+ } else if (e.which === 13) {
163
+ showSearch && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click();
164
+ }
165
+ }
166
+ });
167
+
168
+ $result.on('mouseover', '.search-result__item > a', function() {
169
+ var itemIndex = $(this).parent().data('index');
170
+ itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems());
171
+ });
172
+
173
+ $searchToggle.on('click', function() {
174
+ showSearch = !showSearch;
175
+ showSearch ? openSearchPanel() : closeSearchPanel();
176
+ });
177
+ });