|
12 | 12 | var classNone = 'none';
|
13 | 13 | var classHeader = 'header';
|
14 | 14 |
|
15 |
| - var selectorNone = '.' + classNone; |
16 |
| - var selectorNotNone = ':not(' + selectorNone + ')'; |
| 15 | + var selectorIsNone = '.' + classNone; |
| 16 | + var selectorNotNone = ':not(' + selectorIsNone + ')'; |
17 | 17 | var selectorPathList = '.path-list';
|
18 | 18 | var selectorItemList = '.item-list';
|
19 |
| - var selectorItem = selectorItemList + ' > li:not(.' + classHeader + '):not(.parent)'; |
20 |
| - var selectorItemNone = selectorItem + selectorNone; |
| 19 | + var selectorItem = 'li:not(.' + classHeader + '):not(.parent)'; |
| 20 | + var selectorItemIsNone = selectorItem + selectorIsNone; |
21 | 21 | var selectorItemNotNone = selectorItem + selectorNotNone;
|
22 | 22 |
|
23 | 23 | var leavingEvent = typeof window.onpagehide !== strUndef ? 'pagehide' : 'beforeunload';
|
|
33 | 33 | } catch (err) {
|
34 | 34 | }
|
35 | 35 |
|
| 36 | + var filteredText = ''; |
| 37 | + |
| 38 | + function matchFilter(input) { |
| 39 | + return input.toLowerCase().indexOf(filteredText) >= 0; |
| 40 | + } |
| 41 | + |
36 | 42 | var lastFocused;
|
37 | 43 |
|
38 | 44 | function enableFilter() {
|
39 |
| - // pre check |
40 | 45 | var filter = document.body.querySelector('.filter');
|
41 |
| - if (!filter) { |
42 |
| - return; |
43 |
| - } |
| 46 | + if (!filter) return; |
44 | 47 |
|
45 | 48 | var input = filter.querySelector('input');
|
46 |
| - if (!input) { |
47 |
| - return; |
48 |
| - } |
| 49 | + if (!input) return; |
49 | 50 |
|
50 | 51 | var clear = filter.querySelector('button');
|
| 52 | + if (!clear) clear = document.createElement('button'); |
| 53 | + |
| 54 | + var itemList = document.querySelector(selectorItemList) |
51 | 55 |
|
52 |
| - // event handler |
53 | 56 | var timeoutId;
|
54 |
| - var lastFilterText = ''; |
55 | 57 | var doFilter = function () {
|
56 |
| - var filterText = input.value.trim().toLowerCase(); |
57 |
| - if (filterText === lastFilterText) { |
58 |
| - return; |
59 |
| - } |
| 58 | + var filteringText = input.value.trim().toLowerCase(); |
| 59 | + if (filteringText === filteredText) return; |
60 | 60 |
|
61 |
| - var selector, items, i; |
| 61 | + var items |
| 62 | + if (filteringText) { |
| 63 | + clear.style.display = 'block'; |
62 | 64 |
|
63 |
| - if (!filterText) { // filter cleared, show all items |
64 |
| - if (clear) { |
65 |
| - clear.style.display = ''; |
66 |
| - } |
67 |
| - selector = selectorItemNone; |
68 |
| - items = document.body.querySelectorAll(selector); |
69 |
| - for (i = items.length - 1; i >= 0; i--) { |
70 |
| - items[i].classList.remove(classNone); |
71 |
| - } |
72 |
| - } else { |
73 |
| - if (clear) { |
74 |
| - clear.style.display = 'block'; |
75 |
| - } |
76 |
| - if (filterText.indexOf(lastFilterText) >= 0) { // increment search, find in visible items |
| 65 | + var selector |
| 66 | + if (filteringText.indexOf(filteredText) >= 0) { // increment search, find in visible items |
77 | 67 | selector = selectorItemNotNone;
|
78 |
| - } else if (lastFilterText.indexOf(filterText) >= 0) { // decrement search, find in hidden items |
79 |
| - selector = selectorItemNone; |
| 68 | + } else if (filteredText.indexOf(filteringText) >= 0) { // decrement search, find in hidden items |
| 69 | + selector = selectorItemIsNone; |
80 | 70 | } else {
|
81 | 71 | selector = selectorItem;
|
82 | 72 | }
|
| 73 | + filteredText = filteringText; |
83 | 74 |
|
84 |
| - items = document.body.querySelectorAll(selector); |
85 |
| - for (i = items.length - 1; i >= 0; i--) { |
86 |
| - var item = items[i]; |
| 75 | + items = itemList.querySelectorAll(selector); |
| 76 | + if (!items.forEach) items = Array.prototype.slice.call(items); // IE9+/ClassicEdge |
| 77 | + items.forEach(function (item) { |
87 | 78 | var name = item.querySelector('.name');
|
88 |
| - if (name && name.textContent.toLowerCase().indexOf(filterText) < 0) { |
89 |
| - item.classList.add(classNone); |
| 79 | + if (matchFilter(name.textContent)) { |
| 80 | + if (selector !== selectorItemNotNone) { |
| 81 | + item.classList.remove(classNone); |
| 82 | + } |
90 | 83 | } else {
|
91 |
| - item.classList.remove(classNone); |
| 84 | + if (selector !== selectorItemIsNone) { |
| 85 | + item.classList.add(classNone); |
| 86 | + } |
92 | 87 | }
|
93 |
| - } |
| 88 | + }); |
| 89 | + } else { // filter cleared, show all items |
| 90 | + clear.style.display = ''; |
| 91 | + filteredText = ''; |
| 92 | + |
| 93 | + items = itemList.querySelectorAll(selectorItemIsNone); |
| 94 | + if (!items.forEach) items = Array.prototype.slice.call(items); // IE9+/ClassicEdge |
| 95 | + items.forEach(function (item) { |
| 96 | + item.classList.remove(classNone); |
| 97 | + }); |
94 | 98 | }
|
95 |
| - |
96 |
| - lastFilterText = filterText; |
97 | 99 | };
|
98 | 100 |
|
99 | 101 | var onValueMayChange = function () {
|
100 | 102 | clearTimeout(timeoutId);
|
101 | 103 | timeoutId = setTimeout(doFilter, 350);
|
102 | 104 | };
|
103 |
| - input.addEventListener('input', onValueMayChange, false); |
104 |
| - input.addEventListener('change', onValueMayChange, false); |
| 105 | + input.addEventListener('input', onValueMayChange); |
| 106 | + input.addEventListener('change', onValueMayChange); |
105 | 107 |
|
106 | 108 | var onEnter = function () {
|
107 | 109 | clearTimeout(timeoutId);
|
|
126 | 128 | e.preventDefault();
|
127 | 129 | break;
|
128 | 130 | }
|
129 |
| - }, false); |
| 131 | + }); |
130 | 132 |
|
131 | 133 | clear && clear.addEventListener('click', function () {
|
132 | 134 | clearTimeout(timeoutId);
|
|
138 | 140 | // init
|
139 | 141 | if (hasStorage) {
|
140 | 142 | var prevSessionFilter = sessionStorage.getItem(location.pathname);
|
141 |
| - sessionStorage.removeItem(location.pathname); |
| 143 | + if (prevSessionFilter) { |
| 144 | + input.value = prevSessionFilter; |
| 145 | + } |
| 146 | + if (prevSessionFilter !== null) { |
| 147 | + sessionStorage.removeItem(location.pathname); |
| 148 | + } |
142 | 149 |
|
143 | 150 | window.addEventListener(leavingEvent, function () {
|
144 | 151 | if (input.value) {
|
145 | 152 | sessionStorage.setItem(location.pathname, input.value);
|
146 | 153 | }
|
147 |
| - }, false); |
| 154 | + }); |
148 | 155 |
|
149 |
| - if (prevSessionFilter) { |
150 |
| - input.value = prevSessionFilter; |
151 |
| - } |
152 | 156 | }
|
153 | 157 | if (input.value) {
|
154 | 158 | doFilter();
|
|
0 commit comments