1var SOURCES = window.TEXT_VARIABLES.sources; 2var PAHTS = window.TEXT_VARIABLES.paths; 3window.Lazyload.js([SOURCES.jquery, PAHTS.search_js], function() { 4 var search = (window.search || (window.search = {})); 5 var searchData = window.TEXT_SEARCH_DATA ? initData(window.TEXT_SEARCH_DATA) : {}; 6 7 function memorize(f) { 8 var cache = {}; 9 return function () { 10 var key = Array.prototype.join.call(arguments, ','); 11 if (key in cache) return cache[key]; 12 else return cache[key] = f.apply(this, arguments); 13 }; 14 } 15 16 function initData(data) { 17 var _data = [], i, j, key, keys, cur; 18 keys = Object.keys(data); 19 for (i = 0; i < keys.length; i++) { 20 key = keys[i], _data[key] = []; 21 for (j = 0; j < data[key].length; j++) { 22 cur = data[key][j]; 23 cur.title = window.decodeUrl(cur.title); 24 cur.url = window.decodeUrl(cur.url); 25 _data[key].push(cur); 26 } 27 } 28 return _data; 29 } 30 31 /// search 32 function searchByQuery(query) { 33 var i, j, key, keys, cur, _title, result = {}; 34 keys = Object.keys(searchData); 35 for (i = 0; i < keys.length; i++) { 36 key = keys[i]; 37 for (j = 0; j < searchData[key].length; j++) { 38 cur = searchData[key][j], _title = cur.title; 39 if ((result[key] === undefined || result[key] && result[key].length < 4 ) 40 && _title.toLowerCase().indexOf(query.toLowerCase()) >= 0) { 41 if (result[key] === undefined) { 42 result[key] = []; 43 } 44 result[key].push(cur); 45 } 46 } 47 } 48 return result; 49 } 50 51 var renderHeader = memorize(function(header) { 52 return $('<p class="search-result__header">' + header + '</p>'); 53 }); 54 55 var renderItem = function(index, title, url) { 56 return $('<li class="search-result__item" data-index="' + index + '"><a class="button" href="' + url + '">' + title + '</a></li>'); 57 }; 58 59 function render(data) { 60 if (!data) { return null; } 61 var $root = $('<ul></ul>'), i, j, key, keys, cur, itemIndex = 0; 62 keys = Object.keys(data); 63 for (i = 0; i < keys.length; i++) { 64 key = keys[i]; 65 $root.append(renderHeader(key)); 66 for (j = 0; j < data[key].length; j++) { 67 cur = data[key][j]; 68 $root.append(renderItem(itemIndex++, cur.title, cur.url)); 69 } 70 } 71 return $root; 72 } 73 74 // search box 75 var $result = $('.js-search-result'), $resultItems; 76 var lastActiveIndex, activeIndex; 77 78 function clear() { 79 $result.html(null); 80 $resultItems = $('.search-result__item'); activeIndex = 0; 81 } 82 function onInputNotEmpty(val) { 83 $result.html(render(searchByQuery(val))); 84 $resultItems = $('.search-result__item'); activeIndex = 0; 85 $resultItems.eq(0).addClass('active'); 86 } 87 88 search.clear = clear; 89 search.onInputNotEmpty = onInputNotEmpty; 90 91 function updateResultItems() { 92 lastActiveIndex >= 0 && $resultItems.eq(lastActiveIndex).removeClass('active'); 93 activeIndex >= 0 && $resultItems.eq(activeIndex).addClass('active'); 94 } 95 96 function moveActiveIndex(direction) { 97 var itemsCount = $resultItems ? $resultItems.length : 0; 98 if (itemsCount > 1) { 99 lastActiveIndex = activeIndex; 100 if (direction === 'up') { 101 activeIndex = (activeIndex - 1 + itemsCount) % itemsCount; 102 } else if (direction === 'down') { 103 activeIndex = (activeIndex + 1 + itemsCount) % itemsCount; 104 } 105 updateResultItems(); 106 } 107 } 108 109 // Char Code: 13 Enter, 37 ⬅, 38 ⬆, 39 ➡, 40 ⬇ 110 $(window).on('keyup', function(e) { 111 var modalVisible = search.getModalVisible && search.getModalVisible(); 112 if (modalVisible) { 113 if (e.which === 38) { 114 modalVisible && moveActiveIndex('up'); 115 } else if (e.which === 40) { 116 modalVisible && moveActiveIndex('down'); 117 } else if (e.which === 13) { 118 modalVisible && $resultItems && activeIndex >= 0 && $resultItems.eq(activeIndex).children('a')[0].click(); 119 } 120 } 121 }); 122 123 $result.on('mouseover', '.search-result__item > a', function() { 124 var itemIndex = $(this).parent().data('index'); 125 itemIndex >= 0 && (lastActiveIndex = activeIndex, activeIndex = itemIndex, updateResultItems()); 126 }); 127});