|
32 | 32 | } |
33 | 33 | </style> |
34 | 34 | <script> |
| 35 | + function debounce(func, delay) { |
| 36 | + let timeout; |
| 37 | + return function(...args) { |
| 38 | + const context = this; |
| 39 | + clearTimeout(timeout); |
| 40 | + timeout = setTimeout(() => { |
| 41 | + func.apply(context, args); |
| 42 | + }, delay); |
| 43 | + }; |
| 44 | + } |
35 | 45 | let includeSearchQuery = ""; |
36 | 46 | let excludeSearchQuery = ""; |
37 | 47 |
|
38 | | - async function onExcludeSearchInput(event) { |
39 | | - excludeSearchQuery = event.currentTarget.value.toLowerCase(); |
40 | | - onSearchInput(event); |
41 | | - } |
42 | | -
|
43 | | - async function onIncludeSearchInput(event) { |
44 | | - includeSearchQuery = event.currentTarget.value.toLowerCase(); |
45 | | - onSearchInput(event); |
46 | | - } |
47 | | -
|
48 | 48 | async function onSearchInput(event) { |
49 | 49 | const sidebar = document.querySelectorAll(".sidebar li"); |
50 | 50 | const content = document.querySelectorAll(".content .diff-content"); |
| 51 | + const searchingIcon = document.getElementById("searching_icon"); |
| 52 | +
|
| 53 | + searchingIcon.style.display = "inline-block"; |
| 54 | +
|
| 55 | + let emptySearch = true; |
51 | 56 |
|
52 | 57 | sidebar.forEach(async function(item) { |
53 | 58 | const text = item.textContent.toLowerCase(); |
54 | 59 | const shouldInclude = includeSearchQuery === "" || text.includes(includeSearchQuery); |
55 | 60 | const shouldExclude = excludeSearchQuery !== "" && text.includes(excludeSearchQuery); |
| 61 | + const associatedId = item.querySelector("a").getAttribute("href").substring(1) |
| 62 | + const contentItem = document.getElementById(associatedId); |
56 | 63 |
|
57 | 64 | if (shouldInclude) { |
58 | 65 | if (shouldExclude) { |
59 | 66 | item.style.display = "none"; |
| 67 | + contentItem.style.display = "none"; |
60 | 68 | } else { |
61 | 69 | item.style.display = "list-item"; |
| 70 | + contentItem.style.display = "block"; |
| 71 | + emptySearch = false; |
62 | 72 | } |
63 | 73 | } else { |
64 | 74 | item.style.display = "none"; |
| 75 | + contentItem.style.display = "none"; |
65 | 76 | } |
66 | 77 |
|
67 | 78 | }); |
68 | 79 |
|
69 | | - content.forEach(async function(item) { |
70 | | - const filename = document.getElementById(item.id + "_filename"); |
71 | | - const text = filename.dataset.replacedPaths.toLowerCase(); |
72 | | - const shouldInclude = includeSearchQuery === "" || text.includes(includeSearchQuery); |
73 | | - const shouldExclude = excludeSearchQuery !== "" && text.includes(excludeSearchQuery); |
| 80 | + searchingIcon.style.display = "none"; |
| 81 | + const emptySearchTag = document.getElementById("empty_search"); |
| 82 | + if (emptySearch) { |
| 83 | + emptySearchTag.style.display = "block"; |
| 84 | + } else { |
| 85 | + emptySearchTag.style.display = "none"; |
| 86 | + } |
| 87 | + } |
74 | 88 |
|
75 | | - if (shouldInclude) { |
76 | | - if (shouldExclude) { |
77 | | - item.style.display = "none"; |
78 | | - } else { |
79 | | - item.style.display = "block"; |
80 | | - } |
81 | | - } else { |
82 | | - item.style.display = "none"; |
83 | | - } |
84 | | - }); |
| 89 | + const debouncedOnSearchInput = debounce(onSearchInput, 500); |
| 90 | +
|
| 91 | + async function onExcludeSearchInput(event) { |
| 92 | + excludeSearchQuery = event.currentTarget.value.toLowerCase(); |
| 93 | + debouncedOnSearchInput(event); |
| 94 | + } |
| 95 | +
|
| 96 | + async function onIncludeSearchInput(event) { |
| 97 | + includeSearchQuery = event.currentTarget.value.toLowerCase(); |
| 98 | + debouncedOnSearchInput(event); |
85 | 99 | } |
86 | 100 | </script> |
87 | 101 | </head> |
|
96 | 110 | <h2>File list:</h2> |
97 | 111 | <input type="text" id="search-include" placeholder="Include search..." oninput="onIncludeSearchInput(event)" /> |
98 | 112 | <input type="text" id="search-exclude" placeholder="Exclude search..." oninput="onExcludeSearchInput(event)" /> |
| 113 | + <span id="searching_icon" style="display:none">...</span> |
99 | 114 | <ul> |
100 | 115 | {%- for filename in content.keys() %} |
101 | 116 | <li><a href="#diff_{{- safe_filename(filename) -}}" class="side-link">{{ replace_cache_paths(filename) }}</a></li> |
102 | 117 | {%- endfor %} |
| 118 | + <span id="empty_search" style="display:none">No results found</span> |
103 | 119 | </ul> |
104 | 120 | </div> |
105 | 121 | <div class='content'> |
|
0 commit comments