diff --git a/jig-core/src/main/resources/templates/assets/glossary.js b/jig-core/src/main/resources/templates/assets/glossary.js new file mode 100644 index 000000000..d70840576 --- /dev/null +++ b/jig-core/src/main/resources/templates/assets/glossary.js @@ -0,0 +1,108 @@ +function updateArticleVisibility(controls) { + const showEmptyDescription = controls.showEmptyDescription.checked; + const kindVisibilityMap = { + "パッケージ": controls.showPackage.checked, + "クラス": controls.showClass.checked, + "メソッド": controls.showMethod.checked, + "フィールド": controls.showField.checked, + }; + + const searchKeyword = controls.searchInput.value.toLowerCase(); + const termArticles = document.getElementsByClassName("term"); + + Array.from(termArticles).forEach(term => { + const kindText = term.getElementsByClassName("kind")[0]?.textContent || ""; + + // 種類で絞り込む + if (!kindVisibilityMap[kindText]) { + term.classList.add("hidden"); + return; + } + + // 以降の判定で使用する説明文を取得 + const description = term.getElementsByClassName("description")[0]?.textContent?.toLowerCase() || ""; + + // 説明文有無での判定 + if (!showEmptyDescription && !description) { + term.classList.add("hidden"); + return; + } + // 検索キーワードでの判定(タイトルと説明文) + const title = term.getElementsByClassName("term-title")[0]?.textContent?.toLowerCase() || ""; + if (searchKeyword && !title.includes(searchKeyword) && !description.includes(searchKeyword)) { + term.classList.add("hidden"); + return; + } + + // すべての条件をパスした場合に表示 + term.classList.remove("hidden"); + }); + + // 表示が変わるのでnavも更新する + updateLetterNavigationVisibility(controls); +} + +function updateLetterNavigationVisibility(controls) { + const letterNavigations = Array.from(document.getElementsByClassName("letter-navigation")); + const showNavigation = controls.showLetterNavigation.checked; + if (!showNavigation) { + letterNavigations.forEach(nav => nav.classList.add("invisible")); + return; + } + + letterNavigations.forEach((nav, index) => { + // 1件目は無視 + if (index === 0) { + nav.classList.remove("invisible"); + return; + } + + let visibleCount = 0; + let sibling = nav.previousElementSibling; + while (sibling) { + // 表示しているものだけ対象にする + if (!sibling.classList.contains("invisible")) { + // letter-navigationはカウント対象外 + if (sibling.classList.contains("letter-navigation")) break; + visibleCount++; + // これ以上カウントする意味がないので抜ける + if (visibleCount >= 10) break; + } + sibling = sibling.previousElementSibling; + } + + // 10個以上表示するものがあったら表示する + if (visibleCount >= 10) { + nav.classList.remove("invisible"); + } else { + nav.classList.add("invisible"); + } + }); +} + +document.addEventListener("DOMContentLoaded", function () { + if (!document.body.classList.contains("glossary")) return; + + const controls = { + searchInput: document.getElementById("search-input"), + showEmptyDescription: document.getElementById("show-empty-description"), + showPackage: document.getElementById("show-package"), + showClass: document.getElementById("show-class"), + showMethod: document.getElementById("show-method"), + showField: document.getElementById("show-field"), + showLetterNavigation: document.getElementById("show-letter-navigation"), + }; + + const updateArticles = () => updateArticleVisibility(controls); + const updateNav = () => updateLetterNavigationVisibility(controls); + + controls.searchInput.addEventListener("input", updateArticles); + controls.showEmptyDescription.addEventListener("change", updateArticles); + controls.showPackage.addEventListener("change", updateArticles); + controls.showClass.addEventListener("change", updateArticles); + controls.showMethod.addEventListener("change", updateArticles); + controls.showField.addEventListener("change", updateArticles); + controls.showLetterNavigation.addEventListener("change", updateNav); + + updateNav(); +}); diff --git a/jig-core/src/main/resources/templates/assets/jig.js b/jig-core/src/main/resources/templates/assets/jig.js index 3f72e3f45..d653f3acf 100644 --- a/jig-core/src/main/resources/templates/assets/jig.js +++ b/jig-core/src/main/resources/templates/assets/jig.js @@ -98,89 +98,6 @@ window.addEventListener("popstate", function (event) { } }); -function updateArticleVisibility() { - const showEmptyDescription = document.getElementById("show-empty-description").checked; - const kindVisibilityMap = { - "パッケージ": document.getElementById("show-package").checked, - "クラス": document.getElementById("show-class").checked, - "メソッド": document.getElementById("show-method").checked, - "フィールド": document.getElementById("show-field").checked, - }; - - const searchKeyword = document.getElementById("search-input").value.toLowerCase(); - const termArticles = document.getElementsByClassName("term"); - - Array.from(termArticles).forEach(term => { - const kindText = term.getElementsByClassName("kind")[0]?.textContent || ""; - - // 種類で絞り込む - if (!kindVisibilityMap[kindText]) { - term.classList.add("hidden"); - return; - } - - // 以降の判定で使用する説明文を取得 - const description = term.getElementsByClassName("description")[0]?.textContent?.toLowerCase() || ""; - - // 説明文有無での判定 - if (!showEmptyDescription && !description) { - term.classList.add("hidden"); - return; - } - // 検索キーワードでの判定(タイトルと説明文) - const title = term.getElementsByClassName("term-title")[0]?.textContent?.toLowerCase() || ""; - if (searchKeyword && !title.includes(searchKeyword) && !description.includes(searchKeyword)) { - term.classList.add("hidden"); - return; - } - - // すべての条件をパスした場合に表示 - term.classList.remove("hidden"); - }); - - // 表示が変わるのでnavも更新する - updateLetterNavigationVisibility(); -} - -function updateLetterNavigationVisibility() { - const letterNavigations = Array.from(document.getElementsByClassName("letter-navigation")); - const showNavigation = document.getElementById("show-letter-navigation").checked; - if (!showNavigation) { - letterNavigations.forEach(nav => nav.classList.add("invisible")); - return; - } - - letterNavigations.forEach((nav, index) => { - // 1件目は無視 - if (index === 0) { - nav.classList.remove("invisible"); - return; - } - - let visibleCount = 0; - let sibling = nav.previousElementSibling; - while (sibling) { - // 表示しているものだけ対象にする - if (!sibling.classList.contains("invisible")) { - // letter-navigationはカウント対象外 - if (sibling.classList.contains("letter-navigation")) break; - visibleCount++; - // これ以上カウントする意味がないので抜ける - if (visibleCount >= 10) break; - } - sibling = sibling.previousElementSibling; - } - - // 10個以上表示するものがあったら表示する - if (visibleCount >= 10) { - nav.classList.remove("invisible"); - } else { - nav.classList.add("invisible"); - } - }); -} - - function setupSortableTables() { document.querySelectorAll("table.sortable").forEach(table => { const headers = table.querySelectorAll("thead th"); @@ -281,17 +198,7 @@ function zoomFamilyTables(baseTable, baseRow) { // ページ読み込み時のイベント // リスナーの登録はそのページだけでやる document.addEventListener("DOMContentLoaded", function () { - if (document.body.classList.contains("glossary")) { - document.getElementById("search-input").addEventListener("input", updateArticleVisibility); - document.getElementById("show-empty-description").addEventListener("change", updateArticleVisibility); - document.getElementById("show-package").addEventListener("change", updateArticleVisibility); - document.getElementById("show-class").addEventListener("change", updateArticleVisibility); - document.getElementById("show-method").addEventListener("change", updateArticleVisibility); - document.getElementById("show-field").addEventListener("change", updateArticleVisibility); - document.getElementById("show-letter-navigation").addEventListener("change", updateLetterNavigationVisibility); - - updateLetterNavigationVisibility(); - } else if (document.body.classList.contains("insight")) { + if (document.body.classList.contains("insight")) { setupSortableTables(); setupZoomIcons(); document.getElementById("cancel-zoom").addEventListener("click", cancelZoom); diff --git a/jig-core/src/main/resources/templates/glossary.html b/jig-core/src/main/resources/templates/glossary.html index 8a5b3e676..0d42f5943 100644 --- a/jig-core/src/main/resources/templates/glossary.html +++ b/jig-core/src/main/resources/templates/glossary.html @@ -65,5 +65,6 @@

名称A

+ - \ No newline at end of file +