|
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); |
130 | | - |
131 | | - clear && clear.addEventListener('click', function () { |
132 | | - clearTimeout(timeoutId); |
133 | | - input.value = ''; |
| 131 | + }); |
| 132 | + clear.addEventListener('click', function () { |
| 133 | + onEscape(); |
134 | 134 | input.focus(); |
135 | | - doFilter(); |
136 | 135 | }); |
137 | 136 |
|
138 | 137 | // init |
139 | 138 | if (hasStorage) { |
140 | 139 | var prevSessionFilter = sessionStorage.getItem(location.pathname); |
141 | | - sessionStorage.removeItem(location.pathname); |
| 140 | + if (prevSessionFilter) { |
| 141 | + input.value = prevSessionFilter; |
| 142 | + } |
| 143 | + if (prevSessionFilter !== null) { |
| 144 | + sessionStorage.removeItem(location.pathname); |
| 145 | + } |
142 | 146 |
|
143 | 147 | window.addEventListener(leavingEvent, function () { |
144 | 148 | if (input.value) { |
145 | 149 | sessionStorage.setItem(location.pathname, input.value); |
146 | 150 | } |
147 | | - }, false); |
| 151 | + }); |
148 | 152 |
|
149 | | - if (prevSessionFilter) { |
150 | | - input.value = prevSessionFilter; |
151 | | - } |
152 | 153 | } |
153 | 154 | if (input.value) { |
154 | 155 | doFilter(); |
|
0 commit comments