1document.addEventListener("DOMContentLoaded", function () { 2 // add the search form and bind the events 3 document 4 .querySelector("h1") 5 .insertAdjacentHTML( 6 "afterend", 7 [ 8 "<p>Filter entries by content:", 9 '<input type="text" value="" id="searchbox" style="width: 50%">', 10 '<input type="submit" id="searchbox-submit" value="Filter"></p>', 11 ].join("\n"), 12 ); 13 14 function doFilter() { 15 let query; 16 try { 17 query = new RegExp(document.querySelector("#searchbox").value, "i"); 18 } catch (e) { 19 return; // not a valid regex (yet) 20 } 21 // find headers for the versions (What's new in Python X.Y.Z?) 22 const h2s = document.querySelectorAll("#changelog h2"); 23 for (const h2 of h2s) { 24 let sections_found = 0; 25 // find headers for the sections (Core, Library, etc.) 26 const h3s = h2.parentNode.querySelectorAll("h3"); 27 for (const h3 of h3s) { 28 let entries_found = 0; 29 // find all the entries 30 const lis = h3.parentNode.querySelectorAll("li"); 31 for (let li of lis) { 32 // check if the query matches the entry 33 if (query.test(li.textContent)) { 34 li.style.display = "block"; 35 entries_found++; 36 } else { 37 li.style.display = "none"; 38 } 39 } 40 // if there are entries, show the section, otherwise hide it 41 if (entries_found > 0) { 42 h3.parentNode.style.display = "block"; 43 sections_found++; 44 } else { 45 h3.parentNode.style.display = "none"; 46 } 47 } 48 if (sections_found > 0) { 49 h2.parentNode.style.display = "block"; 50 } else { 51 h2.parentNode.style.display = "none"; 52 } 53 } 54 } 55 document.querySelector("#searchbox").addEventListener("keyup", doFilter); 56 document 57 .querySelector("#searchbox-submit") 58 .addEventListener("click", doFilter); 59}); 60